Refine RFPS enrolling v2

1. Fix skip button doesn't work case
2. Support rotation during enrollment
3. Show error dialog page
4. Show icon touched dialog page

Bug: 260957939
Test: atest FingerprintEnrollFindSensorViewModelTest
      FingerprintEnrollProgressViewModelTest
      FingerprintEnrollmentViewModelTest
      FingerprintEnrollmentActivityTest
Change-Id: I617e3e64a130682002b07551d11aff2864fd4538
This commit is contained in:
Milton Wu
2023-02-08 20:23:14 +08:00
parent 1be63ef9d7
commit fa496047a4
8 changed files with 157 additions and 200 deletions

View File

@@ -18,27 +18,29 @@ package com.android.settings.biometrics2.ui.view;
import android.app.Dialog; import android.app.Dialog;
import android.app.settings.SettingsEnums; import android.app.settings.SettingsEnums;
import android.content.DialogInterface; import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.lifecycle.ViewModelProvider;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment; import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
/** /**
* Icon Touch dialog * Icon Touch dialog
*/ */
public class IconTouchDialog extends InstrumentedDialogFragment { public class FingerprintEnrollEnrollingIconTouchDialog extends InstrumentedDialogFragment {
// private FingerprintEnrollEnrollingViewModel mViewModel; private FingerprintEnrollEnrollingViewModel mViewModel;
//
// @Override @Override
// public void onAttach(Context context) { public void onAttach(Context context) {
// mViewModel = new ViewModelProvider(getActivity()).get( mViewModel = new ViewModelProvider(getActivity()).get(
// FingerprintEnrollEnrollingViewModel.class); FingerprintEnrollEnrollingViewModel.class);
// super.onAttach(context); super.onAttach(context);
// } }
@Override @Override
public Dialog onCreateDialog(Bundle savedInstanceState) { public Dialog onCreateDialog(Bundle savedInstanceState) {
@@ -46,12 +48,11 @@ public class IconTouchDialog extends InstrumentedDialogFragment {
R.style.Theme_AlertDialog); R.style.Theme_AlertDialog);
builder.setTitle(R.string.security_settings_fingerprint_enroll_touch_dialog_title) builder.setTitle(R.string.security_settings_fingerprint_enroll_touch_dialog_title)
.setMessage(R.string.security_settings_fingerprint_enroll_touch_dialog_message) .setMessage(R.string.security_settings_fingerprint_enroll_touch_dialog_message)
.setPositiveButton(R.string.security_settings_fingerprint_enroll_dialog_ok, .setPositiveButton(
new DialogInterface.OnClickListener() { R.string.security_settings_fingerprint_enroll_dialog_ok,
@Override (dialog, which) -> {
public void onClick(DialogInterface dialog, int which) { dialog.dismiss();
dialog.dismiss(); mViewModel.onIconTouchDialogDismiss();
}
}); });
return builder.create(); return builder.create();
} }

View File

@@ -34,6 +34,7 @@ import android.view.LayoutInflater;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils; import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator; import android.view.animation.Interpolator;
import android.widget.ProgressBar; import android.widget.ProgressBar;
@@ -41,12 +42,11 @@ import android.widget.TextView;
import androidx.annotation.IdRes; import androidx.annotation.IdRes;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentActivity;
import androidx.lifecycle.Observer; import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
import androidx.transition.Transition;
import androidx.transition.TransitionSet;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.biometrics.fingerprint.FingerprintErrorDialog; import com.android.settings.biometrics.fingerprint.FingerprintErrorDialog;
@@ -56,7 +56,6 @@ import com.android.settings.biometrics2.ui.viewmodel.DeviceRotationViewModel;
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel; import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel;
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollProgressViewModel; import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollProgressViewModel;
import com.airbnb.lottie.LottieAnimationView;
import com.google.android.setupcompat.template.FooterBarMixin; import com.google.android.setupcompat.template.FooterBarMixin;
import com.google.android.setupcompat.template.FooterButton; import com.google.android.setupcompat.template.FooterButton;
import com.google.android.setupdesign.GlifLayout; import com.google.android.setupdesign.GlifLayout;
@@ -70,6 +69,7 @@ public class FingerprintEnrollEnrollingRfpsFragment extends Fragment {
private static final boolean DEBUG = false; private static final boolean DEBUG = false;
private static final int PROGRESS_BAR_MAX = 10000; private static final int PROGRESS_BAR_MAX = 10000;
private static final long ANIMATION_DURATION = 250L;
private static final long ICON_TOUCH_DURATION_UNTIL_DIALOG_SHOWN = 500; private static final long ICON_TOUCH_DURATION_UNTIL_DIALOG_SHOWN = 500;
private static final int ICON_TOUCH_COUNT_SHOW_UNTIL_DIALOG_SHOWN = 3; private static final int ICON_TOUCH_COUNT_SHOW_UNTIL_DIALOG_SHOWN = 3;
@@ -96,16 +96,6 @@ public class FingerprintEnrollEnrollingRfpsFragment extends Fragment {
private AnimatedVectorDrawable mIconAnimationDrawable; private AnimatedVectorDrawable mIconAnimationDrawable;
private AnimatedVectorDrawable mIconBackgroundBlinksDrawable; private AnimatedVectorDrawable mIconBackgroundBlinksDrawable;
private LottieAnimationView mIllustrationLottie;
private boolean mShouldShowLottie;
private boolean mIsAccessibilityEnabled;
private boolean mHaveShownSfpsNoAnimationLottie;
private boolean mHaveShownSfpsCenterLottie;
private boolean mHaveShownSfpsTipLottie;
private boolean mHaveShownSfpsLeftEdgeLottie;
private boolean mHaveShownSfpsRightEdgeLottie;
private final View.OnClickListener mOnSkipClickListener = v -> { private final View.OnClickListener mOnSkipClickListener = v -> {
mProgressViewModel.cancelEnrollment(); mProgressViewModel.cancelEnrollment();
mEnrollingViewModel.onSkipButtonClick(); mEnrollingViewModel.onSkipButtonClick();
@@ -115,7 +105,7 @@ public class FingerprintEnrollEnrollingRfpsFragment extends Fragment {
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "mProgressObserver(" + progress + ")"); Log.d(TAG, "mProgressObserver(" + progress + ")");
} }
if (progress != null) { if (progress != null && progress.getSteps() >= 0) {
onEnrollmentProgressChange(progress); onEnrollmentProgressChange(progress);
} }
}; };
@@ -128,6 +118,7 @@ public class FingerprintEnrollEnrollingRfpsFragment extends Fragment {
onEnrollmentHelp(helpMessage); onEnrollmentHelp(helpMessage);
} }
}; };
private final Observer<EnrollmentStatusMessage> mErrorMessageObserver = errorMessage -> { private final Observer<EnrollmentStatusMessage> mErrorMessageObserver = errorMessage -> {
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "mErrorMessageObserver(" + errorMessage + ")"); Log.d(TAG, "mErrorMessageObserver(" + errorMessage + ")");
@@ -136,15 +127,6 @@ public class FingerprintEnrollEnrollingRfpsFragment extends Fragment {
onEnrollmentError(errorMessage); onEnrollmentError(errorMessage);
} }
}; };
private final Observer<Boolean> mAcquireObserver = isAcquiredGood -> {
// TODO
};
private final Observer<Integer> mPointerDownObserver = sensorId -> {
// TODO
};
private final Observer<Integer> mPointerUpObserver = sensorId -> {
// TODO
};
private int mIconTouchCount; private int mIconTouchCount;
@@ -156,40 +138,39 @@ public class FingerprintEnrollEnrollingRfpsFragment extends Fragment {
mRotationViewModel = provider.get(DeviceRotationViewModel.class); mRotationViewModel = provider.get(DeviceRotationViewModel.class);
mProgressViewModel = provider.get(FingerprintEnrollProgressViewModel.class); mProgressViewModel = provider.get(FingerprintEnrollProgressViewModel.class);
super.onAttach(context); super.onAttach(context);
final TransitionSet transitionSet = (TransitionSet) getSharedElementEnterTransition(); }
if (transitionSet != null) {
transitionSet.addListener(new Transition.TransitionListener() {
@Override
public void onTransitionStart(@NonNull Transition transition) {
}
@Override @Nullable
public void onTransitionEnd(@NonNull Transition transition) { @Override
transition.removeListener(this); public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
mAnimationCancelled = false; if (enter && nextAnim == R.anim.sud_slide_next_in) {
startIconAnimation(); final Animation animation = AnimationUtils.loadAnimation(getActivity(), nextAnim);
} if (animation != null) {
animation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override @Override
public void onTransitionCancel(@NonNull Transition transition) { public void onAnimationEnd(Animation animation) {
} mAnimationCancelled = false;
startIconAnimation();
}
@Override @Override
public void onTransitionPause(@NonNull Transition transition) { public void onAnimationRepeat(Animation animation) {
} }
});
@Override return animation;
public void onTransitionResume(@NonNull Transition transition) { }
}
});
} }
return super.onCreateAnimation(transit, enter, nextAnim);
} }
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
mEnrollingViewModel.restoreSavedState(savedInstanceState); mEnrollingViewModel.restoreSavedState(savedInstanceState);
mIsAccessibilityEnabled = mEnrollingViewModel.isAccessibilityEnabled();
} }
@Override @Override
@@ -215,12 +196,6 @@ public class FingerprintEnrollEnrollingRfpsFragment extends Fragment {
R.string.security_settings_fingerprint_enroll_start_message)); R.string.security_settings_fingerprint_enroll_start_message));
glifLayoutHelper.setHeaderText(R.string.security_settings_fingerprint_enroll_repeat_title); glifLayoutHelper.setHeaderText(R.string.security_settings_fingerprint_enroll_repeat_title);
// mShouldShowLottie = shouldShowLottie(); // TODO move this call into updateOrientation()?
// boolean isLandscape = BiometricUtils.isReverseLandscape(activity)
// || BiometricUtils.isLandscape(activity);
// updateOrientation(containView, (isLandscape
// ? Configuration.ORIENTATION_LANDSCAPE : Configuration.ORIENTATION_PORTRAIT));
mErrorText = containView.findViewById(R.id.error_text); mErrorText = containView.findViewById(R.id.error_text);
mProgressBar = containView.findViewById(R.id.fingerprint_progress_bar); mProgressBar = containView.findViewById(R.id.fingerprint_progress_bar);
mFooterBarMixin = containView.getMixin(FooterBarMixin.class); mFooterBarMixin = containView.getMixin(FooterBarMixin.class);
@@ -273,9 +248,6 @@ public class FingerprintEnrollEnrollingRfpsFragment extends Fragment {
startEnrollment(); startEnrollment();
updateProgress(false /* animate */, mProgressViewModel.getProgressLiveData().getValue()); updateProgress(false /* animate */, mProgressViewModel.getProgressLiveData().getValue());
updateTitleAndDescription(); updateTitleAndDescription();
if (true /* TODO check mRestoring */) {
startIconAnimation();
}
} }
private void startIconAnimation() { private void startIconAnimation() {
@@ -292,6 +264,7 @@ public class FingerprintEnrollEnrollingRfpsFragment extends Fragment {
} }
private void onCancelEnrollment(@IdRes int errorMsgId) { private void onCancelEnrollment(@IdRes int errorMsgId) {
// TODO
// showErrorDialog() will cause onWindowFocusChanged(false), set mIsCanceled to false // showErrorDialog() will cause onWindowFocusChanged(false), set mIsCanceled to false
// before showErrorDialog() to prevent that another error dialog is triggered again. // before showErrorDialog() to prevent that another error dialog is triggered again.
// TODO mIsCanceled = true; // TODO mIsCanceled = true;
@@ -319,9 +292,6 @@ public class FingerprintEnrollEnrollingRfpsFragment extends Fragment {
mProgressViewModel.getProgressLiveData().removeObserver(mProgressObserver); mProgressViewModel.getProgressLiveData().removeObserver(mProgressObserver);
mProgressViewModel.getHelpMessageLiveData().removeObserver(mHelpMessageObserver); mProgressViewModel.getHelpMessageLiveData().removeObserver(mHelpMessageObserver);
mProgressViewModel.getErrorMessageLiveData().removeObserver(mErrorMessageObserver); mProgressViewModel.getErrorMessageLiveData().removeObserver(mErrorMessageObserver);
mProgressViewModel.getAcquireLiveData().removeObserver(mAcquireObserver);
mProgressViewModel.getPointerDownLiveData().removeObserver(mPointerDownObserver);
mProgressViewModel.getPointerUpLiveData().removeObserver(mPointerUpObserver);
} }
private void cancelEnrollment() { private void cancelEnrollment() {
@@ -330,13 +300,13 @@ public class FingerprintEnrollEnrollingRfpsFragment extends Fragment {
} }
private void startEnrollment() { private void startEnrollment() {
final boolean startResult = mProgressViewModel.startEnrollment(ENROLL_ENROLL);
if (!startResult) {
Log.e(TAG, "startEnrollment(), failed");
}
mProgressViewModel.getProgressLiveData().observe(this, mProgressObserver); mProgressViewModel.getProgressLiveData().observe(this, mProgressObserver);
mProgressViewModel.getHelpMessageLiveData().observe(this, mHelpMessageObserver); mProgressViewModel.getHelpMessageLiveData().observe(this, mHelpMessageObserver);
mProgressViewModel.getErrorMessageLiveData().observe(this, mErrorMessageObserver); 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 onEnrollmentHelp(@NonNull EnrollmentStatusMessage helpMessage) { private void onEnrollmentHelp(@NonNull EnrollmentStatusMessage helpMessage) {
@@ -443,7 +413,7 @@ public class FingerprintEnrollEnrollingRfpsFragment extends Fragment {
mProgressBar.getProgress(), progress); mProgressBar.getProgress(), progress);
anim.addListener(mProgressAnimationListener); anim.addListener(mProgressAnimationListener);
anim.setInterpolator(mFastOutSlowInInterpolator); anim.setInterpolator(mFastOutSlowInInterpolator);
anim.setDuration(250); anim.setDuration(ANIMATION_DURATION);
anim.start(); anim.start();
mProgressAnim = anim; mProgressAnim = anim;
} }
@@ -457,24 +427,6 @@ public class FingerprintEnrollEnrollingRfpsFragment extends Fragment {
} }
}; };
// private void updateOrientation(@NonNull GlifLayout glifLayout, int orientation) {
// switch (orientation) {
// case Configuration.ORIENTATION_LANDSCAPE: {
// mIllustrationLottie = null;
// break;
// }
// case Configuration.ORIENTATION_PORTRAIT: {
// if (shouldShowLottie()) {
// mIllustrationLottie = glifLayout.findViewById(R.id.illustration_lottie);
// }
// break;
// }
// default:
// Log.e(TAG, "Error unhandled configuration change");
// break;
// }
// }
private void animateFlash() { private void animateFlash() {
if (mIconBackgroundBlinksDrawable != null) { if (mIconBackgroundBlinksDrawable != null) {
mIconBackgroundBlinksDrawable.start(); mIconBackgroundBlinksDrawable.start();
@@ -512,9 +464,8 @@ public class FingerprintEnrollEnrollingRfpsFragment extends Fragment {
@Override @Override
public void onAnimationEnd(Animator animation) { public void onAnimationEnd(Animator animation) {
stopIconAnimation(); stopIconAnimation();
if (mProgressBar.getProgress() >= PROGRESS_BAR_MAX) { if (mProgressBar.getProgress() >= PROGRESS_BAR_MAX) {
mProgressBar.postDelayed(mDelayedFinishRunnable, 250L); mProgressBar.postDelayed(mDelayedFinishRunnable, ANIMATION_DURATION);
} }
} }
@@ -523,13 +474,7 @@ public class FingerprintEnrollEnrollingRfpsFragment extends Fragment {
}; };
// Give the user a chance to see progress completed before jumping to the next stage. // Give the user a chance to see progress completed before jumping to the next stage.
private final Runnable mDelayedFinishRunnable = new Runnable() { private final Runnable mDelayedFinishRunnable = () -> mEnrollingViewModel.onEnrollingDone();
@Override
public void run() {
mEnrollingViewModel.onSkipButtonClick();
/* TODO launchFinish(); */
}
};
private final Animatable2.AnimationCallback mIconAnimationCallback = private final Animatable2.AnimationCallback mIconAnimationCallback =
new Animatable2.AnimationCallback() { new Animatable2.AnimationCallback() {
@@ -540,12 +485,7 @@ public class FingerprintEnrollEnrollingRfpsFragment extends Fragment {
} }
// Start animation after it has ended. // Start animation after it has ended.
mProgressBar.post(new Runnable() { mProgressBar.post(() -> startIconAnimation());
@Override
public void run() {
startIconAnimation();
}
});
} }
}; };
} }

