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

Commit cba24eff authored by Diya Bera's avatar Diya Bera
Browse files

Prioritize verify app not enabled error

Flag: android.hardware.biometrics.flag.mandatory_biometrics
Bug: 339910180
Test: atest PreAuthInfoTest
Change-Id: I0002cf96335ce94ad8ff3a3263a75745b2f39c87
parent 53950fa3
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -169,6 +169,12 @@ public interface BiometricConstants {
     */
    int BIOMETRIC_ERROR_MANDATORY_NOT_ACTIVE = 20;

    /**
     * Biometrics is not allowed to verify in apps.
     * @hide
     */
    int BIOMETRIC_ERROR_NOT_ENABLED_FOR_APPS = 21;

    /**
     * This constant is only used by SystemUI. It notifies SystemUI that authentication was paused
     * because the authentication attempt was unsuccessful.
+7 −0
Original line number Diff line number Diff line
@@ -93,6 +93,13 @@ public class BiometricManager {
    public static final int BIOMETRIC_ERROR_MANDATORY_NOT_ACTIVE =
            BiometricConstants.BIOMETRIC_ERROR_MANDATORY_NOT_ACTIVE;

    /**
     * Biometrics is not allowed to verify in apps.
     * @hide
     */
    public static final int BIOMETRIC_ERROR_NOT_ENABLED_FOR_APPS =
            BiometricConstants.BIOMETRIC_ERROR_NOT_ENABLED_FOR_APPS;

    /**
     * A security vulnerability has been discovered and the sensor is unavailable until a
     * security update has addressed this issue. This error can be received if for example,
+8 −0
Original line number Diff line number Diff line
@@ -316,6 +316,7 @@ class PreAuthInfo {
        Pair<BiometricSensor, Integer> sensorNotEnrolled = null;
        Pair<BiometricSensor, Integer> sensorLockout = null;
        Pair<BiometricSensor, Integer> hardwareNotDetected = null;
        Pair<BiometricSensor, Integer> biometricAppNotAllowed = null;
        for (Pair<BiometricSensor, Integer> pair : ineligibleSensors) {
            final int status = pair.second;
            if (status == BIOMETRIC_LOCKOUT_TIMED || status == BIOMETRIC_LOCKOUT_PERMANENT) {
@@ -327,6 +328,9 @@ class PreAuthInfo {
            if (status == BIOMETRIC_HARDWARE_NOT_DETECTED) {
                hardwareNotDetected = pair;
            }
            if (status == BIOMETRIC_NOT_ENABLED_FOR_APPS) {
                biometricAppNotAllowed = pair;
            }
        }

        // If there is a sensor locked out, prioritize lockout over other sensor's error.
@@ -339,6 +343,10 @@ class PreAuthInfo {
            return hardwareNotDetected;
        }

        if (Flags.mandatoryBiometrics() && biometricAppNotAllowed != null) {
            return biometricAppNotAllowed;
        }

        // 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.
+7 −1
Original line number Diff line number Diff line
@@ -321,6 +321,9 @@ public class Utils {
            case BiometricConstants.BIOMETRIC_ERROR_MANDATORY_NOT_ACTIVE:
                biometricManagerCode = BiometricManager.BIOMETRIC_ERROR_MANDATORY_NOT_ACTIVE;
                break;
            case BiometricConstants.BIOMETRIC_ERROR_NOT_ENABLED_FOR_APPS:
                biometricManagerCode = BiometricManager.BIOMETRIC_ERROR_NOT_ENABLED_FOR_APPS;
                break;
            default:
                Slog.e(BiometricService.TAG, "Unhandled result code: " + biometricConstantsCode);
                biometricManagerCode = BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE;
@@ -384,9 +387,12 @@ public class Utils {
                return BiometricConstants.BIOMETRIC_ERROR_SENSOR_PRIVACY_ENABLED;
            case MANDATORY_BIOMETRIC_UNAVAILABLE_ERROR:
                return BiometricConstants.BIOMETRIC_ERROR_MANDATORY_NOT_ACTIVE;
            case BIOMETRIC_NOT_ENABLED_FOR_APPS:
                if (Flags.mandatoryBiometrics()) {
                    return BiometricConstants.BIOMETRIC_ERROR_NOT_ENABLED_FOR_APPS;
                }
            case BIOMETRIC_DISABLED_BY_DEVICE_POLICY:
            case BIOMETRIC_HARDWARE_NOT_DETECTED:
            case BIOMETRIC_NOT_ENABLED_FOR_APPS:
            default:
                return BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE;
        }
+25 −2
Original line number Diff line number Diff line
@@ -558,7 +558,9 @@ public class BiometricServiceTest {
        waitForIdle();
        verify(mReceiver1).onError(
                eq(BiometricAuthenticator.TYPE_NONE),
                eq(BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE),
                eq(Flags.mandatoryBiometrics()
                        ? BiometricConstants.BIOMETRIC_ERROR_NOT_ENABLED_FOR_APPS
                        : BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE),
                eq(0 /* vendorCode */));

        // Enrolled, not disabled in settings, user requires confirmation in settings
@@ -1450,7 +1452,9 @@ public class BiometricServiceTest {
    }

    @Test
    public void testCanAuthenticate_whenBiometricsNotEnabledForApps() throws Exception {
    @RequiresFlagsDisabled(Flags.FLAG_MANDATORY_BIOMETRICS)
    public void testCanAuthenticate_whenBiometricsNotEnabledForApps_returnsHardwareUnavailable()
            throws Exception {
        setupAuthForOnly(TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
        when(mBiometricService.mSettingObserver.getEnabledForApps(anyInt())).thenReturn(false);
        when(mTrustManager.isDeviceSecure(anyInt(), anyInt()))
@@ -1467,6 +1471,25 @@ public class BiometricServiceTest {
                invokeCanAuthenticate(mBiometricService, authenticators));
    }

    @Test
    @RequiresFlagsEnabled(Flags.FLAG_MANDATORY_BIOMETRICS)
    public void testCanAuthenticate_whenBiometricsNotEnabledForApps() throws Exception {
        setupAuthForOnly(TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
        when(mBiometricService.mSettingObserver.getEnabledForApps(anyInt())).thenReturn(false);
        when(mTrustManager.isDeviceSecure(anyInt(), anyInt()))
                .thenReturn(true);

        // When only biometric is requested
        int authenticators = Authenticators.BIOMETRIC_STRONG;
        assertEquals(BiometricManager.BIOMETRIC_ERROR_NOT_ENABLED_FOR_APPS,
                invokeCanAuthenticate(mBiometricService, authenticators));

        // When credential and biometric are requested
        authenticators = Authenticators.BIOMETRIC_STRONG | Authenticators.DEVICE_CREDENTIAL;
        assertEquals(BiometricManager.BIOMETRIC_SUCCESS,
                invokeCanAuthenticate(mBiometricService, authenticators));
    }

    @Test
    public void testCanAuthenticate_whenNoBiometricSensor() throws Exception {
        mBiometricService = new BiometricService(mContext, mInjector, mBiometricHandlerProvider);
Loading