Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9a10e9db authored by wilsonshih's avatar wilsonshih
Browse files

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
parent 44b2b5ac
Loading
Loading
Loading
Loading
+26 −12
Original line number Diff line number Diff line
@@ -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
            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.
         * <p>
         * 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);