diff options
2 files changed, 52 insertions, 26 deletions
diff --git a/services/core/java/com/android/server/biometrics/AuthenticationStatsCollector.java b/services/core/java/com/android/server/biometrics/AuthenticationStatsCollector.java index fdf607d04ec7..64691e0b062b 100644 --- a/services/core/java/com/android/server/biometrics/AuthenticationStatsCollector.java +++ b/services/core/java/com/android/server/biometrics/AuthenticationStatsCollector.java @@ -53,6 +53,9 @@ public class AuthenticationStatsCollector { static final int MAXIMUM_ENROLLMENT_NOTIFICATIONS = 1; @NonNull private final Context mContext; + @NonNull private final PackageManager mPackageManager; + @NonNull private final FaceManager mFaceManager; + @NonNull private final FingerprintManager mFingerprintManager; private final float mThreshold; private final int mModality; @@ -86,6 +89,10 @@ public class AuthenticationStatsCollector { mModality = modality; mBiometricNotification = biometricNotification; + mPackageManager = context.getPackageManager(); + mFaceManager = mContext.getSystemService(FaceManager.class); + mFingerprintManager = mContext.getSystemService(FingerprintManager.class); + IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(Intent.ACTION_USER_REMOVED); context.registerReceiver(mBroadcastReceiver, intentFilter); @@ -108,6 +115,13 @@ public class AuthenticationStatsCollector { /** Update total authentication and rejected attempts. */ public void authenticate(int userId, boolean authenticated) { + + // Don't collect data for single-modality devices or user has both biometrics enrolled. + if (isSingleModalityDevice() + || (hasEnrolledFace(userId) && hasEnrolledFingerprint(userId))) { + return; + } + // SharedPreference is not ready when starting system server, initialize // mUserAuthenticationStatsMap in authentication to ensure SharedPreference // is ready for application use. @@ -150,25 +164,9 @@ public class AuthenticationStatsCollector { authenticationStats.resetData(); - final PackageManager packageManager = mContext.getPackageManager(); - - // Don't send notification to single-modality devices. - if (!packageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT) - || !packageManager.hasSystemFeature(PackageManager.FEATURE_FACE)) { - return; - } - - final FaceManager faceManager = mContext.getSystemService(FaceManager.class); - final boolean hasEnrolledFace = faceManager.hasEnrolledTemplates(userId); + final boolean hasEnrolledFace = hasEnrolledFace(userId); + final boolean hasEnrolledFingerprint = hasEnrolledFingerprint(userId); - final FingerprintManager fingerprintManager = mContext - .getSystemService(FingerprintManager.class); - final boolean hasEnrolledFingerprint = fingerprintManager.hasEnrolledTemplates(userId); - - // Don't send notification when both face and fingerprint are enrolled. - if (hasEnrolledFace && hasEnrolledFingerprint) { - return; - } if (hasEnrolledFace && !hasEnrolledFingerprint) { mBiometricNotification.sendFpEnrollNotification(mContext); authenticationStats.updateNotificationCounter(); @@ -199,6 +197,19 @@ public class AuthenticationStatsCollector { } } + private boolean isSingleModalityDevice() { + return !mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT) + || !mPackageManager.hasSystemFeature(PackageManager.FEATURE_FACE); + } + + private boolean hasEnrolledFace(int userId) { + return mFaceManager.hasEnrolledTemplates(userId); + } + + private boolean hasEnrolledFingerprint(int userId) { + return mFingerprintManager.hasEnrolledTemplates(userId); + } + /** * Only being used in tests. Callers should not make any changes to the returned * authentication stats. diff --git a/services/tests/servicestests/src/com/android/server/biometrics/AuthenticationStatsCollectorTest.java b/services/tests/servicestests/src/com/android/server/biometrics/AuthenticationStatsCollectorTest.java index 0b730f139f3e..fa6e7f60c1b0 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/AuthenticationStatsCollectorTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/AuthenticationStatsCollectorTest.java @@ -115,6 +115,11 @@ public class AuthenticationStatsCollectorTest { // Assert that the user doesn't exist in the map initially. assertThat(mAuthenticationStatsCollector.getAuthenticationStatsForUser(USER_ID_1)).isNull(); + when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) + .thenReturn(true); + when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FACE)).thenReturn(true); + when(mFaceManager.hasEnrolledTemplates(anyInt())).thenReturn(true); + mAuthenticationStatsCollector.authenticate(USER_ID_1, true /* authenticated */); AuthenticationStats authenticationStats = @@ -130,6 +135,11 @@ public class AuthenticationStatsCollectorTest { // Assert that the user doesn't exist in the map initially. assertThat(mAuthenticationStatsCollector.getAuthenticationStatsForUser(USER_ID_1)).isNull(); + when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) + .thenReturn(true); + when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FACE)).thenReturn(true); + when(mFingerprintManager.hasEnrolledTemplates(anyInt())).thenReturn(true); + mAuthenticationStatsCollector.authenticate(USER_ID_1, false /* authenticated */); AuthenticationStats authenticationStats = @@ -176,6 +186,11 @@ public class AuthenticationStatsCollectorTest { 40 /* rejectedAttempts */, 0 /* enrollmentNotifications */, 0 /* modality */)); + when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) + .thenReturn(true); + when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FACE)).thenReturn(true); + when(mFingerprintManager.hasEnrolledTemplates(anyInt())).thenReturn(true); + mAuthenticationStatsCollector.authenticate(USER_ID_1, false /* authenticated */); // Assert that no notification should be sent. @@ -233,13 +248,13 @@ public class AuthenticationStatsCollectorTest { // Assert that no notification should be sent. verify(mBiometricNotification, never()).sendFaceEnrollNotification(any()); verify(mBiometricNotification, never()).sendFpEnrollNotification(any()); - // Assert that data has been reset. + // Assert that data hasn't been reset. AuthenticationStats authenticationStats = mAuthenticationStatsCollector .getAuthenticationStatsForUser(USER_ID_1); - assertThat(authenticationStats.getTotalAttempts()).isEqualTo(0); - assertThat(authenticationStats.getRejectedAttempts()).isEqualTo(0); + assertThat(authenticationStats.getTotalAttempts()).isEqualTo(500); + assertThat(authenticationStats.getRejectedAttempts()).isEqualTo(400); assertThat(authenticationStats.getEnrollmentNotifications()).isEqualTo(0); - assertThat(authenticationStats.getFrr()).isWithin(0f).of(-1.0f); + assertThat(authenticationStats.getFrr()).isWithin(0f).of(0.8f); } @Test @@ -260,13 +275,13 @@ public class AuthenticationStatsCollectorTest { // Assert that no notification should be sent. verify(mBiometricNotification, never()).sendFaceEnrollNotification(any()); verify(mBiometricNotification, never()).sendFpEnrollNotification(any()); - // Assert that data has been reset. + // Assert that data hasn't been reset. AuthenticationStats authenticationStats = mAuthenticationStatsCollector .getAuthenticationStatsForUser(USER_ID_1); - assertThat(authenticationStats.getTotalAttempts()).isEqualTo(0); - assertThat(authenticationStats.getRejectedAttempts()).isEqualTo(0); + assertThat(authenticationStats.getTotalAttempts()).isEqualTo(500); + assertThat(authenticationStats.getRejectedAttempts()).isEqualTo(400); assertThat(authenticationStats.getEnrollmentNotifications()).isEqualTo(0); - assertThat(authenticationStats.getFrr()).isWithin(0f).of(-1.0f); + assertThat(authenticationStats.getFrr()).isWithin(0f).of(0.8f); } @Test |