From b61478c30c7af3befa6935f03e567a86d0d4b122 Mon Sep 17 00:00:00 2001 From: Curtis Belmonte Date: Thu, 15 Jul 2021 16:04:47 -0700 Subject: [PATCH] Ensure fingerprint setup is shown once after face Adds an activity result extra during multi-biometric enroll that ensures fingerprint setup will not be repeated multiple times if explicitly finished or skipped by the user. Also updates various activities in the stack to ensure that they handle all possible result codes correctly and pass along result data. Test: Manually skip and complete at each stage of multi-biometric enroll Test: Manually test single-biometric enroll flows for SUW and Settings Fixes: 193601823 Change-Id: Ic5a8306068eb4c32009f146ad6fff824fde25a11 --- .../BiometricEnrollIntroduction.java | 41 ++++++++++++++---- .../MultiBiometricEnrollHelper.java | 1 + .../biometrics/face/FaceEnrollEducation.java | 11 +++-- .../face/FaceEnrollIntroduction.java | 14 +++++++ .../face/FaceEnrollParentalConsent.java | 10 +++++ .../FingerprintEnrollParentalConsent.java | 10 +++++ .../SetupFingerprintEnrollIntroduction.java | 42 +++++++++++++++---- 7 files changed, 111 insertions(+), 18 deletions(-) diff --git a/src/com/android/settings/biometrics/BiometricEnrollIntroduction.java b/src/com/android/settings/biometrics/BiometricEnrollIntroduction.java index 8d18b1af05e..428e4718ecd 100644 --- a/src/com/android/settings/biometrics/BiometricEnrollIntroduction.java +++ b/src/com/android/settings/biometrics/BiometricEnrollIntroduction.java @@ -36,6 +36,7 @@ import com.android.settings.R; import com.android.settings.SetupWizardUtils; import com.android.settings.password.ChooseLockGeneric; import com.android.settings.password.ChooseLockSettingsHelper; +import com.android.settings.password.SetupSkipDialog; import com.google.android.setupcompat.template.FooterBarMixin; import com.google.android.setupcompat.template.FooterButton; @@ -284,13 +285,11 @@ public abstract class BiometricEnrollIntroduction extends BiometricEnrollBase @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == BIOMETRIC_FIND_SENSOR_REQUEST) { - if (resultCode == RESULT_SKIP || resultCode == RESULT_FINISHED) { - onSkipButtonClick(mFooterBarMixin.getSecondaryButtonView()); - return; + if (isResultSkipOrFinished(resultCode)) { + handleBiometricResultSkipOrFinished(resultCode, data); } else if (resultCode == RESULT_TIMEOUT) { setResult(resultCode, data); finish(); - return; } } else if (requestCode == CHOOSE_LOCK_GENERIC_REQUEST) { mConfirmingCredentials = false; @@ -337,8 +336,8 @@ public abstract class BiometricEnrollIntroduction extends BiometricEnrollBase overridePendingTransition(R.anim.sud_slide_back_in, R.anim.sud_slide_back_out); } else if (requestCode == ENROLL_NEXT_BIOMETRIC_REQUEST) { Log.d(TAG, "ENROLL_NEXT_BIOMETRIC_REQUEST, result: " + resultCode); - if (resultCode == RESULT_SKIP || resultCode == RESULT_FINISHED) { - onSkipButtonClick(mFooterBarMixin.getSecondaryButtonView()); + if (isResultSkipOrFinished(resultCode)) { + handleBiometricResultSkipOrFinished(resultCode, data); } else if (resultCode != RESULT_CANCELED) { setResult(resultCode, data); finish(); @@ -347,6 +346,25 @@ public abstract class BiometricEnrollIntroduction extends BiometricEnrollBase super.onActivityResult(requestCode, resultCode, data); } + private static boolean isResultSkipOrFinished(int resultCode) { + return resultCode == RESULT_SKIP || resultCode == SetupSkipDialog.RESULT_SKIP + || resultCode == RESULT_FINISHED; + } + + private void handleBiometricResultSkipOrFinished(int resultCode, @Nullable Intent data) { + if (data != null + && data.getBooleanExtra( + MultiBiometricEnrollHelper.EXTRA_SKIP_PENDING_ENROLL, false)) { + getIntent().removeExtra(MultiBiometricEnrollHelper.EXTRA_ENROLL_AFTER_FACE); + } + + if (resultCode == RESULT_SKIP) { + onEnrollmentSkipped(data); + } else if (resultCode == RESULT_FINISHED) { + onFinishedEnrolling(data); + } + } + /** * Called after confirming credentials. Can be used to prevent the default * behavior of immediately calling #getChallenge (useful to things like intro @@ -364,7 +382,16 @@ public abstract class BiometricEnrollIntroduction extends BiometricEnrollBase } protected void onSkipButtonClick(View view) { - setResult(RESULT_SKIP); + onEnrollmentSkipped(null /* data */); + } + + protected void onEnrollmentSkipped(@Nullable Intent data) { + setResult(RESULT_SKIP, data); + finish(); + } + + protected void onFinishedEnrolling(@Nullable Intent data) { + setResult(RESULT_FINISHED, data); finish(); } diff --git a/src/com/android/settings/biometrics/MultiBiometricEnrollHelper.java b/src/com/android/settings/biometrics/MultiBiometricEnrollHelper.java index 44d75c5808d..5cc45b1b34e 100644 --- a/src/com/android/settings/biometrics/MultiBiometricEnrollHelper.java +++ b/src/com/android/settings/biometrics/MultiBiometricEnrollHelper.java @@ -37,6 +37,7 @@ public class MultiBiometricEnrollHelper { private static final int REQUEST_FINGERPRINT_ENROLL = 3001; public static final String EXTRA_ENROLL_AFTER_FACE = "enroll_after_face"; + public static final String EXTRA_SKIP_PENDING_ENROLL = "skip_pending_enroll"; @NonNull private final FragmentActivity mActivity; private final long mGkPwHandle; diff --git a/src/com/android/settings/biometrics/face/FaceEnrollEducation.java b/src/com/android/settings/biometrics/face/FaceEnrollEducation.java index f915059407c..08cf5ff12f7 100644 --- a/src/com/android/settings/biometrics/face/FaceEnrollEducation.java +++ b/src/com/android/settings/biometrics/face/FaceEnrollEducation.java @@ -33,6 +33,7 @@ import com.android.settings.Utils; import com.android.settings.biometrics.BiometricEnrollBase; import com.android.settings.biometrics.BiometricUtils; import com.android.settings.password.ChooseLockSettingsHelper; +import com.android.settings.password.SetupSkipDialog; import com.airbnb.lottie.LottieAnimationView; import com.google.android.setupcompat.template.FooterBarMixin; @@ -225,13 +226,17 @@ public class FaceEnrollEducation extends BiometricEnrollBase { protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); mResultIntent = data; - if (requestCode == BIOMETRIC_FIND_SENSOR_REQUEST) { + if (requestCode == BIOMETRIC_FIND_SENSOR_REQUEST + || requestCode == ENROLL_NEXT_BIOMETRIC_REQUEST) { // If the user finished or skipped enrollment, finish this activity - if (resultCode == RESULT_FINISHED || resultCode == RESULT_SKIP - || resultCode == RESULT_TIMEOUT) { + if (resultCode == RESULT_SKIP || resultCode == RESULT_FINISHED + || resultCode == SetupSkipDialog.RESULT_SKIP) { setResult(resultCode, data); finish(); } + } else if (resultCode == RESULT_TIMEOUT) { + setResult(resultCode, data); + finish(); } } diff --git a/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java b/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java index bee1acacf10..e9092c795ea 100644 --- a/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java +++ b/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java @@ -71,6 +71,20 @@ public class FaceEnrollIntroduction extends BiometricEnrollIntroduction { } } + @Override + protected void onEnrollmentSkipped(@Nullable Intent data) { + if (!BiometricUtils.tryStartingNextBiometricEnroll(this, ENROLL_NEXT_BIOMETRIC_REQUEST)) { + super.onEnrollmentSkipped(data); + } + } + + @Override + protected void onFinishedEnrolling(@Nullable Intent data) { + if (!BiometricUtils.tryStartingNextBiometricEnroll(this, ENROLL_NEXT_BIOMETRIC_REQUEST)) { + super.onFinishedEnrolling(data); + } + } + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); diff --git a/src/com/android/settings/biometrics/face/FaceEnrollParentalConsent.java b/src/com/android/settings/biometrics/face/FaceEnrollParentalConsent.java index 81043dc03a6..183e05ef29d 100644 --- a/src/com/android/settings/biometrics/face/FaceEnrollParentalConsent.java +++ b/src/com/android/settings/biometrics/face/FaceEnrollParentalConsent.java @@ -50,6 +50,16 @@ public class FaceEnrollParentalConsent extends FaceEnrollIntroduction { onConsentResult(false /* granted */); } + @Override + protected void onEnrollmentSkipped(@Nullable Intent data) { + onConsentResult(false /* granted */); + } + + @Override + protected void onFinishedEnrolling(@Nullable Intent data) { + onConsentResult(true /* granted */); + } + private void onConsentResult(boolean granted) { final Intent result = new Intent(); result.putExtra(EXTRA_KEY_MODALITY, TYPE_FACE); diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollParentalConsent.java b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollParentalConsent.java index 636e703bae8..a95a91260d5 100644 --- a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollParentalConsent.java +++ b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollParentalConsent.java @@ -51,6 +51,16 @@ public class FingerprintEnrollParentalConsent extends FingerprintEnrollIntroduct onConsentResult(false /* granted */); } + @Override + protected void onEnrollmentSkipped(@Nullable Intent data) { + onConsentResult(false /* granted */); + } + + @Override + protected void onFinishedEnrolling(@Nullable Intent data) { + onConsentResult(true /* granted */); + } + private void onConsentResult(boolean granted) { final Intent result = new Intent(); result.putExtra(EXTRA_KEY_MODALITY, TYPE_FINGERPRINT); diff --git a/src/com/android/settings/biometrics/fingerprint/SetupFingerprintEnrollIntroduction.java b/src/com/android/settings/biometrics/fingerprint/SetupFingerprintEnrollIntroduction.java index 4bd8afd98ed..63faf5e4672 100644 --- a/src/com/android/settings/biometrics/fingerprint/SetupFingerprintEnrollIntroduction.java +++ b/src/com/android/settings/biometrics/fingerprint/SetupFingerprintEnrollIntroduction.java @@ -29,6 +29,7 @@ import com.android.internal.widget.LockPatternUtils; import com.android.settings.SetupWizardUtils; import com.android.settings.Utils; import com.android.settings.biometrics.BiometricUtils; +import com.android.settings.biometrics.MultiBiometricEnrollHelper; import com.android.settings.password.ChooseLockSettingsHelper; import com.android.settings.password.SetupChooseLockGeneric; import com.android.settings.password.SetupSkipDialog; @@ -72,19 +73,28 @@ public class SetupFingerprintEnrollIntroduction extends FingerprintEnrollIntrodu @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { - // if lock was already present, do not return intent data since it must have been - // reported in previous attempts if (requestCode == BIOMETRIC_FIND_SENSOR_REQUEST && isKeyguardSecure()) { - if(!mAlreadyHadLockScreenSetup) { + // if lock was already present, do not return intent data since it must have been + // reported in previous attempts + if (!mAlreadyHadLockScreenSetup) { data = getMetricIntent(data); } // Report fingerprint count if user adding a new fingerprint - if(resultCode == RESULT_FINISHED) { + if (resultCode == RESULT_FINISHED) { data = setFingerprintCount(data); } } + // If user has skipped or finished enrolling, don't restart enrollment. + final boolean isEnrollRequest = requestCode == BIOMETRIC_FIND_SENSOR_REQUEST + || requestCode == ENROLL_NEXT_BIOMETRIC_REQUEST; + final boolean isResultSkipOrFinished = resultCode == RESULT_SKIP + || resultCode == SetupSkipDialog.RESULT_SKIP || resultCode == RESULT_FINISHED; + if (isEnrollRequest && isResultSkipOrFinished) { + data = setSkipPendingEnroll(data); + } + super.onActivityResult(requestCode, resultCode, data); } @@ -112,17 +122,33 @@ public class SetupFingerprintEnrollIntroduction extends FingerprintEnrollIntrodu return data; } + private Intent setSkipPendingEnroll(Intent data) { + if (data == null) { + data = new Intent(); + } + data.putExtra(MultiBiometricEnrollHelper.EXTRA_SKIP_PENDING_ENROLL, true); + return data; + } + @Override protected void onCancelButtonClick(View view) { + final int resultCode; + Intent data; if (isKeyguardSecure()) { // If the keyguard is already set up securely (maybe the user added a backup screen // lock and skipped fingerprint), return RESULT_SKIP directly. - setResult(RESULT_SKIP, mAlreadyHadLockScreenSetup ? null : getMetricIntent(null)); - finish(); + resultCode = RESULT_SKIP; + data = mAlreadyHadLockScreenSetup ? null : getMetricIntent(null); } else { - setResult(SetupSkipDialog.RESULT_SKIP); - finish(); + resultCode = SetupSkipDialog.RESULT_SKIP; + data = null; } + + // User has explicitly canceled enroll. Don't restart it automatically. + data = setSkipPendingEnroll(data); + + setResult(resultCode, data); + finish(); } @Override