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
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 58a6c17..d8d7fb7 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -1882,9 +1882,8 @@
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 @@
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.
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index 59eb6c5..d015842 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -438,14 +438,14 @@
}
@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
diff --git a/services/core/java/com/android/server/biometrics/face/FaceService.java b/services/core/java/com/android/server/biometrics/face/FaceService.java
index a0573db..b512475 100644
--- a/services/core/java/com/android/server/biometrics/face/FaceService.java
+++ b/services/core/java/com/android/server/biometrics/face/FaceService.java
@@ -962,9 +962,10 @@
@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;