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

Commit 0ea56b4f authored by Austin Delgado's avatar Austin Delgado
Browse files

Hide enrollment options that don't match requested biometric strength

When calling biometric enroll intent with biometric_strong, don't include
weak enrollments as options.

Bug: 265898482
Test: Tested manually by calling enrollment and verifying correct
options are shown
Test: atest BiometricEnrollActivityTest

Change-Id: I5fa650a593aee536955ae806f5963ffbdc135a2e
parent e346dc67
Loading
Loading
Loading
Loading
+24 −6
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import android.hardware.biometrics.BiometricAuthenticator;
import android.hardware.biometrics.BiometricManager;
import android.hardware.biometrics.BiometricManager.Authenticators;
import android.hardware.biometrics.BiometricManager.BiometricError;
import android.hardware.biometrics.SensorProperties;
import android.hardware.face.FaceManager;
import android.hardware.face.FaceSensorPropertiesInternal;
import android.hardware.fingerprint.FingerprintManager;
@@ -198,7 +199,7 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
        // Default behavior is to enroll BIOMETRIC_WEAK or above. See ACTION_BIOMETRIC_ENROLL.
        final int authenticators = getIntent().getIntExtra(
                EXTRA_BIOMETRIC_AUTHENTICATORS_ALLOWED, Authenticators.BIOMETRIC_WEAK);
        Log.d(TAG, "Authenticators: " + authenticators);
        Log.d(TAG, "Authenticators: " + BiometricManager.authenticatorToStr(authenticators));

        mParentalOptionsRequired = intent.getBooleanExtra(EXTRA_REQUIRE_PARENTAL_CONSENT, false);
        mSkipReturnToParent = intent.getBooleanExtra(EXTRA_SKIP_RETURN_TO_PARENT, false);
@@ -222,9 +223,16 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
                final FaceSensorPropertiesInternal props = faceProperties.get(0);
                final int maxEnrolls =
                        isSetupWizard ? maxFacesEnrollableIfSUW : props.maxEnrollmentsPerUser;
                final boolean isFaceStrong =
                        props.sensorStrength == SensorProperties.STRENGTH_STRONG;
                mIsFaceEnrollable =
                        faceManager.getEnrolledFaces(mUserId).size() < maxEnrolls;

                // If we expect strong bio only, check if face is strong
                if (authenticators == Authenticators.BIOMETRIC_STRONG && !isFaceStrong) {
                    mIsFaceEnrollable = false;
                }

                final boolean parentalConsent = isSetupWizard || (mParentalOptionsRequired
                        && !WizardManagerHelper.isUserSetupComplete(this));
                if (parentalConsent && isMultiSensor && mIsFaceEnrollable) {
@@ -278,6 +286,9 @@ public class BiometricEnrollActivity extends InstrumentedActivity {

    private void updateFingerprintEnrollable(boolean isSetupWizard) {
        if (mHasFeatureFingerprint) {
            final int authenticators = getIntent().getIntExtra(
                    EXTRA_BIOMETRIC_AUTHENTICATORS_ALLOWED, Authenticators.BIOMETRIC_WEAK);

            final FingerprintManager fpManager = getSystemService(FingerprintManager.class);
            final List<FingerprintSensorPropertiesInternal> fpProperties =
                    fpManager.getSensorPropertiesInternal();
@@ -287,8 +298,15 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
                final int maxEnrolls =
                        isSetupWizard ? maxFingerprintsEnrollableIfSUW
                                : fpProperties.get(0).maxEnrollmentsPerUser;
                final boolean isFingerprintStrong =
                        fpProperties.get(0).sensorStrength == SensorProperties.STRENGTH_STRONG;
                mIsFingerprintEnrollable =
                        fpManager.getEnrolledFingerprints(mUserId).size() < maxEnrolls;

                // If we expect strong bio only, check if fingerprint is strong
                if (authenticators == Authenticators.BIOMETRIC_STRONG && !isFingerprintStrong) {
                    mIsFingerprintEnrollable = false;
                }
            }
        }
    }
@@ -308,8 +326,8 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
            }
        }

        boolean canUseFace = mHasFeatureFace;
        boolean canUseFingerprint = mHasFeatureFingerprint;
        boolean canUseFace = mIsFaceEnrollable;
        boolean canUseFingerprint = mIsFingerprintEnrollable;
        if (mParentalOptionsRequired) {
            if (mParentalOptions == null) {
                throw new IllegalStateException("consent options required, but not set");
@@ -612,11 +630,11 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
        Intent intent = BiometricUtils.getChooseLockIntent(this, getIntent());
        intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.HIDE_INSECURE_OPTIONS, true);
        intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW_HANDLE, true);
        if (mHasFeatureFingerprint && mHasFeatureFace) {
        if (mIsFingerprintEnrollable && mIsFaceEnrollable) {
            intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_BIOMETRICS, true);
        } else if (mHasFeatureFace) {
        } else if (mIsFaceEnrollable) {
            intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FACE, true);
        } else if (mHasFeatureFingerprint) {
        } else if (mIsFingerprintEnrollable) {
            intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, true);
        }

