1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License
15  */
16 
17 package com.android.systemui.keyguard;
18 
19 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
20 import static android.view.RemoteAnimationTarget.MODE_CLOSING;
21 import static android.view.RemoteAnimationTarget.MODE_OPENING;
22 import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_APPEARING;
23 import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY;
24 import static android.view.WindowManager.TRANSIT_KEYGUARD_GOING_AWAY;
25 import static android.view.WindowManager.TRANSIT_KEYGUARD_OCCLUDE;
26 import static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE;
27 import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_GOING_AWAY;
28 import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER;
29 import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_OCCLUDE;
30 import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_OCCLUDE_BY_DREAM;
31 import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_UNOCCLUDE;
32 import static android.view.WindowManager.TRANSIT_OLD_NONE;
33 import static android.view.WindowManager.TRANSIT_TO_BACK;
34 import static android.view.WindowManager.TransitionFlags;
35 import static android.view.WindowManager.TransitionOldType;
36 import static android.view.WindowManager.TransitionType;
37 
38 import android.annotation.NonNull;
39 import android.app.ActivityManager;
40 import android.app.ActivityTaskManager;
41 import android.app.Service;
42 import android.app.WindowConfiguration;
43 import android.content.Intent;
44 import android.os.Binder;
45 import android.os.Bundle;
46 import android.os.Debug;
47 import android.os.IBinder;
48 import android.os.PowerManager;
49 import android.os.Process;
50 import android.os.RemoteException;
51 import android.os.Trace;
52 import android.util.ArrayMap;
53 import android.util.Log;
54 import android.util.RotationUtils;
55 import android.util.Slog;
56 import android.view.IRemoteAnimationFinishedCallback;
57 import android.view.IRemoteAnimationRunner;
58 import android.view.RemoteAnimationAdapter;
59 import android.view.RemoteAnimationDefinition;
60 import android.view.RemoteAnimationTarget;
61 import android.view.SurfaceControl;
62 import android.view.WindowManager;
63 import android.view.WindowManagerPolicyConstants;
64 import android.window.IRemoteTransition;
65 import android.window.IRemoteTransitionFinishedCallback;
66 import android.window.TransitionInfo;
67 
68 import com.android.internal.annotations.GuardedBy;
69 import com.android.internal.policy.IKeyguardDismissCallback;
70 import com.android.internal.policy.IKeyguardDrawnCallback;
71 import com.android.internal.policy.IKeyguardExitCallback;
72 import com.android.internal.policy.IKeyguardService;
73 import com.android.internal.policy.IKeyguardStateCallback;
74 import com.android.keyguard.mediator.ScreenOnCoordinator;
75 import com.android.systemui.SystemUIApplication;
76 import com.android.systemui.dagger.qualifiers.Application;
77 import com.android.systemui.flags.FeatureFlags;
78 import com.android.systemui.flags.Flags;
79 import com.android.systemui.keyguard.ui.binder.KeyguardSurfaceBehindParamsApplier;
80 import com.android.systemui.keyguard.ui.binder.KeyguardSurfaceBehindViewBinder;
81 import com.android.systemui.keyguard.ui.binder.WindowManagerLockscreenVisibilityViewBinder;
82 import com.android.systemui.keyguard.ui.viewmodel.KeyguardSurfaceBehindViewModel;
83 import com.android.systemui.keyguard.ui.viewmodel.WindowManagerLockscreenVisibilityViewModel;
84 import com.android.systemui.settings.DisplayTracker;
85 import com.android.wm.shell.transition.ShellTransitions;
86 import com.android.wm.shell.transition.Transitions;
87 import com.android.wm.shell.util.CounterRotator;
88 import com.android.wm.shell.util.TransitionUtil;
89 
90 import java.util.ArrayList;
91 import java.util.Map;
92 import java.util.WeakHashMap;
93 
94 import javax.inject.Inject;
95 
96 import kotlinx.coroutines.CoroutineScope;
97 
98 public class KeyguardService extends Service {
99     static final String TAG = "KeyguardService";
100     static final String PERMISSION = android.Manifest.permission.CONTROL_KEYGUARD;
101 
102     private final FeatureFlags mFlags;
103     private final KeyguardViewMediator mKeyguardViewMediator;
104     private final KeyguardLifecyclesDispatcher mKeyguardLifecyclesDispatcher;
105     private final ScreenOnCoordinator mScreenOnCoordinator;
106     private final ShellTransitions mShellTransitions;
107     private final DisplayTracker mDisplayTracker;
108 
newModeToLegacyMode(int newMode)109     private static int newModeToLegacyMode(int newMode) {
110         switch (newMode) {
111             case WindowManager.TRANSIT_OPEN:
112             case WindowManager.TRANSIT_TO_FRONT:
113                 return MODE_OPENING;
114             case WindowManager.TRANSIT_CLOSE:
115             case WindowManager.TRANSIT_TO_BACK:
116                 return MODE_CLOSING;
117             default:
118                 return 2; // MODE_CHANGING
119         }
120     }
121 
wrap(TransitionInfo info, boolean wallpapers, SurfaceControl.Transaction t, ArrayMap<SurfaceControl, SurfaceControl> leashMap, CounterRotator counterWallpaper)122     private static RemoteAnimationTarget[] wrap(TransitionInfo info, boolean wallpapers,
123             SurfaceControl.Transaction t, ArrayMap<SurfaceControl, SurfaceControl> leashMap,
124             CounterRotator counterWallpaper) {
125         final ArrayList<RemoteAnimationTarget> out = new ArrayList<>();
126         for (int i = 0; i < info.getChanges().size(); i++) {
127             boolean changeIsWallpaper =
128                     (info.getChanges().get(i).getFlags() & TransitionInfo.FLAG_IS_WALLPAPER) != 0;
129             if (wallpapers != changeIsWallpaper) continue;
130 
131             final TransitionInfo.Change change = info.getChanges().get(i);
132             final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
133             final int taskId = taskInfo != null ? change.getTaskInfo().taskId : -1;
134 
135             if (taskId != -1 && change.getParent() != null) {
136                 final TransitionInfo.Change parentChange = info.getChange(change.getParent());
137                 if (parentChange != null && parentChange.getTaskInfo() != null) {
138                     // Only adding the root task as the animation target.
139                     continue;
140                 }
141             }
142 
143             // Avoid wrapping non-task and non-wallpaper changes as they don't need to animate
144             // for keyguard unlock animation.
145             if (taskId < 0 && !wallpapers) continue;
146 
147             final RemoteAnimationTarget target = TransitionUtil.newTarget(change,
148                     // wallpapers go into the "below" layer space
149                     info.getChanges().size() - i,
150                     // keyguard treats wallpaper as translucent
151                     (change.getFlags() & TransitionInfo.FLAG_SHOW_WALLPAPER) != 0,
152                     info, t, leashMap);
153 
154             if (changeIsWallpaper) {
155                 int rotateDelta = RotationUtils.deltaRotation(change.getStartRotation(),
156                         change.getEndRotation());
157                 if (rotateDelta != 0 && change.getParent() != null
158                         && change.getMode() == TRANSIT_TO_BACK) {
159                     final TransitionInfo.Change parent = info.getChange(change.getParent());
160                     if (parent != null) {
161                         float displayW = parent.getEndAbsBounds().width();
162                         float displayH = parent.getEndAbsBounds().height();
163                         counterWallpaper.setup(t, parent.getLeash(), rotateDelta, displayW,
164                                 displayH);
165                     }
166                     if (counterWallpaper.getSurface() != null) {
167                         t.setLayer(counterWallpaper.getSurface(), -1);
168                         counterWallpaper.addChild(t, leashMap.get(change.getLeash()));
169                     }
170                 }
171             }
172 
173             out.add(target);
174         }
175         return out.toArray(new RemoteAnimationTarget[out.size()]);
176     }
177 
getTransitionOldType(@ransitionType int type, @TransitionFlags int flags, RemoteAnimationTarget[] apps)178     private static @TransitionOldType int getTransitionOldType(@TransitionType int type,
179             @TransitionFlags int flags, RemoteAnimationTarget[] apps) {
180         if (type == TRANSIT_KEYGUARD_GOING_AWAY
181                 || (flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY) != 0) {
182             return apps.length == 0 ? TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER
183                     : TRANSIT_OLD_KEYGUARD_GOING_AWAY;
184         } else if (type == TRANSIT_KEYGUARD_OCCLUDE) {
185             boolean isOccludeByDream = apps.length > 0 && apps[0].taskInfo != null
186                     && apps[0].taskInfo.topActivityType == WindowConfiguration.ACTIVITY_TYPE_DREAM;
187             if (isOccludeByDream) return TRANSIT_OLD_KEYGUARD_OCCLUDE_BY_DREAM;
188             return TRANSIT_OLD_KEYGUARD_OCCLUDE;
189         } else if (type == TRANSIT_KEYGUARD_UNOCCLUDE) {
190             return TRANSIT_OLD_KEYGUARD_UNOCCLUDE;
191         } else {
192             Slog.d(TAG, "Unexpected transit type: " + type);
193             return TRANSIT_OLD_NONE;
194         }
195     }
196 
197     // Wrap Keyguard going away animation.
198     // Note: Also used for wrapping occlude by Dream animation. It works (with some redundancy).
wrap(final KeyguardViewMediator keyguardViewMediator, final IRemoteAnimationRunner runner, final boolean lockscreenLiveWallpaperEnabled)199     public static IRemoteTransition wrap(final KeyguardViewMediator keyguardViewMediator,
200         final IRemoteAnimationRunner runner, final boolean lockscreenLiveWallpaperEnabled) {
201         return new IRemoteTransition.Stub() {
202 
203             @GuardedBy("mLeashMap")
204             private final ArrayMap<SurfaceControl, SurfaceControl> mLeashMap = new ArrayMap<>();
205             private final CounterRotator mCounterRotator = new CounterRotator();
206 
207             @GuardedBy("mLeashMap")
208             private final Map<IBinder, IRemoteTransitionFinishedCallback> mFinishCallbacks =
209                     new WeakHashMap<>();
210 
211             @Override
212             public void startAnimation(IBinder transition, TransitionInfo info,
213                     SurfaceControl.Transaction t, IRemoteTransitionFinishedCallback finishCallback)
214                     throws RemoteException {
215                 Slog.d(TAG, "Starts IRemoteAnimationRunner: info=" + info);
216 
217                 final RemoteAnimationTarget[] apps;
218                 final RemoteAnimationTarget[] wallpapers;
219                 final RemoteAnimationTarget[] nonApps = new RemoteAnimationTarget[0];
220                 synchronized (mLeashMap) {
221                     apps = wrap(info, false /* wallpapers */, t, mLeashMap, mCounterRotator);
222                     wallpapers = wrap(info, true /* wallpapers */, t, mLeashMap, mCounterRotator);
223                     mFinishCallbacks.put(transition, finishCallback);
224                 }
225 
226                 // Set alpha back to 1 for the independent changes because we will be animating
227                 // children instead.
228                 for (TransitionInfo.Change chg : info.getChanges()) {
229                     if (TransitionInfo.isIndependent(chg, info)) {
230                         t.setAlpha(chg.getLeash(), 1.f);
231                     }
232                 }
233                 initAlphaForAnimationTargets(t, apps);
234                 if (lockscreenLiveWallpaperEnabled) {
235                     initAlphaForAnimationTargets(t, wallpapers);
236                 }
237                 t.apply();
238 
239                 runner.onAnimationStart(
240                         getTransitionOldType(info.getType(), info.getFlags(), apps),
241                         apps, wallpapers, nonApps,
242                         new IRemoteAnimationFinishedCallback.Stub() {
243                             @Override
244                             public void onAnimationFinished() throws RemoteException {
245                                 Slog.d(TAG, "Finish IRemoteAnimationRunner.");
246                                 finish(transition);
247                             }
248                         });
249             }
250 
251             public void mergeAnimation(IBinder candidateTransition, TransitionInfo candidateInfo,
252                     SurfaceControl.Transaction candidateT, IBinder currentTransition,
253                     IRemoteTransitionFinishedCallback candidateFinishCallback)
254                     throws RemoteException {
255                 if ((candidateInfo.getFlags() & TRANSIT_FLAG_KEYGUARD_APPEARING) != 0) {
256                     keyguardViewMediator.setPendingLock(true);
257                     keyguardViewMediator.cancelKeyguardExitAnimation();
258                     return;
259                 }
260 
261                 try {
262                     runner.onAnimationCancelled();
263                     finish(currentTransition);
264                 } catch (RemoteException e) {
265                     // nothing, we'll just let it finish on its own I guess.
266                 }
267             }
268 
269             private static void initAlphaForAnimationTargets(@NonNull SurfaceControl.Transaction t,
270                     @NonNull RemoteAnimationTarget[] targets) {
271                 for (RemoteAnimationTarget target : targets) {
272                     if (target.mode != MODE_OPENING) continue;
273                     t.setAlpha(target.leash, 0.f);
274                 }
275             }
276 
277             private void finish(IBinder transition) throws RemoteException {
278                 IRemoteTransitionFinishedCallback finishCallback = null;
279                 SurfaceControl.Transaction finishTransaction = null;
280 
281                 synchronized (mLeashMap) {
282                     if (mCounterRotator.getSurface() != null
283                             && mCounterRotator.getSurface().isValid()) {
284                         finishTransaction = new SurfaceControl.Transaction();
285                         mCounterRotator.cleanUp(finishTransaction);
286                     }
287                     mLeashMap.clear();
288                     finishCallback = mFinishCallbacks.remove(transition);
289                 }
290 
291                 if (finishCallback != null) {
292                     finishCallback.onTransitionFinished(null /* wct */, finishTransaction);
293                 } else if (finishTransaction != null) {
294                     finishTransaction.apply();
295                 }
296             }
297         };
298     }
299 
300     @Inject
KeyguardService(KeyguardViewMediator keyguardViewMediator, KeyguardLifecyclesDispatcher keyguardLifecyclesDispatcher, ScreenOnCoordinator screenOnCoordinator, ShellTransitions shellTransitions, DisplayTracker displayTracker, WindowManagerLockscreenVisibilityViewModel wmLockscreenVisibilityViewModel, WindowManagerLockscreenVisibilityManager wmLockscreenVisibilityManager, KeyguardSurfaceBehindViewModel keyguardSurfaceBehindViewModel, KeyguardSurfaceBehindParamsApplier keyguardSurfaceBehindAnimator, @Application CoroutineScope scope, FeatureFlags featureFlags)301     public KeyguardService(KeyguardViewMediator keyguardViewMediator,
302                            KeyguardLifecyclesDispatcher keyguardLifecyclesDispatcher,
303                            ScreenOnCoordinator screenOnCoordinator,
304                            ShellTransitions shellTransitions,
305                            DisplayTracker displayTracker,
306                            WindowManagerLockscreenVisibilityViewModel
307                                    wmLockscreenVisibilityViewModel,
308                            WindowManagerLockscreenVisibilityManager wmLockscreenVisibilityManager,
309                            KeyguardSurfaceBehindViewModel keyguardSurfaceBehindViewModel,
310                            KeyguardSurfaceBehindParamsApplier keyguardSurfaceBehindAnimator,
311                            @Application CoroutineScope scope,
312                            FeatureFlags featureFlags) {
313         super();
314         mKeyguardViewMediator = keyguardViewMediator;
315         mKeyguardLifecyclesDispatcher = keyguardLifecyclesDispatcher;
316         mScreenOnCoordinator = screenOnCoordinator;
317         mShellTransitions = shellTransitions;
318         mDisplayTracker = displayTracker;
319         mFlags = featureFlags;
320 
321         if (mFlags.isEnabled(Flags.KEYGUARD_WM_STATE_REFACTOR)) {
322             WindowManagerLockscreenVisibilityViewBinder.bind(
323                     wmLockscreenVisibilityViewModel,
324                     wmLockscreenVisibilityManager,
325                     scope);
326 
327             KeyguardSurfaceBehindViewBinder.bind(
328                     keyguardSurfaceBehindViewModel,
329                     keyguardSurfaceBehindAnimator,
330                     scope);
331         }
332     }
333 
334     @Override
onCreate()335     public void onCreate() {
336         ((SystemUIApplication) getApplication()).startServicesIfNeeded();
337 
338         if (mShellTransitions == null || !Transitions.ENABLE_SHELL_TRANSITIONS) {
339             RemoteAnimationDefinition definition = new RemoteAnimationDefinition();
340             final RemoteAnimationAdapter exitAnimationAdapter =
341                     new RemoteAnimationAdapter(
342                             mKeyguardViewMediator.getExitAnimationRunner(), 0, 0);
343             definition.addRemoteAnimation(TRANSIT_OLD_KEYGUARD_GOING_AWAY,
344                     exitAnimationAdapter);
345             definition.addRemoteAnimation(TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER,
346                     exitAnimationAdapter);
347             final RemoteAnimationAdapter occludeAnimationAdapter =
348                     new RemoteAnimationAdapter(
349                             mKeyguardViewMediator.getOccludeAnimationRunner(), 0, 0);
350             definition.addRemoteAnimation(TRANSIT_OLD_KEYGUARD_OCCLUDE,
351                     occludeAnimationAdapter);
352 
353             final RemoteAnimationAdapter occludeByDreamAnimationAdapter =
354                     new RemoteAnimationAdapter(
355                             mKeyguardViewMediator.getOccludeByDreamAnimationRunner(), 0, 0);
356             definition.addRemoteAnimation(TRANSIT_OLD_KEYGUARD_OCCLUDE_BY_DREAM,
357                     occludeByDreamAnimationAdapter);
358 
359             final RemoteAnimationAdapter unoccludeAnimationAdapter =
360                     new RemoteAnimationAdapter(
361                             mKeyguardViewMediator.getUnoccludeAnimationRunner(), 0, 0);
362             definition.addRemoteAnimation(TRANSIT_OLD_KEYGUARD_UNOCCLUDE,
363                     unoccludeAnimationAdapter);
364             ActivityTaskManager.getInstance().registerRemoteAnimationsForDisplay(
365                     mDisplayTracker.getDefaultDisplayId(), definition);
366         }
367     }
368 
369     @Override
onBind(Intent intent)370     public IBinder onBind(Intent intent) {
371         return mBinder;
372     }
373 
checkPermission()374     void checkPermission() {
375         // Avoid deadlock by avoiding calling back into the system process.
376         if (Binder.getCallingUid() == Process.SYSTEM_UID) return;
377 
378         // Otherwise,explicitly check for caller permission ...
379         if (getBaseContext().checkCallingOrSelfPermission(PERMISSION) != PERMISSION_GRANTED) {
380             Log.w(TAG, "Caller needs permission '" + PERMISSION + "' to call " + Debug.getCaller());
381             throw new SecurityException("Access denied to process: " + Binder.getCallingPid()
382                     + ", must have permission " + PERMISSION);
383         }
384     }
385 
386     private final IKeyguardService.Stub mBinder = new IKeyguardService.Stub() {
387         private static final String TRACK_NAME = "IKeyguardService";
388 
389         /**
390          * Helper for tracing the most-recent call on the IKeyguardService interface.
391          * IKeyguardService is oneway, so we are most interested in the order of the calls as they
392          * are received. We use an async track to make it easier to visualize in the trace.
393          * @param name name of the trace section
394          */
395         private static void trace(String name) {
396             Trace.asyncTraceForTrackEnd(Trace.TRACE_TAG_APP, TRACK_NAME, 0);
397             Trace.asyncTraceForTrackBegin(Trace.TRACE_TAG_APP, TRACK_NAME, name, 0);
398         }
399 
400         @Override // Binder interface
401         public void addStateMonitorCallback(IKeyguardStateCallback callback) {
402             trace("addStateMonitorCallback");
403             checkPermission();
404             mKeyguardViewMediator.addStateMonitorCallback(callback);
405         }
406 
407         @Override // Binder interface
408         public void verifyUnlock(IKeyguardExitCallback callback) {
409             trace("verifyUnlock");
410             Trace.beginSection("KeyguardService.mBinder#verifyUnlock");
411             checkPermission();
412             mKeyguardViewMediator.verifyUnlock(callback);
413             Trace.endSection();
414         }
415 
416         @Override // Binder interface
417         public void setOccluded(boolean isOccluded, boolean animate) {
418             trace("setOccluded isOccluded=" + isOccluded + " animate=" + animate);
419             Log.d(TAG, "setOccluded(" + isOccluded + ")");
420 
421             Trace.beginSection("KeyguardService.mBinder#setOccluded");
422             checkPermission();
423             mKeyguardViewMediator.setOccluded(isOccluded, animate);
424             Trace.endSection();
425         }
426 
427         @Override // Binder interface
428         public void dismiss(IKeyguardDismissCallback callback, CharSequence message) {
429             trace("dismiss message=" + message);
430             checkPermission();
431             mKeyguardViewMediator.dismiss(callback, message);
432         }
433 
434         @Override // Binder interface
435         public void onDreamingStarted() {
436             trace("onDreamingStarted");
437             checkPermission();
438             mKeyguardViewMediator.onDreamingStarted();
439         }
440 
441         @Override // Binder interface
442         public void onDreamingStopped() {
443             trace("onDreamingStopped");
444             checkPermission();
445             mKeyguardViewMediator.onDreamingStopped();
446         }
447 
448         @Override // Binder interface
449         public void onStartedGoingToSleep(@PowerManager.GoToSleepReason int pmSleepReason) {
450             trace("onStartedGoingToSleep pmSleepReason=" + pmSleepReason);
451             checkPermission();
452             mKeyguardViewMediator.onStartedGoingToSleep(
453                     WindowManagerPolicyConstants.translateSleepReasonToOffReason(pmSleepReason));
454             mKeyguardLifecyclesDispatcher.dispatch(
455                     KeyguardLifecyclesDispatcher.STARTED_GOING_TO_SLEEP, pmSleepReason);
456         }
457 
458         @Override // Binder interface
459         public void onFinishedGoingToSleep(
460                 @PowerManager.GoToSleepReason int pmSleepReason, boolean cameraGestureTriggered) {
461             trace("onFinishedGoingToSleep pmSleepReason=" + pmSleepReason
462                     + " cameraGestureTriggered=" + cameraGestureTriggered);
463             checkPermission();
464             mKeyguardViewMediator.onFinishedGoingToSleep(
465                     WindowManagerPolicyConstants.translateSleepReasonToOffReason(pmSleepReason),
466                     cameraGestureTriggered);
467             mKeyguardLifecyclesDispatcher.dispatch(
468                     KeyguardLifecyclesDispatcher.FINISHED_GOING_TO_SLEEP);
469         }
470 
471         @Override // Binder interface
472         public void onStartedWakingUp(
473                 @PowerManager.WakeReason int pmWakeReason, boolean cameraGestureTriggered) {
474             trace("onStartedWakingUp pmWakeReason=" + pmWakeReason
475                     + " cameraGestureTriggered=" + cameraGestureTriggered);
476             Trace.beginSection("KeyguardService.mBinder#onStartedWakingUp");
477             checkPermission();
478             mKeyguardViewMediator.onStartedWakingUp(pmWakeReason, cameraGestureTriggered);
479             mKeyguardLifecyclesDispatcher.dispatch(
480                     KeyguardLifecyclesDispatcher.STARTED_WAKING_UP, pmWakeReason);
481             Trace.endSection();
482         }
483 
484         @Override // Binder interface
485         public void onFinishedWakingUp() {
486             trace("onFinishedWakingUp");
487             Trace.beginSection("KeyguardService.mBinder#onFinishedWakingUp");
488             checkPermission();
489             mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.FINISHED_WAKING_UP);
490             Trace.endSection();
491         }
492 
493         @Override // Binder interface
494         public void onScreenTurningOn(IKeyguardDrawnCallback callback) {
495             trace("onScreenTurningOn");
496             Trace.beginSection("KeyguardService.mBinder#onScreenTurningOn");
497             checkPermission();
498             mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.SCREEN_TURNING_ON,
499                     callback);
500 
501             final String onDrawWaitingTraceTag = "Waiting for KeyguardDrawnCallback#onDrawn";
502             final int traceCookie = System.identityHashCode(callback);
503             Trace.beginAsyncSection(onDrawWaitingTraceTag, traceCookie);
504 
505             // Ensure the drawn callback is only ever called once
506             mScreenOnCoordinator.onScreenTurningOn(new Runnable() {
507                 boolean mInvoked;
508                 @Override
509                 public void run() {
510                     if (callback == null) return;
511                     if (!mInvoked) {
512                         mInvoked = true;
513                         try {
514                             Trace.endAsyncSection(onDrawWaitingTraceTag, traceCookie);
515                             callback.onDrawn();
516                         } catch (RemoteException e) {
517                             Log.w(TAG, "Exception calling onDrawn():", e);
518                         }
519                     } else {
520                         Log.w(TAG, "KeyguardDrawnCallback#onDrawn() invoked > 1 times");
521                     }
522                 }
523             });
524 
525             Trace.endSection();
526         }
527 
528         @Override // Binder interface
529         public void onScreenTurnedOn() {
530             trace("onScreenTurnedOn");
531             Trace.beginSection("KeyguardService.mBinder#onScreenTurnedOn");
532             checkPermission();
533             mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.SCREEN_TURNED_ON);
534             mScreenOnCoordinator.onScreenTurnedOn();
535             Trace.endSection();
536         }
537 
538         @Override // Binder interface
539         public void onScreenTurningOff() {
540             trace("onScreenTurningOff");
541             checkPermission();
542             mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.SCREEN_TURNING_OFF);
543         }
544 
545         @Override // Binder interface
546         public void onScreenTurnedOff() {
547             trace("onScreenTurnedOff");
548             checkPermission();
549             mKeyguardViewMediator.onScreenTurnedOff();
550             mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.SCREEN_TURNED_OFF);
551             mScreenOnCoordinator.onScreenTurnedOff();
552         }
553 
554         @Override // Binder interface
555         public void setKeyguardEnabled(boolean enabled) {
556             trace("setKeyguardEnabled enabled" + enabled);
557             checkPermission();
558             mKeyguardViewMediator.setKeyguardEnabled(enabled);
559         }
560 
561         @Override // Binder interface
562         public void onSystemReady() {
563             trace("onSystemReady");
564             Trace.beginSection("KeyguardService.mBinder#onSystemReady");
565             checkPermission();
566             mKeyguardViewMediator.onSystemReady();
567             Trace.endSection();
568         }
569 
570         @Override // Binder interface
571         public void doKeyguardTimeout(Bundle options) {
572             trace("doKeyguardTimeout");
573             checkPermission();
574             mKeyguardViewMediator.doKeyguardTimeout(options);
575         }
576 
577         @Override // Binder interface
578         public void setSwitchingUser(boolean switching) {
579             trace("setSwitchingUser switching=" + switching);
580             checkPermission();
581             mKeyguardViewMediator.setSwitchingUser(switching);
582         }
583 
584         @Override // Binder interface
585         public void setCurrentUser(int userId) {
586             trace("setCurrentUser userId=" + userId);
587             checkPermission();
588             mKeyguardViewMediator.setCurrentUser(userId);
589         }
590 
591         @Override // Binder interface
592         public void onBootCompleted() {
593             trace("onBootCompleted");
594             checkPermission();
595             mKeyguardViewMediator.onBootCompleted();
596         }
597 
598         /**
599          * @deprecated When remote animation is enabled, this won't be called anymore. Use
600          * {@code IRemoteAnimationRunner#onAnimationStart} instead.
601          */
602         @Deprecated
603         @Override // Binder interface
604         public void startKeyguardExitAnimation(long startTime, long fadeoutDuration) {
605             trace("startKeyguardExitAnimation startTime=" + startTime
606                     + " fadeoutDuration=" + fadeoutDuration);
607             Trace.beginSection("KeyguardService.mBinder#startKeyguardExitAnimation");
608             checkPermission();
609             mKeyguardViewMediator.startKeyguardExitAnimation(startTime, fadeoutDuration);
610             Trace.endSection();
611         }
612 
613         @Override // Binder interface
614         public void onShortPowerPressedGoHome() {
615             trace("onShortPowerPressedGoHome");
616             checkPermission();
617             mKeyguardViewMediator.onShortPowerPressedGoHome();
618         }
619 
620         @Override // Binder interface
621         public void dismissKeyguardToLaunch(Intent intentToLaunch) {
622             trace("dismissKeyguardToLaunch");
623             checkPermission();
624             mKeyguardViewMediator.dismissKeyguardToLaunch(intentToLaunch);
625         }
626 
627         @Override // Binder interface
628         public void onSystemKeyPressed(int keycode) {
629             trace("onSystemKeyPressed keycode=" + keycode);
630             checkPermission();
631             mKeyguardViewMediator.onSystemKeyPressed(keycode);
632         }
633     };
634 }
635 
636