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

Commit 556a113a authored by wilsonshih's avatar wilsonshih
Browse files

Only update keyguard status from top focusable visible task.

In original sequence we do KeyguardController#visibilitiesUpdated
at endActivityVisibilityUpdate, so without the check from
mVisibilityTransactionDepth, KeyguardController#visibilitiesUpdated
can actually do RootWindowContainer#ensureActivitiesVisible again
if occluded state has changed. But actually only the top non-pinned
activity on each display can affect the keyguard status. So to make
ensureActivitiesVisible faster, update keyguard status from this task
at beginActivityVisibilityUpdate, then update visibility for each
activities after sleep token is stable.

Bug: 163993448
Bug: 168776729
Test: atest ActivityVisibilityTests KeyguardTests KeyguardLockedTests
KeyguardTransitionTests AppConfigurationTests ReplaceWindowTests
Test: atest ActivityRecordTests RecentTasksTest ActivityStackTests
DisplayContentTests

Change-Id: I6428c59245fc84b0093778d4aaa5906a0b1a26e3
parent a0b1e8ec
Loading
Loading
Loading
Loading
+5 −22
Original line number Original line Diff line number Diff line
@@ -2700,7 +2700,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
                // activities be updated, they may be seen by users.
                // activities be updated, they may be seen by users.
                ensureVisibility = true;
                ensureVisibility = true;
            } else if (mStackSupervisor.getKeyguardController().isKeyguardLocked()
            } else if (mStackSupervisor.getKeyguardController().isKeyguardLocked()
                    && stack.topActivityOccludesKeyguard()) {
                    && mStackSupervisor.getKeyguardController().topActivityOccludesKeyguard(this)) {
                // Ensure activity visibilities and update lockscreen occluded/dismiss state when
                // Ensure activity visibilities and update lockscreen occluded/dismiss state when
                // finishing the top activity that occluded keyguard. So that, the
                // finishing the top activity that occluded keyguard. So that, the
                // ActivityStack#mTopActivityOccludesKeyguard can be updated and the activity below
                // ActivityStack#mTopActivityOccludesKeyguard can be updated and the activity below
@@ -4628,15 +4628,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        mDisplayContent.mUnknownAppVisibilityController.notifyLaunched(this);
        mDisplayContent.mUnknownAppVisibilityController.notifyLaunched(this);
    }
    }


    private void updateVisibleIgnoringKeyguard(boolean behindFullscreenActivity) {
        // Check whether activity should be visible without Keyguard influence
        visibleIgnoringKeyguard = (!behindFullscreenActivity || mLaunchTaskBehind)
                && okToShowLocked();
    }

    /** @return {@code true} if this activity should be made visible. */
    /** @return {@code true} if this activity should be made visible. */
    private boolean shouldBeVisible(boolean behindFullscreenActivity, boolean ignoringKeyguard) {
    private boolean shouldBeVisible(boolean behindFullscreenActivity, boolean ignoringKeyguard) {
        updateVisibleIgnoringKeyguard(behindFullscreenActivity);
        updateVisibilityIgnoringKeyguard(behindFullscreenActivity);


        if (ignoringKeyguard) {
        if (ignoringKeyguard) {
            return visibleIgnoringKeyguard;
            return visibleIgnoringKeyguard;
@@ -4670,20 +4664,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        return mStackSupervisor.getKeyguardController().checkKeyguardVisibility(this);
        return mStackSupervisor.getKeyguardController().checkKeyguardVisibility(this);
    }
    }


    void updateVisibility(boolean behindFullscreenActivity) {
    void updateVisibilityIgnoringKeyguard(boolean behindFullscreenActivity) {
        updateVisibleIgnoringKeyguard(behindFullscreenActivity);
        visibleIgnoringKeyguard = (!behindFullscreenActivity || mLaunchTaskBehind)
        final Task task = getRootTask();
                && okToShowLocked();
        if (task == null || !visibleIgnoringKeyguard) {
            return;
        }
        // Now check whether it's really visible depending on Keyguard state, and update
        // {@link ActivityStack} internal states.
        // Inform the method if this activity is the top activity of this stack, but exclude the
        // case where this is the top activity in a pinned stack.
        final boolean isTop = this == task.getTopNonFinishingActivity();
        final boolean isTopNotPinnedStack = task.isAttached()
                && task.getDisplayArea().isTopNotFinishNotPinnedStack(task);
        task.updateKeyguardVisibility(this, isTop && isTopNotPinnedStack);
    }
    }


    boolean shouldBeVisible() {
    boolean shouldBeVisible() {
+4 −8
Original line number Original line Diff line number Diff line
@@ -2304,18 +2304,14 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {


    /** Starts a batch of visibility updates. */
    /** Starts a batch of visibility updates. */
    void beginActivityVisibilityUpdate() {
    void beginActivityVisibilityUpdate() {
        if (mVisibilityTransactionDepth == 0) {
            getKeyguardController().updateVisibility();
        }
        mVisibilityTransactionDepth++;
        mVisibilityTransactionDepth++;
    }
    }


    /** Ends a batch of visibility updates. */
    /** Ends a batch of visibility updates. */
    void endActivityVisibilityUpdate(ActivityRecord starting, int configChanges,
    void endActivityVisibilityUpdate() {
            boolean preserveWindows, boolean notifyClients) {
        if (mVisibilityTransactionDepth == 1) {
            getKeyguardController().visibilitiesUpdated();
            // commit visibility to activities
            mRootWindowContainer.commitActivitiesVisible(starting, configChanges, preserveWindows,
                    notifyClients);
        }
        mVisibilityTransactionDepth--;
        mVisibilityTransactionDepth--;
    }
    }


+47 −70
Original line number Original line Diff line number Diff line
@@ -63,26 +63,8 @@ class EnsureActivitiesVisibleHelper {
    }
    }


    /**
    /**
     * Update visibility to activities.
     * Update and commit visibility with an option to also update the configuration of visible
     * @see Task#ensureActivitiesVisible(ActivityRecord, int, boolean)
     * activities.
     * @see RootWindowContainer#ensureActivitiesVisible(ActivityRecord, int, boolean)
     * @param starting The top most activity in the task.
     *                 The activity is either starting or resuming.
     *                 Caller should ensure starting activity is visible.
     *
     */
    void processUpdate(@Nullable ActivityRecord starting) {
        reset(starting, 0 /* configChanges */, false /* preserveWindows */,
                false /* notifyClients */);
        if (DEBUG_VISIBILITY) {
            Slog.v(TAG_VISIBILITY, "ensureActivitiesVisible processUpdate behind " + mTop);
        }

        mTask.forAllActivities(this::updateActivityVisibility);
    }

    /**
     * Commit visibility with an option to also update the configuration of visible activities.
     * @see Task#ensureActivitiesVisible(ActivityRecord, int, boolean)
     * @see Task#ensureActivitiesVisible(ActivityRecord, int, boolean)
     * @see RootWindowContainer#ensureActivitiesVisible(ActivityRecord, int, boolean)
     * @see RootWindowContainer#ensureActivitiesVisible(ActivityRecord, int, boolean)
     * @param starting The top most activity in the task.
     * @param starting The top most activity in the task.
@@ -95,12 +77,13 @@ class EnsureActivitiesVisibleHelper {
     * @param notifyClients Flag indicating whether the configuration and visibility changes shoulc
     * @param notifyClients Flag indicating whether the configuration and visibility changes shoulc
     *                      be sent to the clients.
     *                      be sent to the clients.
     */
     */
    void processCommit(ActivityRecord starting, int configChanges,
    void process(@Nullable ActivityRecord starting, int configChanges, boolean preserveWindows,
            boolean preserveWindows, boolean notifyClients) {
            boolean notifyClients) {
        reset(starting, configChanges, preserveWindows, notifyClients);
        reset(starting, configChanges, preserveWindows, notifyClients);


        if (DEBUG_VISIBILITY) {
        if (DEBUG_VISIBILITY) {
            Slog.v(TAG_VISIBILITY, "ensureActivitiesVisible processCommit behind " + mTop);
            Slog.v(TAG_VISIBILITY, "ensureActivitiesVisible behind " + mTop
                    + " configChanges=0x" + Integer.toHexString(configChanges));
        }
        }
        if (mTop != null) {
        if (mTop != null) {
            mTask.checkTranslucentActivityWaiting(mTop);
            mTask.checkTranslucentActivityWaiting(mTop);
@@ -114,25 +97,20 @@ class EnsureActivitiesVisibleHelper {
                && (starting == null || !starting.isDescendantOf(mTask));
                && (starting == null || !starting.isDescendantOf(mTask));


        mTask.forAllActivities(a -> {
        mTask.forAllActivities(a -> {
            commitActivityVisibility(a, starting, resumeTopActivity);
            setActivityVisibilityState(a, starting, resumeTopActivity);
        });
        });
    }
    }


    private boolean isAboveTop(boolean isTop) {
    private void setActivityVisibilityState(ActivityRecord r, ActivityRecord starting,
        if (mAboveTop && !isTop) {
            final boolean resumeTopActivity) {
            return true;
        }
        mAboveTop = false;
        return false;
    }

    private void updateActivityVisibility(ActivityRecord r) {
        final boolean isTop = r == mTop;
        final boolean isTop = r == mTop;
        if (isAboveTop(isTop)) {
        if (mAboveTop && !isTop) {
            return;
            return;
        }
        }
        mAboveTop = false;


        r.updateVisibility(mBehindFullscreenActivity);
        r.updateVisibilityIgnoringKeyguard(mBehindFullscreenActivity);
        final boolean reallyVisible = r.shouldBeVisibleUnchecked();


        // Check whether activity should be visible without Keyguard influence
        // Check whether activity should be visible without Keyguard influence
        if (r.visibleIgnoringKeyguard) {
        if (r.visibleIgnoringKeyguard) {
@@ -149,36 +127,14 @@ class EnsureActivitiesVisibleHelper {
            }
            }
        }
        }


        if (!mBehindFullscreenActivity && mTask.isActivityTypeHome() && r.isRootOfTask()) {
            if (DEBUG_VISIBILITY) {
                Slog.v(TAG_VISIBILITY, "Home task: at " + mTask
                        + " stackShouldBeVisible=" + mContainerShouldBeVisible
                        + " behindFullscreenActivity=" + mBehindFullscreenActivity);
            }
            // No other task in the home stack should be visible behind the home activity.
            // Home activities is usually a translucent activity with the wallpaper behind
            // them. However, when they don't have the wallpaper behind them, we want to
            // show activities in the next application stack behind them vs. another
            // task in the home stack like recents.
            mBehindFullscreenActivity = true;
        }
    }

    private void commitActivityVisibility(ActivityRecord r, ActivityRecord starting,
            final boolean resumeTopActivity) {
        final boolean isTop = r == mTop;
        if (isAboveTop(isTop)) {
            return;
        }

        final boolean reallyVisible = r.shouldBeVisibleUnchecked();

        if (reallyVisible) {
        if (reallyVisible) {
            if (r.finishing) {
            if (r.finishing) {
                return;
                return;
            }
            }
            if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Make visible? " + r
            if (DEBUG_VISIBILITY) {
                Slog.v(TAG_VISIBILITY, "Make visible? " + r
                        + " finishing=" + r.finishing + " state=" + r.getState());
                        + " finishing=" + r.finishing + " state=" + r.getState());
            }
            // First: if this is not the current activity being started, make
            // First: if this is not the current activity being started, make
            // sure it matches the current configuration.
            // sure it matches the current configuration.
            if (r != mStarting && mNotifyClients) {
            if (r != mStarting && mNotifyClients) {
@@ -191,8 +147,9 @@ class EnsureActivitiesVisibleHelper {
                        resumeTopActivity && isTop, r);
                        resumeTopActivity && isTop, r);
            } else if (r.mVisibleRequested) {
            } else if (r.mVisibleRequested) {
                // If this activity is already visible, then there is nothing to do here.
                // If this activity is already visible, then there is nothing to do here.
                if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
                if (DEBUG_VISIBILITY) {
                        "Skipping: already visible at " + r);
                    Slog.v(TAG_VISIBILITY, "Skipping: already visible at " + r);
                }


                if (r.mClientVisibilityDeferred && mNotifyClients) {
                if (r.mClientVisibilityDeferred && mNotifyClients) {
                    r.makeActiveIfNeeded(r.mClientVisibilityDeferred ? null : starting);
                    r.makeActiveIfNeeded(r.mClientVisibilityDeferred ? null : starting);
@@ -209,13 +166,29 @@ class EnsureActivitiesVisibleHelper {
            // Aggregate current change flags.
            // Aggregate current change flags.
            mConfigChanges |= r.configChangeFlags;
            mConfigChanges |= r.configChangeFlags;
        } else {
        } else {
            if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Make invisible? " + r
            if (DEBUG_VISIBILITY) {
                Slog.v(TAG_VISIBILITY, "Make invisible? " + r
                        + " finishing=" + r.finishing + " state=" + r.getState()
                        + " finishing=" + r.finishing + " state=" + r.getState()
                        + " stackShouldBeVisible=" + mContainerShouldBeVisible
                        + " stackShouldBeVisible=" + mContainerShouldBeVisible
                        + " behindFullscreenActivity=" + mBehindFullscreenActivity
                        + " behindFullscreenActivity=" + mBehindFullscreenActivity
                        + " mLaunchTaskBehind=" + r.mLaunchTaskBehind);
                        + " mLaunchTaskBehind=" + r.mLaunchTaskBehind);
            }
            r.makeInvisible();
            r.makeInvisible();
        }
        }

        if (!mBehindFullscreenActivity && mTask.isActivityTypeHome() && r.isRootOfTask()) {
            if (DEBUG_VISIBILITY) {
                Slog.v(TAG_VISIBILITY, "Home task: at " + mTask
                        + " stackShouldBeVisible=" + mContainerShouldBeVisible
                        + " behindFullscreenActivity=" + mBehindFullscreenActivity);
            }
            // No other task in the home stack should be visible behind the home activity.
            // Home activities is usually a translucent activity with the wallpaper behind
            // them. However, when they don't have the wallpaper behind them, we want to
            // show activities in the next application stack behind them vs. another
            // task in the home stack like recents.
            mBehindFullscreenActivity = true;
        }
    }
    }


    private void makeVisibleAndRestartIfNeeded(ActivityRecord starting, int configChanges,
    private void makeVisibleAndRestartIfNeeded(ActivityRecord starting, int configChanges,
@@ -230,12 +203,16 @@ class EnsureActivitiesVisibleHelper {


        // This activity needs to be visible, but isn't even running...
        // This activity needs to be visible, but isn't even running...
        // get it started and resume if no other stack in this stack is resumed.
        // get it started and resume if no other stack in this stack is resumed.
        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Start and freeze screen for " + r);
        if (DEBUG_VISIBILITY) {
            Slog.v(TAG_VISIBILITY, "Start and freeze screen for " + r);
        }
        if (r != starting) {
        if (r != starting) {
            r.startFreezingScreenLocked(configChanges);
            r.startFreezingScreenLocked(configChanges);
        }
        }
        if (!r.mVisibleRequested || r.mLaunchTaskBehind) {
        if (!r.mVisibleRequested || r.mLaunchTaskBehind) {
            if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Starting and making visible: " + r);
            if (DEBUG_VISIBILITY) {
                Slog.v(TAG_VISIBILITY, "Starting and making visible: " + r);
            }
            r.setVisibility(true);
            r.setVisibility(true);
        }
        }
        if (r != starting) {
        if (r != starting) {
+80 −52
Original line number Original line Diff line number Diff line
@@ -124,6 +124,14 @@ class KeyguardController {
        return mKeyguardShowing && !mKeyguardGoingAway;
        return mKeyguardShowing && !mKeyguardGoingAway;
    }
    }


    /**
     *
     * @return true if the activity is controlling keyguard state.
     */
    boolean topActivityOccludesKeyguard(ActivityRecord r) {
        return getDisplayState(r.getDisplayId()).mTopOccludesActivity == r;
    }

    /**
    /**
     * @return {@code true} if the keyguard is going away, {@code false} otherwise.
     * @return {@code true} if the keyguard is going away, {@code false} otherwise.
     */
     */
@@ -258,15 +266,14 @@ class KeyguardController {
     * @return True if we may show an activity while Keyguard is showing because we are in the
     * @return True if we may show an activity while Keyguard is showing because we are in the
     *         process of dismissing it anyways, false otherwise.
     *         process of dismissing it anyways, false otherwise.
     */
     */
    boolean canShowActivityWhileKeyguardShowing(ActivityRecord r, boolean dismissKeyguard) {
    boolean canShowActivityWhileKeyguardShowing(ActivityRecord r) {

        // Allow to show it when we are about to dismiss Keyguard. This isn't allowed if r is
        // Allow to show it when we are about to dismiss Keyguard. This isn't allowed if r is
        // already the dismissing activity, in which case we don't allow it to repeatedly dismiss
        // already the dismissing activity, in which case we don't allow it to repeatedly dismiss
        // Keyguard.
        // Keyguard.
        return dismissKeyguard && canDismissKeyguard() && !mAodShowing
        return r.containsDismissKeyguardWindow() && canDismissKeyguard() && !mAodShowing
                && (mDismissalRequested
                && (mDismissalRequested
                || (r.canShowWhenLocked()
                || (r.canShowWhenLocked()
                        && getDisplay(r.getDisplayId()).mDismissingKeyguardActivity != r));
                        && getDisplayState(r.getDisplayId()).mDismissingKeyguardActivity != r));
    }
    }


    /**
    /**
@@ -290,7 +297,7 @@ class KeyguardController {
        if (isKeyguardOrAodShowing(r.mDisplayContent.getDisplayId())) {
        if (isKeyguardOrAodShowing(r.mDisplayContent.getDisplayId())) {
            // If keyguard is showing, nothing is visible, except if we are able to dismiss Keyguard
            // If keyguard is showing, nothing is visible, except if we are able to dismiss Keyguard
            // right away and AOD isn't visible.
            // right away and AOD isn't visible.
            return canShowActivityWhileKeyguardShowing(r, r.containsDismissKeyguardWindow());
            return canShowActivityWhileKeyguardShowing(r);
        } else if (isKeyguardLocked()) {
        } else if (isKeyguardLocked()) {
            return canShowWhileOccluded(r.containsDismissKeyguardWindow(), r.canShowWhenLocked());
            return canShowWhileOccluded(r.containsDismissKeyguardWindow(), r.canShowWhenLocked());
        } else {
        } else {
@@ -299,16 +306,17 @@ class KeyguardController {
    }
    }


    /**
    /**
     * Makes sure to update lockscreen occluded/dismiss state if needed after completing all
     * Makes sure to update lockscreen occluded/dismiss/turnScreenOn state if needed before
     * visibility updates ({@link ActivityStackSupervisor#endActivityVisibilityUpdate}).
     * completing set all visibility
     * ({@link ActivityStackSupervisor#beginActivityVisibilityUpdate}).
     */
     */
    void visibilitiesUpdated() {
    void updateVisibility() {
        boolean requestDismissKeyguard = false;
        boolean requestDismissKeyguard = false;
        for (int displayNdx = mRootWindowContainer.getChildCount() - 1;
        for (int displayNdx = mRootWindowContainer.getChildCount() - 1;
             displayNdx >= 0; displayNdx--) {
             displayNdx >= 0; displayNdx--) {
            final DisplayContent display = mRootWindowContainer.getChildAt(displayNdx);
            final DisplayContent display = mRootWindowContainer.getChildAt(displayNdx);
            final KeyguardDisplayState state = getDisplay(display.mDisplayId);
            final KeyguardDisplayState state = getDisplayState(display.mDisplayId);
            state.visibilitiesUpdated(this, display);
            state.updateVisibility(this, display);
            requestDismissKeyguard |= state.mRequestDismissKeyguard;
            requestDismissKeyguard |= state.mRequestDismissKeyguard;
        }
        }


@@ -340,7 +348,6 @@ class KeyguardController {
                                false /* alwaysKeepCurrent */, 0 /* flags */,
                                false /* alwaysKeepCurrent */, 0 /* flags */,
                                true /* forceOverride */);
                                true /* forceOverride */);
                updateKeyguardSleepToken(DEFAULT_DISPLAY);
                updateKeyguardSleepToken(DEFAULT_DISPLAY);
                mRootWindowContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
                mWindowManager.executeAppTransition();
                mWindowManager.executeAppTransition();
            } finally {
            } finally {
                mService.continueWindowLayout();
                mService.continueWindowLayout();
@@ -370,13 +377,12 @@ class KeyguardController {
                && dc.mAppTransition.getAppTransition() == TRANSIT_KEYGUARD_UNOCCLUDE) {
                && dc.mAppTransition.getAppTransition() == TRANSIT_KEYGUARD_UNOCCLUDE) {
            dc.prepareAppTransition(mBeforeUnoccludeTransit, false /* alwaysKeepCurrent */,
            dc.prepareAppTransition(mBeforeUnoccludeTransit, false /* alwaysKeepCurrent */,
                    0 /* flags */, true /* forceOverride */);
                    0 /* flags */, true /* forceOverride */);
            mRootWindowContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
            mWindowManager.executeAppTransition();
            mWindowManager.executeAppTransition();
        }
        }
    }
    }


    private boolean isDisplayOccluded(int displayId) {
    boolean isDisplayOccluded(int displayId) {
        return getDisplay(displayId).mOccluded;
        return getDisplayState(displayId).mOccluded;
    }
    }


    /**
    /**
@@ -433,7 +439,7 @@ class KeyguardController {
    }
    }


    private void updateKeyguardSleepToken(int displayId) {
    private void updateKeyguardSleepToken(int displayId) {
        final KeyguardDisplayState state = getDisplay(displayId);
        final KeyguardDisplayState state = getDisplayState(displayId);
        if (isKeyguardUnoccludedOrAodShowing(displayId)) {
        if (isKeyguardUnoccludedOrAodShowing(displayId)) {
            state.mSleepTokenAcquirer.acquire(displayId);
            state.mSleepTokenAcquirer.acquire(displayId);
        } else if (!isKeyguardUnoccludedOrAodShowing(displayId)) {
        } else if (!isKeyguardUnoccludedOrAodShowing(displayId)) {
@@ -441,7 +447,7 @@ class KeyguardController {
        }
        }
    }
    }


    private KeyguardDisplayState getDisplay(int displayId) {
    private KeyguardDisplayState getDisplayState(int displayId) {
        KeyguardDisplayState state = mDisplayStates.get(displayId);
        KeyguardDisplayState state = mDisplayStates.get(displayId);
        if (state == null) {
        if (state == null) {
            state = new KeyguardDisplayState(mService, displayId, mSleepTokenAcquirer);
            state = new KeyguardDisplayState(mService, displayId, mSleepTokenAcquirer);
@@ -462,8 +468,11 @@ class KeyguardController {
    private static class KeyguardDisplayState {
    private static class KeyguardDisplayState {
        private final int mDisplayId;
        private final int mDisplayId;
        private boolean mOccluded;
        private boolean mOccluded;

        private ActivityRecord mTopOccludesActivity;
        private ActivityRecord mDismissingKeyguardActivity;
        private ActivityRecord mDismissingKeyguardActivity;
        private ActivityRecord mTopTurnScreenOnActivity;
        private ActivityRecord mTopTurnScreenOnActivity;

        private boolean mRequestDismissKeyguard;
        private boolean mRequestDismissKeyguard;
        private final ActivityTaskManagerService mService;
        private final ActivityTaskManagerService mService;
        private final ActivityTaskManagerInternal.SleepTokenAcquirer mSleepTokenAcquirer;
        private final ActivityTaskManagerInternal.SleepTokenAcquirer mSleepTokenAcquirer;
@@ -476,58 +485,77 @@ class KeyguardController {
        }
        }


        void onRemoved() {
        void onRemoved() {
            mTopOccludesActivity = null;
            mDismissingKeyguardActivity = null;
            mDismissingKeyguardActivity = null;
            mTopTurnScreenOnActivity = null;
            mTopTurnScreenOnActivity = null;
            mSleepTokenAcquirer.release(mDisplayId);
            mSleepTokenAcquirer.release(mDisplayId);
        }
        }


        void visibilitiesUpdated(KeyguardController controller, DisplayContent display) {
        /**
         * Updates {@link #mOccluded}, {@link #mTopTurnScreenOnActivity} and
         * {@link #mDismissingKeyguardActivity} if the top task could be visible.
         */
        void updateVisibility(KeyguardController controller, DisplayContent display) {
            final boolean lastOccluded = mOccluded;
            final boolean lastOccluded = mOccluded;
            final ActivityRecord lastDismissActivity = mDismissingKeyguardActivity;

            final ActivityRecord lastDismissKeyguardActivity = mDismissingKeyguardActivity;
            final ActivityRecord lastTurnScreenOnActivity = mTopTurnScreenOnActivity;
            final ActivityRecord lastTurnScreenOnActivity = mTopTurnScreenOnActivity;

            mRequestDismissKeyguard = false;
            mRequestDismissKeyguard = false;
            mOccluded = false;
            mOccluded = false;

            mTopOccludesActivity = null;
            mDismissingKeyguardActivity = null;
            mDismissingKeyguardActivity = null;
            mTopTurnScreenOnActivity = null;
            mTopTurnScreenOnActivity = null;


            // only top + focusable + visible task can control occluding.
            boolean occludedByActivity = false;
            final Task stack = getStackForControllingOccluding(display);
            final Task task = getRootTaskForControllingOccluding(display);
            if (stack != null) {
            if (task != null) {
                final ActivityRecord topDismissing = stack.getTopDismissingKeyguardActivity();
                final ActivityRecord r = task.getTopNonFinishingActivity();
                final ActivityRecord topTurnScreenOn = stack.getTopTurnScreenOnActivity();
                if (r != null) {
                mOccluded = stack.topActivityOccludesKeyguard() || (topDismissing != null
                    final boolean showWhenLocked = r.canShowWhenLocked();
                        && stack.topRunningActivity() == topDismissing
                    if (r.containsDismissKeyguardWindow()) {
                        && controller.canShowWhileOccluded(
                        mDismissingKeyguardActivity = r;
                                true /* dismissKeyguard */,
                    }
                                false /* showWhenLocked */));
                    if (r.getTurnScreenOnFlag()
                if (topDismissing != null) {
                            && r.currentLaunchCanTurnScreenOn()) {
                    mDismissingKeyguardActivity = topDismissing;
                        mTopTurnScreenOnActivity = r;
                    }
                    }
                if (topTurnScreenOn != null) {

                    mTopTurnScreenOnActivity = topTurnScreenOn;
                    if (showWhenLocked) {
                        mTopOccludesActivity = r;
                    }
                    }

                    // Only the top activity may control occluded, as we can't occlude the Keyguard
                    // if the top app doesn't want to occlude it.
                    occludedByActivity = showWhenLocked || (mDismissingKeyguardActivity != null
                            && task.topRunningActivity() == mDismissingKeyguardActivity
                            && controller.canShowWhileOccluded(
                                    true /* dismissKeyguard */, false /* showWhenLocked */));
                    // FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD only apply for secondary display.
                    // FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD only apply for secondary display.
                if (mDisplayId != DEFAULT_DISPLAY && stack.mDisplayContent != null) {
                    if (mDisplayId != DEFAULT_DISPLAY && task.mDisplayContent != null) {
                    mOccluded |= stack.mDisplayContent.canShowWithInsecureKeyguard()
                        occludedByActivity |=
                                task.mDisplayContent.canShowWithInsecureKeyguard()
                                && controller.canDismissKeyguard();
                                && controller.canDismissKeyguard();
                    }
                    }
                }
                }
            // TODO(b/123372519): isShowingDream can only works on default display.
            if (mDisplayId == DEFAULT_DISPLAY) {
                mOccluded |= mService.mRootWindowContainer.getDefaultDisplay()
                        .getDisplayPolicy().isShowingDreamLw();
            }
            }

            // TODO(b/123372519): isShowingDream can only works on default display.
            mRequestDismissKeyguard = lastDismissActivity != mDismissingKeyguardActivity
            mOccluded = occludedByActivity || (mDisplayId == DEFAULT_DISPLAY
                    && mService.mRootWindowContainer.getDefaultDisplay()
                    .getDisplayPolicy().isShowingDreamLw());
            mRequestDismissKeyguard = lastDismissKeyguardActivity != mDismissingKeyguardActivity
                    && !mOccluded
                    && !mOccluded
                    && mDismissingKeyguardActivity != null
                    && mDismissingKeyguardActivity != null
                    && controller.mWindowManager.isKeyguardSecure(
                    && controller.mWindowManager.isKeyguardSecure(
                    controller.mService.getCurrentUserId());
                    controller.mService.getCurrentUserId());


            if (mTopTurnScreenOnActivity != null
            if (mTopTurnScreenOnActivity != lastTurnScreenOnActivity
                    && mTopTurnScreenOnActivity != lastTurnScreenOnActivity
                    && mTopTurnScreenOnActivity != null
                    && !mService.mWindowManager.mPowerManager.isInteractive()) {
                    && !mService.mWindowManager.mPowerManager.isInteractive()
                    && (mRequestDismissKeyguard || occludedByActivity)) {
                controller.mStackSupervisor.wakeUp("handleTurnScreenOn");
                controller.mStackSupervisor.wakeUp("handleTurnScreenOn");
                mTopOccludesActivity.setCurrentLaunchCanTurnScreenOn(false);
            }
            }


            if (lastOccluded != mOccluded) {
            if (lastOccluded != mOccluded) {
@@ -542,13 +570,13 @@ class KeyguardController {
         * occlusion state.
         * occlusion state.
         */
         */
        @Nullable
        @Nullable
        private Task getStackForControllingOccluding(DisplayContent display) {
        private Task getRootTaskForControllingOccluding(DisplayContent display) {
            return display.getItemFromTaskDisplayAreas(taskDisplayArea -> {
            return display.getItemFromTaskDisplayAreas(taskDisplayArea -> {
                for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
                for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
                    final Task stack = taskDisplayArea.getStackAt(sNdx);
                    final Task task = taskDisplayArea.getStackAt(sNdx);
                    if (stack != null && stack.isFocusableAndVisible()
                    if (task != null && task.isFocusableAndVisible()
                            && !stack.inPinnedWindowingMode()) {
                            && !task.inPinnedWindowingMode()) {
                        return stack;
                        return task;
                    }
                    }
                }
                }
                return null;
                return null;
+1 −13
Original line number Original line Diff line number Diff line
@@ -1995,20 +1995,8 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
                        notifyClients);
                        notifyClients);
            }
            }
        } finally {
        } finally {
            mStackSupervisor.endActivityVisibilityUpdate(starting, configChanges, preserveWindows,
            mStackSupervisor.endActivityVisibilityUpdate();
                    notifyClients);
        }
    }

    void commitActivitiesVisible(ActivityRecord starting, int configChanges,
            boolean preserveWindows, boolean notifyClients) {
        forAllTaskDisplayAreas(taskDisplayArea -> {
            for (int stackNdx = taskDisplayArea.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
                final Task task = taskDisplayArea.getStackAt(stackNdx);
                task.commitActivitiesVisible(starting, configChanges, preserveWindows,
                        notifyClients);
        }
        }
        });
    }
    }


    boolean switchUser(int userId, UserState uss) {
    boolean switchUser(int userId, UserState uss) {
Loading