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

Commit 8b3cc0a4 authored by Wenhui Yang's avatar Wenhui Yang
Browse files

FRR - Add a device overlay to control QPR1 release targets

Bug: 300537127
Test: AuthenticationStatsCollectorTest
Change-Id: I0e4e6747af1598aa1b5a9610cfe98197a14f61bf
parent 4df399ec
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -5348,6 +5348,10 @@
         to enroll the other eligible biometric. -->
    <fraction name="config_biometricNotificationFrrThreshold">25%</fraction>

    <!-- Whether to enable the biometric notification for dual-modality device that enrolled a
         single biometric and experiences high FRR. -->
    <bool name="config_biometricFrrNotificationEnabled">false</bool>

    <!-- The component name for the default profile supervisor, which can be set as a profile owner
    even after user setup is complete. The defined component should be used for supervision purposes
    only. The component must be part of a system app. -->
+1 −0
Original line number Diff line number Diff line
@@ -2584,6 +2584,7 @@

  <!-- Biometric FRR config -->
  <java-symbol type="fraction" name="config_biometricNotificationFrrThreshold" />
  <java-symbol type="bool" name="config_biometricFrrNotificationEnabled" />

  <!-- Biometric FRR notification messages -->
  <java-symbol type="string" name="device_unlock_notification_name" />
+7 −0
Original line number Diff line number Diff line
@@ -57,6 +57,7 @@ public class AuthenticationStatsCollector {
    @NonNull private final FaceManager mFaceManager;
    @NonNull private final FingerprintManager mFingerprintManager;

    private final boolean mEnabled;
    private final float mThreshold;
    private final int mModality;
    private boolean mPersisterInitialized = false;
@@ -83,6 +84,7 @@ public class AuthenticationStatsCollector {
    public AuthenticationStatsCollector(@NonNull Context context, int modality,
            @NonNull BiometricNotification biometricNotification) {
        mContext = context;
        mEnabled = context.getResources().getBoolean(R.bool.config_biometricFrrNotificationEnabled);
        mThreshold = context.getResources()
                .getFraction(R.fraction.config_biometricNotificationFrrThreshold, 1, 1);
        mUserAuthenticationStatsMap = new HashMap<>();
@@ -116,6 +118,11 @@ public class AuthenticationStatsCollector {
    /** Update total authentication and rejected attempts. */
    public void authenticate(int userId, boolean authenticated) {

        // Don't collect data if the feature is disabled.
        if (!mEnabled) {
            return;
        }

        // Don't collect data for single-modality devices or user has both biometrics enrolled.
        if (isSingleModalityDevice()
                || (hasEnrolledFace(userId) && hasEnrolledFingerprint(userId))) {
+30 −1
Original line number Diff line number Diff line
@@ -87,6 +87,8 @@ public class AuthenticationStatsCollectorTest {
    public void setUp() {

        when(mContext.getResources()).thenReturn(mResources);
        when(mResources.getBoolean(eq(R.bool.config_biometricFrrNotificationEnabled)))
                .thenReturn(true);
        when(mResources.getFraction(eq(R.fraction.config_biometricNotificationFrrThreshold),
                anyInt(), anyInt())).thenReturn(FRR_THRESHOLD);

@@ -109,7 +111,6 @@ public class AuthenticationStatsCollectorTest {
                0 /* modality */, mBiometricNotification);
    }


    @Test
    public void authenticate_authenticationSucceeded_mapShouldBeUpdated() {
        // Assert that the user doesn't exist in the map initially.
@@ -341,4 +342,32 @@ public class AuthenticationStatsCollectorTest {
        // Assert that notification count has been updated.
        assertThat(authenticationStats.getEnrollmentNotifications()).isEqualTo(1);
    }

    @Test
    public void authenticate_featureDisabled_mapMustNotBeUpdated() {
        // Disable the feature.
        when(mResources.getBoolean(eq(R.bool.config_biometricFrrNotificationEnabled)))
                .thenReturn(false);
        AuthenticationStatsCollector authenticationStatsCollector =
                new AuthenticationStatsCollector(mContext, 0 /* modality */,
                        mBiometricNotification);

        authenticationStatsCollector.setAuthenticationStatsForUser(USER_ID_1,
                new AuthenticationStats(USER_ID_1, 500 /* totalAttempts */,
                        400 /* rejectedAttempts */, 0 /* enrollmentNotifications */,
                        0 /* modality */));

        authenticationStatsCollector.authenticate(USER_ID_1, false /* authenticated */);

        // Assert that no notification should be sent.
        verify(mBiometricNotification, never()).sendFaceEnrollNotification(any());
        verify(mBiometricNotification, never()).sendFpEnrollNotification(any());
        // Assert that data hasn't been updated.
        AuthenticationStats authenticationStats = authenticationStatsCollector
                .getAuthenticationStatsForUser(USER_ID_1);
        assertThat(authenticationStats.getTotalAttempts()).isEqualTo(500);
        assertThat(authenticationStats.getRejectedAttempts()).isEqualTo(400);
        assertThat(authenticationStats.getEnrollmentNotifications()).isEqualTo(0);
        assertThat(authenticationStats.getFrr()).isWithin(0f).of(0.8f);
    }
}