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