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

Commit 744ed220 authored by Shawn Lin's avatar Shawn Lin Committed by Android (Google) Code Review
Browse files

Merge "Support the ability to enroll face unlock first" into main

parents 17053176 52874a64
Loading
Loading
Loading
Loading
+25 −6
Original line number Diff line number Diff line
@@ -107,7 +107,10 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
    // intent will include this extra containing a bundle of the form:
    // "modality" -> consented (boolean).
    public static final String EXTRA_PARENTAL_CONSENT_STATUS = "consent_status";

    // Whether the face enrollment should be launched first when there are multiple biometrics
    // supported.
    public static final String EXTRA_LAUNCH_FACE_ENROLL_FIRST =
            "launch_face_enroll_first";
    private static final String SAVED_STATE_CONFIRMING_CREDENTIALS = "confirming_credentials";
    private static final String SAVED_STATE_IS_SINGLE_ENROLLING =
            "is_single_enrolling";
@@ -130,6 +133,7 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
    private boolean mIsFingerprintEnrollable = false;
    private boolean mParentalOptionsRequired = false;
    private boolean mSkipReturnToParent = false;
    private boolean mLaunchFaceEnrollFirst = false;
    private Bundle mParentalOptions;
    @Nullable private Long mGkPwHandle;
    @Nullable private ParentalConsentHelper mParentalConsentHelper;
