From 94b421b253d641d929ec94466754aa56a2fa216c Mon Sep 17 00:00:00 2001 From: Milton Wu Date: Sat, 25 Feb 2023 00:17:10 +0800 Subject: [PATCH] Refine FingerprintEnrollmentActivity 1. Fix backstacks after enrolling finish 2. Support skipFindSensor and skipIntro Bug: 260957939 Test: Manually test it on different sensor devices Change-Id: I4061e29999a47bf4859d6562ad82330fb0f6f620 --- .../settings/biometrics/BiometricUtils.java | 9 +- .../fingerprint/FingerprintSettings.java | 12 +- .../ui/model/EnrollmentRequest.java | 19 +- ...ingerprintEnrollEnrollingRfpsFragment.java | 61 ++--- ...ingerprintEnrollEnrollingSfpsFragment.java | 12 - ...ngerprintEnrollEnrollingUdfpsFragment.java | 231 +++++++----------- .../view/FingerprintEnrollIntroFragment.java | 4 - .../view/FingerprintEnrollmentActivity.java | 119 +++++---- .../FingerprintEnrollEnrollingViewModel.java | 25 -- 9 files changed, 208 insertions(+), 284 deletions(-) diff --git a/src/com/android/settings/biometrics/BiometricUtils.java b/src/com/android/settings/biometrics/BiometricUtils.java index 342423af982..772aec33bfd 100644 --- a/src/com/android/settings/biometrics/BiometricUtils.java +++ b/src/com/android/settings/biometrics/BiometricUtils.java @@ -242,7 +242,14 @@ public class BiometricUtils { */ public static Intent getFingerprintFindSensorIntent(@NonNull Context context, @NonNull Intent activityIntent) { - if (WizardManagerHelper.isAnySetupWizard(activityIntent)) { + if (FeatureFlagUtils.isEnabled(context, FeatureFlagUtils.SETTINGS_BIOMETRICS2_ENROLLMENT)) { + final Intent intent = new Intent(context, FingerprintEnrollmentActivity.class); + intent.putExtra(BiometricEnrollActivity.EXTRA_SKIP_INTRO, true); + if (WizardManagerHelper.isAnySetupWizard(activityIntent)) { + SetupWizardUtils.copySetupExtras(activityIntent, intent); + } + return intent; + } else if (WizardManagerHelper.isAnySetupWizard(activityIntent)) { Intent intent = new Intent(context, SetupFingerprintEnrollFindSensor.class); SetupWizardUtils.copySetupExtras(activityIntent, intent); return intent; diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java b/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java index 74d40d132ea..f2ed1200717 100644 --- a/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java +++ b/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java @@ -68,6 +68,7 @@ import com.android.settings.Utils; import com.android.settings.biometrics.BiometricEnrollBase; import com.android.settings.biometrics.BiometricUtils; import com.android.settings.biometrics.GatekeeperPasswordProvider; +import com.android.settings.biometrics2.ui.model.EnrollmentRequest; import com.android.settings.biometrics2.ui.view.FingerprintEnrollmentActivity; import com.android.settings.core.SettingsBaseActivity; import com.android.settings.core.instrumentation.InstrumentedDialogFragment; @@ -687,8 +688,15 @@ public class FingerprintSettings extends SubSettings { if (KEY_FINGERPRINT_ADD.equals(key)) { mIsEnrolling = true; Intent intent = new Intent(); - intent.setClassName(SETTINGS_PACKAGE_NAME, - FingerprintEnrollEnrolling.class.getName()); + if (FeatureFlagUtils.isEnabled(getContext(), + FeatureFlagUtils.SETTINGS_BIOMETRICS2_ENROLLMENT)) { + intent.setClassName(SETTINGS_PACKAGE_NAME, + FingerprintEnrollmentActivity.class.getName()); + intent.putExtra(EnrollmentRequest.EXTRA_SKIP_FIND_SENSOR, true); + } else { + intent.setClassName(SETTINGS_PACKAGE_NAME, + FingerprintEnrollEnrolling.class.getName()); + } intent.putExtra(Intent.EXTRA_USER_ID, mUserId); intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, mToken); startActivityForResult(intent, ADD_FINGERPRINT_REQUEST); diff --git a/src/com/android/settings/biometrics2/ui/model/EnrollmentRequest.java b/src/com/android/settings/biometrics2/ui/model/EnrollmentRequest.java index de8526a1657..4849b5e5cdb 100644 --- a/src/com/android/settings/biometrics2/ui/model/EnrollmentRequest.java +++ b/src/com/android/settings/biometrics2/ui/model/EnrollmentRequest.java @@ -27,6 +27,7 @@ import android.os.Bundle; import androidx.annotation.NonNull; import com.android.settings.SetupWizardUtils; +import com.android.settings.biometrics.BiometricEnrollActivity; import com.google.android.setupcompat.util.WizardManagerHelper; @@ -36,13 +37,19 @@ import com.google.android.setupcompat.util.WizardManagerHelper; * 2. isAfterSuwOrSuwSuggestedAction * 3. theme * 4. isFromSettingsSummery - * 5. a helper method, getSetupWizardExtras + * 5. isSkipIntro + * 6. isSkipFindSensor + * 7. a helper method, getSetupWizardExtras */ public final class EnrollmentRequest { + public static final String EXTRA_SKIP_FIND_SENSOR = "skip_find_sensor"; + private final boolean mIsSuw; private final boolean mIsAfterSuwOrSuwSuggestedAction; private final boolean mIsFromSettingsSummery; + private final boolean mIsSkipIntro; + private final boolean mIsSkipFindSensor; private final int mTheme; private final Bundle mSuwExtras; @@ -53,6 +60,8 @@ public final class EnrollmentRequest { || intent.getBooleanExtra(EXTRA_IS_SUW_SUGGESTED_ACTION_FLOW, false); mSuwExtras = getSuwExtras(mIsSuw, intent); mIsFromSettingsSummery = intent.getBooleanExtra(EXTRA_FROM_SETTINGS_SUMMARY, false); + mIsSkipIntro = intent.getBooleanExtra(BiometricEnrollActivity.EXTRA_SKIP_INTRO, false); + mIsSkipFindSensor = intent.getBooleanExtra(EXTRA_SKIP_FIND_SENSOR, false); mTheme = SetupWizardUtils.getTheme(context, intent); } @@ -68,6 +77,14 @@ public final class EnrollmentRequest { return mIsFromSettingsSummery; } + public boolean isSkipIntro() { + return mIsSkipIntro; + } + + public boolean isSkipFindSensor() { + return mIsSkipFindSensor; + } + public int getTheme() { return mTheme; } diff --git a/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollEnrollingRfpsFragment.java b/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollEnrollingRfpsFragment.java index 74ae6fb4cce..8e022e0c091 100644 --- a/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollEnrollingRfpsFragment.java +++ b/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollEnrollingRfpsFragment.java @@ -35,7 +35,6 @@ import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; -import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.view.animation.Interpolator; import android.widget.ProgressBar; @@ -43,7 +42,6 @@ import android.widget.TextView; import androidx.activity.OnBackPressedCallback; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentActivity; import androidx.lifecycle.Observer; @@ -127,6 +125,15 @@ public class FingerprintEnrollEnrollingRfpsFragment extends Fragment { } }; + private final OnBackPressedCallback mOnBackPressedCallback = new OnBackPressedCallback(true) { + @Override + public void handleOnBackPressed() { + setEnabled(false); + mEnrollingViewModel.setOnBackPressed(); + cancelEnrollment(); + } + }; + @Override public void onAttach(@NonNull Context context) { final FragmentActivity activity = getActivity(); @@ -134,53 +141,13 @@ public class FingerprintEnrollEnrollingRfpsFragment extends Fragment { mEnrollingViewModel = provider.get(FingerprintEnrollEnrollingViewModel.class); mProgressViewModel = provider.get(FingerprintEnrollProgressViewModel.class); super.onAttach(context); - requireActivity().getOnBackPressedDispatcher().addCallback(new OnBackPressedCallback(true) { - @Override - public void handleOnBackPressed() { - setEnabled(false); - mEnrollingViewModel.setOnBackPressed(); - cancelEnrollment(); - } - }); - } - - @Nullable - @Override - public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) { - if (enter && nextAnim == R.anim.sud_slide_next_in) { - final Animation animation = AnimationUtils.loadAnimation(getActivity(), nextAnim); - if (animation != null) { - animation.setAnimationListener(new Animation.AnimationListener() { - @Override - public void onAnimationStart(Animation animation) { - } - - @Override - public void onAnimationEnd(Animation animation) { - mAnimationCancelled = false; - startIconAnimation(); - } - - @Override - public void onAnimationRepeat(Animation animation) { - } - }); - return animation; - } - } - return super.onCreateAnimation(transit, enter, nextAnim); + activity.getOnBackPressedDispatcher().addCallback(mOnBackPressedCallback); } @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - mEnrollingViewModel.restoreSavedState(savedInstanceState); - } - - @Override - public void onSaveInstanceState(@NonNull Bundle outState) { - mEnrollingViewModel.onSaveInstanceState(outState); - super.onSaveInstanceState(outState); + public void onDetach() { + mOnBackPressedCallback.setEnabled(false); + super.onDetach(); } @Override @@ -248,6 +215,8 @@ public class FingerprintEnrollEnrollingRfpsFragment extends Fragment { @Override public void onStart() { super.onStart(); + mAnimationCancelled = false; + startIconAnimation(); startEnrollment(); updateProgress(false /* animate */, mProgressViewModel.getProgressLiveData().getValue()); updateTitleAndDescription(); diff --git a/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollEnrollingSfpsFragment.java b/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollEnrollingSfpsFragment.java index be18b9c3e3f..ab772e3771b 100644 --- a/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollEnrollingSfpsFragment.java +++ b/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollEnrollingSfpsFragment.java @@ -151,18 +151,6 @@ public class FingerprintEnrollEnrollingSfpsFragment extends Fragment { }); } - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - mEnrollingViewModel.restoreSavedState(savedInstanceState); - } - - @Override - public void onSaveInstanceState(@NonNull Bundle outState) { - mEnrollingViewModel.onSaveInstanceState(outState); - super.onSaveInstanceState(outState); - } - @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { diff --git a/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollEnrollingUdfpsFragment.java b/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollEnrollingUdfpsFragment.java index ad8a8ae3ae7..b48571396d2 100644 --- a/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollEnrollingUdfpsFragment.java +++ b/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollEnrollingUdfpsFragment.java @@ -22,8 +22,7 @@ import android.annotation.RawRes; import android.app.Activity; import android.content.Context; import android.content.res.Configuration; -import android.graphics.drawable.Animatable2; -import android.graphics.drawable.Drawable; +import android.hardware.fingerprint.FingerprintManager; import android.os.Bundle; import android.text.TextUtils; import android.util.DisplayMetrics; @@ -37,16 +36,16 @@ import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.TextView; +import androidx.activity.OnBackPressedCallback; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentActivity; import androidx.lifecycle.Observer; import androidx.lifecycle.ViewModelProvider; -import androidx.transition.Transition; -import androidx.transition.TransitionSet; import com.android.settings.R; import com.android.settings.biometrics.BiometricUtils; +import com.android.settings.biometrics.fingerprint.FingerprintErrorDialog; import com.android.settings.biometrics2.ui.model.EnrollmentProgress; import com.android.settings.biometrics2.ui.model.EnrollmentStatusMessage; import com.android.settings.biometrics2.ui.viewmodel.DeviceRotationViewModel; @@ -78,8 +77,6 @@ public class FingerprintEnrollEnrollingUdfpsFragment extends Fragment { private DeviceRotationViewModel mRotationViewModel; private FingerprintEnrollProgressViewModel mProgressViewModel; - private boolean mAnimationCancelled; - private LottieAnimationView mIllustrationLottie; private boolean mHaveShownUdfpsTipLottie; private boolean mHaveShownUdfpsLeftEdgeLottie; @@ -87,12 +84,8 @@ public class FingerprintEnrollEnrollingUdfpsFragment extends Fragment { private boolean mHaveShownUdfpsCenterLottie; private boolean mHaveShownUdfpsGuideLottie; - private RelativeLayout mView; - private ImageView mIcon; - private TextView mErrorText; private TextView mTitleText; private TextView mSubTitleText; - private Button mSkipBtn; private UdfpsEnrollView mUdfpsEnrollView; private boolean mShouldShowLottie; @@ -101,20 +94,22 @@ public class FingerprintEnrollEnrollingUdfpsFragment extends Fragment { private final View.OnClickListener mOnSkipClickListener = (v) -> mEnrollingViewModel.onCancelledDueToOnSkipPressed(); - private Observer mProgressObserver = progress -> { + private final Observer mProgressObserver = progress -> { if (progress != null) { onEnrollmentProgressChange(progress); } }; - private Observer mHelpMessageObserver = helpMessage -> { + private final Observer mHelpMessageObserver = helpMessage -> { if (helpMessage != null) { - onEnrollmentHelp(helpMessage.getMsgId(), helpMessage.getStr()); + onEnrollmentHelp(helpMessage.getStr()); } }; - private Observer mErrorMessageObserver = errorMessage -> { - // TODO + private final Observer mErrorMessageObserver = errorMessage -> { + if (errorMessage != null) { + onEnrollmentError(errorMessage); + } }; - private Observer mAcquireObserver = isAcquiredGood -> { + private final Observer mAcquireObserver = isAcquiredGood -> { if (isAcquiredGood != null) { onAcquired(isAcquiredGood); } @@ -129,8 +124,14 @@ public class FingerprintEnrollEnrollingUdfpsFragment extends Fragment { onPointerUp(sensorId); } }; - - private int mIconTouchCount; + private final OnBackPressedCallback mOnBackPressedCallback = new OnBackPressedCallback(true) { + @Override + public void handleOnBackPressed() { + setEnabled(false); + mEnrollingViewModel.setOnBackPressed(); + cancelEnrollment(); + } + }; @Override @@ -141,81 +142,42 @@ public class FingerprintEnrollEnrollingUdfpsFragment extends Fragment { mRotationViewModel = provider.get(DeviceRotationViewModel.class); mProgressViewModel = provider.get(FingerprintEnrollProgressViewModel.class); super.onAttach(context); - final TransitionSet transitionSet = (TransitionSet) getSharedElementEnterTransition(); - if (transitionSet != null) { - transitionSet.addListener(new Transition.TransitionListener() { - @Override - public void onTransitionStart(@NonNull Transition transition) { + activity.getOnBackPressedDispatcher().addCallback(mOnBackPressedCallback); + } - } - - @Override - public void onTransitionEnd(@NonNull Transition transition) { - transition.removeListener(this); - startEnrollment(); - mAnimationCancelled = false; - startIconAnimation(); - } - - @Override - public void onTransitionCancel(@NonNull Transition transition) { - - } - - @Override - public void onTransitionPause(@NonNull Transition transition) { - - } - - @Override - public void onTransitionResume(@NonNull Transition transition) { - - } - }); - } + @Override + public void onDetach() { + mOnBackPressedCallback.setEnabled(false); + super.onDetach(); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - mEnrollingViewModel.restoreSavedState(savedInstanceState); mIsAccessibilityEnabled = mEnrollingViewModel.isAccessibilityEnabled(); } - @Override - public void onSaveInstanceState(@NonNull Bundle outState) { - mEnrollingViewModel.onSaveInstanceState(outState); - super.onSaveInstanceState(outState); - } - @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - mView = initUdfpsLayout(inflater, container); - return mView; - } - - private RelativeLayout initUdfpsLayout(LayoutInflater inflater, ViewGroup container) { final RelativeLayout containView = (RelativeLayout) inflater.inflate( R.layout.udfps_enroll_enrolling_v2, container, false); final Activity activity = getActivity(); - mIcon = containView.findViewById(R.id.sud_layout_icon); + final ImageView icon = containView.findViewById(R.id.sud_layout_icon); mTitleText = containView.findViewById(R.id.suc_layout_title); mSubTitleText = containView.findViewById(R.id.sud_layout_subtitle); - mErrorText = containView.findViewById(R.id.error_text); - mSkipBtn = containView.findViewById(R.id.skip_btn); - mSkipBtn.setOnClickListener(mOnSkipClickListener); + final Button skipBtn = containView.findViewById(R.id.skip_btn); + skipBtn.setOnClickListener(mOnSkipClickListener); mUdfpsEnrollView = containView.findViewById(R.id.udfps_animation_view); mUdfpsEnrollView.setSensorProperties( mEnrollingViewModel.getFirstFingerprintSensorPropertiesInternal()); mShouldShowLottie = shouldShowLottie(); - boolean isLandscape = BiometricUtils.isReverseLandscape(activity) + final boolean isLandscape = BiometricUtils.isReverseLandscape(activity) || BiometricUtils.isLandscape(activity); updateOrientation(containView, (isLandscape ? Configuration.ORIENTATION_LANDSCAPE : Configuration.ORIENTATION_PORTRAIT)); - final int rotation = mRotationViewModel.getLiveData().getValue(); if (rotation == Surface.ROTATION_270) { RelativeLayout.LayoutParams iconLP = new RelativeLayout.LayoutParams(-2, -2); @@ -223,7 +185,7 @@ public class FingerprintEnrollEnrollingUdfpsFragment extends Fragment { iconLP.addRule(RelativeLayout.END_OF, R.id.udfps_animation_view); iconLP.topMargin = (int) convertDpToPixel(76.64f, activity); iconLP.leftMargin = (int) convertDpToPixel(151.54f, activity); - mIcon.setLayoutParams(iconLP); + icon.setLayoutParams(iconLP); RelativeLayout.LayoutParams titleLP = new RelativeLayout.LayoutParams(-1, -2); titleLP.addRule(RelativeLayout.ALIGN_PARENT_TOP); @@ -245,7 +207,7 @@ public class FingerprintEnrollEnrollingUdfpsFragment extends Fragment { iconLP.addRule(RelativeLayout.ALIGN_PARENT_START); iconLP.topMargin = (int) convertDpToPixel(76.64f, activity); iconLP.leftMargin = (int) convertDpToPixel(71.99f, activity); - mIcon.setLayoutParams(iconLP); + icon.setLayoutParams(iconLP); RelativeLayout.LayoutParams titleLP = new RelativeLayout.LayoutParams( metrics.widthPixels / 2, -2); @@ -266,10 +228,10 @@ public class FingerprintEnrollEnrollingUdfpsFragment extends Fragment { if (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270) { RelativeLayout.LayoutParams skipBtnLP = - (RelativeLayout.LayoutParams) mIcon.getLayoutParams(); + (RelativeLayout.LayoutParams) icon.getLayoutParams(); skipBtnLP.topMargin = (int) convertDpToPixel(26f, activity); skipBtnLP.leftMargin = (int) convertDpToPixel(54f, activity); - mSkipBtn.requestLayout(); + skipBtn.requestLayout(); } return containView; } @@ -277,43 +239,49 @@ public class FingerprintEnrollEnrollingUdfpsFragment extends Fragment { @Override public void onStart() { super.onStart(); - if (true /* TODO mRestoring && !mIsCanceled */) { - startEnrollment(); - } + startEnrollment(); updateProgress(false /* animate */, mProgressViewModel.getProgressLiveData().getValue()); updateTitleAndDescription(); - if (true /* TODO mRestoring */) { - startIconAnimation(); - } } @Override public void onStop() { - stopIconAnimation(); - removeEnrollmentObserver(); - if (!getActivity().isChangingConfigurations()) { + removeEnrollmentObservers(); + if (!getActivity().isChangingConfigurations() && mProgressViewModel.isEnrolling()) { mProgressViewModel.cancelEnrollment(); } super.onStop(); } - private void removeEnrollmentObserver() { + private void removeEnrollmentObservers() { + preRemoveEnrollmentObservers(); + mProgressViewModel.getErrorMessageLiveData().removeObserver(mErrorMessageObserver); + } + + private void preRemoveEnrollmentObservers() { mProgressViewModel.getProgressLiveData().removeObserver(mProgressObserver); mProgressViewModel.getHelpMessageLiveData().removeObserver(mHelpMessageObserver); - mProgressViewModel.getErrorMessageLiveData().removeObserver(mErrorMessageObserver); mProgressViewModel.getAcquireLiveData().removeObserver(mAcquireObserver); mProgressViewModel.getPointerDownLiveData().removeObserver(mPointerDownObserver); mProgressViewModel.getPointerUpLiveData().removeObserver(mPointerUpObserver); } + private void cancelEnrollment() { + preRemoveEnrollmentObservers(); + mProgressViewModel.cancelEnrollment(); + } + private void startEnrollment() { + final boolean startResult = mProgressViewModel.startEnrollment(ENROLL_ENROLL); + if (!startResult) { + Log.e(TAG, "startEnrollment(), failed"); + } mProgressViewModel.getProgressLiveData().observe(this, mProgressObserver); mProgressViewModel.getHelpMessageLiveData().observe(this, mHelpMessageObserver); mProgressViewModel.getErrorMessageLiveData().observe(this, mErrorMessageObserver); mProgressViewModel.getAcquireLiveData().observe(this, mAcquireObserver); mProgressViewModel.getPointerDownLiveData().observe(this, mPointerDownObserver); mProgressViewModel.getPointerUpLiveData().observe(this, mPointerUpObserver); - mProgressViewModel.startEnrollment(ENROLL_ENROLL); } private void updateProgress(boolean animate, @NonNull EnrollmentProgress enrollmentProgress) { @@ -343,12 +311,6 @@ public class FingerprintEnrollEnrollingUdfpsFragment extends Fragment { return PROGRESS_BAR_MAX * displayProgress / (progress.getSteps() + 1); } - @Override - public void onDestroy() { - // TODO stopListenOrientationEvent(); - super.onDestroy(); - } - private void animateProgress(int progress) { // UDFPS animations are owned by SystemUI if (progress >= PROGRESS_BAR_MAX) { @@ -363,13 +325,13 @@ public class FingerprintEnrollEnrollingUdfpsFragment extends Fragment { mTitleText.setText(R.string.security_settings_fingerprint_enroll_repeat_title); if (mIsAccessibilityEnabled || mIllustrationLottie == null) { mSubTitleText.setText(R.string.security_settings_udfps_enroll_start_message); - } else if (!mHaveShownUdfpsCenterLottie && mIllustrationLottie != null) { + } else if (!mHaveShownUdfpsCenterLottie) { mHaveShownUdfpsCenterLottie = true; // Note: Update string reference when differentiate in between udfps & sfps mIllustrationLottie.setContentDescription( getString(R.string.security_settings_sfps_enroll_finger_center_title) ); - configureEnrollmentStage("", R.raw.udfps_center_hint_lottie); + configureEnrollmentStage(R.raw.udfps_center_hint_lottie); } break; @@ -378,13 +340,13 @@ public class FingerprintEnrollEnrollingUdfpsFragment extends Fragment { if (mIsAccessibilityEnabled || mIllustrationLottie == null) { mSubTitleText.setText( R.string.security_settings_udfps_enroll_repeat_a11y_message); - } else if (!mHaveShownUdfpsGuideLottie && mIllustrationLottie != null) { + } else if (!mHaveShownUdfpsGuideLottie) { mHaveShownUdfpsGuideLottie = true; mIllustrationLottie.setContentDescription( getString(R.string.security_settings_fingerprint_enroll_repeat_message) ); // TODO(b/228100413) Could customize guided lottie animation - configureEnrollmentStage("", R.raw.udfps_center_hint_lottie); + configureEnrollmentStage(R.raw.udfps_center_hint_lottie); } break; case STAGE_FINGERTIP: @@ -394,7 +356,7 @@ public class FingerprintEnrollEnrollingUdfpsFragment extends Fragment { mIllustrationLottie.setContentDescription( getString(R.string.security_settings_udfps_tip_fingerprint_help) ); - configureEnrollmentStage("", R.raw.udfps_tip_hint_lottie); + configureEnrollmentStage(R.raw.udfps_tip_hint_lottie); } break; case STAGE_LEFT_EDGE: @@ -404,7 +366,7 @@ public class FingerprintEnrollEnrollingUdfpsFragment extends Fragment { mIllustrationLottie.setContentDescription( getString(R.string.security_settings_udfps_side_fingerprint_help) ); - configureEnrollmentStage("", R.raw.udfps_left_edge_hint_lottie); + configureEnrollmentStage(R.raw.udfps_left_edge_hint_lottie); } else if (mIllustrationLottie == null) { if (isStageHalfCompleted()) { mSubTitleText.setText( @@ -421,7 +383,7 @@ public class FingerprintEnrollEnrollingUdfpsFragment extends Fragment { mIllustrationLottie.setContentDescription( getString(R.string.security_settings_udfps_side_fingerprint_help) ); - configureEnrollmentStage("", R.raw.udfps_right_edge_hint_lottie); + configureEnrollmentStage(R.raw.udfps_right_edge_hint_lottie); } else if (mIllustrationLottie == null) { if (isStageHalfCompleted()) { @@ -471,13 +433,6 @@ public class FingerprintEnrollEnrollingUdfpsFragment extends Fragment { } } - private void startIconAnimation() { - } - - private void stopIconAnimation() { - mAnimationCancelled = true; - } - private int getCurrentStage() { EnrollmentProgress progressLiveData = mProgressViewModel.getProgressLiveData().getValue(); @@ -533,14 +488,8 @@ public class FingerprintEnrollEnrollingUdfpsFragment extends Fragment { * mEnrollingViewModel.getEnrollStageThreshold(index)); } - private void showIconTouchDialog() { - mIconTouchCount = 0; - //TODO EnrollingActivity should observe live data and add dialog fragment - mEnrollingViewModel.onIconTouchDialogShow(); - } - - private void configureEnrollmentStage(CharSequence description, @RawRes int lottie) { - mSubTitleText.setText(description); + private void configureEnrollmentStage(@RawRes int lottie) { + mSubTitleText.setText(""); LottieCompositionFactory.fromRawRes(getActivity(), lottie) .addListener((c) -> { mIllustrationLottie.setComposition(c); @@ -565,13 +514,34 @@ public class FingerprintEnrollEnrollingUdfpsFragment extends Fragment { } - private void onEnrollmentHelp(int helpMsgId, CharSequence helpString) { + private void onEnrollmentHelp(CharSequence helpString) { if (!TextUtils.isEmpty(helpString)) { showError(helpString); mUdfpsEnrollView.onEnrollmentHelp(); } } + private void onEnrollmentError(@NonNull EnrollmentStatusMessage errorMessage) { + removeEnrollmentObservers(); + + if (mEnrollingViewModel.getOnBackPressed() + && errorMessage.getMsgId() == FingerprintManager.FINGERPRINT_ERROR_CANCELED) { + mEnrollingViewModel.onCancelledDueToOnBackPressed(); + } else if (mEnrollingViewModel.getOnSkipPressed() + && errorMessage.getMsgId() == FingerprintManager.FINGERPRINT_ERROR_CANCELED) { + mEnrollingViewModel.onCancelledDueToOnSkipPressed(); + } else { + final int errMsgId = errorMessage.getMsgId(); + mEnrollingViewModel.showErrorDialog( + new FingerprintEnrollEnrollingViewModel.ErrorDialogData( + getString(FingerprintErrorDialog.getErrorMessage(errMsgId)), + getString(FingerprintErrorDialog.getErrorTitle(errMsgId)), + errMsgId + )); + mProgressViewModel.cancelEnrollment(); + } + } + private void onAcquired(boolean isAcquiredGood) { if (mUdfpsEnrollView != null) { mUdfpsEnrollView.onAcquired(isAcquiredGood); @@ -597,8 +567,7 @@ public class FingerprintEnrollEnrollingUdfpsFragment extends Fragment { } private float convertDpToPixel(float dp, Context context) { - float px = dp * getDensity(context); - return px; + return dp * getDensity(context); } private float getDensity(Context context) { @@ -606,38 +575,6 @@ public class FingerprintEnrollEnrollingUdfpsFragment extends Fragment { return metrics.density; } - private final Runnable mShowDialogRunnable = new Runnable() { - @Override - public void run() { - showIconTouchDialog(); - } - }; - // Give the user a chance to see progress completed before jumping to the next stage. - private final Runnable mDelayedFinishRunnable = new Runnable() { - @Override - public void run() { - /* TODO launchFinish(); */ - } - }; - - private final Animatable2.AnimationCallback mIconAnimationCallback = - new Animatable2.AnimationCallback() { - @Override - public void onAnimationEnd(Drawable d) { - if (mAnimationCancelled) { - return; - } - - // Start animation after it has ended. - /* TODO check mProgressBar? - mProgressBar.post(new Runnable() { - @Override - public void run() { - startIconAnimation(); - } - }); - */ - } - }; + private final Runnable mDelayedFinishRunnable = () -> mEnrollingViewModel.onEnrollingDone(); } diff --git a/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollIntroFragment.java b/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollIntroFragment.java index e6b91163a43..be1f0bda623 100644 --- a/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollIntroFragment.java +++ b/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollIntroFragment.java @@ -76,10 +76,6 @@ public class FingerprintEnrollIntroFragment extends Fragment { private TextView mFooterMessage6 = null; @Nullable private PorterDuffColorFilter mIconColorFilter; - public FingerprintEnrollIntroFragment() { - super(); - } - @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, diff --git a/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollmentActivity.java b/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollmentActivity.java index eba9bba2628..ff43e8bea30 100644 --- a/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollmentActivity.java +++ b/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollmentActivity.java @@ -114,6 +114,10 @@ public class FingerprintEnrollmentActivity extends FragmentActivity { protected static final int LAUNCH_CONFIRM_LOCK_ACTIVITY = 1; + // This flag is used for addBackStack(), we do not save it in ViewModel because it is just used + // during FragmentManager calls + private boolean mIsFirstFragmentAdded = false; + private ViewModelProvider mViewModelProvider; private FingerprintEnrollmentViewModel mViewModel; private AutoCredentialViewModel mAutoCredentialViewModel; @@ -195,8 +199,16 @@ public class FingerprintEnrollmentActivity extends FragmentActivity { Log.e(TAG, "onCreate() has savedInstance:" + (savedInstanceState != null)); } if (savedInstanceState == null) { + Log.d(TAG, "onCreate()"); // Use to differentiate biometrics v2 checkCredential(); - startIntroFragment(); + final EnrollmentRequest request = mViewModel.getRequest(); + if (request.isSkipFindSensor()) { + startEnrollingFragment(); + } else if (request.isSkipIntro()) { + startFindSensorFragment(); + } else { + startIntroFragment(); + } } else { final FragmentManager manager = getSupportFragmentManager(); String[] tags = new String[] { @@ -244,16 +256,36 @@ public class FingerprintEnrollmentActivity extends FragmentActivity { this::onGenerateChallengeFailed); } + private void startFragment(@NonNull Class fragmentClass, + @NonNull String tag) { + if (!mIsFirstFragmentAdded) { + getSupportFragmentManager().beginTransaction() + .setReorderingAllowed(true) + .replace(R.id.fragment_container_view, fragmentClass, null, tag) + .commit(); + mIsFirstFragmentAdded = true; + } else { + getSupportFragmentManager().beginTransaction() + .setReorderingAllowed(true) + .replace(R.id.fragment_container_view, fragmentClass, null, tag) + .setCustomAnimations(R.anim.sud_slide_next_in, R.anim.sud_slide_next_out, + R.anim.sud_slide_back_in, R.anim.sud_slide_back_out) + .addToBackStack(tag) + .commit(); + } + } + private void startIntroFragment() { attachIntroViewModel(); - getSupportFragmentManager().beginTransaction() - .setReorderingAllowed(true) - .replace(R.id.fragment_container_view, FingerprintEnrollIntroFragment.class, null, - INTRO_TAG) - .commit(); + startFragment(FingerprintEnrollIntroFragment.class, INTRO_TAG); } private void attachIntroViewModel() { + final EnrollmentRequest request = mViewModel.getRequest(); + if (request.isSkipIntro() || request.isSkipFindSensor()) { + return; + } + final FingerprintEnrollIntroViewModel introViewModel = mViewModelProvider.get(FingerprintEnrollIntroViewModel.class); @@ -283,16 +315,14 @@ public class FingerprintEnrollmentActivity extends FragmentActivity { tag = FIND_RFPS_TAG; fragmentClass = FingerprintEnrollFindRfpsFragment.class; } - getSupportFragmentManager().beginTransaction() - .setReorderingAllowed(true) - .setCustomAnimations(R.anim.sud_slide_next_in, R.anim.sud_slide_next_out, - R.anim.sud_slide_back_in, R.anim.sud_slide_back_out) - .replace(R.id.fragment_container_view, fragmentClass, null, tag) - .addToBackStack(tag) - .commit(); + startFragment(fragmentClass, tag); } private void attachFindSensorViewModel() { + if (mViewModel.getRequest().isSkipFindSensor()) { + return; + } + final FingerprintEnrollFindSensorViewModel findSensorViewModel = mViewModelProvider.get(FingerprintEnrollFindSensorViewModel.class); @@ -321,14 +351,7 @@ public class FingerprintEnrollmentActivity extends FragmentActivity { tag = ENROLLING_RFPS_TAG; fragmentClass = FingerprintEnrollEnrollingRfpsFragment.class; } - - getSupportFragmentManager().beginTransaction() - .setReorderingAllowed(true) - .setCustomAnimations(R.anim.sud_slide_next_in, R.anim.sud_slide_next_out, - R.anim.sud_slide_back_in, R.anim.sud_slide_back_out) - .replace(R.id.fragment_container_view, fragmentClass, null, tag) - .addToBackStack(tag) - .commit(); + startFragment(fragmentClass, tag); } private void attachEnrollingViewModel() { @@ -342,16 +365,31 @@ public class FingerprintEnrollmentActivity extends FragmentActivity { } private void startFinishFragment() { + mViewModel.setIsNewFingerprintAdded(); attachFinishViewModel(); - getSupportFragmentManager().beginTransaction() - .setReorderingAllowed(true) - .setCustomAnimations(R.anim.sud_slide_next_in, R.anim.sud_slide_next_out, - R.anim.sud_slide_back_in, R.anim.sud_slide_back_out) - .replace(R.id.fragment_container_view, FingerprintEnrollFinishFragment.class, null, - FINISH_TAG) - .addToBackStack(FINISH_TAG) - .commit(); + getSupportFragmentManager().popBackStack(); + if (getSupportFragmentManager().getBackStackEntryCount() == 0) { + // Replace enrolling page + getSupportFragmentManager().beginTransaction() + .setReorderingAllowed(true) + .replace(R.id.fragment_container_view, FingerprintEnrollFinishFragment.class, + null, FINISH_TAG) + .setCustomAnimations(R.anim.sud_slide_next_in, R.anim.sud_slide_next_out, + R.anim.sud_slide_back_in, R.anim.sud_slide_back_out) + .commit(); + } else { + // Remove Enrolling page from backstack, and add Finish page. Latest backstack will + // be changed from Intro->FindSensor->Enrolling to Intro->FindSensor->Finish + getSupportFragmentManager().beginTransaction() + .setReorderingAllowed(true) + .replace(R.id.fragment_container_view, FingerprintEnrollFinishFragment.class, + null, FINISH_TAG) + .setCustomAnimations(R.anim.sud_slide_next_in, R.anim.sud_slide_next_out, + R.anim.sud_slide_back_in, R.anim.sud_slide_back_out) + .addToBackStack(FINISH_TAG) + .commit(); + } } private void attachFinishViewModel() { @@ -366,10 +404,12 @@ public class FingerprintEnrollmentActivity extends FragmentActivity { } private void onSetActivityResult(@NonNull ActivityResult result) { + final Bundle challengeExtras = mAutoCredentialViewModel.createGeneratingChallengeExtras(); final ActivityResult overrideResult = mViewModel.getOverrideActivityResult( - result, mAutoCredentialViewModel.createGeneratingChallengeExtras()); + result, challengeExtras); if (DEBUG) { - Log.d(TAG, "onSetActivityResult(" + result + "), override:" + overrideResult + ")"); + Log.d(TAG, "onSetActivityResult(" + result + "), override:" + overrideResult + + ") challengeExtras:" + challengeExtras); } setResult(overrideResult.getResultCode(), overrideResult.getData()); finish(); @@ -460,11 +500,6 @@ public class FingerprintEnrollmentActivity extends FragmentActivity { private void onEnrollingAction(@FingerprintEnrollEnrollingAction int action) { switch (action) { case FINGERPRINT_ENROLL_ENROLLING_ACTION_DONE: { - mViewModel.setIsNewFingerprintAdded(); - - // Remove Enrolling page from backstack, and add Finish page. Latest backstack will - // be changed from Intro->FindSensor->Enrolling to Intro->FindSensor->Finish - getSupportFragmentManager().popBackStack(); startFinishFragment(); break; } @@ -482,17 +517,10 @@ public class FingerprintEnrollmentActivity extends FragmentActivity { break; } case FINGERPRINT_ENROLL_ENROLLING_CANCELED_BECAUSE_BACK_PRESSED: { - if (mViewModel.isNewFingerprintAdded()) { - // Add another fingerprint case. Remove Enrolling page from - // backstack, and add Finish page. Latest backstack will be changed from - // Intro->FindSensor->Enrolling to Intro->FindSensor->Finish + if (getSupportFragmentManager().getBackStackEntryCount() > 0) { getSupportFragmentManager().popBackStack(); - startFinishFragment(); } else { - // First fingerprint case. Remove Enrolling page from backstack, and add Finish - // page. Latest backstack will be changed from - // Intro->FindSensor->Enrolling to Intro->FindSensor - getSupportFragmentManager().popBackStack(); + onSetActivityResult(new ActivityResult(RESULT_CANCELED, null)); } break; } @@ -513,7 +541,6 @@ public class FingerprintEnrollmentActivity extends FragmentActivity { private void onFinishAction(@FingerprintEnrollFinishAction int action) { switch (action) { case FINGERPRINT_ENROLL_FINISH_ACTION_ADD_BUTTON_CLICK: { - getSupportFragmentManager().popBackStack(); // Remove Finish page from backstack startEnrollingFragment(); break; } diff --git a/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollEnrollingViewModel.java b/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollEnrollingViewModel.java index 6fde44cb054..194bc1e2ed9 100644 --- a/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollEnrollingViewModel.java +++ b/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollEnrollingViewModel.java @@ -19,7 +19,6 @@ package com.android.settings.biometrics2.ui.viewmodel; import android.annotation.IntDef; import android.app.Application; import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; -import android.os.Bundle; import android.os.VibrationAttributes; import android.os.VibrationEffect; import android.util.Log; @@ -324,30 +323,6 @@ public class FingerprintEnrollEnrollingViewModel extends AndroidViewModel { return mFingerprintRepository.canAssumeUdfps(); } - /** - * Saves current state to outState - */ - public void onSaveInstanceState(@NonNull Bundle outState) { - // TODO -// mRestoring = true; -// mIsCanceled = savedInstanceState.getBoolean(KEY_STATE_CANCELED, false); -// mPreviousRotation = savedInstanceState.getInt(KEY_STATE_PREVIOUS_ROTATION, -// getDisplay().getRotation()); -// mIsOrientationChanged = mPreviousRotation != getDisplay().getRotation(); - } - - /** - * Restores saved state from previous savedInstanceState - */ - public void restoreSavedState(@Nullable Bundle savedInstanceState) { - if (savedInstanceState == null) { - return; - } - // TODO -// outState.putBoolean(KEY_STATE_CANCELED, mIsCanceled); -// outState.putInt(KEY_STATE_PREVIOUS_ROTATION, mPreviousRotation); - } - /** * Data for passing to FingerprintEnrollEnrollingErrorDialog */