View File

@@ -172,7 +172,7 @@ public class FingerprintEnrollFindRfpsFragment extends Fragment {
Log.d(TAG, "onStop(), current enrolling: " + isEnrolling + ", animation exist:" Log.d(TAG, "onStop(), current enrolling: " + isEnrolling + ", animation exist:"
+ (mAnimation != null)); + (mAnimation != null));
} }
if (!isEnrolling) { if (isEnrolling) {
stopLookingForFingerprint(false); stopLookingForFingerprint(false);
} }
} }
@@ -184,12 +184,11 @@ public class FingerprintEnrollFindRfpsFragment extends Fragment {
return; return;
} }
mProgressViewModel.clearProgressLiveData();
mProgressViewModel.getProgressLiveData().observe(this, mProgressObserver);
final boolean startResult = mProgressViewModel.startEnrollment(ENROLL_FIND_SENSOR); final boolean startResult = mProgressViewModel.startEnrollment(ENROLL_FIND_SENSOR);
if (!startResult) { if (!startResult) {
Log.e(TAG, "startLookingForFingerprint(), failed to start enrollment"); Log.e(TAG, "startLookingForFingerprint(), failed to start enrollment");
} }
mProgressViewModel.getProgressLiveData().observe(this, mProgressObserver);
} }
private void stopLookingForFingerprint(boolean waitForLastCancelErrMsg) { private void stopLookingForFingerprint(boolean waitForLastCancelErrMsg) {

View File

@@ -98,7 +98,6 @@ public class FingerprintEnrollFindSfpsFragment extends Fragment {
Log.d(TAG, "mProgressObserver(" + progress + ")"); Log.d(TAG, "mProgressObserver(" + progress + ")");
} }
if (progress != null && !progress.isInitialStep()) { if (progress != null && !progress.isInitialStep()) {
mProgressViewModel.clearProgressLiveData();
mViewModel.onStartButtonClick(); mViewModel.onStartButtonClick();
} }
}; };

