Loading src/com/android/settings/biometrics/BiometricEnrollActivity.java +25 −6 Original line number Diff line number Diff line Loading @@ -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"; Loading @@ -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; Loading Loading @@ -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()); Loading @@ -221,6 +226,7 @@ public class BiometricEnrollActivity extends InstrumentedActivity { Log.d(TAG, "parentalOptionsRequired: " + mParentalOptionsRequired + ", skipReturnToParent: " + mSkipReturnToParent + ", launchFaceEnrollFirst: " + mLaunchFaceEnrollFirst + ", isSetupWizard: " + isSetupWizard + ", isMultiSensor: " + isMultiSensor); Loading Loading @@ -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(); Loading Loading @@ -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()); Loading @@ -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(); Loading @@ -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 Loading @@ -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); Loading @@ -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 { Loading src/com/android/settings/biometrics/BiometricUtils.java +2 −3 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; } Loading tests/componenttests/src/com/android/settings/biometrics/BiometricEnrollActivityTest.java +34 −3 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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) -> { Loading @@ -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); Loading @@ -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; } Loading Loading
src/com/android/settings/biometrics/BiometricEnrollActivity.java +25 −6 Original line number Diff line number Diff line Loading @@ -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"; Loading @@ -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; Loading Loading @@ -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()); Loading @@ -221,6 +226,7 @@ public class BiometricEnrollActivity extends InstrumentedActivity { Log.d(TAG, "parentalOptionsRequired: " + mParentalOptionsRequired + ", skipReturnToParent: " + mSkipReturnToParent + ", launchFaceEnrollFirst: " + mLaunchFaceEnrollFirst + ", isSetupWizard: " + isSetupWizard + ", isMultiSensor: " + isMultiSensor); Loading Loading @@ -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(); Loading Loading @@ -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()); Loading @@ -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(); Loading @@ -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 Loading @@ -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); Loading @@ -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 { Loading
src/com/android/settings/biometrics/BiometricUtils.java +2 −3 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; } Loading
tests/componenttests/src/com/android/settings/biometrics/BiometricEnrollActivityTest.java +34 −3 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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) -> { Loading @@ -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); Loading @@ -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; } Loading