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

Commit c47df86c authored by Curtis Belmonte's avatar Curtis Belmonte
Browse files

Persist face error message for permanent lockout

Fixes the existing Keyguard and FaceService logic to correctly check for
and show a persistent error message when face authentication is in
permanent lockout mode due to too many failed attempts.

Test: atest com.android.keyguard
Test: On Pixel 4/4XL, fail face auth 6+ times on lock screen

Before: Error message shown after 5th attempt, but not future attempts

After: Error message shown after 5th and all subsequent attempts

Fixes: 140134198
Change-Id: I9d43f156c056c10f7176146c4709a734653689ac
parent bd35832d
Loading
Loading
Loading
Loading
+4 −5
Original line number Diff line number Diff line
@@ -1882,9 +1882,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
        final boolean awakeKeyguard = mKeyguardIsVisible && mDeviceInteractive && !mGoingToSleep;
        final int user = getCurrentUser();
        final int strongAuth = mStrongAuthTracker.getStrongAuthForUser(user);
        final boolean isLockOutOrLockDown =
                containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_LOCKOUT)
                        || containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW)
        final boolean isLockDown =
                containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW)
                        || containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
        final boolean isEncryptedOrTimedOut =
                containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_BOOT)
@@ -1898,9 +1897,9 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
        boolean becauseCannotSkipBouncer = !getUserCanSkipBouncer(user) || canBypass;

        // Scan even when encrypted or timeout to show a preemptive bouncer when bypassing.
        // Lockout/lockdown modes shouldn't scan, since they are more explicit.
        // Lock-down mode shouldn't scan, since it is more explicit.
        boolean strongAuthAllowsScanning = (!isEncryptedOrTimedOut || canBypass && !mBouncer)
                && !isLockOutOrLockDown;
                && !isLockDown;

        // Only listen if this KeyguardUpdateMonitor belongs to the primary user. There is an
        // instance of KeyguardUpdateMonitor for each user but KeyguardUpdateMonitor is user-aware.
+2 −2
Original line number Diff line number Diff line
@@ -438,14 +438,14 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
    }

    @Test
    public void testIgnoresAuth_whenLockout() {
    public void testTriesToAuthenticate_whenLockout() {
        mKeyguardUpdateMonitor.dispatchStartedWakingUp();
        mTestableLooper.processAllMessages();
        when(mStrongAuthTracker.getStrongAuthForUser(anyInt())).thenReturn(
                KeyguardUpdateMonitor.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT);

        mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(true);
        verify(mFaceManager, never()).authenticate(any(), any(), anyInt(), any(), any(), anyInt());
        verify(mFaceManager).authenticate(any(), any(), anyInt(), any(), any(), anyInt());
    }

    @Test
+2 −1
Original line number Diff line number Diff line
@@ -962,9 +962,10 @@ public class FaceService extends BiometricServiceBase {
        @Override
        public void onLockoutChanged(long duration) {
            Slog.d(TAG, "onLockoutChanged: " + duration);

            if (duration == 0) {
                mCurrentUserLockoutMode = AuthenticationClient.LOCKOUT_NONE;
            } else if (duration == Long.MAX_VALUE) {
            } else if (duration == -1 || duration == Long.MAX_VALUE) {
                mCurrentUserLockoutMode = AuthenticationClient.LOCKOUT_PERMANENT;
            } else {
                mCurrentUserLockoutMode = AuthenticationClient.LOCKOUT_TIMED;