Loading services/core/java/com/android/server/biometrics/PreAuthInfo.java +19 −6 Original line number Diff line number Diff line Loading @@ -267,17 +267,30 @@ class PreAuthInfo { } private Pair<BiometricSensor, Integer> calculateErrorByPriority() { // If the caller requested STRONG, and the device contains both STRONG and non-STRONG // sensors, prioritize BIOMETRIC_NOT_ENROLLED over the weak sensor's // BIOMETRIC_INSUFFICIENT_STRENGTH error. Pretty sure we can always prioritize // BIOMETRIC_NOT_ENROLLED over any other error (unless of course its calculation is // wrong, in which case we should fix that instead). Pair<BiometricSensor, Integer> sensorNotEnrolled = null; Pair<BiometricSensor, Integer> sensorLockout = null; for (Pair<BiometricSensor, Integer> pair : ineligibleSensors) { int status = pair.second; if (status == BIOMETRIC_LOCKOUT_TIMED || status == BIOMETRIC_LOCKOUT_PERMANENT) { sensorLockout = pair; } if (pair.second == BIOMETRIC_NOT_ENROLLED) { return pair; sensorNotEnrolled = pair; } } // If there is a sensor locked out, prioritize lockout over other sensor's error. // See b/286923477. if (sensorLockout != null) { return sensorLockout; } // If the caller requested STRONG, and the device contains both STRONG and non-STRONG // sensors, prioritize BIOMETRIC_NOT_ENROLLED over the weak sensor's // BIOMETRIC_INSUFFICIENT_STRENGTH error. if (sensorNotEnrolled != null) { return sensorNotEnrolled; } return ineligibleSensors.get(0); } Loading services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java +39 −1 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ package com.android.server.biometrics; import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT; import static android.hardware.biometrics.BiometricManager.Authenticators; import static android.hardware.biometrics.SensorProperties.STRENGTH_STRONG; import static android.view.DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS; import static com.android.server.biometrics.BiometricServiceStateProto.STATE_AUTHENTICATED_PENDING_SYSUI; Loading Loading @@ -902,6 +901,45 @@ public class BiometricServiceTest { eq(biometricPromptError), eq(0) /* vendorCode */); } @Test public void testMultiBiometricAuth_whenLockoutTimed_sendsErrorAndModality() throws Exception { testMultiBiometricAuth_whenLockout(LockoutTracker.LOCKOUT_TIMED, BiometricPrompt.BIOMETRIC_ERROR_LOCKOUT); } @Test public void testMultiBiometricAuth_whenLockoutPermanent_sendsErrorAndModality() throws Exception { testMultiBiometricAuth_whenLockout(LockoutTracker.LOCKOUT_PERMANENT, BiometricPrompt.BIOMETRIC_ERROR_LOCKOUT_PERMANENT); } private void testMultiBiometricAuth_whenLockout(@LockoutTracker.LockoutMode int lockoutMode, int biometricPromptError) throws Exception { final int[] modalities = new int[] { TYPE_FINGERPRINT, BiometricAuthenticator.TYPE_FACE, }; final int[] strengths = new int[] { Authenticators.BIOMETRIC_STRONG, Authenticators.BIOMETRIC_STRONG, }; setupAuthForMultiple(modalities, strengths); when(mFingerprintAuthenticator.getLockoutModeForUser(anyInt())) .thenReturn(lockoutMode); when(mFaceAuthenticator.hasEnrolledTemplates(anyInt(), any())).thenReturn(false); invokeAuthenticate(mBiometricService.mImpl, mReceiver1, false /* requireConfirmation */, null /* authenticators */); waitForIdle(); // The lockout error should be sent, instead of ERROR_NONE_ENROLLED. See b/286923477. verify(mReceiver1).onError(eq(TYPE_FINGERPRINT), eq(biometricPromptError), eq(0) /* vendorCode */); } @Test public void testBiometricOrCredentialAuth_whenBiometricLockout_showsCredential() throws Exception { Loading Loading
services/core/java/com/android/server/biometrics/PreAuthInfo.java +19 −6 Original line number Diff line number Diff line Loading @@ -267,17 +267,30 @@ class PreAuthInfo { } private Pair<BiometricSensor, Integer> calculateErrorByPriority() { // If the caller requested STRONG, and the device contains both STRONG and non-STRONG // sensors, prioritize BIOMETRIC_NOT_ENROLLED over the weak sensor's // BIOMETRIC_INSUFFICIENT_STRENGTH error. Pretty sure we can always prioritize // BIOMETRIC_NOT_ENROLLED over any other error (unless of course its calculation is // wrong, in which case we should fix that instead). Pair<BiometricSensor, Integer> sensorNotEnrolled = null; Pair<BiometricSensor, Integer> sensorLockout = null; for (Pair<BiometricSensor, Integer> pair : ineligibleSensors) { int status = pair.second; if (status == BIOMETRIC_LOCKOUT_TIMED || status == BIOMETRIC_LOCKOUT_PERMANENT) { sensorLockout = pair; } if (pair.second == BIOMETRIC_NOT_ENROLLED) { return pair; sensorNotEnrolled = pair; } } // If there is a sensor locked out, prioritize lockout over other sensor's error. // See b/286923477. if (sensorLockout != null) { return sensorLockout; } // If the caller requested STRONG, and the device contains both STRONG and non-STRONG // sensors, prioritize BIOMETRIC_NOT_ENROLLED over the weak sensor's // BIOMETRIC_INSUFFICIENT_STRENGTH error. if (sensorNotEnrolled != null) { return sensorNotEnrolled; } return ineligibleSensors.get(0); } Loading
services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java +39 −1 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ package com.android.server.biometrics; import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT; import static android.hardware.biometrics.BiometricManager.Authenticators; import static android.hardware.biometrics.SensorProperties.STRENGTH_STRONG; import static android.view.DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS; import static com.android.server.biometrics.BiometricServiceStateProto.STATE_AUTHENTICATED_PENDING_SYSUI; Loading Loading @@ -902,6 +901,45 @@ public class BiometricServiceTest { eq(biometricPromptError), eq(0) /* vendorCode */); } @Test public void testMultiBiometricAuth_whenLockoutTimed_sendsErrorAndModality() throws Exception { testMultiBiometricAuth_whenLockout(LockoutTracker.LOCKOUT_TIMED, BiometricPrompt.BIOMETRIC_ERROR_LOCKOUT); } @Test public void testMultiBiometricAuth_whenLockoutPermanent_sendsErrorAndModality() throws Exception { testMultiBiometricAuth_whenLockout(LockoutTracker.LOCKOUT_PERMANENT, BiometricPrompt.BIOMETRIC_ERROR_LOCKOUT_PERMANENT); } private void testMultiBiometricAuth_whenLockout(@LockoutTracker.LockoutMode int lockoutMode, int biometricPromptError) throws Exception { final int[] modalities = new int[] { TYPE_FINGERPRINT, BiometricAuthenticator.TYPE_FACE, }; final int[] strengths = new int[] { Authenticators.BIOMETRIC_STRONG, Authenticators.BIOMETRIC_STRONG, }; setupAuthForMultiple(modalities, strengths); when(mFingerprintAuthenticator.getLockoutModeForUser(anyInt())) .thenReturn(lockoutMode); when(mFaceAuthenticator.hasEnrolledTemplates(anyInt(), any())).thenReturn(false); invokeAuthenticate(mBiometricService.mImpl, mReceiver1, false /* requireConfirmation */, null /* authenticators */); waitForIdle(); // The lockout error should be sent, instead of ERROR_NONE_ENROLLED. See b/286923477. verify(mReceiver1).onError(eq(TYPE_FINGERPRINT), eq(biometricPromptError), eq(0) /* vendorCode */); } @Test public void testBiometricOrCredentialAuth_whenBiometricLockout_showsCredential() throws Exception { Loading