@@ -214,6 +218,7 @@ public class BiometricEnrollActivity extends InstrumentedActivity {

        mParentalOptionsRequired = intent.getBooleanExtra(EXTRA_REQUIRE_PARENTAL_CONSENT, false);
        mSkipReturnToParent = intent.getBooleanExtra(EXTRA_SKIP_RETURN_TO_PARENT, false);
        mLaunchFaceEnrollFirst = intent.getBooleanExtra(EXTRA_LAUNCH_FACE_ENROLL_FIRST, false);

        // determine what can be enrolled
        final boolean isSetupWizard = WizardManagerHelper.isAnySetupWizard(getIntent());
@@ -221,6 +226,7 @@ public class BiometricEnrollActivity extends InstrumentedActivity {

        Log.d(TAG, "parentalOptionsRequired: " + mParentalOptionsRequired
                + ", skipReturnToParent: " + mSkipReturnToParent
                + ", launchFaceEnrollFirst: " + mLaunchFaceEnrollFirst
                + ", isSetupWizard: " + isSetupWizard
                + ", isMultiSensor: " + isMultiSensor);

@@ -356,7 +362,8 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
        } else if (canUseFace || canUseFingerprint) {
            if (mGkPwHandle == null) {
                setOrConfirmCredentialsNow();
            } else if (canUseFingerprint && mIsFingerprintEnrollable) {
            } else if (canUseFingerprint && mIsFingerprintEnrollable
                    && !(canUseFace && mIsFaceEnrollable && mLaunchFaceEnrollFirst)) {
                launchFingerprintOnlyEnroll();
            } else if (canUseFace && mIsFaceEnrollable) {
                launchFaceOnlyEnroll();
@@ -510,7 +517,8 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
            int requestCode, int resultCode, Intent data) {

        Log.d(TAG, "handleOnActivityResultWhileEnrolling, request = " + requestCode + ""
                + ", resultCode = " + resultCode);
                + ", resultCode = " + resultCode + ", launchFaceEnrollFirst="
                + mLaunchFaceEnrollFirst);
        switch (requestCode) {
            case REQUEST_HANDOFF_PARENT:
                setResult(RESULT_OK, newResultIntent());
@@ -526,7 +534,8 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
                    // SetupFingerprintEnrollIntroduction/FingerprintEnrollmentActivity
                    TransitionHelper.applyForwardTransition(this, TRANSITION_FADE_THROUGH);
                    updateGatekeeperPasswordHandle(data);
                    if (mIsFingerprintEnrollable) {
                    if (mIsFingerprintEnrollable
                            && !(mIsFaceEnrollable && mLaunchFaceEnrollFirst)) {
                        launchFingerprintOnlyEnroll();
                    } else {
                        launchFaceOnlyEnroll();
@@ -548,7 +557,7 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
                }
                if ((resultCode == BiometricEnrollBase.RESULT_SKIP
                        || resultCode == BiometricEnrollBase.RESULT_FINISHED)
                        && mIsFaceEnrollable) {
                        && mIsFaceEnrollable && !mLaunchFaceEnrollFirst) {
                    // Apply forward animation during the transition from
                    // SetupFingerprintEnroll*/FingerprintEnrollmentActivity to
                    // SetupFaceEnrollIntroduction
@@ -556,6 +565,9 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
                    mIsPreviousEnrollmentCanceled =
                            resultCode != BiometricEnrollBase.RESULT_FINISHED;
                    launchFaceOnlyEnroll();
                } else if (resultCode == Activity.RESULT_CANCELED && mIsFaceEnrollable
                        && mLaunchFaceEnrollFirst) {
                    launchFaceOnlyEnroll();
                } else {
                    notifySafetyIssueActionLaunchedIfNeeded(resultCode);
                    finishOrLaunchHandToParent(resultCode);
@@ -563,7 +575,14 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
                break;
            case REQUEST_SINGLE_ENROLL_FACE:
                mIsSingleEnrolling = false;
                if (resultCode == Activity.RESULT_CANCELED && mIsFingerprintEnrollable) {
                if ((resultCode == BiometricEnrollBase.RESULT_SKIP
                        || resultCode == BiometricEnrollBase.RESULT_FINISHED)
                        && mIsFingerprintEnrollable && mLaunchFaceEnrollFirst) {
                    mIsPreviousEnrollmentCanceled =
                            resultCode != BiometricEnrollBase.RESULT_FINISHED;
                    launchFingerprintOnlyEnroll();
                } else if (resultCode == Activity.RESULT_CANCELED && mIsFingerprintEnrollable
                        && !mLaunchFaceEnrollFirst) {
                    mIsPreviousEnrollmentCanceled = true;
                    launchFingerprintOnlyEnroll();
                } else {
+2 −3
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.VerifyCredentialResponse;
import com.android.settings.R;
import com.android.settings.SetupWizardUtils;
import com.android.settings.biometrics.face.FaceEnroll;
import com.android.settings.biometrics.fingerprint.FingerprintEnroll;
import com.android.settings.biometrics.fingerprint.FingerprintEnrollFindSensor;
import com.android.settings.biometrics.fingerprint.SetupFingerprintEnrollFindSensor;
@@ -282,9 +283,7 @@ public class BiometricUtils {
     */
    public static Intent getFaceIntroIntent(@NonNull Context context,
            @NonNull Intent activityIntent) {
        final Intent intent = new Intent(context,
                FeatureFactory.getFeatureFactory().getFaceFeatureProvider()
                        .getEnrollActivityClassProvider().getNext());
        final Intent intent = new Intent(context, FaceEnroll.class);
        WizardManagerHelper.copyWizardManagerExtras(activityIntent, intent);
        return intent;
    }
+34 −3
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import static androidx.test.espresso.intent.Intents.intended;
import static androidx.test.espresso.intent.matcher.IntentMatchers.hasComponent;
import static androidx.test.espresso.intent.matcher.IntentMatchers.hasExtra;

import static com.android.settings.biometrics.BiometricEnrollActivity.EXTRA_LAUNCH_FACE_ENROLL_FIRST;
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_FOR_BIOMETRICS;
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_FOR_FACE;
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT;
@@ -39,6 +40,7 @@ import android.hardware.face.FaceManager;
import android.hardware.face.FaceSensorPropertiesInternal;
import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.os.Bundle;
import android.os.UserHandle;
import android.provider.Settings;

@@ -145,7 +147,7 @@ public class BiometricEnrollActivityTest {
        assumeTrue(mHasFace || mHasFingerprint);

        setPin();
        final Intent intent = getIntent(true /* useInternal */);
        final Intent intent = getIntent(true /* useInternal */, null);
        LockPatternChecker.verifyCredential(new LockPatternUtils(mContext),
                LockscreenCredential.createPin(TEST_PIN), UserHandle.myUserId(),
                LockPatternUtils.VERIFY_FLAG_REQUEST_GK_PW_HANDLE, (response, timeoutMs) -> {
@@ -162,6 +164,26 @@ public class BiometricEnrollActivityTest {
        }
    }

    @Test
    public void launchWithPinAndPwHandle_confirmsPin_firstEnrollmentIsFace() throws Exception {
        assumeTrue(mHasFace && mHasFingerprint);

        setPin();
        final Intent intent = getFaceEnrollFirstIntent();
        LockPatternChecker.verifyCredential(new LockPatternUtils(mContext),
                LockscreenCredential.createPin(TEST_PIN), UserHandle.myUserId(),
                LockPatternUtils.VERIFY_FLAG_REQUEST_GK_PW_HANDLE, (response, timeoutMs) -> {
                    assertThat(response.containsGatekeeperPasswordHandle()).isTrue();
                    intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE,
                            response.getGatekeeperPasswordHandle());
                }).get();

        try (ActivityScenario<BiometricEnrollActivity> scenario =
                     ActivityScenario.launch(intent)) {
            intended(hasComponent(FaceEnroll.class.getName()));
        }
    }

    @Test
    public void launchWithStrongBiometricAllowed_doNotEnrollWeak() throws Exception {
        assumeTrue(mHasFace || mHasFingerprint);
@@ -184,13 +206,22 @@ public class BiometricEnrollActivityTest {
    }

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

    private Intent getFaceEnrollFirstIntent() {
        final Bundle bundle = new Bundle();
        bundle.putBoolean(EXTRA_LAUNCH_FACE_ENROLL_FIRST, true);
        return getIntent(true /* useInternal */, bundle);
    }

    private Intent getIntent(boolean useInternal) {
    private Intent getIntent(boolean useInternal, Bundle bundle) {
        final Intent intent = new Intent(mContext, useInternal
                ? BiometricEnrollActivity.InternalActivity.class : BiometricEnrollActivity.class);
        intent.setAction(ACTION_BIOMETRIC_ENROLL);
        if (bundle != null && !bundle.isEmpty()) {
            intent.putExtras(bundle);
        }
        return intent;
    }