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

Commit 7467f6b2 authored by Robin Lee's avatar Robin Lee
Browse files

Defer creating+sending SLEEP transitions

The SLEEP transition is a sync to wind down all animations since the
display isn't animating any more. Since SLEEP is forcibly merged into
existing transitions, this can be problematic when the screen is still
on during dream/keyguard because we need to let those animations finish
uninterrupted.

This lets us remove the special case extension for SLEEP timeouts for
keyguard animations and also makes some other cases like home swipe on
top of the lock screen work properly.

Test: atest CtsWindowManagerDeviceKeyguard:KeyguardTests
Bug: 293862576
Change-Id: Ic8416c303848fd96241a715a82dcf53a3561a2eb
parent ff6053cf
Loading
Loading
Loading
Loading
+1 −10
Original line number Diff line number Diff line
@@ -204,12 +204,6 @@ public class Transitions implements RemoteCallable<Transitions>,
     */
    private static final int SYNC_ALLOWANCE_MS = 120;

    /**
     * Keyguard gets a more generous timeout to finish its animations, because we are always holding
     * a sleep token during occlude/unocclude transitions and we want them to finish playing cleanly
     */
    private static final int SYNC_ALLOWANCE_KEYGUARD_MS = 2000;

    /** For testing only. Disables the force-finish timeout on sync. */
    private boolean mDisableForceSync = false;

@@ -1203,11 +1197,8 @@ public class Transitions implements RemoteCallable<Transitions>,
            if (track.mActiveTransition == playing) {
                if (!mDisableForceSync) {
                    // Give it a short amount of time to process it before forcing.
                    final int tolerance = KeyguardTransitionHandler.handles(playing.mInfo)
                            ? SYNC_ALLOWANCE_KEYGUARD_MS
                            : SYNC_ALLOWANCE_MS;
                    mMainExecutor.executeDelayed(
                            () -> finishForSync(reason, trackIdx, playing), tolerance);
                            () -> finishForSync(reason, trackIdx, playing), SYNC_ALLOWANCE_MS);
                }
                break;
            }
+52 −28
Original line number Diff line number Diff line
@@ -174,10 +174,14 @@ class RootWindowContainer extends WindowContainer<DisplayContent>

    private static final int SET_SCREEN_BRIGHTNESS_OVERRIDE = 1;
    private static final int SET_USER_ACTIVITY_TIMEOUT = 2;
    private static final int MSG_SEND_SLEEP_TRANSITION = 3;

    static final String TAG_TASKS = TAG + POSTFIX_TASKS;
    static final String TAG_STATES = TAG + POSTFIX_STATES;
    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;

    private static final long SLEEP_TRANSITION_WAIT_MILLIS = 1000L;

    private Object mLastWindowFreezeSource = null;
    private float mScreenBrightnessOverride = PowerManager.BRIGHTNESS_INVALID_FLOAT;
    private long mUserActivityTimeout = -1;
@@ -1132,6 +1136,11 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
                    mWmService.mPowerManagerInternal.
                            setUserActivityTimeoutOverrideFromWindowManager((Long) msg.obj);
                    break;
                case MSG_SEND_SLEEP_TRANSITION:
                    synchronized (mService.mGlobalLock) {
                        sendSleepTransition((DisplayContent) msg.obj);
                    }
                    break;
                default:
                    break;
            }
@@ -2442,21 +2451,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
        return result;
    }

    void applySleepTokens(boolean applyToRootTasks) {
        boolean builtSleepTransition = false;
        for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
            // Set the sleeping state of the display.
            final DisplayContent display = getChildAt(displayNdx);
            final boolean displayShouldSleep = display.shouldSleep();
            if (displayShouldSleep == display.isSleeping()) {
                continue;
            }
            display.setIsSleeping(displayShouldSleep);

            if (display.mTransitionController.isShellTransitionsEnabled() && !builtSleepTransition
                    // Only care if there are actual sleep tokens.
                    && displayShouldSleep && !display.mAllSleepTokens.isEmpty()) {
                builtSleepTransition = true;
    void sendSleepTransition(final DisplayContent display) {
        // We don't actually care about collecting anything here. We really just want
        // this as a signal to the transition-player.
        final Transition transition = new Transition(TRANSIT_SLEEP, 0 /* flags */,
@@ -2485,6 +2480,31 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
        }
    }

    void applySleepTokens(boolean applyToRootTasks) {
        boolean scheduledSleepTransition = false;

        for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
            // Set the sleeping state of the display.
            final DisplayContent display = getChildAt(displayNdx);
            final boolean displayShouldSleep = display.shouldSleep();
            if (displayShouldSleep == display.isSleeping()) {
                continue;
            }
            display.setIsSleeping(displayShouldSleep);

            if (display.mTransitionController.isShellTransitionsEnabled()
                    && !scheduledSleepTransition
                    // Only care if there are actual sleep tokens.
                    && displayShouldSleep && !display.mAllSleepTokens.isEmpty()) {
                scheduledSleepTransition = true;

                if (!mHandler.hasMessages(MSG_SEND_SLEEP_TRANSITION)) {
                    mHandler.sendMessageDelayed(
                            mHandler.obtainMessage(MSG_SEND_SLEEP_TRANSITION, display),
                            SLEEP_TRANSITION_WAIT_MILLIS);
                }
            }

            if (!applyToRootTasks) {
                continue;
            }
@@ -2535,6 +2555,10 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
                }
            });
        }

        if (!scheduledSleepTransition) {
            mHandler.removeMessages(MSG_SEND_SLEEP_TRANSITION);
        }
    }

    protected Task getRootTask(int rooTaskId) {