diff --git a/src/com/android/settings/biometrics/BiometricEnrollActivity.java b/src/com/android/settings/biometrics/BiometricEnrollActivity.java index e682934c321..79e2ea357b4 100644 --- a/src/com/android/settings/biometrics/BiometricEnrollActivity.java +++ b/src/com/android/settings/biometrics/BiometricEnrollActivity.java @@ -93,6 +93,8 @@ public class BiometricEnrollActivity extends InstrumentedActivity { public static final String EXTRA_PARENTAL_CONSENT_STATUS = "consent_status"; private static final String SAVED_STATE_CONFIRMING_CREDENTIALS = "confirming_credentials"; + private static final String SAVED_STATE_FINGERPRINT_ONLY_ENROLLING = + "fingerprint_only_enrolling"; private static final String SAVED_STATE_ENROLL_ACTION_LOGGED = "enroll_action_logged"; private static final String SAVED_STATE_PARENTAL_OPTIONS = "enroll_preferences"; private static final String SAVED_STATE_GK_PW_HANDLE = "gk_pw_handle"; @@ -101,6 +103,7 @@ public class BiometricEnrollActivity extends InstrumentedActivity { private int mUserId = UserHandle.myUserId(); private boolean mConfirmingCredentials; + private boolean mFingerprintOnlyEnrolling; private boolean mIsEnrollActionLogged; private boolean mHasFeatureFace = false; private boolean mHasFeatureFingerprint = false; @@ -129,6 +132,8 @@ public class BiometricEnrollActivity extends InstrumentedActivity { if (savedInstanceState != null) { mConfirmingCredentials = savedInstanceState.getBoolean( SAVED_STATE_CONFIRMING_CREDENTIALS, false); + mFingerprintOnlyEnrolling = savedInstanceState.getBoolean( + SAVED_STATE_FINGERPRINT_ONLY_ENROLLING, false); mIsEnrollActionLogged = savedInstanceState.getBoolean( SAVED_STATE_ENROLL_ACTION_LOGGED, false); mParentalOptions = savedInstanceState.getBundle(SAVED_STATE_PARENTAL_OPTIONS); @@ -302,7 +307,11 @@ public class BiometricEnrollActivity extends InstrumentedActivity { setOrConfirmCredentialsNow(); } } else if (canUseFingerprint) { - launchFingerprintOnlyEnroll(); + if (mGkPwHandle != null) { + launchFingerprintOnlyEnroll(); + } else { + setOrConfirmCredentialsNow(); + } } else if (canUseFace) { launchFaceOnlyEnroll(); } else { // no modalities available @@ -320,6 +329,7 @@ public class BiometricEnrollActivity extends InstrumentedActivity { protected void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); outState.putBoolean(SAVED_STATE_CONFIRMING_CREDENTIALS, mConfirmingCredentials); + outState.putBoolean(SAVED_STATE_FINGERPRINT_ONLY_ENROLLING, mFingerprintOnlyEnrolling); outState.putBoolean(SAVED_STATE_ENROLL_ACTION_LOGGED, mIsEnrollActionLogged); if (mParentalOptions != null) { outState.putBundle(SAVED_STATE_PARENTAL_OPTIONS, mParentalOptions); @@ -432,11 +442,14 @@ public class BiometricEnrollActivity extends InstrumentedActivity { mConfirmingCredentials = false; final boolean isOk = isSuccessfulConfirmOrChooseCredential(requestCode, resultCode); - // single modality enrollment requests confirmation directly + // single face enrollment requests confirmation directly // via BiometricEnrollBase#onCreate and should never get here if (isOk && mHasFeatureFace && mHasFeatureFingerprint) { updateGatekeeperPasswordHandle(data); launchFaceAndFingerprintEnroll(); + } else if (isOk && mHasFeatureFingerprint) { + updateGatekeeperPasswordHandle(data); + launchFingerprintOnlyEnroll(); } else { Log.d(TAG, "Unknown result for set/choose lock: " + resultCode); setResult(resultCode); @@ -444,6 +457,7 @@ public class BiometricEnrollActivity extends InstrumentedActivity { } break; case REQUEST_SINGLE_ENROLL: + mFingerprintOnlyEnrolling = false; finishOrLaunchHandToParent(resultCode); break; default: @@ -572,15 +586,18 @@ public class BiometricEnrollActivity extends InstrumentedActivity { } private void launchFingerprintOnlyEnroll() { - final Intent intent; - // ChooseLockGeneric can request to start fingerprint enroll bypassing the intro screen. - if (getIntent().getBooleanExtra(EXTRA_SKIP_INTRO, false) - && this instanceof InternalActivity) { - intent = BiometricUtils.getFingerprintFindSensorIntent(this, getIntent()); - } else { - intent = BiometricUtils.getFingerprintIntroIntent(this, getIntent()); + if (!mFingerprintOnlyEnrolling) { + mFingerprintOnlyEnrolling = true; + final Intent intent; + // ChooseLockGeneric can request to start fingerprint enroll bypassing the intro screen. + if (getIntent().getBooleanExtra(EXTRA_SKIP_INTRO, false) + && this instanceof InternalActivity) { + intent = BiometricUtils.getFingerprintFindSensorIntent(this, getIntent()); + } else { + intent = BiometricUtils.getFingerprintIntroIntent(this, getIntent()); + } + launchSingleSensorEnrollActivity(intent, REQUEST_SINGLE_ENROLL); } - launchSingleSensorEnrollActivity(intent, REQUEST_SINGLE_ENROLL); } private void launchFaceOnlyEnroll() { diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java index 26a661a6fbd..ca79a246b06 100644 --- a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java +++ b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java @@ -76,6 +76,7 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling { private static final String TAG = "FingerprintEnrollEnrolling"; static final String TAG_SIDECAR = "sidecar"; + static final String KEY_STATE_CANCELED = "is_canceled"; private static final int PROGRESS_BAR_MAX = 10000; @@ -130,6 +131,7 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling { private boolean mRestoring; private Vibrator mVibrator; private boolean mIsSetupWizard; + private boolean mIsCanceled; private AccessibilityManager mAccessibilityManager; private boolean mIsAccessibilityEnabled; private LottieAnimationView mIllustrationLottie; @@ -154,6 +156,9 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + if (savedInstanceState != null) { + restoreSavedState(savedInstanceState); + } mFingerprintManager = getSystemService(FingerprintManager.class); final List props = mFingerprintManager.getSensorPropertiesInternal(); @@ -240,7 +245,6 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling { return true; }); } - mRestoring = savedInstanceState != null; } @Override @@ -255,11 +259,22 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling { if (mCanAssumeUdfps) { // Continue enrollment if restoring (e.g. configuration changed). Otherwise, wait // for the entry animation to complete before starting. - return mRestoring; + return mRestoring && !mIsCanceled; } return true; } + @Override + protected void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + outState.putBoolean(KEY_STATE_CANCELED, mIsCanceled); + } + + private void restoreSavedState(Bundle savedInstanceState) { + mRestoring = true; + mIsCanceled = savedInstanceState.getBoolean(KEY_STATE_CANCELED, false); + } + @Override protected void onStart() { super.onStart(); @@ -500,7 +515,10 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling { @Override public void onEnrollmentError(int errMsgId, CharSequence errString) { FingerprintErrorDialog.showErrorDialog(this, errMsgId); + mIsCanceled = true; + cancelEnrollment(); stopIconAnimation(); + stopListenOrientationEvent(); if (!mCanAssumeUdfps) { mErrorText.removeCallbacks(mTouchAgainRunnable); } diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroduction.java b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroduction.java index 8ce38453ceb..71d0c8eceba 100644 --- a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroduction.java +++ b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroduction.java @@ -241,6 +241,8 @@ public class FingerprintEnrollIntroduction extends BiometricEnrollIntroduction { final boolean isSetupWizard = WizardManagerHelper.isAnySetupWizard(getIntent()); final boolean isDeferredSetupWizard = WizardManagerHelper.isDeferredSetupWizard(getIntent()); + final boolean isPortalSetupWizard = + WizardManagerHelper.isPortalSetupWizard(getIntent()); if (mFingerprintManager != null) { final List props = mFingerprintManager.getSensorPropertiesInternal(); @@ -252,7 +254,7 @@ public class FingerprintEnrollIntroduction extends BiometricEnrollIntroduction { getApplicationContext() .getResources() .getInteger(R.integer.suw_max_fingerprints_enrollable); - if (isSetupWizard && !isDeferredSetupWizard) { + if (isSetupWizard && !isDeferredSetupWizard && !isPortalSetupWizard) { if (numEnrolledFingerprints >= maxFingerprintsEnrollableIfSUW) { return R.string.fingerprint_intro_error_max; } else { diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintErrorDialog.java b/src/com/android/settings/biometrics/fingerprint/FingerprintErrorDialog.java index cea44ba9720..9f9efdc6995 100644 --- a/src/com/android/settings/biometrics/fingerprint/FingerprintErrorDialog.java +++ b/src/com/android/settings/biometrics/fingerprint/FingerprintErrorDialog.java @@ -18,11 +18,13 @@ package com.android.settings.biometrics.fingerprint; import static com.android.settings.biometrics.BiometricEnrollBase.RESULT_FINISHED; import static com.android.settings.biometrics.BiometricEnrollBase.RESULT_TIMEOUT; +import static com.android.settings.biometrics.fingerprint.FingerprintEnrollEnrolling.KEY_STATE_CANCELED; import android.app.Activity; import android.app.Dialog; import android.app.settings.SettingsEnums; import android.content.DialogInterface; +import android.content.Intent; import android.hardware.biometrics.BiometricConstants; import android.hardware.fingerprint.FingerprintManager; import android.os.Bundle; @@ -68,7 +70,11 @@ public class FingerprintErrorDialog extends InstrumentedDialogFragment { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); - getActivity().recreate(); + Activity activity = getActivity(); + Intent intent = activity.getIntent(); + intent.putExtra(KEY_STATE_CANCELED, false); + activity.startActivity(intent); + activity.finish(); } }) .setNegativeButton( diff --git a/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroductionTest.java b/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroductionTest.java index d8852dbb739..1096f4085a4 100644 --- a/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroductionTest.java +++ b/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroductionTest.java @@ -173,4 +173,24 @@ public class FingerprintEnrollIntroductionTest { assertThat(result).isEqualTo(R.string.fingerprint_intro_error_max); } + + @Test + public void intro_CheckCanEnrollDuringPortal() { + setupFingerprintEnrollIntroWith( + new Intent().putExtra(WizardManagerHelper.EXTRA_IS_PORTAL_SETUP, true)); + setFingerprintManagerToHave(2 /* numEnrollments */); + int result = mFingerprintEnrollIntroduction.checkMaxEnrolled(); + + assertThat(result).isEqualTo(0); + } + + @Test + public void intro_CheckMaxEnrolledDuringPortal() { + setupFingerprintEnrollIntroWith( + new Intent().putExtra(WizardManagerHelper.EXTRA_IS_PORTAL_SETUP, true)); + setFingerprintManagerToHave(6 /* numEnrollments */); + int result = mFingerprintEnrollIntroduction.checkMaxEnrolled(); + + assertThat(result).isEqualTo(R.string.fingerprint_intro_error_max); + } }