+54 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.settings.biometrics;

import static android.hardware.biometrics.BiometricManager.Authenticators.BIOMETRIC_STRONG;
import static android.provider.Settings.ACTION_BIOMETRIC_ENROLL;

import static androidx.test.espresso.intent.Intents.intended;
@@ -33,7 +34,13 @@ import static org.junit.Assume.assumeTrue;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.hardware.biometrics.SensorProperties;
import android.hardware.face.FaceManager;
import android.hardware.face.FaceSensorPropertiesInternal;
import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.os.UserHandle;
import android.provider.Settings;

import androidx.test.core.app.ActivityScenario;
import androidx.test.core.app.ApplicationProvider;
@@ -56,6 +63,8 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.util.List;

@RunWith(AndroidJUnit4.class)
@MediumTest
public class BiometricEnrollActivityTest {
@@ -67,6 +76,8 @@ public class BiometricEnrollActivityTest {
    private final Context  mContext = ApplicationProvider.getApplicationContext();
    private boolean mHasFace;
    private boolean mHasFingerprint;
    private boolean mIsFaceStrong;
    private boolean mIsFingerprintStrong;

    @Before
    public void setup() {
@@ -74,6 +85,28 @@ public class BiometricEnrollActivityTest {
        final PackageManager pm = mContext.getPackageManager();
        mHasFingerprint = pm.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT);
        mHasFace = pm.hasSystemFeature(PackageManager.FEATURE_FACE);

        if (mHasFace) {
            final FaceManager faceManager = mContext.getSystemService(FaceManager.class);
            final List<FaceSensorPropertiesInternal> faceProperties =
                    faceManager.getSensorPropertiesInternal();
            if (!faceProperties.isEmpty()) {
                final FaceSensorPropertiesInternal faceProp = faceProperties.get(0);
                mIsFaceStrong = faceProp.sensorStrength == SensorProperties.STRENGTH_STRONG;
            }
        }

        if (mHasFingerprint) {
            final FingerprintManager fingerprintManager = mContext.getSystemService(
                    FingerprintManager.class);
            final List<FingerprintSensorPropertiesInternal> fingerProperties =
                    fingerprintManager.getSensorPropertiesInternal();
            if (!fingerProperties.isEmpty()) {
                final FingerprintSensorPropertiesInternal fingerProp = fingerProperties.get(0);
                mIsFingerprintStrong =
                        fingerProp.sensorStrength == SensorProperties.STRENGTH_STRONG;
            }
        }
    }

    @After
@@ -129,6 +162,27 @@ public class BiometricEnrollActivityTest {
        }
    }

    @Test
    public void launchWithStrongBiometricAllowed_doNotEnrollWeak() throws Exception {
        assumeTrue(mHasFace || mHasFingerprint);

        // Allow only strong biometrics
        Intent intent = getIntent();
        intent.putExtra(Settings.EXTRA_BIOMETRIC_AUTHENTICATORS_ALLOWED, BIOMETRIC_STRONG);

        try (ActivityScenario<BiometricEnrollActivity> scenario =
                     ActivityScenario.launch(intent)) {
            intended(hasComponent(ChooseLockGeneric.class.getName()));
            if (mIsFaceStrong && mIsFingerprintStrong) {
                intended(hasExtra(EXTRA_KEY_FOR_BIOMETRICS, true));
            } else if (mIsFaceStrong) {
                intended(hasExtra(EXTRA_KEY_FOR_FACE, true));
            } else if (mIsFingerprintStrong) {
                intended(hasExtra(EXTRA_KEY_FOR_FINGERPRINT, true));
            }
        }
    }

    private Intent getIntent() {
        return getIntent(false /* useInternal */);
    }