From 09770ff815e47c92dc37d0f9d4d9becf2f59297a Mon Sep 17 00:00:00 2001 From: Josh Tsuji Date: Thu, 5 Jan 2023 23:05:56 -0500 Subject: [PATCH] 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 --- .../keyguard/KeyguardViewMediator.java | 8 ++-- .../keyguard/KeyguardViewMediatorTest.java | 39 +++++++++++++++++++ 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index 8aada1f12b0c3..05d7945f58031 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -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."); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java index 804960dc3b181..0f4e4490ef448 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java @@ -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,