View File

@@ -27,6 +27,14 @@ import static com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewMo
import static com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.CREDENTIAL_IS_GENERATING_CHALLENGE; import static com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.CREDENTIAL_IS_GENERATING_CHALLENGE;
import static com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.CREDENTIAL_VALID; import static com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.CREDENTIAL_VALID;
import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.ErrorDialogData; import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.ErrorDialogData;
import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ENROLL_ENROLLING_ACTION_DISMISS_ICON_TOUCH_DIALOG;
import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ENROLL_ENROLLING_ACTION_DONE;
import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ENROLL_ENROLLING_ACTION_SHOW_ICON_TOUCH_DIALOG;
import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ENROLL_ENROLLING_ACTION_SKIP;
import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_FINISH;
import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_TIMEOUT;
import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FingerprintEnrollEnrollingAction;
import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FingerprintErrorDialogAction;
import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollFindSensorViewModel.FINGERPRINT_ENROLL_FIND_SENSOR_ACTION_DIALOG; import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollFindSensorViewModel.FINGERPRINT_ENROLL_FIND_SENSOR_ACTION_DIALOG;
import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollFindSensorViewModel.FINGERPRINT_ENROLL_FIND_SENSOR_ACTION_SKIP; import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollFindSensorViewModel.FINGERPRINT_ENROLL_FIND_SENSOR_ACTION_SKIP;
import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollFindSensorViewModel.FINGERPRINT_ENROLL_FIND_SENSOR_ACTION_START; import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollFindSensorViewModel.FINGERPRINT_ENROLL_FIND_SENSOR_ACTION_START;
@@ -122,12 +130,12 @@ public class FingerprintEnrollmentActivity extends FragmentActivity {
onFindSensorAction(action); onFindSensorAction(action);
} }
}; };
private final Observer<Boolean> mEnrollingDoneObserver = isDone -> { private final Observer<Integer> mEnrollingActionObserver = action -> {
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "mEnrollingDoneObserver(" + isDone + ")"); Log.d(TAG, "mEnrollingActionObserver(" + action + ")");
} }
if (isDone != null) { if (action != null) {
onEnrollingDone(isDone); onEnrollingAction(action);
} }
}; };
private final Observer<ErrorDialogData> mEnrollingErrorDialogObserver = data -> { private final Observer<ErrorDialogData> mEnrollingErrorDialogObserver = data -> {
@@ -135,7 +143,16 @@ public class FingerprintEnrollmentActivity extends FragmentActivity {
Log.d(TAG, "mEnrollingErrorDialogObserver(" + data + ")"); Log.d(TAG, "mEnrollingErrorDialogObserver(" + data + ")");
} }
if (data != null) { if (data != null) {
startEnrollingErrorDialog(); new FingerprintEnrollEnrollingErrorDialog().show(getSupportFragmentManager(),
ENROLLING_ERROR_DIALOG_TAG);
}
};
private final Observer<Integer> mEnrollingErrorDialogActionObserver = action -> {
if (DEBUG) {
Log.d(TAG, "mEnrollingErrorDialogActionObserver(" + action + ")");
}
if (action != null) {
onEnrollingErrorDialogAction(action);
} }
}; };
private final ActivityResultCallback<ActivityResult> mNextActivityResultCallback = private final ActivityResultCallback<ActivityResult> mNextActivityResultCallback =
@@ -292,6 +309,7 @@ public class FingerprintEnrollmentActivity extends FragmentActivity {
tag = ENROLLING_RFPS_TAG; tag = ENROLLING_RFPS_TAG;
fragmentClass = FingerprintEnrollEnrollingRfpsFragment.class; fragmentClass = FingerprintEnrollEnrollingRfpsFragment.class;
} }
getSupportFragmentManager().beginTransaction() getSupportFragmentManager().beginTransaction()
.setReorderingAllowed(true) .setReorderingAllowed(true)
.setCustomAnimations(R.anim.sud_slide_next_in, R.anim.sud_slide_next_out, .setCustomAnimations(R.anim.sud_slide_next_in, R.anim.sud_slide_next_out,
@@ -304,15 +322,18 @@ public class FingerprintEnrollmentActivity extends FragmentActivity {
private void attachEnrollingViewModel() { private void attachEnrollingViewModel() {
final FingerprintEnrollEnrollingViewModel enrollingViewModel = final FingerprintEnrollEnrollingViewModel enrollingViewModel =
mViewModelProvider.get(FingerprintEnrollEnrollingViewModel.class); mViewModelProvider.get(FingerprintEnrollEnrollingViewModel.class);
enrollingViewModel.clearBackPressedData(); enrollingViewModel.clearActionLiveData();
enrollingViewModel.getActionLiveData().observe(this, mEnrollingActionObserver);
enrollingViewModel.getErrorDialogLiveData().observe(this, mEnrollingErrorDialogObserver); enrollingViewModel.getErrorDialogLiveData().observe(this, mEnrollingErrorDialogObserver);
enrollingViewModel.getErrorDialogActionLiveData().observe(this,
final FingerprintEnrollProgressViewModel progressViewModel = mEnrollingErrorDialogActionObserver);
mViewModelProvider.get(FingerprintEnrollProgressViewModel.class);
progressViewModel.getDoneLiveData().observe(this, mEnrollingDoneObserver);
} }
private void startFinishActivity() { private void startFinishActivity() {
final FingerprintEnrollEnrollingViewModel enrollingViewModel =
mViewModelProvider.get(FingerprintEnrollEnrollingViewModel.class);
enrollingViewModel.clearActionLiveData();
final boolean isSuw = mViewModel.getRequest().isSuw(); final boolean isSuw = mViewModel.getRequest().isSuw();
if (!mViewModel.isWaitingActivityResult().compareAndSet(false, true)) { if (!mViewModel.isWaitingActivityResult().compareAndSet(false, true)) {
Log.w(TAG, "startNext, isSuw:" + isSuw + ", fail to set isWaiting flag"); Log.w(TAG, "startNext, isSuw:" + isSuw + ", fail to set isWaiting flag");
@@ -325,16 +346,6 @@ public class FingerprintEnrollmentActivity extends FragmentActivity {
mNextActivityLauncher.launch(intent); mNextActivityLauncher.launch(intent);
} }
private void startSkipSetupFindFpsDialog() {
new SkipSetupFindFpsDialog().show(getSupportFragmentManager(),
SKIP_SETUP_FIND_FPS_DIALOG_TAG);
}
private void startEnrollingErrorDialog() {
new FingerprintEnrollEnrollingErrorDialog().show(getSupportFragmentManager(),
ENROLLING_ERROR_DIALOG_TAG);
}
private void onGenerateChallengeFailed(@NonNull Boolean ignoredBoolean) { private void onGenerateChallengeFailed(@NonNull Boolean ignoredBoolean) {
onSetActivityResult(new ActivityResult(RESULT_CANCELED, null)); onSetActivityResult(new ActivityResult(RESULT_CANCELED, null));
} }
@@ -366,6 +377,10 @@ public class FingerprintEnrollmentActivity extends FragmentActivity {
final Intent intent = resultCode == BiometricEnrollBase.RESULT_FINISHED final Intent intent = resultCode == BiometricEnrollBase.RESULT_FINISHED
? createSetResultIntentWithGeneratingChallengeExtra(result.getData()) ? createSetResultIntentWithGeneratingChallengeExtra(result.getData())
: result.getData(); : result.getData();
if (DEBUG) {
Log.d(TAG, "onSetActivityResult(" + result + "), call setResult(" + resultCode
+ ", " + intent + ")");
}
setResult(resultCode, intent); setResult(resultCode, intent);
finish(); finish();
} }
@@ -443,7 +458,8 @@ public class FingerprintEnrollmentActivity extends FragmentActivity {
return; return;
} }
case FINGERPRINT_ENROLL_FIND_SENSOR_ACTION_DIALOG: { case FINGERPRINT_ENROLL_FIND_SENSOR_ACTION_DIALOG: {
startSkipSetupFindFpsDialog(); new SkipSetupFindFpsDialog().show(getSupportFragmentManager(),
SKIP_SETUP_FIND_FPS_DIALOG_TAG);
return; return;
} }
case FINGERPRINT_ENROLL_FIND_SENSOR_ACTION_START: { case FINGERPRINT_ENROLL_FIND_SENSOR_ACTION_START: {
@@ -452,15 +468,37 @@ public class FingerprintEnrollmentActivity extends FragmentActivity {
} }
} }
private void onEnrollingDone(boolean isDone) { private void onEnrollingAction(@FingerprintEnrollEnrollingAction int action) {
if (!isDone) { switch (action) {
return; case FINGERPRINT_ENROLL_ENROLLING_ACTION_DONE: {
startFinishActivity();
break;
}
case FINGERPRINT_ENROLL_ENROLLING_ACTION_SKIP: {
onSetActivityResult(new ActivityResult(BiometricEnrollBase.RESULT_SKIP, null));
break;
}
case FINGERPRINT_ENROLL_ENROLLING_ACTION_SHOW_ICON_TOUCH_DIALOG: {
new FingerprintEnrollEnrollingIconTouchDialog().show(getSupportFragmentManager(),
SKIP_SETUP_FIND_FPS_DIALOG_TAG);
break;
}
case FINGERPRINT_ENROLL_ENROLLING_ACTION_DISMISS_ICON_TOUCH_DIALOG: {
onSetActivityResult(new ActivityResult(BiometricEnrollBase.RESULT_TIMEOUT, null));
break;
}
} }
final FingerprintEnrollProgressViewModel progressViewModel = }
mViewModelProvider.get(FingerprintEnrollProgressViewModel.class);
progressViewModel.clearProgressLiveData();
startFinishActivity(); private void onEnrollingErrorDialogAction(@FingerprintErrorDialogAction int action) {
switch (action) {
case FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_FINISH:
onSetActivityResult(new ActivityResult(BiometricEnrollBase.RESULT_FINISHED, null));
break;
case FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_TIMEOUT:
onSetActivityResult(new ActivityResult(BiometricEnrollBase.RESULT_TIMEOUT, null));
break;
}
} }
@Override @Override
@@ -469,21 +507,6 @@ public class FingerprintEnrollmentActivity extends FragmentActivity {
mViewModel.checkFinishActivityDuringOnPause(isFinishing(), isChangingConfigurations()); mViewModel.checkFinishActivityDuringOnPause(isFinishing(), isChangingConfigurations());
} }
@Override
public void onBackPressed() {
final FragmentManager manager = getSupportFragmentManager();
final String[] tags = new String[] {ENROLLING_UDFPS_TAG, ENROLLING_SFPS_TAG,
ENROLLING_RFPS_TAG };
for (String tag: tags) {
final Fragment fragment = manager.findFragmentByTag(tag);
if (fragment != null) {
mViewModelProvider.get(FingerprintEnrollEnrollingViewModel.class).onBackPressed();
break;
}
}
super.onBackPressed();
}
@Override @Override
protected void onApplyThemeResource(Resources.Theme theme, @StyleRes int resid, boolean first) { protected void onApplyThemeResource(Resources.Theme theme, @StyleRes int resid, boolean first) {
theme.applyStyle(R.style.SetupWizardPartnerResource, true); theme.applyStyle(R.style.SetupWizardPartnerResource, true);

View File

@@ -64,18 +64,18 @@ public class FingerprintEnrollEnrollingViewModel extends AndroidViewModel {
/** /**
* Icon touch dialog show * Icon touch dialog show
*/ */
public static final int FINGERPRINT_ENROLL_ENROLLING_ACTION_SHOW_DIALOG = 2; public static final int FINGERPRINT_ENROLL_ENROLLING_ACTION_SHOW_ICON_TOUCH_DIALOG = 2;
/** /**
* Icon touch dialog dismiss * Icon touch dialog dismiss
*/ */
public static final int FINGERPRINT_ENROLL_ENROLLING_ACTION_DISMISS_DIALOG = 3; public static final int FINGERPRINT_ENROLL_ENROLLING_ACTION_DISMISS_ICON_TOUCH_DIALOG = 3;
@IntDef(prefix = { "FINGERPRINT_ENROLL_ENROLLING_ACTION_" }, value = { @IntDef(prefix = { "FINGERPRINT_ENROLL_ENROLLING_ACTION_" }, value = {
FINGERPRINT_ENROLL_ENROLLING_ACTION_SKIP, FINGERPRINT_ENROLL_ENROLLING_ACTION_SKIP,
FINGERPRINT_ENROLL_ENROLLING_ACTION_DONE, FINGERPRINT_ENROLL_ENROLLING_ACTION_DONE,
FINGERPRINT_ENROLL_ENROLLING_ACTION_SHOW_DIALOG, FINGERPRINT_ENROLL_ENROLLING_ACTION_SHOW_ICON_TOUCH_DIALOG,
FINGERPRINT_ENROLL_ENROLLING_ACTION_DISMISS_DIALOG FINGERPRINT_ENROLL_ENROLLING_ACTION_DISMISS_ICON_TOUCH_DIALOG
}) })
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
public @interface FingerprintEnrollEnrollingAction {} public @interface FingerprintEnrollEnrollingAction {}
@@ -109,8 +109,7 @@ public class FingerprintEnrollEnrollingViewModel extends AndroidViewModel {
private final AccessibilityRepository mAccessibilityRepository; private final AccessibilityRepository mAccessibilityRepository;
private final VibratorRepository mVibratorRepository; private final VibratorRepository mVibratorRepository;
private final MutableLiveData<Boolean> mBackPressedLiveData = new MutableLiveData<>(false); private final MutableLiveData<Integer> mActionLiveData = new MutableLiveData<>();
private final MutableLiveData<Integer> mEnrollingLiveData = new MutableLiveData<>();
private final MutableLiveData<Integer> mIconTouchDialogLiveData = new MutableLiveData<>(); private final MutableLiveData<Integer> mIconTouchDialogLiveData = new MutableLiveData<>();
private final MutableLiveData<ErrorDialogData> mErrorDialogLiveData = new MutableLiveData<>(); private final MutableLiveData<ErrorDialogData> mErrorDialogLiveData = new MutableLiveData<>();
private final MutableLiveData<Integer> mErrorDialogActionLiveData = new MutableLiveData<>(); private final MutableLiveData<Integer> mErrorDialogActionLiveData = new MutableLiveData<>();
@@ -138,6 +137,21 @@ public class FingerprintEnrollEnrollingViewModel extends AndroidViewModel {
return mErrorDialogLiveData; return mErrorDialogLiveData;
} }
public LiveData<Integer> getErrorDialogActionLiveData() {
return mErrorDialogActionLiveData;
}
public LiveData<Integer> getActionLiveData() {
return mActionLiveData;
}
/**
* Clears action live data
*/
public void clearActionLiveData() {
mActionLiveData.setValue(null);
}
/** /**
* Saves new user dialog action to mErrorDialogActionLiveData * Saves new user dialog action to mErrorDialogActionLiveData
*/ */
@@ -148,20 +162,6 @@ public class FingerprintEnrollEnrollingViewModel extends AndroidViewModel {
mErrorDialogActionLiveData.postValue(action); mErrorDialogActionLiveData.postValue(action);
} }
/**
* Clears back press data
*/
public void clearBackPressedData() {
mBackPressedLiveData.setValue(false);
}
/**
* User trigger back pressed
*/
public void onBackPressed() {
mBackPressedLiveData.postValue(true);
}
/** /**
* User clicks skip button * User clicks skip button
*/ */
@@ -170,25 +170,25 @@ public class FingerprintEnrollEnrollingViewModel extends AndroidViewModel {
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "onSkipButtonClick, post action " + action); Log.d(TAG, "onSkipButtonClick, post action " + action);
} }
mEnrollingLiveData.postValue(action); mActionLiveData.postValue(action);
} }
/** /**
* Is enrolling finished * Is enrolling finished
*/ */
public void onEnrollingDone() { public void onEnrollingDone() {
final int action = FINGERPRINT_ENROLL_ENROLLING_ACTION_SKIP; final int action = FINGERPRINT_ENROLL_ENROLLING_ACTION_DONE;
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "onEnrollingDone, post action " + action); Log.d(TAG, "onEnrollingDone, post action " + action);
} }
mEnrollingLiveData.postValue(action); mActionLiveData.postValue(action);
} }
/** /**
* Icon touch dialog show * Icon touch dialog show
*/ */
public void onIconTouchDialogShow() { public void onIconTouchDialogShow() {
final int action = FINGERPRINT_ENROLL_ENROLLING_ACTION_SHOW_DIALOG; final int action = FINGERPRINT_ENROLL_ENROLLING_ACTION_SHOW_ICON_TOUCH_DIALOG;
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "onIconTouchDialogShow, post action " + action); Log.d(TAG, "onIconTouchDialogShow, post action " + action);
} }
@@ -199,7 +199,7 @@ public class FingerprintEnrollEnrollingViewModel extends AndroidViewModel {
* Icon touch dialog dismiss * Icon touch dialog dismiss
*/ */
public void onIconTouchDialogDismiss() { public void onIconTouchDialogDismiss() {
final int action = FINGERPRINT_ENROLL_ENROLLING_ACTION_DISMISS_DIALOG; final int action = FINGERPRINT_ENROLL_ENROLLING_ACTION_DISMISS_ICON_TOUCH_DIALOG;
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "onIconTouchDialogDismiss, post action " + action); Log.d(TAG, "onIconTouchDialogDismiss, post action " + action);
} }
@@ -313,7 +313,8 @@ public class FingerprintEnrollEnrollingViewModel extends AndroidViewModel {
@Override @Override
public String toString() { public String toString() {
return ErrorDialogData.class.getSimpleName() + "{id:" + mErrMsgId + "}"; return getClass().getSimpleName() + "@" + Integer.toHexString(hashCode())
+ "{id:" + mErrMsgId + "}";
} }
} }
} }

