From 9a10e9db6ac2ba69e7e7b21c8e475acc6716d79d Mon Sep 17 00:00:00 2001 From: wilsonshih Date: Fri, 11 Jan 2019 14:39:27 +0800 Subject: [PATCH] Disallow pinned stack to control occluded state. In the original design, we check the top focus stack of each display to control its occlusion state. However, the start time of pinned activity may start later than the user's application, such as PipMenuActivity. In which case the top focus activity will not be what the user expects. To prevent this, we can ignore Pinned stack when checking visibility for a display. Fix: 120445909 Test: atest KeyguardTests KeyguardLockedTests Test: atest ActivityManagerMultiDisplayTests Test: atest ActivityManagerDisplayLockedKeyguardTests ActivityManagerDisplayKeyguardTests Change-Id: I3be19a803aa59c21841e476aa46a0222d156e21e --- .../android/server/wm/KeyguardController.java | 38 +++++++++++++------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/services/core/java/com/android/server/wm/KeyguardController.java b/services/core/java/com/android/server/wm/KeyguardController.java index 5f56fe59c1f2a..177f244129f45 100644 --- a/services/core/java/com/android/server/wm/KeyguardController.java +++ b/services/core/java/com/android/server/wm/KeyguardController.java @@ -462,22 +462,19 @@ class KeyguardController { mOccluded = false; mDismissingKeyguardActivity = null; - // Only the top activity of the focused stack on each display may control it's - // occluded state. - final ActivityStack focusedStack = display.getFocusedStack(); - if (focusedStack != null) { - final ActivityRecord topDismissing = - focusedStack.getTopDismissingKeyguardActivity(); - mOccluded = focusedStack.topActivityOccludesKeyguard() || (topDismissing != null - && focusedStack.topRunningActivityLocked() == topDismissing - && controller.canShowWhileOccluded( + final ActivityStack stack = getStackForControllingOccluding(display); + if (stack != null) { + final ActivityRecord topDismissing = stack.getTopDismissingKeyguardActivity(); + mOccluded = stack.topActivityOccludesKeyguard() || (topDismissing != null + && stack.topRunningActivityLocked() == topDismissing + && controller.canShowWhileOccluded( true /* dismissKeyguard */, false /* showWhenLocked */)); - if (focusedStack.getTopDismissingKeyguardActivity() != null) { - mDismissingKeyguardActivity = focusedStack.getTopDismissingKeyguardActivity(); + if (stack.getTopDismissingKeyguardActivity() != null) { + mDismissingKeyguardActivity = stack.getTopDismissingKeyguardActivity(); } - mOccluded |= controller.mWindowManager.isShowingDream(); } + mOccluded |= controller.mWindowManager.isShowingDream(); // TODO(b/113840485): Handle app transition for individual display, and apply occluded // state change to secondary displays. @@ -492,6 +489,23 @@ class KeyguardController { } } + /** + * Gets the stack used to check the occluded state. + *

+ * Only the top non-pinned activity of the focusable stack on each display can control its + * occlusion state. + */ + private ActivityStack getStackForControllingOccluding(ActivityDisplay display) { + for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { + final ActivityStack stack = display.getChildAt(stackNdx); + if (stack != null && stack.isFocusableAndVisible() + && !stack.inPinnedWindowingMode()) { + return stack; + } + } + return null; + } + void dumpStatus(PrintWriter pw, String prefix) { final StringBuilder sb = new StringBuilder(); sb.append(prefix);