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

Commit 6d93228c authored by Bryce Lee's avatar Bryce Lee
Browse files

Order awakening from dream after unlocking.

This changelist ensures that the keyguard is unlocked before awakening
from a dream in the BiometricUnlockController.

Test: atest BiometricsUnlockControllerTest#onSideFingerprintSuccess_dreaming_unlockThenWake
Fixes: 289861878
Change-Id: I3ba4478e7f26a77ef7d3e3be380e75e7c197edc2
Merged-In: I3ba4478e7f26a77ef7d3e3be380e75e7c197edc2
parent a38d45c6
Loading
Loading
Loading
Loading
+21 −3
Original line number Diff line number Diff line
@@ -160,6 +160,7 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
    private KeyguardViewController mKeyguardViewController;
    private DozeScrimController mDozeScrimController;
    private KeyguardViewMediator mKeyguardViewMediator;
    private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
    private PendingAuthenticated mPendingAuthenticated = null;
    private boolean mHasScreenTurnedOnSinceAuthenticating;
    private boolean mFadedAwayAfterWakeAndUnlock;
@@ -280,7 +281,8 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
            LatencyTracker latencyTracker,
            ScreenOffAnimationController screenOffAnimationController,
            VibratorHelper vibrator,
            SystemClock systemClock
            SystemClock systemClock,
            StatusBarKeyguardViewManager statusBarKeyguardViewManager
    ) {
        mPowerManager = powerManager;
        mUpdateMonitor = keyguardUpdateMonitor;
@@ -308,6 +310,7 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
        mVibratorHelper = vibrator;
        mLogger = biometricUnlockLogger;
        mSystemClock = systemClock;
        mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;

        dumpManager.registerDumpable(getClass().getName(), this);
    }
