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.os.Trace.TRACE_TAG_ACTIVITY_MANAGER; 20 import static android.view.Display.DEFAULT_DISPLAY; 21 import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION; 22 import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_SUBTLE_ANIMATION; 23 import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE; 24 import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER; 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_UNSET; 29 import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS; 30 import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_SUBTLE_WINDOW_ANIMATIONS; 31 import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_TO_SHADE; 32 import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER; 33 34 import static com.android.server.am.KeyguardControllerProto.AOD_SHOWING; 35 import static com.android.server.am.KeyguardControllerProto.KEYGUARD_OCCLUDED_STATES; 36 import static com.android.server.am.KeyguardControllerProto.KEYGUARD_SHOWING; 37 import static com.android.server.am.KeyguardOccludedProto.DISPLAY_ID; 38 import static com.android.server.am.KeyguardOccludedProto.KEYGUARD_OCCLUDED; 39 import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS; 40 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM; 41 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME; 42 43 import android.os.IBinder; 44 import android.os.RemoteException; 45 import android.os.Trace; 46 import android.util.Slog; 47 import android.util.SparseArray; 48 import android.util.proto.ProtoOutputStream; 49 50 import com.android.internal.policy.IKeyguardDismissCallback; 51 import com.android.server.policy.WindowManagerPolicy; 52 import com.android.server.wm.ActivityTaskManagerInternal.SleepToken; 53 54 import java.io.PrintWriter; 55 56 /** 57 * Controls Keyguard occluding, dismissing and transitions depending on what kind of activities are 58 * currently visible. 59 * <p> 60 * Note that everything in this class should only be accessed with the AM lock being held. 61 */ 62 class KeyguardController { 63 64 private static final String TAG = TAG_WITH_CLASS_NAME ? "KeyguardController" : TAG_ATM; 65 66 private final ActivityStackSupervisor mStackSupervisor; 67 private WindowManagerService mWindowManager; 68 private boolean mKeyguardShowing; 69 private boolean mAodShowing; 70 private boolean mKeyguardGoingAway; 71 private boolean mDismissalRequested; 72 private int[] mSecondaryDisplayIdsShowing; 73 private int mBeforeUnoccludeTransit; 74 private int mVisibilityTransactionDepth; 75 private final SparseArray<KeyguardDisplayState> mDisplayStates = new SparseArray<>(); 76 private final ActivityTaskManagerService mService; 77 private RootActivityContainer mRootActivityContainer; 78 KeyguardController(ActivityTaskManagerService service, ActivityStackSupervisor stackSupervisor)79 KeyguardController(ActivityTaskManagerService service, 80 ActivityStackSupervisor stackSupervisor) { 81 mService = service; 82 mStackSupervisor = stackSupervisor; 83 } 84 setWindowManager(WindowManagerService windowManager)85 void setWindowManager(WindowManagerService windowManager) { 86 mWindowManager = windowManager; 87 mRootActivityContainer = mService.mRootActivityContainer; 88 } 89 90 /** 91 * @return true if either Keyguard or AOD are showing, not going away, and not being occluded 92 * on the given display, false otherwise. 93 */ isKeyguardOrAodShowing(int displayId)94 boolean isKeyguardOrAodShowing(int displayId) { 95 return (mKeyguardShowing || mAodShowing) && !mKeyguardGoingAway 96 && !isDisplayOccluded(displayId); 97 } 98 99 /** 100 * @return {@code true} for default display when AOD is showing. Otherwise, same as 101 * {@link #isKeyguardOrAodShowing(int)} 102 * TODO(b/125198167): Replace isKeyguardOrAodShowing() by this logic. 103 */ isKeyguardUnoccludedOrAodShowing(int displayId)104 boolean isKeyguardUnoccludedOrAodShowing(int displayId) { 105 if (displayId == DEFAULT_DISPLAY && mAodShowing) { 106 return true; 107 } 108 return isKeyguardOrAodShowing(displayId); 109 } 110 111 /** 112 * @return true if Keyguard is showing, not going away, and not being occluded on the given 113 * display, false otherwise 114 */ isKeyguardShowing(int displayId)115 boolean isKeyguardShowing(int displayId) { 116 return mKeyguardShowing && !mKeyguardGoingAway && !isDisplayOccluded(displayId); 117 } 118 119 /** 120 * @return true if Keyguard is either showing or occluded, but not going away 121 */ isKeyguardLocked()122 boolean isKeyguardLocked() { 123 return mKeyguardShowing && !mKeyguardGoingAway; 124 } 125 126 /** 127 * @return {@code true} if the keyguard is going away, {@code false} otherwise. 128 */ isKeyguardGoingAway()129 boolean isKeyguardGoingAway() { 130 // Also check keyguard showing in case value is stale. 131 return mKeyguardGoingAway && mKeyguardShowing; 132 } 133 134 /** 135 * Update the Keyguard showing state. 136 */ setKeyguardShown(boolean keyguardShowing, boolean aodShowing)137 void setKeyguardShown(boolean keyguardShowing, boolean aodShowing) { 138 // If keyguard is going away, but SystemUI aborted the transition, need to reset state. 139 final boolean keyguardChanged = keyguardShowing != mKeyguardShowing 140 || mKeyguardGoingAway && keyguardShowing; 141 final boolean aodChanged = aodShowing != mAodShowing; 142 if (!keyguardChanged && !aodChanged) { 143 return; 144 } 145 mKeyguardShowing = keyguardShowing; 146 mAodShowing = aodShowing; 147 mWindowManager.setAodShowing(aodShowing); 148 149 if (keyguardChanged) { 150 // Irrelevant to AOD. 151 dismissDockedStackIfNeeded(); 152 setKeyguardGoingAway(false); 153 if (keyguardShowing) { 154 mDismissalRequested = false; 155 } 156 } 157 // TODO(b/113840485): Check usage for non-default display 158 mWindowManager.setKeyguardOrAodShowingOnDefaultDisplay( 159 isKeyguardOrAodShowing(DEFAULT_DISPLAY)); 160 161 // Update the sleep token first such that ensureActivitiesVisible has correct sleep token 162 // state when evaluating visibilities. 163 updateKeyguardSleepToken(); 164 mRootActivityContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS); 165 } 166 167 /** 168 * Called when Keyguard is going away. 169 * 170 * @param flags See {@link WindowManagerPolicy#KEYGUARD_GOING_AWAY_FLAG_TO_SHADE} 171 * etc. 172 */ keyguardGoingAway(int flags)173 void keyguardGoingAway(int flags) { 174 if (!mKeyguardShowing) { 175 return; 176 } 177 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "keyguardGoingAway"); 178 mWindowManager.deferSurfaceLayout(); 179 try { 180 setKeyguardGoingAway(true); 181 mRootActivityContainer.getDefaultDisplay().mDisplayContent 182 .prepareAppTransition(TRANSIT_KEYGUARD_GOING_AWAY, 183 false /* alwaysKeepCurrent */, convertTransitFlags(flags), 184 false /* forceOverride */); 185 updateKeyguardSleepToken(); 186 187 // Some stack visibility might change (e.g. docked stack) 188 mRootActivityContainer.resumeFocusedStacksTopActivities(); 189 mRootActivityContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS); 190 mRootActivityContainer.addStartingWindowsForVisibleActivities( 191 true /* taskSwitch */); 192 mWindowManager.executeAppTransition(); 193 } finally { 194 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "keyguardGoingAway: surfaceLayout"); 195 mWindowManager.continueSurfaceLayout(); 196 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER); 197 198 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER); 199 } 200 } 201 dismissKeyguard(IBinder token, IKeyguardDismissCallback callback, CharSequence message)202 void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback, CharSequence message) { 203 final ActivityRecord activityRecord = ActivityRecord.forTokenLocked(token); 204 if (activityRecord == null || !activityRecord.visibleIgnoringKeyguard) { 205 failCallback(callback); 206 return; 207 } 208 Slog.i(TAG, "Activity requesting to dismiss Keyguard: " + activityRecord); 209 210 // If the client has requested to dismiss the keyguard and the Activity has the flag to 211 // turn the screen on, wakeup the screen if it's the top Activity. 212 if (activityRecord.getTurnScreenOnFlag() && activityRecord.isTopRunningActivity()) { 213 mStackSupervisor.wakeUp("dismissKeyguard"); 214 } 215 216 mWindowManager.dismissKeyguard(callback, message); 217 } 218 setKeyguardGoingAway(boolean keyguardGoingAway)219 private void setKeyguardGoingAway(boolean keyguardGoingAway) { 220 mKeyguardGoingAway = keyguardGoingAway; 221 mWindowManager.setKeyguardGoingAway(keyguardGoingAway); 222 } 223 failCallback(IKeyguardDismissCallback callback)224 private void failCallback(IKeyguardDismissCallback callback) { 225 try { 226 callback.onDismissError(); 227 } catch (RemoteException e) { 228 Slog.w(TAG, "Failed to call callback", e); 229 } 230 } 231 convertTransitFlags(int keyguardGoingAwayFlags)232 private int convertTransitFlags(int keyguardGoingAwayFlags) { 233 int result = 0; 234 if ((keyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_TO_SHADE) != 0) { 235 result |= TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE; 236 } 237 if ((keyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS) != 0) { 238 result |= TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION; 239 } 240 if ((keyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER) != 0) { 241 result |= TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER; 242 } 243 if ((keyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_SUBTLE_WINDOW_ANIMATIONS) != 0) { 244 result |= TRANSIT_FLAG_KEYGUARD_GOING_AWAY_SUBTLE_ANIMATION; 245 } 246 return result; 247 } 248 249 /** 250 * Starts a batch of visibility updates. 251 */ beginActivityVisibilityUpdate()252 void beginActivityVisibilityUpdate() { 253 mVisibilityTransactionDepth++; 254 } 255 256 /** 257 * Ends a batch of visibility updates. After all batches are done, this method makes sure to 258 * update lockscreen occluded/dismiss state if needed. 259 */ endActivityVisibilityUpdate()260 void endActivityVisibilityUpdate() { 261 mVisibilityTransactionDepth--; 262 if (mVisibilityTransactionDepth == 0) { 263 visibilitiesUpdated(); 264 } 265 } 266 267 /** 268 * @return True if we may show an activity while Keyguard is showing because we are in the 269 * process of dismissing it anyways, false otherwise. 270 */ canShowActivityWhileKeyguardShowing(ActivityRecord r, boolean dismissKeyguard)271 boolean canShowActivityWhileKeyguardShowing(ActivityRecord r, boolean dismissKeyguard) { 272 273 // Allow to show it when we are about to dismiss Keyguard. This isn't allowed if r is 274 // already the dismissing activity, in which case we don't allow it to repeatedly dismiss 275 // Keyguard. 276 return dismissKeyguard && canDismissKeyguard() && !mAodShowing 277 && (mDismissalRequested 278 || (r.canShowWhenLocked() 279 && getDisplay(r.getDisplayId()).mDismissingKeyguardActivity != r)); 280 } 281 282 /** 283 * @return True if we may show an activity while Keyguard is occluded, false otherwise. 284 */ canShowWhileOccluded(boolean dismissKeyguard, boolean showWhenLocked)285 boolean canShowWhileOccluded(boolean dismissKeyguard, boolean showWhenLocked) { 286 return showWhenLocked || dismissKeyguard 287 && !mWindowManager.isKeyguardSecure(mService.getCurrentUserId()); 288 } 289 visibilitiesUpdated()290 private void visibilitiesUpdated() { 291 boolean requestDismissKeyguard = false; 292 for (int displayNdx = mRootActivityContainer.getChildCount() - 1; 293 displayNdx >= 0; displayNdx--) { 294 final ActivityDisplay display = mRootActivityContainer.getChildAt(displayNdx); 295 final KeyguardDisplayState state = getDisplay(display.mDisplayId); 296 state.visibilitiesUpdated(this, display); 297 requestDismissKeyguard |= state.mRequestDismissKeyguard; 298 } 299 300 // Dismissing Keyguard happens globally using the information from all displays. 301 if (requestDismissKeyguard) { 302 handleDismissKeyguard(); 303 } 304 } 305 306 /** 307 * Called when occluded state changed. 308 */ handleOccludedChanged(int displayId)309 private void handleOccludedChanged(int displayId) { 310 // TODO(b/113840485): Handle app transition for individual display, and apply occluded 311 // state change to secondary displays. 312 // For now, only default display fully supports occluded change. Other displays only 313 // updates keygaurd sleep token on that display. 314 if (displayId != DEFAULT_DISPLAY) { 315 updateKeyguardSleepToken(displayId); 316 return; 317 } 318 319 mWindowManager.onKeyguardOccludedChanged(isDisplayOccluded(DEFAULT_DISPLAY)); 320 if (isKeyguardLocked()) { 321 mWindowManager.deferSurfaceLayout(); 322 try { 323 mRootActivityContainer.getDefaultDisplay().mDisplayContent 324 .prepareAppTransition(resolveOccludeTransit(), 325 false /* alwaysKeepCurrent */, 0 /* flags */, 326 true /* forceOverride */); 327 updateKeyguardSleepToken(DEFAULT_DISPLAY); 328 mRootActivityContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS); 329 mWindowManager.executeAppTransition(); 330 } finally { 331 mWindowManager.continueSurfaceLayout(); 332 } 333 } 334 dismissDockedStackIfNeeded(); 335 } 336 337 /** 338 * Called when somebody wants to dismiss the Keyguard via the flag. 339 */ handleDismissKeyguard()340 private void handleDismissKeyguard() { 341 // We only allow dismissing Keyguard via the flag when Keyguard is secure for legacy 342 // reasons, because that's how apps used to dismiss Keyguard in the secure case. In the 343 // insecure case, we actually show it on top of the lockscreen. See #canShowWhileOccluded. 344 if (!mWindowManager.isKeyguardSecure(mService.getCurrentUserId())) { 345 return; 346 } 347 348 mWindowManager.dismissKeyguard(null /* callback */, null /* message */); 349 mDismissalRequested = true; 350 351 // If we are about to unocclude the Keyguard, but we can dismiss it without security, 352 // we immediately dismiss the Keyguard so the activity gets shown without a flicker. 353 final DisplayContent dc = 354 mRootActivityContainer.getDefaultDisplay().mDisplayContent; 355 if (mKeyguardShowing && canDismissKeyguard() 356 && dc.mAppTransition.getAppTransition() == TRANSIT_KEYGUARD_UNOCCLUDE) { 357 dc.prepareAppTransition(mBeforeUnoccludeTransit, false /* alwaysKeepCurrent */, 358 0 /* flags */, true /* forceOverride */); 359 mRootActivityContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS); 360 mWindowManager.executeAppTransition(); 361 } 362 } 363 isDisplayOccluded(int displayId)364 private boolean isDisplayOccluded(int displayId) { 365 return getDisplay(displayId).mOccluded; 366 } 367 368 /** 369 * @return true if Keyguard can be currently dismissed without entering credentials. 370 */ canDismissKeyguard()371 boolean canDismissKeyguard() { 372 return mWindowManager.isKeyguardTrusted() 373 || !mWindowManager.isKeyguardSecure(mService.getCurrentUserId()); 374 } 375 resolveOccludeTransit()376 private int resolveOccludeTransit() { 377 final DisplayContent dc = 378 mService.mRootActivityContainer.getDefaultDisplay().mDisplayContent; 379 if (mBeforeUnoccludeTransit != TRANSIT_UNSET 380 && dc.mAppTransition.getAppTransition() == TRANSIT_KEYGUARD_UNOCCLUDE 381 // TODO(b/113840485): Handle app transition for individual display. 382 && isDisplayOccluded(DEFAULT_DISPLAY)) { 383 384 // Reuse old transit in case we are occluding Keyguard again, meaning that we never 385 // actually occclude/unocclude Keyguard, but just run a normal transition. 386 return mBeforeUnoccludeTransit; 387 // TODO(b/113840485): Handle app transition for individual display. 388 } else if (!isDisplayOccluded(DEFAULT_DISPLAY)) { 389 390 // Save transit in case we dismiss/occlude Keyguard shortly after. 391 mBeforeUnoccludeTransit = dc.mAppTransition.getAppTransition(); 392 return TRANSIT_KEYGUARD_UNOCCLUDE; 393 } else { 394 return TRANSIT_KEYGUARD_OCCLUDE; 395 } 396 } 397 dismissDockedStackIfNeeded()398 private void dismissDockedStackIfNeeded() { 399 // TODO(b/113840485): Handle docked stack for individual display. 400 if (mKeyguardShowing && isDisplayOccluded(DEFAULT_DISPLAY)) { 401 // The lock screen is currently showing, but is occluded by a window that can 402 // show on top of the lock screen. In this can we want to dismiss the docked 403 // stack since it will be complicated/risky to try to put the activity on top 404 // of the lock screen in the right fullscreen configuration. 405 final ActivityStack stack = 406 mRootActivityContainer.getDefaultDisplay().getSplitScreenPrimaryStack(); 407 if (stack == null) { 408 return; 409 } 410 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, 411 stack.isFocusedStackOnDisplay()); 412 } 413 } 414 updateKeyguardSleepToken()415 private void updateKeyguardSleepToken() { 416 for (int displayNdx = mRootActivityContainer.getChildCount() - 1; 417 displayNdx >= 0; displayNdx--) { 418 final ActivityDisplay display = mRootActivityContainer.getChildAt(displayNdx); 419 updateKeyguardSleepToken(display.mDisplayId); 420 } 421 } 422 updateKeyguardSleepToken(int displayId)423 private void updateKeyguardSleepToken(int displayId) { 424 final KeyguardDisplayState state = getDisplay(displayId); 425 if (isKeyguardUnoccludedOrAodShowing(displayId) && state.mSleepToken == null) { 426 state.acquiredSleepToken(); 427 } else if (!isKeyguardUnoccludedOrAodShowing(displayId) && state.mSleepToken != null) { 428 state.releaseSleepToken(); 429 } 430 } 431 getDisplay(int displayId)432 private KeyguardDisplayState getDisplay(int displayId) { 433 KeyguardDisplayState state = mDisplayStates.get(displayId); 434 if (state == null) { 435 state = new KeyguardDisplayState(mService, displayId); 436 mDisplayStates.append(displayId, state); 437 } 438 return state; 439 } 440 onDisplayRemoved(int displayId)441 void onDisplayRemoved(int displayId) { 442 final KeyguardDisplayState state = mDisplayStates.get(displayId); 443 if (state != null) { 444 state.onRemoved(); 445 mDisplayStates.remove(displayId); 446 } 447 } 448 449 /** Represents Keyguard state per individual display. */ 450 private static class KeyguardDisplayState { 451 private final int mDisplayId; 452 private boolean mOccluded; 453 private ActivityRecord mDismissingKeyguardActivity; 454 private boolean mRequestDismissKeyguard; 455 private final ActivityTaskManagerService mService; 456 private SleepToken mSleepToken; 457 KeyguardDisplayState(ActivityTaskManagerService service, int displayId)458 KeyguardDisplayState(ActivityTaskManagerService service, int displayId) { 459 mService = service; 460 mDisplayId = displayId; 461 } 462 onRemoved()463 void onRemoved() { 464 mDismissingKeyguardActivity = null; 465 releaseSleepToken(); 466 } 467 acquiredSleepToken()468 void acquiredSleepToken() { 469 if (mSleepToken == null) { 470 mSleepToken = mService.acquireSleepToken("keyguard", mDisplayId); 471 } 472 } 473 releaseSleepToken()474 void releaseSleepToken() { 475 if (mSleepToken != null) { 476 mSleepToken.release(); 477 mSleepToken = null; 478 } 479 } 480 visibilitiesUpdated(KeyguardController controller, ActivityDisplay display)481 void visibilitiesUpdated(KeyguardController controller, ActivityDisplay display) { 482 final boolean lastOccluded = mOccluded; 483 final ActivityRecord lastDismissActivity = mDismissingKeyguardActivity; 484 mRequestDismissKeyguard = false; 485 mOccluded = false; 486 mDismissingKeyguardActivity = null; 487 488 final ActivityStack stack = getStackForControllingOccluding(display); 489 if (stack != null) { 490 final ActivityRecord topDismissing = stack.getTopDismissingKeyguardActivity(); 491 mOccluded = stack.topActivityOccludesKeyguard() || (topDismissing != null 492 && stack.topRunningActivityLocked() == topDismissing 493 && controller.canShowWhileOccluded( 494 true /* dismissKeyguard */, 495 false /* showWhenLocked */)); 496 if (stack.getTopDismissingKeyguardActivity() != null) { 497 mDismissingKeyguardActivity = stack.getTopDismissingKeyguardActivity(); 498 } 499 // FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD only apply for secondary display. 500 if (mDisplayId != DEFAULT_DISPLAY) { 501 mOccluded |= stack.canShowWithInsecureKeyguard() 502 && controller.canDismissKeyguard(); 503 } 504 } 505 // TODO(b/123372519): isShowingDream can only works on default display. 506 if (mDisplayId == DEFAULT_DISPLAY) { 507 mOccluded |= controller.mWindowManager.isShowingDream(); 508 } 509 510 if (lastOccluded != mOccluded) { 511 controller.handleOccludedChanged(mDisplayId); 512 } 513 if (lastDismissActivity != mDismissingKeyguardActivity && !mOccluded 514 && mDismissingKeyguardActivity != null 515 && controller.mWindowManager.isKeyguardSecure( 516 controller.mService.getCurrentUserId())) { 517 mRequestDismissKeyguard = true; 518 } 519 } 520 521 /** 522 * Gets the stack used to check the occluded state. 523 * <p> 524 * Only the top non-pinned activity of the focusable stack on each display can control its 525 * occlusion state. 526 */ getStackForControllingOccluding(ActivityDisplay display)527 private ActivityStack getStackForControllingOccluding(ActivityDisplay display) { 528 for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { 529 final ActivityStack stack = display.getChildAt(stackNdx); 530 if (stack != null && stack.isFocusableAndVisible() 531 && !stack.inPinnedWindowingMode()) { 532 return stack; 533 } 534 } 535 return null; 536 } 537 dumpStatus(PrintWriter pw, String prefix)538 void dumpStatus(PrintWriter pw, String prefix) { 539 final StringBuilder sb = new StringBuilder(); 540 sb.append(prefix); 541 sb.append(" Occluded=").append(mOccluded) 542 .append(" DismissingKeyguardActivity=") 543 .append(mDismissingKeyguardActivity) 544 .append(" at display=") 545 .append(mDisplayId); 546 pw.println(sb.toString()); 547 } 548 writeToProto(ProtoOutputStream proto, long fieldId)549 void writeToProto(ProtoOutputStream proto, long fieldId) { 550 final long token = proto.start(fieldId); 551 proto.write(DISPLAY_ID, mDisplayId); 552 proto.write(KEYGUARD_OCCLUDED, mOccluded); 553 proto.end(token); 554 } 555 } 556 dump(PrintWriter pw, String prefix)557 void dump(PrintWriter pw, String prefix) { 558 pw.println(prefix + "KeyguardController:"); 559 pw.println(prefix + " mKeyguardShowing=" + mKeyguardShowing); 560 pw.println(prefix + " mAodShowing=" + mAodShowing); 561 pw.println(prefix + " mKeyguardGoingAway=" + mKeyguardGoingAway); 562 dumpDisplayStates(pw, prefix); 563 pw.println(prefix + " mDismissalRequested=" + mDismissalRequested); 564 pw.println(prefix + " mVisibilityTransactionDepth=" + mVisibilityTransactionDepth); 565 } 566 writeToProto(ProtoOutputStream proto, long fieldId)567 void writeToProto(ProtoOutputStream proto, long fieldId) { 568 final long token = proto.start(fieldId); 569 proto.write(AOD_SHOWING, mAodShowing); 570 proto.write(KEYGUARD_SHOWING, mKeyguardShowing); 571 writeDisplayStatesToProto(proto, KEYGUARD_OCCLUDED_STATES); 572 proto.end(token); 573 } 574 dumpDisplayStates(PrintWriter pw, String prefix)575 private void dumpDisplayStates(PrintWriter pw, String prefix) { 576 for (int i = 0; i < mDisplayStates.size(); i++) { 577 mDisplayStates.valueAt(i).dumpStatus(pw, prefix); 578 } 579 } 580 writeDisplayStatesToProto(ProtoOutputStream proto, long fieldId)581 private void writeDisplayStatesToProto(ProtoOutputStream proto, long fieldId) { 582 for (int i = 0; i < mDisplayStates.size(); i++) { 583 mDisplayStates.valueAt(i).writeToProto(proto, fieldId); 584 } 585 } 586 } 587