View File

@@ -190,6 +190,12 @@ public class FingerprintEnrollProgressViewModel extends AndroidViewModel {
Log.e(TAG, "startEnrollment(" + reason + ")"); Log.e(TAG, "startEnrollment(" + reason + ")");
} }
// Clear data
mProgressLiveData.setValue(new EnrollmentProgress(INITIAL_STEPS, INITIAL_REMAINING));
mDoneLiveData.setValue(false);
mHelpMessageLiveData.setValue(null);
mErrorMessageLiveData.setValue(null);
mCancellationSignal = new CancellationSignal(); mCancellationSignal = new CancellationSignal();
mFingerprintUpdater.enroll(mToken, mCancellationSignal, mUserId, mFingerprintUpdater.enroll(mToken, mCancellationSignal, mUserId,
mMessageDisplayController != null ? mMessageDisplayController : mEnrollmentCallback, mMessageDisplayController != null ? mMessageDisplayController : mEnrollmentCallback,

View File

@@ -21,8 +21,6 @@ import static android.hardware.fingerprint.FingerprintManager.ENROLL_FIND_SENSOR
import static android.hardware.fingerprint.FingerprintManager.EnrollReason; import static android.hardware.fingerprint.FingerprintManager.EnrollReason;
import static android.hardware.fingerprint.FingerprintManager.EnrollmentCallback; import static android.hardware.fingerprint.FingerprintManager.EnrollmentCallback;
import static com.android.settings.biometrics2.ui.model.EnrollmentProgress.INITIAL_STEPS;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyInt;
@@ -147,24 +145,14 @@ public class FingerprintEnrollProgressViewModelTest {
EnrollmentProgress progress = mViewModel.getProgressLiveData().getValue(); EnrollmentProgress progress = mViewModel.getProgressLiveData().getValue();
assertThat(progress).isNotNull(); assertThat(progress).isNotNull();
assertThat(progress.getSteps()).isEqualTo(25); assertThat(progress.getSteps()).isEqualTo(25);
// TODO(b/260957933) verify getRemaining() when it is really used assertThat(progress.getRemaining()).isEqualTo(25);
//assertThat(progress.getRemaining()).isEqualTo(25);
// Update second progress // Update second progress
callbackWrapper.mValue.onEnrollmentProgress(20); callbackWrapper.mValue.onEnrollmentProgress(20);
progress = mViewModel.getProgressLiveData().getValue(); progress = mViewModel.getProgressLiveData().getValue();
assertThat(progress).isNotNull(); assertThat(progress).isNotNull();
assertThat(progress.getSteps()).isEqualTo(25); assertThat(progress.getSteps()).isEqualTo(25);
// TODO(b/260957933) verify getRemaining() when it is really used assertThat(progress.getRemaining()).isEqualTo(20);
//assertThat(progress.getRemaining()).isEqualTo(20);
// Clear progress
mViewModel.clearProgressLiveData();
progress = mViewModel.getProgressLiveData().getValue();
assertThat(progress).isNotNull();
assertThat(progress.getSteps()).isEqualTo(INITIAL_STEPS);
// TODO(b/260957933) verify getRemaining() when it is really used
//assertThat(progress.getRemaining()).isEqualTo(INITIAL_REMAINING);
} }
// TODO(b/260957933): FingerprintEnrollProgressViewModel::getErrorLiveData() and // TODO(b/260957933): FingerprintEnrollProgressViewModel::getErrorLiveData() and