@@ -449,8 +452,19 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
        // During wake and unlock, we need to draw black before waking up to avoid abrupt
        // brightness changes due to display state transitions.
        Runnable wakeUp = ()-> {
            if (!wasDeviceInteractive || mUpdateMonitor.isDreaming()) {
            // Check to see if we are still locked when we are waking and unlocking from dream.
            // This runnable should be executed after unlock. If that's true, we could be not
            // dreaming, but still locked. In this case, we should attempt to authenticate instead
            // of waking up.
            if (mode == MODE_WAKE_AND_UNLOCK_FROM_DREAM
                    && !mKeyguardStateController.isUnlocked()
                    && !mUpdateMonitor.isDreaming()) {
                // Post wakeUp runnable is called from a callback in keyguard.
                mHandler.post(() -> mKeyguardViewController.notifyKeyguardAuthenticated(
                        false /* primaryAuth */));
            } else if (!wasDeviceInteractive || mUpdateMonitor.isDreaming()) {
                mLogger.i("bio wakelock: Authenticated, waking up...");

                mPowerManager.wakeUp(
                        mSystemClock.uptimeMillis(),
                        PowerManager.WAKE_REASON_BIOMETRIC,
@@ -462,7 +476,7 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
            Trace.endSection();
        };

        if (mMode != MODE_NONE) {
        if (mMode != MODE_NONE && mMode != MODE_WAKE_AND_UNLOCK_FROM_DREAM) {
            wakeUp.run();
        }
        switch (mMode) {
@@ -484,6 +498,10 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
                Trace.endSection();
                break;
            case MODE_WAKE_AND_UNLOCK_FROM_DREAM:
                // In the case of waking and unlocking from dream, waking up is delayed until after
                // unlock is complete to avoid conflicts during each sequence's transitions.
                mStatusBarKeyguardViewManager.addAfterKeyguardGoneRunnable(wakeUp);
                // Execution falls through here to proceed unlocking.
            case MODE_WAKE_AND_UNLOCK_PULSING:
            case MODE_WAKE_AND_UNLOCK:
                if (mMode == MODE_WAKE_AND_UNLOCK_PULSING) {
+70 −1
Original line number Diff line number Diff line
@@ -142,7 +142,8 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase {
                mNotificationMediaManager, mWakefulnessLifecycle, mScreenLifecycle,
                mAuthController, mStatusBarStateController,
                mSessionTracker, mLatencyTracker, mScreenOffAnimationController, mVibratorHelper,
                mSystemClock
                mSystemClock,
                mStatusBarKeyguardViewManager
        );
        mBiometricUnlockController.setKeyguardViewController(mStatusBarKeyguardViewManager);
        mBiometricUnlockController.addListener(mBiometricUnlockEventsListener);
@@ -463,6 +464,69 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase {
        verify(mVibratorHelper, never()).vibrateAuthSuccess(anyString());
    }

    @Test
    public void onSideFingerprintSuccess_dreaming_unlockThenWake() {
        when(mAuthController.isSfpsEnrolled(anyInt())).thenReturn(true);
        when(mWakefulnessLifecycle.getLastWakeReason())
                .thenReturn(PowerManager.WAKE_REASON_POWER_BUTTON);
        final ArgumentCaptor<Runnable> afterKeyguardGoneRunnableCaptor =
                ArgumentCaptor.forClass(Runnable.class);
        givenDreamingLocked();
        mBiometricUnlockController.startWakeAndUnlock(BiometricSourceType.FINGERPRINT, true);

        // Make sure the BiometricUnlockController has registered a callback for when the keyguard
        // is gone
        verify(mStatusBarKeyguardViewManager).addAfterKeyguardGoneRunnable(
                afterKeyguardGoneRunnableCaptor.capture());
        // Ensure that the power hasn't been told to wake up yet.
        verify(mPowerManager, never()).wakeUp(anyLong(), anyInt(), anyString());
        // Check that the keyguard has been told to unlock.
        verify(mKeyguardViewMediator).onWakeAndUnlocking();

        // Simulate the keyguard disappearing.
        afterKeyguardGoneRunnableCaptor.getValue().run();
        // Verify that the power manager has been told to wake up now.
        verify(mPowerManager).wakeUp(anyLong(), anyInt(), anyString());
    }

    @Test
    public void onSideFingerprintSuccess_dreaming_unlockIfStillLockedNotDreaming() {
        when(mAuthController.isSfpsEnrolled(anyInt())).thenReturn(true);
        when(mWakefulnessLifecycle.getLastWakeReason())
                .thenReturn(PowerManager.WAKE_REASON_POWER_BUTTON);
        final ArgumentCaptor<Runnable> afterKeyguardGoneRunnableCaptor =
                ArgumentCaptor.forClass(Runnable.class);
        givenDreamingLocked();
        mBiometricUnlockController.startWakeAndUnlock(BiometricSourceType.FINGERPRINT, true);

        // Make sure the BiometricUnlockController has registered a callback for when the keyguard
        // is gone
        verify(mStatusBarKeyguardViewManager).addAfterKeyguardGoneRunnable(
                afterKeyguardGoneRunnableCaptor.capture());
        // Ensure that the power hasn't been told to wake up yet.
        verify(mPowerManager, never()).wakeUp(anyLong(), anyInt(), anyString());
        // Check that the keyguard has been told to unlock.
        verify(mKeyguardViewMediator).onWakeAndUnlocking();

        when(mUpdateMonitor.isDreaming()).thenReturn(false);
        when(mKeyguardStateController.isUnlocked()).thenReturn(false);

        // Simulate the keyguard disappearing.
        afterKeyguardGoneRunnableCaptor.getValue().run();

        final ArgumentCaptor<Runnable> dismissKeyguardRunnableCaptor =
                ArgumentCaptor.forClass(Runnable.class);
        verify(mHandler).post(dismissKeyguardRunnableCaptor.capture());

        // Verify that the power manager was not told to wake up.
        verify(mPowerManager, never()).wakeUp(anyLong(), anyInt(), anyString());

        dismissKeyguardRunnableCaptor.getValue().run();
        // Verify that the keyguard controller is told to unlock.
        verify(mStatusBarKeyguardViewManager).notifyKeyguardAuthenticated(eq(false));
    }


    @Test
    public void onSideFingerprintSuccess_oldPowerButtonPress_playHaptic() {
        // GIVEN side fingerprint enrolled, last wake reason was power button
@@ -537,6 +601,11 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase {
        verify(mStatusBarKeyguardViewManager).showPrimaryBouncer(anyBoolean());
    }

    private void givenDreamingLocked() {
        when(mUpdateMonitor.isDreaming()).thenReturn(true);
        when(mUpdateMonitor.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(true);
    }

    private void givenFingerprintModeUnlockCollapsing() {
        when(mUpdateMonitor.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(true);
        when(mUpdateMonitor.isDeviceInteractive()).thenReturn(true);