diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index fa8d273918710..71d7eb7e9c031 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -1926,13 +1926,23 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, return; } - // if the keyguard is already showing, don't bother. check flags in both files - // to account for the hiding animation which results in a delay and discrepancy - // between flags + // If the keyguard is already showing, see if we don't need to bother re-showing it. Check + // flags in both files to account for the hiding animation which results in a delay and + // discrepancy between flags. if (mShowing && mKeyguardStateController.isShowing()) { - if (DEBUG) Log.d(TAG, "doKeyguard: not showing because it is already showing"); - resetStateLocked(); - return; + if (mPM.isInteractive()) { + // It's already showing, and we're not trying to show it while the screen is off. + // We can simply reset all of the views. + if (DEBUG) Log.d(TAG, "doKeyguard: not showing because it is already showing"); + resetStateLocked(); + return; + } else { + // We are trying to show the keyguard while the screen is off - this results from + // race conditions involving locking while unlocking. Don't short-circuit here and + // ensure the keyguard is fully re-shown. + Log.e(TAG, + "doKeyguard: already showing, but re-showing since we're not interactive"); + } } // In split system user mode, we never unlock system user. 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 122d7fdbfa473..f55b86686152a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java @@ -29,6 +29,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.atLeast; +import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; @@ -485,6 +486,38 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { assertTrue(mViewMediator.isShowingAndNotOccluded()); } + @Test + @TestableLooper.RunWithLooper(setAsMainLooper = true) + public void testDoKeyguardWhileInteractive_resets() { + mViewMediator.setShowingLocked(true); + when(mKeyguardStateController.isShowing()).thenReturn(true); + TestableLooper.get(this).processAllMessages(); + + when(mPowerManager.isInteractive()).thenReturn(true); + + mViewMediator.onSystemReady(); + TestableLooper.get(this).processAllMessages(); + + assertTrue(mViewMediator.isShowingAndNotOccluded()); + verify(mStatusBarKeyguardViewManager).reset(anyBoolean()); + } + + @Test + @TestableLooper.RunWithLooper(setAsMainLooper = true) + public void testDoKeyguardWhileNotInteractive_showsInsteadOfResetting() { + mViewMediator.setShowingLocked(true); + when(mKeyguardStateController.isShowing()).thenReturn(true); + TestableLooper.get(this).processAllMessages(); + + when(mPowerManager.isInteractive()).thenReturn(false); + + mViewMediator.onSystemReady(); + TestableLooper.get(this).processAllMessages(); + + assertTrue(mViewMediator.isShowingAndNotOccluded()); + verify(mStatusBarKeyguardViewManager, never()).reset(anyBoolean()); + } + private void createAndStartViewMediator() { mViewMediator = new KeyguardViewMediator( mContext,