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

Commit 09770ff8 authored by Josh Tsuji's avatar Josh Tsuji
Browse files

Fix lockscreen jump-cutting in during screen off.

isKeyguardShowDelayed() only returns true if the screen off
animation is currently playing, but since wakefulness events
are dispatched async, it's possible that we try to handle the
pending lock in onFinishedGoingToSleep() before the screen off
animator actually starts running.

We can instead check whether we're intending to delay the
keyguard show, even if we haven't quite started the animation
yet.

Fixes: 256803842
Test: atest KeyguardViewMediatorTest
Test: atest UnlockedScreenOffAnimationControllerTest
Change-Id: I4fbac5c995d535d1fb962e5663e3d47d8f3bf00f
parent cc678f04
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -1458,16 +1458,16 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
    public void maybeHandlePendingLock() {
        if (mPendingLock) {

            // The screen off animation is playing, so if we lock now, the foreground app will
            // vanish and the keyguard will jump-cut in. Delay it, until either:
            // The screen off animation is playing or is about to be, so if we lock now, the
            // foreground app will vanish and the keyguard will jump-cut in. Delay it, until either:
            //   - The screen off animation ends. We will call maybeHandlePendingLock from
            //     the end action in UnlockedScreenOffAnimationController#animateInKeyguard.
            //   - The screen off animation is cancelled by the device waking back up. We will call
            //     maybeHandlePendingLock from KeyguardViewMediator#onStartedWakingUp.
            if (mScreenOffAnimationController.isKeyguardShowDelayed()) {
            if (mScreenOffAnimationController.shouldDelayKeyguardShow()) {
                if (DEBUG) {
                    Log.d(TAG, "#maybeHandlePendingLock: not handling because the screen off "
                            + "animation's isKeyguardShowDelayed() returned true. This should be "
                            + "animation's shouldDelayKeyguardShow() returned true. This should be "
                            + "handled soon by #onStartedWakingUp, or by the end actions of the "
                            + "screen off animation.");
                }
+39 −0
Original line number Diff line number Diff line
@@ -369,6 +369,45 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
        assertTrue(mViewMediator.isAnimatingBetweenKeyguardAndSurfaceBehind());
    }

    @Test
    @TestableLooper.RunWithLooper(setAsMainLooper = true)
    public void testKeyguardDelayedOnGoingToSleep_ifScreenOffAnimationWillPlayButIsntPlayingYet() {
        mViewMediator.onSystemReady();
        TestableLooper.get(this).processAllMessages();

        mViewMediator.setShowingLocked(false);
        TestableLooper.get(this).processAllMessages();

        mViewMediator.onStartedGoingToSleep(OFF_BECAUSE_OF_USER);
        TestableLooper.get(this).processAllMessages();

        when(mScreenOffAnimationController.shouldDelayKeyguardShow()).thenReturn(true);
        when(mScreenOffAnimationController.isKeyguardShowDelayed()).thenReturn(false);
        mViewMediator.onFinishedGoingToSleep(OFF_BECAUSE_OF_USER, false);
        TestableLooper.get(this).processAllMessages();

        assertFalse(mViewMediator.isShowingAndNotOccluded());
    }

    @Test
    @TestableLooper.RunWithLooper(setAsMainLooper = true)
    public void testKeyguardNotDelayedOnGoingToSleep_ifScreenOffAnimationWillNotPlay() {
        mViewMediator.onSystemReady();
        TestableLooper.get(this).processAllMessages();

        mViewMediator.setShowingLocked(false);
        TestableLooper.get(this).processAllMessages();

        mViewMediator.onStartedGoingToSleep(OFF_BECAUSE_OF_USER);
        TestableLooper.get(this).processAllMessages();

        when(mScreenOffAnimationController.shouldDelayKeyguardShow()).thenReturn(false);
        mViewMediator.onFinishedGoingToSleep(OFF_BECAUSE_OF_USER, false);
        TestableLooper.get(this).processAllMessages();

        assertTrue(mViewMediator.isShowingAndNotOccluded());
    }

    private void createAndStartViewMediator() {
        mViewMediator = new KeyguardViewMediator(
                mContext,