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

Commit e87a4dcd authored by Josh Tsuji's avatar Josh Tsuji
Browse files

Explicitly re-show rather than reset keyguard if we're not interactive.

Showing the keyguard while not interactive should only happen
during race conditions involving locking and unlocking
simultaneously, where we want to make sure we end up locked.
"Resetting" is a short-circuit to just reset the lockscreen
views if we are asked to show while already showing. If we
are asked to show keyguard while not interactive, even if we
think we're already showing, we should not short-circuit and
instead fully re-show the keyguard to ensure we end up in the
correct state.

Fixes: 265025247
Test: mash power/unlock repeatedly until hitting this case
Test: atest KeyguardViewMediatorTest
Change-Id: Ibb80fdd3d292c4cf05203ea89bfcc113481830d6
parent cc678f04
Loading
Loading
Loading
Loading
+16 −6
Original line number Diff line number Diff line
@@ -1907,13 +1907,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 (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.
+33 −0
Original line number Diff line number Diff line
@@ -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;
@@ -369,6 +370,38 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
        assertTrue(mViewMediator.isAnimatingBetweenKeyguardAndSurfaceBehind());
    }

    @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,