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_CLOSE; 23 import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY; 24 import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_LOCKED; 25 import static android.view.WindowManager.TRANSIT_KEYGUARD_GOING_AWAY; 26 import static android.view.WindowManager.TRANSIT_KEYGUARD_OCCLUDE; 27 import static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE; 28 import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_GOING_AWAY; 29 import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER; 30 import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_OCCLUDE; 31 import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_OCCLUDE_BY_DREAM; 32 import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_UNOCCLUDE; 33 import static android.view.WindowManager.TRANSIT_OLD_NONE; 34 import static android.view.WindowManager.TRANSIT_OPEN; 35 import static android.view.WindowManager.TRANSIT_TO_BACK; 36 import static android.view.WindowManager.TRANSIT_TO_FRONT; 37 import static android.view.WindowManager.TransitionFlags; 38 import static android.view.WindowManager.TransitionOldType; 39 import static android.view.WindowManager.TransitionType; 40 import static android.window.TransitionInfo.FLAG_OCCLUDES_KEYGUARD; 41 42 import android.app.ActivityManager; 43 import android.app.ActivityTaskManager; 44 import android.app.Service; 45 import android.app.WindowConfiguration; 46 import android.content.Intent; 47 import android.graphics.Point; 48 import android.graphics.Rect; 49 import android.os.Binder; 50 import android.os.Bundle; 51 import android.os.Debug; 52 import android.os.IBinder; 53 import android.os.PowerManager; 54 import android.os.Process; 55 import android.os.RemoteException; 56 import android.os.SystemProperties; 57 import android.os.Trace; 58 import android.util.ArrayMap; 59 import android.util.Log; 60 import android.util.Slog; 61 import android.view.IRemoteAnimationFinishedCallback; 62 import android.view.IRemoteAnimationRunner; 63 import android.view.RemoteAnimationAdapter; 64 import android.view.RemoteAnimationDefinition; 65 import android.view.RemoteAnimationTarget; 66 import android.view.SurfaceControl; 67 import android.view.WindowManager; 68 import android.view.WindowManagerPolicyConstants; 69 import android.window.IRemoteTransition; 70 import android.window.IRemoteTransitionFinishedCallback; 71 import android.window.RemoteTransition; 72 import android.window.TransitionFilter; 73 import android.window.TransitionInfo; 74 75 import com.android.internal.policy.IKeyguardDismissCallback; 76 import com.android.internal.policy.IKeyguardDrawnCallback; 77 import com.android.internal.policy.IKeyguardExitCallback; 78 import com.android.internal.policy.IKeyguardService; 79 import com.android.internal.policy.IKeyguardStateCallback; 80 import com.android.keyguard.mediator.ScreenOnCoordinator; 81 import com.android.systemui.SystemUIApplication; 82 import com.android.systemui.settings.DisplayTracker; 83 import com.android.wm.shell.transition.ShellTransitions; 84 import com.android.wm.shell.transition.Transitions; 85 86 import java.util.ArrayList; 87 88 import javax.inject.Inject; 89 90 public class KeyguardService extends Service { 91 static final String TAG = "KeyguardService"; 92 static final String PERMISSION = android.Manifest.permission.CONTROL_KEYGUARD; 93 94 /** 95 * Run Keyguard animation as remote animation in System UI instead of local animation in 96 * the server process. 97 * 98 * 0: Runs all keyguard animation as local animation 99 * 1: Only runs keyguard going away animation as remote animation 100 * 2: Runs all keyguard animation as remote animation 101 * 102 * Note: Must be consistent with WindowManagerService. 103 */ 104 private static final String ENABLE_REMOTE_KEYGUARD_ANIMATION_PROPERTY = 105 "persist.wm.enable_remote_keyguard_animation"; 106 107 private static final int sEnableRemoteKeyguardAnimation = 108 SystemProperties.getInt(ENABLE_REMOTE_KEYGUARD_ANIMATION_PROPERTY, 2); 109 110 /** 111 * @see #ENABLE_REMOTE_KEYGUARD_ANIMATION_PROPERTY 112 */ 113 public static boolean sEnableRemoteKeyguardGoingAwayAnimation = 114 sEnableRemoteKeyguardAnimation >= 1; 115 116 /** 117 * @see #ENABLE_REMOTE_KEYGUARD_ANIMATION_PROPERTY 118 */ 119 public static boolean sEnableRemoteKeyguardOccludeAnimation = 120 sEnableRemoteKeyguardAnimation >= 2; 121 122 private final KeyguardViewMediator mKeyguardViewMediator; 123 private final KeyguardLifecyclesDispatcher mKeyguardLifecyclesDispatcher; 124 private final ScreenOnCoordinator mScreenOnCoordinator; 125 private final ShellTransitions mShellTransitions; 126 private final DisplayTracker mDisplayTracker; 127 newModeToLegacyMode(int newMode)128 private static int newModeToLegacyMode(int newMode) { 129 switch (newMode) { 130 case WindowManager.TRANSIT_OPEN: 131 case WindowManager.TRANSIT_TO_FRONT: 132 return MODE_OPENING; 133 case WindowManager.TRANSIT_CLOSE: 134 case WindowManager.TRANSIT_TO_BACK: 135 return MODE_CLOSING; 136 default: 137 return 2; // MODE_CHANGING 138 } 139 } 140 wrap(TransitionInfo info, boolean wallpapers)141 private static RemoteAnimationTarget[] wrap(TransitionInfo info, boolean wallpapers) { 142 final ArrayList<RemoteAnimationTarget> out = new ArrayList<>(); 143 for (int i = 0; i < info.getChanges().size(); i++) { 144 boolean changeIsWallpaper = 145 (info.getChanges().get(i).getFlags() & TransitionInfo.FLAG_IS_WALLPAPER) != 0; 146 if (wallpapers != changeIsWallpaper) continue; 147 148 final TransitionInfo.Change change = info.getChanges().get(i); 149 final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo(); 150 final int taskId = taskInfo != null ? change.getTaskInfo().taskId : -1; 151 boolean isNotInRecents; 152 WindowConfiguration windowConfiguration = null; 153 if (taskInfo != null) { 154 if (taskInfo.getConfiguration() != null) { 155 windowConfiguration = 156 change.getTaskInfo().getConfiguration().windowConfiguration; 157 } 158 isNotInRecents = !change.getTaskInfo().isRunning; 159 } else { 160 isNotInRecents = true; 161 } 162 Rect localBounds = new Rect(change.getEndAbsBounds()); 163 localBounds.offsetTo(change.getEndRelOffset().x, change.getEndRelOffset().y); 164 165 final RemoteAnimationTarget target = new RemoteAnimationTarget( 166 taskId, 167 newModeToLegacyMode(change.getMode()), 168 change.getLeash(), 169 (change.getFlags() & TransitionInfo.FLAG_TRANSLUCENT) != 0 170 || (change.getFlags() & TransitionInfo.FLAG_SHOW_WALLPAPER) != 0, 171 null /* clipRect */, 172 new Rect(0, 0, 0, 0) /* contentInsets */, 173 info.getChanges().size() - i, 174 new Point(), localBounds, new Rect(change.getEndAbsBounds()), 175 windowConfiguration, isNotInRecents, null /* startLeash */, 176 change.getStartAbsBounds(), taskInfo, false /* allowEnterPip */); 177 // Use hasAnimatingParent to mark the anything below root task 178 if (taskId != -1 && change.getParent() != null) { 179 final TransitionInfo.Change parentChange = info.getChange(change.getParent()); 180 if (parentChange != null && parentChange.getTaskInfo() != null) { 181 target.hasAnimatingParent = true; 182 } 183 } 184 out.add(target); 185 } 186 return out.toArray(new RemoteAnimationTarget[out.size()]); 187 } 188 getTransitionOldType(@ransitionType int type, @TransitionFlags int flags, RemoteAnimationTarget[] apps)189 private static @TransitionOldType int getTransitionOldType(@TransitionType int type, 190 @TransitionFlags int flags, RemoteAnimationTarget[] apps) { 191 if (type == TRANSIT_KEYGUARD_GOING_AWAY 192 || (flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY) != 0) { 193 return apps.length == 0 ? TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER 194 : TRANSIT_OLD_KEYGUARD_GOING_AWAY; 195 } else if (type == TRANSIT_KEYGUARD_OCCLUDE) { 196 boolean isOccludeByDream = apps.length > 0 && apps[0].taskInfo.topActivityType 197 == WindowConfiguration.ACTIVITY_TYPE_DREAM; 198 if (isOccludeByDream) return TRANSIT_OLD_KEYGUARD_OCCLUDE_BY_DREAM; 199 return TRANSIT_OLD_KEYGUARD_OCCLUDE; 200 } else if (type == TRANSIT_KEYGUARD_UNOCCLUDE) { 201 return TRANSIT_OLD_KEYGUARD_UNOCCLUDE; 202 } else { 203 Slog.d(TAG, "Unexpected transit type: " + type); 204 return TRANSIT_OLD_NONE; 205 } 206 } 207 208 // Wrap Keyguard going away animation. 209 // Note: Also used for wrapping occlude by Dream animation. It works (with some redundancy). wrap(IRemoteAnimationRunner runner)210 private static IRemoteTransition wrap(IRemoteAnimationRunner runner) { 211 return new IRemoteTransition.Stub() { 212 final ArrayMap<IBinder, IRemoteTransitionFinishedCallback> mFinishCallbacks = 213 new ArrayMap<>(); 214 215 @Override 216 public void startAnimation(IBinder transition, TransitionInfo info, 217 SurfaceControl.Transaction t, IRemoteTransitionFinishedCallback finishCallback) 218 throws RemoteException { 219 Slog.d(TAG, "Starts IRemoteAnimationRunner: info=" + info); 220 final RemoteAnimationTarget[] apps = wrap(info, false /* wallpapers */); 221 final RemoteAnimationTarget[] wallpapers = wrap(info, true /* wallpapers */); 222 final RemoteAnimationTarget[] nonApps = new RemoteAnimationTarget[0]; 223 224 // Sets the alpha to 0 for the opening root task for fade in animation. And since 225 // the fade in animation can only apply on the first opening app, so set alpha to 1 226 // for anything else. 227 boolean foundOpening = false; 228 for (RemoteAnimationTarget target : apps) { 229 if (target.taskId != -1 230 && target.mode == RemoteAnimationTarget.MODE_OPENING 231 && !target.hasAnimatingParent) { 232 if (foundOpening) { 233 Log.w(TAG, "More than one opening target"); 234 t.setAlpha(target.leash, 1.0f); 235 continue; 236 } 237 t.setAlpha(target.leash, 0.0f); 238 foundOpening = true; 239 } else { 240 t.setAlpha(target.leash, 1.0f); 241 } 242 } 243 t.apply(); 244 synchronized (mFinishCallbacks) { 245 mFinishCallbacks.put(transition, finishCallback); 246 } 247 runner.onAnimationStart(getTransitionOldType(info.getType(), info.getFlags(), apps), 248 apps, wallpapers, nonApps, 249 new IRemoteAnimationFinishedCallback.Stub() { 250 @Override 251 public void onAnimationFinished() throws RemoteException { 252 synchronized (mFinishCallbacks) { 253 if (mFinishCallbacks.remove(transition) == null) return; 254 } 255 info.releaseAllSurfaces(); 256 Slog.d(TAG, "Finish IRemoteAnimationRunner."); 257 finishCallback.onTransitionFinished(null /* wct */, null /* t */); 258 } 259 } 260 ); 261 } 262 263 public void mergeAnimation(IBinder candidateTransition, TransitionInfo candidateInfo, 264 SurfaceControl.Transaction candidateT, IBinder currentTransition, 265 IRemoteTransitionFinishedCallback candidateFinishCallback) { 266 try { 267 final IRemoteTransitionFinishedCallback currentFinishCB; 268 synchronized (mFinishCallbacks) { 269 currentFinishCB = mFinishCallbacks.remove(currentTransition); 270 } 271 if (currentFinishCB == null) { 272 Slog.e(TAG, "Called mergeAnimation, but finish callback is missing"); 273 return; 274 } 275 runner.onAnimationCancelled(false /* isKeyguardOccluded */); 276 currentFinishCB.onTransitionFinished(null /* wct */, null /* t */); 277 } catch (RemoteException e) { 278 // nothing, we'll just let it finish on its own I guess. 279 } 280 } 281 }; 282 } 283 284 @Inject KeyguardService(KeyguardViewMediator keyguardViewMediator, KeyguardLifecyclesDispatcher keyguardLifecyclesDispatcher, ScreenOnCoordinator screenOnCoordinator, ShellTransitions shellTransitions, DisplayTracker displayTracker)285 public KeyguardService(KeyguardViewMediator keyguardViewMediator, 286 KeyguardLifecyclesDispatcher keyguardLifecyclesDispatcher, 287 ScreenOnCoordinator screenOnCoordinator, 288 ShellTransitions shellTransitions, 289 DisplayTracker displayTracker) { 290 super(); 291 mKeyguardViewMediator = keyguardViewMediator; 292 mKeyguardLifecyclesDispatcher = keyguardLifecyclesDispatcher; 293 mScreenOnCoordinator = screenOnCoordinator; 294 mShellTransitions = shellTransitions; 295 mDisplayTracker = displayTracker; 296 } 297 298 @Override onCreate()299 public void onCreate() { 300 ((SystemUIApplication) getApplication()).startServicesIfNeeded(); 301 302 if (mShellTransitions == null || !Transitions.ENABLE_SHELL_TRANSITIONS) { 303 RemoteAnimationDefinition definition = new RemoteAnimationDefinition(); 304 if (sEnableRemoteKeyguardGoingAwayAnimation) { 305 final RemoteAnimationAdapter exitAnimationAdapter = 306 new RemoteAnimationAdapter(mExitAnimationRunner, 0, 0); 307 definition.addRemoteAnimation(TRANSIT_OLD_KEYGUARD_GOING_AWAY, 308 exitAnimationAdapter); 309 definition.addRemoteAnimation(TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER, 310 exitAnimationAdapter); 311 } 312 if (sEnableRemoteKeyguardOccludeAnimation) { 313 final RemoteAnimationAdapter occludeAnimationAdapter = 314 new RemoteAnimationAdapter( 315 mKeyguardViewMediator.getOccludeAnimationRunner(), 0, 0); 316 definition.addRemoteAnimation(TRANSIT_OLD_KEYGUARD_OCCLUDE, 317 occludeAnimationAdapter); 318 319 final RemoteAnimationAdapter occludeByDreamAnimationAdapter = 320 new RemoteAnimationAdapter( 321 mKeyguardViewMediator.getOccludeByDreamAnimationRunner(), 0, 0); 322 definition.addRemoteAnimation(TRANSIT_OLD_KEYGUARD_OCCLUDE_BY_DREAM, 323 occludeByDreamAnimationAdapter); 324 325 final RemoteAnimationAdapter unoccludeAnimationAdapter = 326 new RemoteAnimationAdapter( 327 mKeyguardViewMediator.getUnoccludeAnimationRunner(), 0, 0); 328 definition.addRemoteAnimation(TRANSIT_OLD_KEYGUARD_UNOCCLUDE, 329 unoccludeAnimationAdapter); 330 } 331 ActivityTaskManager.getInstance().registerRemoteAnimationsForDisplay( 332 mDisplayTracker.getDefaultDisplayId(), definition); 333 return; 334 } 335 if (sEnableRemoteKeyguardGoingAwayAnimation) { 336 Slog.d(TAG, "KeyguardService registerRemote: TRANSIT_KEYGUARD_GOING_AWAY"); 337 TransitionFilter f = new TransitionFilter(); 338 f.mFlags = TRANSIT_FLAG_KEYGUARD_GOING_AWAY; 339 mShellTransitions.registerRemote(f, 340 new RemoteTransition(wrap(mExitAnimationRunner), getIApplicationThread())); 341 } 342 if (sEnableRemoteKeyguardOccludeAnimation) { 343 Slog.d(TAG, "KeyguardService registerRemote: TRANSIT_KEYGUARD_(UN)OCCLUDE"); 344 // Register for occluding 345 final RemoteTransition occludeTransition = new RemoteTransition( 346 mOccludeAnimation, getIApplicationThread()); 347 TransitionFilter f = new TransitionFilter(); 348 f.mFlags = TRANSIT_FLAG_KEYGUARD_LOCKED; 349 f.mRequirements = new TransitionFilter.Requirement[]{ 350 new TransitionFilter.Requirement(), new TransitionFilter.Requirement()}; 351 // First require at-least one app showing that occludes. 352 f.mRequirements[0].mMustBeIndependent = false; 353 f.mRequirements[0].mFlags = FLAG_OCCLUDES_KEYGUARD; 354 f.mRequirements[0].mModes = new int[]{TRANSIT_OPEN, TRANSIT_TO_FRONT}; 355 // Then require that we aren't closing any occludes (because this would mean a 356 // regular task->task or activity->activity animation not involving keyguard). 357 f.mRequirements[1].mNot = true; 358 f.mRequirements[1].mMustBeIndependent = false; 359 f.mRequirements[1].mFlags = FLAG_OCCLUDES_KEYGUARD; 360 f.mRequirements[1].mModes = new int[]{TRANSIT_CLOSE, TRANSIT_TO_BACK}; 361 mShellTransitions.registerRemote(f, occludeTransition); 362 363 // Now register for un-occlude. 364 final RemoteTransition unoccludeTransition = new RemoteTransition( 365 mUnoccludeAnimation, getIApplicationThread()); 366 f = new TransitionFilter(); 367 f.mFlags = TRANSIT_FLAG_KEYGUARD_LOCKED; 368 f.mRequirements = new TransitionFilter.Requirement[]{ 369 new TransitionFilter.Requirement(), new TransitionFilter.Requirement()}; 370 // First require at-least one app going-away (doesn't need occlude flag 371 // as that is implicit by it having been visible and we don't want to exclude 372 // cases where we are un-occluding because the app removed its showWhenLocked 373 // capability at runtime). 374 f.mRequirements[1].mMustBeIndependent = false; 375 f.mRequirements[1].mModes = new int[]{TRANSIT_CLOSE, TRANSIT_TO_BACK}; 376 f.mRequirements[1].mMustBeTask = true; 377 // Then require that we aren't opening any occludes (otherwise we'd remain 378 // occluded). 379 f.mRequirements[0].mNot = true; 380 f.mRequirements[0].mMustBeIndependent = false; 381 f.mRequirements[0].mFlags = FLAG_OCCLUDES_KEYGUARD; 382 f.mRequirements[0].mModes = new int[]{TRANSIT_OPEN, TRANSIT_TO_FRONT}; 383 mShellTransitions.registerRemote(f, unoccludeTransition); 384 385 // Register for specific transition type. 386 // Above filter cannot fulfill all conditions. 387 // E.g. close top activity while screen off but next activity is occluded, this should 388 // an occluded transition, but since the activity is invisible, the condition would 389 // match unoccluded transition. 390 // But on the contrary, if we add above condition in occluded transition, then when user 391 // trying to dismiss occluded activity when unlock keyguard, the condition would match 392 // occluded transition. 393 f = new TransitionFilter(); 394 f.mTypeSet = new int[]{TRANSIT_KEYGUARD_OCCLUDE}; 395 mShellTransitions.registerRemote(f, occludeTransition); 396 397 f = new TransitionFilter(); 398 f.mTypeSet = new int[]{TRANSIT_KEYGUARD_UNOCCLUDE}; 399 mShellTransitions.registerRemote(f, unoccludeTransition); 400 401 Slog.d(TAG, "KeyguardService registerRemote: TRANSIT_KEYGUARD_OCCLUDE for DREAM"); 402 // Register for occluding by Dream 403 f = new TransitionFilter(); 404 f.mFlags = TRANSIT_FLAG_KEYGUARD_LOCKED; 405 f.mRequirements = new TransitionFilter.Requirement[]{ 406 new TransitionFilter.Requirement(), new TransitionFilter.Requirement()}; 407 // First require at-least one app of type DREAM showing that occludes. 408 f.mRequirements[0].mActivityType = WindowConfiguration.ACTIVITY_TYPE_DREAM; 409 f.mRequirements[0].mMustBeIndependent = false; 410 f.mRequirements[0].mFlags = FLAG_OCCLUDES_KEYGUARD; 411 f.mRequirements[0].mModes = new int[]{TRANSIT_OPEN, TRANSIT_TO_FRONT}; 412 // Then require that we aren't closing any occludes (because this would mean a 413 // regular task->task or activity->activity animation not involving keyguard). 414 f.mRequirements[1].mNot = true; 415 f.mRequirements[1].mMustBeIndependent = false; 416 f.mRequirements[1].mFlags = FLAG_OCCLUDES_KEYGUARD; 417 f.mRequirements[1].mModes = new int[]{TRANSIT_CLOSE, TRANSIT_TO_BACK}; 418 mShellTransitions.registerRemote(f, new RemoteTransition( 419 wrap(mKeyguardViewMediator.getOccludeByDreamAnimationRunner()), 420 getIApplicationThread())); 421 } 422 } 423 424 @Override onBind(Intent intent)425 public IBinder onBind(Intent intent) { 426 return mBinder; 427 } 428 checkPermission()429 void checkPermission() { 430 // Avoid deadlock by avoiding calling back into the system process. 431 if (Binder.getCallingUid() == Process.SYSTEM_UID) return; 432 433 // Otherwise,explicitly check for caller permission ... 434 if (getBaseContext().checkCallingOrSelfPermission(PERMISSION) != PERMISSION_GRANTED) { 435 Log.w(TAG, "Caller needs permission '" + PERMISSION + "' to call " + Debug.getCaller()); 436 throw new SecurityException("Access denied to process: " + Binder.getCallingPid() 437 + ", must have permission " + PERMISSION); 438 } 439 } 440 441 private final IRemoteAnimationRunner.Stub mExitAnimationRunner = 442 new IRemoteAnimationRunner.Stub() { 443 @Override // Binder interface 444 public void onAnimationStart(@WindowManager.TransitionOldType int transit, 445 RemoteAnimationTarget[] apps, 446 RemoteAnimationTarget[] wallpapers, 447 RemoteAnimationTarget[] nonApps, 448 IRemoteAnimationFinishedCallback finishedCallback) { 449 Trace.beginSection("mExitAnimationRunner.onAnimationStart#startKeyguardExitAnimation"); 450 checkPermission(); 451 mKeyguardViewMediator.startKeyguardExitAnimation(transit, apps, wallpapers, 452 nonApps, finishedCallback); 453 Trace.endSection(); 454 } 455 456 @Override // Binder interface 457 public void onAnimationCancelled(boolean isKeyguardOccluded) { 458 mKeyguardViewMediator.cancelKeyguardExitAnimation(); 459 } 460 }; 461 462 final IRemoteTransition mOccludeAnimation = new IRemoteTransition.Stub() { 463 @Override 464 public void startAnimation(IBinder transition, TransitionInfo info, 465 SurfaceControl.Transaction t, IRemoteTransitionFinishedCallback finishCallback) 466 throws RemoteException { 467 t.apply(); 468 mBinder.setOccluded(true /* isOccluded */, true /* animate */); 469 finishCallback.onTransitionFinished(null /* wct */, null /* wctCB */); 470 info.releaseAllSurfaces(); 471 } 472 473 @Override 474 public void mergeAnimation(IBinder transition, TransitionInfo info, 475 SurfaceControl.Transaction t, IBinder mergeTarget, 476 IRemoteTransitionFinishedCallback finishCallback) { 477 t.close(); 478 info.releaseAllSurfaces(); 479 } 480 }; 481 482 final IRemoteTransition mUnoccludeAnimation = new IRemoteTransition.Stub() { 483 @Override 484 public void startAnimation(IBinder transition, TransitionInfo info, 485 SurfaceControl.Transaction t, IRemoteTransitionFinishedCallback finishCallback) 486 throws RemoteException { 487 t.apply(); 488 mBinder.setOccluded(false /* isOccluded */, true /* animate */); 489 finishCallback.onTransitionFinished(null /* wct */, null /* wctCB */); 490 info.releaseAllSurfaces(); 491 } 492 493 @Override 494 public void mergeAnimation(IBinder transition, TransitionInfo info, 495 SurfaceControl.Transaction t, IBinder mergeTarget, 496 IRemoteTransitionFinishedCallback finishCallback) { 497 t.close(); 498 info.releaseAllSurfaces(); 499 } 500 }; 501 502 private final IKeyguardService.Stub mBinder = new IKeyguardService.Stub() { 503 504 @Override // Binder interface 505 public void addStateMonitorCallback(IKeyguardStateCallback callback) { 506 checkPermission(); 507 mKeyguardViewMediator.addStateMonitorCallback(callback); 508 } 509 510 @Override // Binder interface 511 public void verifyUnlock(IKeyguardExitCallback callback) { 512 Trace.beginSection("KeyguardService.mBinder#verifyUnlock"); 513 checkPermission(); 514 mKeyguardViewMediator.verifyUnlock(callback); 515 Trace.endSection(); 516 } 517 518 @Override // Binder interface 519 public void setOccluded(boolean isOccluded, boolean animate) { 520 Log.d(TAG, "setOccluded(" + isOccluded + ")"); 521 522 Trace.beginSection("KeyguardService.mBinder#setOccluded"); 523 checkPermission(); 524 mKeyguardViewMediator.setOccluded(isOccluded, animate); 525 Trace.endSection(); 526 } 527 528 @Override // Binder interface 529 public void dismiss(IKeyguardDismissCallback callback, CharSequence message) { 530 checkPermission(); 531 mKeyguardViewMediator.dismiss(callback, message); 532 } 533 534 @Override // Binder interface 535 public void onDreamingStarted() { 536 checkPermission(); 537 mKeyguardViewMediator.onDreamingStarted(); 538 } 539 540 @Override // Binder interface 541 public void onDreamingStopped() { 542 checkPermission(); 543 mKeyguardViewMediator.onDreamingStopped(); 544 } 545 546 @Override // Binder interface 547 public void onStartedGoingToSleep(@PowerManager.GoToSleepReason int pmSleepReason) { 548 checkPermission(); 549 mKeyguardViewMediator.onStartedGoingToSleep( 550 WindowManagerPolicyConstants.translateSleepReasonToOffReason(pmSleepReason)); 551 mKeyguardLifecyclesDispatcher.dispatch( 552 KeyguardLifecyclesDispatcher.STARTED_GOING_TO_SLEEP, pmSleepReason); 553 } 554 555 @Override // Binder interface 556 public void onFinishedGoingToSleep( 557 @PowerManager.GoToSleepReason int pmSleepReason, boolean cameraGestureTriggered) { 558 checkPermission(); 559 mKeyguardViewMediator.onFinishedGoingToSleep( 560 WindowManagerPolicyConstants.translateSleepReasonToOffReason(pmSleepReason), 561 cameraGestureTriggered); 562 mKeyguardLifecyclesDispatcher.dispatch( 563 KeyguardLifecyclesDispatcher.FINISHED_GOING_TO_SLEEP); 564 } 565 566 @Override // Binder interface 567 public void onStartedWakingUp( 568 @PowerManager.WakeReason int pmWakeReason, boolean cameraGestureTriggered) { 569 Trace.beginSection("KeyguardService.mBinder#onStartedWakingUp"); 570 checkPermission(); 571 mKeyguardViewMediator.onStartedWakingUp(pmWakeReason, cameraGestureTriggered); 572 mKeyguardLifecyclesDispatcher.dispatch( 573 KeyguardLifecyclesDispatcher.STARTED_WAKING_UP, pmWakeReason); 574 Trace.endSection(); 575 } 576 577 @Override // Binder interface 578 public void onFinishedWakingUp() { 579 Trace.beginSection("KeyguardService.mBinder#onFinishedWakingUp"); 580 checkPermission(); 581 mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.FINISHED_WAKING_UP); 582 Trace.endSection(); 583 } 584 585 @Override // Binder interface 586 public void onScreenTurningOn(IKeyguardDrawnCallback callback) { 587 Trace.beginSection("KeyguardService.mBinder#onScreenTurningOn"); 588 checkPermission(); 589 mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.SCREEN_TURNING_ON, 590 callback); 591 592 final String onDrawWaitingTraceTag = "Waiting for KeyguardDrawnCallback#onDrawn"; 593 final int traceCookie = System.identityHashCode(callback); 594 Trace.beginAsyncSection(onDrawWaitingTraceTag, traceCookie); 595 596 // Ensure the drawn callback is only ever called once 597 mScreenOnCoordinator.onScreenTurningOn(new Runnable() { 598 boolean mInvoked; 599 @Override 600 public void run() { 601 if (callback == null) return; 602 if (!mInvoked) { 603 mInvoked = true; 604 try { 605 Trace.endAsyncSection(onDrawWaitingTraceTag, traceCookie); 606 callback.onDrawn(); 607 } catch (RemoteException e) { 608 Log.w(TAG, "Exception calling onDrawn():", e); 609 } 610 } else { 611 Log.w(TAG, "KeyguardDrawnCallback#onDrawn() invoked > 1 times"); 612 } 613 } 614 }); 615 616 Trace.endSection(); 617 } 618 619 @Override // Binder interface 620 public void onScreenTurnedOn() { 621 Trace.beginSection("KeyguardService.mBinder#onScreenTurnedOn"); 622 checkPermission(); 623 mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.SCREEN_TURNED_ON); 624 mScreenOnCoordinator.onScreenTurnedOn(); 625 Trace.endSection(); 626 } 627 628 @Override // Binder interface 629 public void onScreenTurningOff() { 630 checkPermission(); 631 mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.SCREEN_TURNING_OFF); 632 } 633 634 @Override // Binder interface 635 public void onScreenTurnedOff() { 636 checkPermission(); 637 mKeyguardViewMediator.onScreenTurnedOff(); 638 mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.SCREEN_TURNED_OFF); 639 mScreenOnCoordinator.onScreenTurnedOff(); 640 } 641 642 @Override // Binder interface 643 public void setKeyguardEnabled(boolean enabled) { 644 checkPermission(); 645 mKeyguardViewMediator.setKeyguardEnabled(enabled); 646 } 647 648 @Override // Binder interface 649 public void onSystemReady() { 650 Trace.beginSection("KeyguardService.mBinder#onSystemReady"); 651 checkPermission(); 652 mKeyguardViewMediator.onSystemReady(); 653 Trace.endSection(); 654 } 655 656 @Override // Binder interface 657 public void doKeyguardTimeout(Bundle options) { 658 checkPermission(); 659 mKeyguardViewMediator.doKeyguardTimeout(options); 660 } 661 662 @Override // Binder interface 663 public void setSwitchingUser(boolean switching) { 664 checkPermission(); 665 mKeyguardViewMediator.setSwitchingUser(switching); 666 } 667 668 @Override // Binder interface 669 public void setCurrentUser(int userId) { 670 checkPermission(); 671 mKeyguardViewMediator.setCurrentUser(userId); 672 } 673 674 @Override 675 public void onBootCompleted() { 676 checkPermission(); 677 mKeyguardViewMediator.onBootCompleted(); 678 } 679 680 /** 681 * @deprecated When remote animation is enabled, this won't be called anymore. Use 682 * {@code IRemoteAnimationRunner#onAnimationStart} instead. 683 */ 684 @Deprecated 685 @Override 686 public void startKeyguardExitAnimation(long startTime, long fadeoutDuration) { 687 Trace.beginSection("KeyguardService.mBinder#startKeyguardExitAnimation"); 688 checkPermission(); 689 mKeyguardViewMediator.startKeyguardExitAnimation(startTime, fadeoutDuration); 690 Trace.endSection(); 691 } 692 693 @Override 694 public void onShortPowerPressedGoHome() { 695 checkPermission(); 696 mKeyguardViewMediator.onShortPowerPressedGoHome(); 697 } 698 699 @Override 700 public void dismissKeyguardToLaunch(Intent intentToLaunch) { 701 checkPermission(); 702 mKeyguardViewMediator.dismissKeyguardToLaunch(intentToLaunch); 703 } 704 705 @Override 706 public void onSystemKeyPressed(int keycode) { 707 checkPermission(); 708 mKeyguardViewMediator.onSystemKeyPressed(keycode); 709 } 710 }; 711 } 712 713