1 /* 2 * Copyright (C) 2016 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.server.wm; 18 19 import static android.app.WindowConfiguration.ACTIVITY_TYPE_DREAM; 20 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; 21 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; 22 import static android.view.Display.DEFAULT_DISPLAY; 23 import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY; 24 import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION; 25 import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_SUBTLE_ANIMATION; 26 import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_LAUNCHER_CLEAR_SNAPSHOT; 27 import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE; 28 import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER; 29 import static android.view.WindowManager.TRANSIT_KEYGUARD_GOING_AWAY; 30 import static android.view.WindowManager.TRANSIT_KEYGUARD_OCCLUDE; 31 import static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE; 32 import static android.view.WindowManager.TRANSIT_OPEN; 33 import static android.view.WindowManager.TRANSIT_TO_BACK; 34 import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS; 35 import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_SUBTLE_WINDOW_ANIMATIONS; 36 import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_TO_LAUNCHER_CLEAR_SNAPSHOT; 37 import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_TO_SHADE; 38 import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER; 39 40 import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; 41 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM; 42 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME; 43 import static com.android.server.wm.ActivityTaskSupervisor.PRESERVE_WINDOWS; 44 import static com.android.server.wm.KeyguardControllerProto.AOD_SHOWING; 45 import static com.android.server.wm.KeyguardControllerProto.KEYGUARD_GOING_AWAY; 46 import static com.android.server.wm.KeyguardControllerProto.KEYGUARD_PER_DISPLAY; 47 import static com.android.server.wm.KeyguardControllerProto.KEYGUARD_SHOWING; 48 49 import android.annotation.Nullable; 50 import android.os.IBinder; 51 import android.os.RemoteException; 52 import android.os.Trace; 53 import android.util.Slog; 54 import android.util.SparseArray; 55 import android.util.proto.ProtoOutputStream; 56 import android.view.Display; 57 import android.view.WindowManager; 58 59 import com.android.internal.policy.IKeyguardDismissCallback; 60 import com.android.server.inputmethod.InputMethodManagerInternal; 61 import com.android.server.policy.WindowManagerPolicy; 62 63 import java.io.PrintWriter; 64 65 /** 66 * Controls Keyguard occluding, dismissing and transitions depending on what kind of activities are 67 * currently visible. 68 * <p> 69 * Note that everything in this class should only be accessed with the AM lock being held. 70 */ 71 class KeyguardController { 72 73 private static final String TAG = TAG_WITH_CLASS_NAME ? "KeyguardController" : TAG_ATM; 74 75 static final String KEYGUARD_SLEEP_TOKEN_TAG = "keyguard"; 76 77 private static final int DEFER_WAKE_TRANSITION_TIMEOUT_MS = 5000; 78 79 private final ActivityTaskSupervisor mTaskSupervisor; 80 private WindowManagerService mWindowManager; 81 82 private final SparseArray<KeyguardDisplayState> mDisplayStates = new SparseArray<>(); 83 private final ActivityTaskManagerService mService; 84 private RootWindowContainer mRootWindowContainer; 85 private final ActivityTaskManagerInternal.SleepTokenAcquirer mSleepTokenAcquirer; 86 private boolean mWaitingForWakeTransition; 87 KeyguardController(ActivityTaskManagerService service, ActivityTaskSupervisor taskSupervisor)88 KeyguardController(ActivityTaskManagerService service, 89 ActivityTaskSupervisor taskSupervisor) { 90 mService = service; 91 mTaskSupervisor = taskSupervisor; 92 mSleepTokenAcquirer = mService.new SleepTokenAcquirerImpl(KEYGUARD_SLEEP_TOKEN_TAG); 93 } 94 setWindowManager(WindowManagerService windowManager)95 void setWindowManager(WindowManagerService windowManager) { 96 mWindowManager = windowManager; 97 mRootWindowContainer = mService.mRootWindowContainer; 98 } 99 isAodShowing(int displayId)100 boolean isAodShowing(int displayId) { 101 return getDisplayState(displayId).mAodShowing; 102 } 103 104 /** 105 * @return true if either Keyguard or AOD are showing, not going away, and not being occluded 106 * on the given display, false otherwise. 107 */ isKeyguardOrAodShowing(int displayId)108 boolean isKeyguardOrAodShowing(int displayId) { 109 final KeyguardDisplayState state = getDisplayState(displayId); 110 return (state.mKeyguardShowing || state.mAodShowing) 111 && !state.mKeyguardGoingAway 112 && !isDisplayOccluded(displayId); 113 } 114 115 /** 116 * @return {@code true} for default display when AOD is showing, not going away. Otherwise, same 117 * as {@link #isKeyguardOrAodShowing(int)} 118 * TODO(b/125198167): Replace isKeyguardOrAodShowing() by this logic. 119 */ isKeyguardUnoccludedOrAodShowing(int displayId)120 boolean isKeyguardUnoccludedOrAodShowing(int displayId) { 121 final KeyguardDisplayState state = getDisplayState(displayId); 122 if (displayId == DEFAULT_DISPLAY && state.mAodShowing) { 123 return !state.mKeyguardGoingAway; 124 } 125 return isKeyguardOrAodShowing(displayId); 126 } 127 128 /** 129 * @return true if Keyguard is showing, not going away, and not being occluded on the given 130 * display, false otherwise 131 */ isKeyguardShowing(int displayId)132 boolean isKeyguardShowing(int displayId) { 133 final KeyguardDisplayState state = getDisplayState(displayId); 134 return state.mKeyguardShowing && !state.mKeyguardGoingAway 135 && !isDisplayOccluded(displayId); 136 } 137 138 /** 139 * @return true if Keyguard is either showing or occluded, but not going away 140 */ isKeyguardLocked(int displayId)141 boolean isKeyguardLocked(int displayId) { 142 final KeyguardDisplayState state = getDisplayState(displayId); 143 return state.mKeyguardShowing && !state.mKeyguardGoingAway; 144 } 145 146 /** 147 * 148 * @return true if the activity is controlling keyguard state. 149 */ topActivityOccludesKeyguard(ActivityRecord r)150 boolean topActivityOccludesKeyguard(ActivityRecord r) { 151 return getDisplayState(r.getDisplayId()).mTopOccludesActivity == r; 152 } 153 154 /** 155 * @return {@code true} if the keyguard is going away, {@code false} otherwise. 156 */ isKeyguardGoingAway(int displayId)157 boolean isKeyguardGoingAway(int displayId) { 158 final KeyguardDisplayState state = getDisplayState(displayId); 159 // Also check keyguard showing in case value is stale. 160 return state.mKeyguardGoingAway && state.mKeyguardShowing; 161 } 162 163 /** 164 * Update the Keyguard showing state. 165 */ setKeyguardShown(int displayId, boolean keyguardShowing, boolean aodShowing)166 void setKeyguardShown(int displayId, boolean keyguardShowing, boolean aodShowing) { 167 if (mRootWindowContainer.getDisplayContent(displayId).isKeyguardAlwaysUnlocked()) { 168 Slog.i(TAG, "setKeyguardShown ignoring always unlocked display " + displayId); 169 return; 170 } 171 172 final KeyguardDisplayState state = getDisplayState(displayId); 173 final boolean aodChanged = aodShowing != state.mAodShowing; 174 final boolean aodRemoved = state.mAodShowing && !aodShowing; 175 // If keyguard is going away, but SystemUI aborted the transition, need to reset state. 176 // Do not reset keyguardChanged status when only AOD is removed. 177 final boolean keyguardChanged = (keyguardShowing != state.mKeyguardShowing) 178 || (state.mKeyguardGoingAway && keyguardShowing && !aodRemoved); 179 if (aodRemoved) { 180 updateDeferTransitionForAod(false /* waiting */); 181 } 182 if (!keyguardChanged && !aodChanged) { 183 setWakeTransitionReady(); 184 return; 185 } 186 EventLogTags.writeWmSetKeyguardShown( 187 displayId, 188 keyguardShowing ? 1 : 0, 189 aodShowing ? 1 : 0, 190 state.mKeyguardGoingAway ? 1 : 0, 191 state.mOccluded ? 1 : 0, 192 "setKeyguardShown"); 193 194 // Update the task snapshot if the screen will not be turned off. To make sure that the 195 // unlocking animation can animate consistent content. The conditions are: 196 // - Either AOD or keyguard changes to be showing. So if the states change individually, 197 // the later one can be skipped to avoid taking snapshot again. While it still accepts 198 // if both of them change to show at the same time. 199 // - Keyguard was not going away. Because if it was, the closing transition is able to 200 // handle the snapshot. 201 // - The display state is ON. Because if AOD is not on or pulsing, the display state will 202 // be OFF or DOZE (the path of screen off may have handled it). 203 if (((aodShowing ^ keyguardShowing) || (aodShowing && aodChanged && keyguardChanged)) 204 && !state.mKeyguardGoingAway && Display.isOnState( 205 mRootWindowContainer.getDefaultDisplay().getDisplayInfo().state)) { 206 mWindowManager.mTaskSnapshotController.snapshotForSleeping(DEFAULT_DISPLAY); 207 } 208 209 state.mKeyguardShowing = keyguardShowing; 210 state.mAodShowing = aodShowing; 211 212 if (keyguardChanged) { 213 // Irrelevant to AOD. 214 dismissMultiWindowModeForTaskIfNeeded(displayId, 215 null /* currentTaskControllsingOcclusion */); 216 state.mKeyguardGoingAway = false; 217 if (keyguardShowing) { 218 state.mDismissalRequested = false; 219 } 220 } 221 222 // Update the sleep token first such that ensureActivitiesVisible has correct sleep token 223 // state when evaluating visibilities. 224 updateKeyguardSleepToken(); 225 mRootWindowContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS); 226 InputMethodManagerInternal.get().updateImeWindowStatus(false /* disableImeIcon */); 227 setWakeTransitionReady(); 228 if (aodChanged) { 229 // Ensure the new state takes effect. 230 mWindowManager.mWindowPlacerLocked.performSurfacePlacement(); 231 } 232 } 233 setWakeTransitionReady()234 private void setWakeTransitionReady() { 235 if (mWindowManager.mAtmService.getTransitionController().getCollectingTransitionType() 236 == WindowManager.TRANSIT_WAKE) { 237 mWindowManager.mAtmService.getTransitionController().setReady( 238 mRootWindowContainer.getDefaultDisplay()); 239 } 240 } 241 242 /** 243 * Called when Keyguard is going away. 244 * 245 * @param flags See {@link WindowManagerPolicy#KEYGUARD_GOING_AWAY_FLAG_TO_SHADE} 246 * etc. 247 */ keyguardGoingAway(int displayId, int flags)248 void keyguardGoingAway(int displayId, int flags) { 249 final KeyguardDisplayState state = getDisplayState(displayId); 250 if (!state.mKeyguardShowing || state.mKeyguardGoingAway) { 251 return; 252 } 253 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "keyguardGoingAway"); 254 mService.deferWindowLayout(); 255 state.mKeyguardGoingAway = true; 256 try { 257 EventLogTags.writeWmSetKeyguardShown( 258 displayId, 259 state.mKeyguardShowing ? 1 : 0, 260 state.mAodShowing ? 1 : 0, 261 1 /* keyguardGoingAway */, 262 state.mOccluded ? 1 : 0, 263 "keyguardGoingAway"); 264 final int transitFlags = convertTransitFlags(flags); 265 final DisplayContent dc = mRootWindowContainer.getDefaultDisplay(); 266 dc.prepareAppTransition(TRANSIT_KEYGUARD_GOING_AWAY, transitFlags); 267 // We are deprecating TRANSIT_KEYGUARD_GOING_AWAY for Shell transition and use 268 // TRANSIT_FLAG_KEYGUARD_GOING_AWAY to indicate that it should animate keyguard going 269 // away. 270 dc.mAtmService.getTransitionController().requestTransitionIfNeeded( 271 TRANSIT_TO_BACK, transitFlags, null /* trigger */, dc); 272 updateKeyguardSleepToken(); 273 274 // Some stack visibility might change (e.g. docked stack) 275 mRootWindowContainer.resumeFocusedTasksTopActivities(); 276 mRootWindowContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS); 277 mRootWindowContainer.addStartingWindowsForVisibleActivities(); 278 mWindowManager.executeAppTransition(); 279 } finally { 280 mService.continueWindowLayout(); 281 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); 282 } 283 } 284 dismissKeyguard(IBinder token, IKeyguardDismissCallback callback, CharSequence message)285 void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback, CharSequence message) { 286 final ActivityRecord activityRecord = ActivityRecord.forTokenLocked(token); 287 if (activityRecord == null || !activityRecord.visibleIgnoringKeyguard) { 288 failCallback(callback); 289 return; 290 } 291 Slog.i(TAG, "Activity requesting to dismiss Keyguard: " + activityRecord); 292 293 // If the client has requested to dismiss the keyguard and the Activity has the flag to 294 // turn the screen on, wakeup the screen if it's the top Activity. 295 if (activityRecord.getTurnScreenOnFlag() && activityRecord.isTopRunningActivity()) { 296 mTaskSupervisor.wakeUp("dismissKeyguard"); 297 } 298 299 mWindowManager.dismissKeyguard(callback, message); 300 } 301 failCallback(IKeyguardDismissCallback callback)302 private void failCallback(IKeyguardDismissCallback callback) { 303 try { 304 callback.onDismissError(); 305 } catch (RemoteException e) { 306 Slog.w(TAG, "Failed to call callback", e); 307 } 308 } 309 convertTransitFlags(int keyguardGoingAwayFlags)310 private int convertTransitFlags(int keyguardGoingAwayFlags) { 311 int result = TRANSIT_FLAG_KEYGUARD_GOING_AWAY; 312 if ((keyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_TO_SHADE) != 0) { 313 result |= TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE; 314 } 315 if ((keyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS) != 0) { 316 result |= TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION; 317 } 318 if ((keyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER) != 0) { 319 result |= TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER; 320 } 321 if ((keyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_SUBTLE_WINDOW_ANIMATIONS) != 0) { 322 result |= TRANSIT_FLAG_KEYGUARD_GOING_AWAY_SUBTLE_ANIMATION; 323 } 324 if ((keyguardGoingAwayFlags 325 & KEYGUARD_GOING_AWAY_FLAG_TO_LAUNCHER_CLEAR_SNAPSHOT) != 0) { 326 result |= TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_LAUNCHER_CLEAR_SNAPSHOT; 327 } 328 return result; 329 } 330 331 /** 332 * @return True if we may show an activity while Keyguard is showing because we are in the 333 * process of dismissing it anyways, false otherwise. 334 */ canShowActivityWhileKeyguardShowing(ActivityRecord r)335 boolean canShowActivityWhileKeyguardShowing(ActivityRecord r) { 336 // Allow to show it when we are about to dismiss Keyguard. This isn't allowed if r is 337 // already the dismissing activity, in which case we don't allow it to repeatedly dismiss 338 // Keyguard. 339 final KeyguardDisplayState state = getDisplayState(r.getDisplayId()); 340 return r.containsDismissKeyguardWindow() && canDismissKeyguard() && !state.mAodShowing 341 && (state.mDismissalRequested 342 || (r.canShowWhenLocked() && state.mDismissingKeyguardActivity != r)); 343 } 344 345 /** 346 * @return True if we may show an activity while Keyguard is occluded, false otherwise. 347 */ canShowWhileOccluded(boolean dismissKeyguard, boolean showWhenLocked)348 boolean canShowWhileOccluded(boolean dismissKeyguard, boolean showWhenLocked) { 349 return showWhenLocked || dismissKeyguard 350 && !mWindowManager.isKeyguardSecure(mService.getCurrentUserId()); 351 } 352 353 /** 354 * Checks whether {@param r} should be visible depending on Keyguard state. 355 * 356 * @return true if {@param r} is visible taken Keyguard state into account, false otherwise 357 */ checkKeyguardVisibility(ActivityRecord r)358 boolean checkKeyguardVisibility(ActivityRecord r) { 359 if (r.mDisplayContent.canShowWithInsecureKeyguard() && canDismissKeyguard()) { 360 return true; 361 } 362 363 if (isKeyguardOrAodShowing(r.mDisplayContent.getDisplayId())) { 364 // If keyguard is showing, nothing is visible, except if we are able to dismiss Keyguard 365 // right away and AOD isn't visible. 366 return canShowActivityWhileKeyguardShowing(r); 367 } else if (isKeyguardLocked(r.getDisplayId())) { 368 return canShowWhileOccluded(r.containsDismissKeyguardWindow(), r.canShowWhenLocked()); 369 } else { 370 return true; 371 } 372 } 373 374 /** 375 * Makes sure to update lockscreen occluded/dismiss/turnScreenOn state if needed before 376 * completing set all visibility 377 * ({@link ActivityTaskSupervisor#beginActivityVisibilityUpdate}). 378 */ updateVisibility()379 void updateVisibility() { 380 for (int displayNdx = mRootWindowContainer.getChildCount() - 1; 381 displayNdx >= 0; displayNdx--) { 382 final DisplayContent display = mRootWindowContainer.getChildAt(displayNdx); 383 if (display.isRemoving() || display.isRemoved()) continue; 384 final KeyguardDisplayState state = getDisplayState(display.mDisplayId); 385 state.updateVisibility(this, display); 386 if (state.mRequestDismissKeyguard) { 387 handleDismissKeyguard(display.getDisplayId()); 388 } 389 } 390 } 391 392 /** 393 * Called when occluded state changed. 394 * 395 * @param topActivity the activity that controls the state whether keyguard should 396 * be occluded. That is the activity to be shown on top of keyguard if it requests so. 397 */ handleOccludedChanged(int displayId, @Nullable ActivityRecord topActivity)398 private void handleOccludedChanged(int displayId, @Nullable ActivityRecord topActivity) { 399 // TODO(b/113840485): Handle app transition for individual display, and apply occluded 400 // state change to secondary displays. 401 // For now, only default display fully supports occluded change. Other displays only 402 // updates keyguard sleep token on that display. 403 if (displayId != DEFAULT_DISPLAY) { 404 updateKeyguardSleepToken(displayId); 405 return; 406 } 407 408 final boolean waitAppTransition = isKeyguardLocked(displayId); 409 mWindowManager.mPolicy.onKeyguardOccludedChangedLw(isDisplayOccluded(DEFAULT_DISPLAY), 410 waitAppTransition); 411 if (waitAppTransition) { 412 mService.deferWindowLayout(); 413 try { 414 mRootWindowContainer.getDefaultDisplay() 415 .requestTransitionAndLegacyPrepare( 416 isDisplayOccluded(DEFAULT_DISPLAY) 417 ? TRANSIT_KEYGUARD_OCCLUDE 418 : TRANSIT_KEYGUARD_UNOCCLUDE, 0 /* flags */); 419 updateKeyguardSleepToken(DEFAULT_DISPLAY); 420 mWindowManager.executeAppTransition(); 421 } finally { 422 mService.continueWindowLayout(); 423 } 424 } 425 dismissMultiWindowModeForTaskIfNeeded(displayId, topActivity != null 426 ? topActivity.getRootTask() : null); 427 } 428 429 /** 430 * Called when keyguard going away state changed. 431 */ handleKeyguardGoingAwayChanged(DisplayContent dc)432 private void handleKeyguardGoingAwayChanged(DisplayContent dc) { 433 mService.deferWindowLayout(); 434 try { 435 dc.prepareAppTransition(TRANSIT_KEYGUARD_GOING_AWAY, 0 /* transitFlags */); 436 // We are deprecating TRANSIT_KEYGUARD_GOING_AWAY for Shell transition and use 437 // TRANSIT_FLAG_KEYGUARD_GOING_AWAY to indicate that it should animate keyguard going 438 // away. 439 dc.mAtmService.getTransitionController().requestTransitionIfNeeded( 440 TRANSIT_OPEN, TRANSIT_FLAG_KEYGUARD_GOING_AWAY, null /* trigger */, dc); 441 updateKeyguardSleepToken(); 442 mWindowManager.executeAppTransition(); 443 } finally { 444 mService.continueWindowLayout(); 445 } 446 } 447 448 /** 449 * Called when somebody wants to dismiss the Keyguard via the flag. 450 */ handleDismissKeyguard(int displayId)451 private void handleDismissKeyguard(int displayId) { 452 // We only allow dismissing Keyguard via the flag when Keyguard is secure for legacy 453 // reasons, because that's how apps used to dismiss Keyguard in the secure case. In the 454 // insecure case, we actually show it on top of the lockscreen. See #canShowWhileOccluded. 455 if (!mWindowManager.isKeyguardSecure(mService.getCurrentUserId())) { 456 return; 457 } 458 459 mWindowManager.dismissKeyguard(null /* callback */, null /* message */); 460 final KeyguardDisplayState state = getDisplayState(displayId); 461 state.mDismissalRequested = true; 462 463 // If we are about to unocclude the Keyguard, but we can dismiss it without security, 464 // we immediately dismiss the Keyguard so the activity gets shown without a flicker. 465 final DisplayContent dc = mRootWindowContainer.getDefaultDisplay(); 466 if (state.mKeyguardShowing && canDismissKeyguard() 467 && dc.mAppTransition.containsTransitRequest(TRANSIT_KEYGUARD_UNOCCLUDE)) { 468 mWindowManager.executeAppTransition(); 469 } 470 } 471 isDisplayOccluded(int displayId)472 boolean isDisplayOccluded(int displayId) { 473 return getDisplayState(displayId).mOccluded; 474 } 475 476 /** 477 * @return true if Keyguard can be currently dismissed without entering credentials. 478 */ canDismissKeyguard()479 boolean canDismissKeyguard() { 480 return mWindowManager.mPolicy.isKeyguardTrustedLw() 481 || !mWindowManager.isKeyguardSecure(mService.getCurrentUserId()); 482 } 483 484 /** 485 * @return Whether the dream activity is on top of default display. 486 */ isShowingDream()487 boolean isShowingDream() { 488 return getDisplayState(DEFAULT_DISPLAY).mShowingDream; 489 } 490 dismissMultiWindowModeForTaskIfNeeded(int displayId, @Nullable Task currentTaskControllingOcclusion)491 private void dismissMultiWindowModeForTaskIfNeeded(int displayId, 492 @Nullable Task currentTaskControllingOcclusion) { 493 // TODO(b/113840485): Handle docked stack for individual display. 494 if (!getDisplayState(displayId).mKeyguardShowing || !isDisplayOccluded(DEFAULT_DISPLAY)) { 495 return; 496 } 497 498 // Dismiss freeform windowing mode 499 if (currentTaskControllingOcclusion == null) { 500 return; 501 } 502 if (currentTaskControllingOcclusion.inFreeformWindowingMode()) { 503 currentTaskControllingOcclusion.setWindowingMode(WINDOWING_MODE_FULLSCREEN); 504 } 505 } 506 updateKeyguardSleepToken()507 private void updateKeyguardSleepToken() { 508 for (int displayNdx = mRootWindowContainer.getChildCount() - 1; 509 displayNdx >= 0; displayNdx--) { 510 final DisplayContent display = mRootWindowContainer.getChildAt(displayNdx); 511 updateKeyguardSleepToken(display.mDisplayId); 512 } 513 } 514 updateKeyguardSleepToken(int displayId)515 private void updateKeyguardSleepToken(int displayId) { 516 final KeyguardDisplayState state = getDisplayState(displayId); 517 if (isKeyguardUnoccludedOrAodShowing(displayId)) { 518 state.mSleepTokenAcquirer.acquire(displayId); 519 } else { 520 state.mSleepTokenAcquirer.release(displayId); 521 } 522 } 523 getDisplayState(int displayId)524 private KeyguardDisplayState getDisplayState(int displayId) { 525 KeyguardDisplayState state = mDisplayStates.get(displayId); 526 if (state == null) { 527 state = new KeyguardDisplayState(mService, displayId, mSleepTokenAcquirer); 528 mDisplayStates.append(displayId, state); 529 } 530 return state; 531 } 532 onDisplayRemoved(int displayId)533 void onDisplayRemoved(int displayId) { 534 final KeyguardDisplayState state = mDisplayStates.get(displayId); 535 if (state != null) { 536 state.onRemoved(); 537 mDisplayStates.remove(displayId); 538 } 539 } 540 541 private final Runnable mResetWaitTransition = () -> { 542 synchronized (mWindowManager.mGlobalLock) { 543 updateDeferTransitionForAod(false /* waiting */); 544 } 545 }; 546 547 // Defer transition until AOD dismissed. updateDeferTransitionForAod(boolean waiting)548 void updateDeferTransitionForAod(boolean waiting) { 549 if (waiting == mWaitingForWakeTransition) { 550 return; 551 } 552 if (!mService.getTransitionController().isCollecting()) { 553 return; 554 } 555 // if AOD is showing, defer the wake transition until AOD state changed. 556 if (waiting && isAodShowing(DEFAULT_DISPLAY)) { 557 mWaitingForWakeTransition = true; 558 mWindowManager.mAtmService.getTransitionController().deferTransitionReady(); 559 mWindowManager.mH.postDelayed(mResetWaitTransition, DEFER_WAKE_TRANSITION_TIMEOUT_MS); 560 } else if (!waiting) { 561 // dismiss the deferring if the AOD state change or cancel awake. 562 mWaitingForWakeTransition = false; 563 mWindowManager.mAtmService.getTransitionController().continueTransitionReady(); 564 mWindowManager.mH.removeCallbacks(mResetWaitTransition); 565 } 566 } 567 568 569 /** Represents Keyguard state per individual display. */ 570 private static class KeyguardDisplayState { 571 private final int mDisplayId; 572 private boolean mKeyguardShowing; 573 private boolean mAodShowing; 574 private boolean mKeyguardGoingAway; 575 private boolean mDismissalRequested; 576 private boolean mOccluded; 577 private boolean mShowingDream; 578 579 private ActivityRecord mTopOccludesActivity; 580 private ActivityRecord mDismissingKeyguardActivity; 581 private ActivityRecord mTopTurnScreenOnActivity; 582 583 private boolean mRequestDismissKeyguard; 584 private final ActivityTaskManagerService mService; 585 private final ActivityTaskManagerInternal.SleepTokenAcquirer mSleepTokenAcquirer; 586 KeyguardDisplayState(ActivityTaskManagerService service, int displayId, ActivityTaskManagerInternal.SleepTokenAcquirer acquirer)587 KeyguardDisplayState(ActivityTaskManagerService service, int displayId, 588 ActivityTaskManagerInternal.SleepTokenAcquirer acquirer) { 589 mService = service; 590 mDisplayId = displayId; 591 mSleepTokenAcquirer = acquirer; 592 } 593 onRemoved()594 void onRemoved() { 595 mTopOccludesActivity = null; 596 mDismissingKeyguardActivity = null; 597 mTopTurnScreenOnActivity = null; 598 mSleepTokenAcquirer.release(mDisplayId); 599 } 600 601 /** 602 * Updates keyguard status if the top task could be visible. The top task may occlude 603 * keyguard, request to dismiss keyguard or make insecure keyguard go away based on its 604 * properties. 605 */ updateVisibility(KeyguardController controller, DisplayContent display)606 void updateVisibility(KeyguardController controller, DisplayContent display) { 607 final boolean lastOccluded = mOccluded; 608 final boolean lastKeyguardGoingAway = mKeyguardGoingAway; 609 610 final ActivityRecord lastDismissKeyguardActivity = mDismissingKeyguardActivity; 611 final ActivityRecord lastTurnScreenOnActivity = mTopTurnScreenOnActivity; 612 613 mRequestDismissKeyguard = false; 614 mOccluded = false; 615 mShowingDream = false; 616 617 mTopOccludesActivity = null; 618 mDismissingKeyguardActivity = null; 619 mTopTurnScreenOnActivity = null; 620 621 boolean occludedByActivity = false; 622 final Task task = getRootTaskForControllingOccluding(display); 623 final ActivityRecord top = task != null ? task.getTopNonFinishingActivity() : null; 624 if (top != null) { 625 if (top.containsDismissKeyguardWindow()) { 626 mDismissingKeyguardActivity = top; 627 } 628 if (top.getTurnScreenOnFlag() && top.currentLaunchCanTurnScreenOn()) { 629 mTopTurnScreenOnActivity = top; 630 } 631 632 if (top.mDismissKeyguard && mKeyguardShowing) { 633 mKeyguardGoingAway = true; 634 } else if (top.canShowWhenLocked()) { 635 mTopOccludesActivity = top; 636 } 637 top.mDismissKeyguard = false; 638 639 // Only the top activity may control occluded, as we can't occlude the Keyguard 640 // if the top app doesn't want to occlude it. 641 occludedByActivity = mTopOccludesActivity != null 642 || (mDismissingKeyguardActivity != null 643 && task.topRunningActivity() == mDismissingKeyguardActivity 644 && controller.canShowWhileOccluded( 645 true /* dismissKeyguard */, false /* showWhenLocked */)); 646 // FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD only apply for secondary display. 647 if (mDisplayId != DEFAULT_DISPLAY) { 648 occludedByActivity |= display.canShowWithInsecureKeyguard() 649 && controller.canDismissKeyguard(); 650 } 651 } 652 653 mShowingDream = display.getDisplayPolicy().isShowingDreamLw() && (top != null 654 && top.getActivityType() == ACTIVITY_TYPE_DREAM); 655 mOccluded = mShowingDream || occludedByActivity; 656 mRequestDismissKeyguard = lastDismissKeyguardActivity != mDismissingKeyguardActivity 657 && !mOccluded && !mKeyguardGoingAway 658 && mDismissingKeyguardActivity != null; 659 if (mOccluded && mKeyguardShowing && !display.isSleeping() && !top.fillsParent() 660 && display.mWallpaperController.getWallpaperTarget() == null) { 661 // The occluding activity may be translucent or not fill screen. Then let wallpaper 662 // to check whether it should set itself as target to avoid blank background. 663 display.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER; 664 } 665 666 if (mTopTurnScreenOnActivity != lastTurnScreenOnActivity 667 && mTopTurnScreenOnActivity != null 668 && !mService.mWindowManager.mPowerManager.isInteractive() 669 && (mRequestDismissKeyguard || occludedByActivity)) { 670 controller.mTaskSupervisor.wakeUp("handleTurnScreenOn"); 671 mTopTurnScreenOnActivity.setCurrentLaunchCanTurnScreenOn(false); 672 } 673 674 boolean hasChange = false; 675 if (lastOccluded != mOccluded) { 676 if (mDisplayId == DEFAULT_DISPLAY) { 677 EventLogTags.writeWmSetKeyguardShown( 678 mDisplayId, 679 mKeyguardShowing ? 1 : 0, 680 mAodShowing ? 1 : 0, 681 mKeyguardGoingAway ? 1 : 0, 682 mOccluded ? 1 : 0, 683 "updateVisibility"); 684 } 685 controller.handleOccludedChanged(mDisplayId, mTopOccludesActivity); 686 hasChange = true; 687 } else if (!lastKeyguardGoingAway && mKeyguardGoingAway) { 688 controller.handleKeyguardGoingAwayChanged(display); 689 hasChange = true; 690 } 691 // Collect the participates for shell transition, so that transition won't happen too 692 // early since the transition was set ready. 693 if (hasChange && top != null && (mOccluded || mKeyguardGoingAway)) { 694 display.mTransitionController.collect(top); 695 } 696 } 697 698 /** 699 * Gets the stack used to check the occluded state. 700 * <p> 701 * Only the top non-pinned activity of the focusable stack on each display can control its 702 * occlusion state. 703 */ 704 @Nullable getRootTaskForControllingOccluding(DisplayContent display)705 private Task getRootTaskForControllingOccluding(DisplayContent display) { 706 return display.getRootTask(task -> 707 task != null && task.isFocusableAndVisible() && !task.inPinnedWindowingMode()); 708 } 709 dumpStatus(PrintWriter pw, String prefix)710 void dumpStatus(PrintWriter pw, String prefix) { 711 final StringBuilder sb = new StringBuilder(); 712 sb.append(prefix); 713 sb.append(" KeyguardShowing=") 714 .append(mKeyguardShowing) 715 .append(" AodShowing=") 716 .append(mAodShowing) 717 .append(" KeyguardGoingAway=") 718 .append(mKeyguardGoingAway) 719 .append(" DismissalRequested=") 720 .append(mDismissalRequested) 721 .append(" Occluded=") 722 .append(mOccluded) 723 .append(" DismissingKeyguardActivity=") 724 .append(mDismissingKeyguardActivity) 725 .append(" TurnScreenOnActivity=") 726 .append(mTopTurnScreenOnActivity) 727 .append(" at display=") 728 .append(mDisplayId); 729 pw.println(sb.toString()); 730 } 731 dumpDebug(ProtoOutputStream proto, long fieldId)732 void dumpDebug(ProtoOutputStream proto, long fieldId) { 733 final long token = proto.start(fieldId); 734 proto.write(KeyguardPerDisplayProto.DISPLAY_ID, mDisplayId); 735 proto.write(KeyguardPerDisplayProto.KEYGUARD_SHOWING, mKeyguardShowing); 736 proto.write(KeyguardPerDisplayProto.AOD_SHOWING, mAodShowing); 737 proto.write(KeyguardPerDisplayProto.KEYGUARD_OCCLUDED, mOccluded); 738 proto.write(KeyguardPerDisplayProto.KEYGUARD_GOING_AWAY, mKeyguardGoingAway); 739 proto.end(token); 740 } 741 } 742 dump(PrintWriter pw, String prefix)743 void dump(PrintWriter pw, String prefix) { 744 final KeyguardDisplayState default_state = getDisplayState(DEFAULT_DISPLAY); 745 pw.println(prefix + "KeyguardController:"); 746 pw.println(prefix + " mKeyguardShowing=" + default_state.mKeyguardShowing); 747 pw.println(prefix + " mAodShowing=" + default_state.mAodShowing); 748 pw.println(prefix + " mKeyguardGoingAway=" + default_state.mKeyguardGoingAway); 749 dumpDisplayStates(pw, prefix); 750 pw.println(prefix + " mDismissalRequested=" + default_state.mDismissalRequested); 751 pw.println(); 752 } 753 dumpDebug(ProtoOutputStream proto, long fieldId)754 void dumpDebug(ProtoOutputStream proto, long fieldId) { 755 final KeyguardDisplayState default_state = getDisplayState(DEFAULT_DISPLAY); 756 final long token = proto.start(fieldId); 757 proto.write(AOD_SHOWING, default_state.mAodShowing); 758 proto.write(KEYGUARD_SHOWING, default_state.mKeyguardShowing); 759 proto.write(KEYGUARD_GOING_AWAY, default_state.mKeyguardGoingAway); 760 writeDisplayStatesToProto(proto, KEYGUARD_PER_DISPLAY); 761 proto.end(token); 762 } 763 dumpDisplayStates(PrintWriter pw, String prefix)764 private void dumpDisplayStates(PrintWriter pw, String prefix) { 765 for (int i = 0; i < mDisplayStates.size(); i++) { 766 mDisplayStates.valueAt(i).dumpStatus(pw, prefix); 767 } 768 } 769 writeDisplayStatesToProto(ProtoOutputStream proto, long fieldId)770 private void writeDisplayStatesToProto(ProtoOutputStream proto, long fieldId) { 771 for (int i = 0; i < mDisplayStates.size(); i++) { 772 mDisplayStates.valueAt(i).dumpDebug(proto, fieldId); 773 } 774 } 775 } 776