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