Biometrics v2 RFPS enrolling refine

1. Fix back key in enrolling page
2. Fix 0.5 sec black screen if user presses skip

Bug: 260957939
Test: atest FingerprintEnrollmentActivity
Change-Id: If5308246ed380c2e3dd12f19f13aa38fc8c178a8
This commit is contained in:
Milton Wu
2023-02-14 11:08:13 +08:00
parent 56f1eb0fbf
commit f7845d823b
5 changed files with 98 additions and 42 deletions

View File

@@ -27,6 +27,7 @@ import android.graphics.drawable.Animatable2;
import android.graphics.drawable.AnimatedVectorDrawable; import android.graphics.drawable.AnimatedVectorDrawable;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable; import android.graphics.drawable.LayerDrawable;
import android.hardware.fingerprint.FingerprintManager;
import android.os.Bundle; import android.os.Bundle;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
@@ -40,7 +41,7 @@ import android.view.animation.Interpolator;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.IdRes; import androidx.activity.OnBackPressedCallback;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
@@ -52,7 +53,6 @@ import com.android.settings.R;
import com.android.settings.biometrics.fingerprint.FingerprintErrorDialog; import com.android.settings.biometrics.fingerprint.FingerprintErrorDialog;
import com.android.settings.biometrics2.ui.model.EnrollmentProgress; import com.android.settings.biometrics2.ui.model.EnrollmentProgress;
import com.android.settings.biometrics2.ui.model.EnrollmentStatusMessage; import com.android.settings.biometrics2.ui.model.EnrollmentStatusMessage;
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;
@@ -80,7 +80,6 @@ public class FingerprintEnrollEnrollingRfpsFragment extends Fragment {
private static final int HINT_TIMEOUT_DURATION = 2500; private static final int HINT_TIMEOUT_DURATION = 2500;
private FingerprintEnrollEnrollingViewModel mEnrollingViewModel; private FingerprintEnrollEnrollingViewModel mEnrollingViewModel;
private DeviceRotationViewModel mRotationViewModel;
private FingerprintEnrollProgressViewModel mProgressViewModel; private FingerprintEnrollProgressViewModel mProgressViewModel;
private Interpolator mFastOutSlowInInterpolator; private Interpolator mFastOutSlowInInterpolator;
@@ -92,13 +91,13 @@ public class FingerprintEnrollEnrollingRfpsFragment extends Fragment {
private ProgressBar mProgressBar; private ProgressBar mProgressBar;
private ObjectAnimator mProgressAnim; private ObjectAnimator mProgressAnim;
private TextView mErrorText; private TextView mErrorText;
private FooterBarMixin mFooterBarMixin;
private AnimatedVectorDrawable mIconAnimationDrawable; private AnimatedVectorDrawable mIconAnimationDrawable;
private AnimatedVectorDrawable mIconBackgroundBlinksDrawable; private AnimatedVectorDrawable mIconBackgroundBlinksDrawable;
private int mIconTouchCount;
private final View.OnClickListener mOnSkipClickListener = v -> { private final View.OnClickListener mOnSkipClickListener = v -> {
mProgressViewModel.cancelEnrollment(); mEnrollingViewModel.setOnSkipPressed();
mEnrollingViewModel.onSkipButtonClick(); cancelEnrollment();
}; };
private final Observer<EnrollmentProgress> mProgressObserver = progress -> { private final Observer<EnrollmentProgress> mProgressObserver = progress -> {
@@ -128,16 +127,21 @@ public class FingerprintEnrollEnrollingRfpsFragment extends Fragment {
} }
}; };
private int mIconTouchCount;
@Override @Override
public void onAttach(@NonNull Context context) { public void onAttach(@NonNull Context context) {
final FragmentActivity activity = getActivity(); final FragmentActivity activity = getActivity();
final ViewModelProvider provider = new ViewModelProvider(activity); final ViewModelProvider provider = new ViewModelProvider(activity);
mEnrollingViewModel = provider.get(FingerprintEnrollEnrollingViewModel.class); mEnrollingViewModel = provider.get(FingerprintEnrollEnrollingViewModel.class);
mRotationViewModel = provider.get(DeviceRotationViewModel.class);
mProgressViewModel = provider.get(FingerprintEnrollProgressViewModel.class); mProgressViewModel = provider.get(FingerprintEnrollProgressViewModel.class);
super.onAttach(context); super.onAttach(context);
requireActivity().getOnBackPressedDispatcher().addCallback(new OnBackPressedCallback(true) {
@Override
public void handleOnBackPressed() {
setEnabled(false);
mEnrollingViewModel.setOnBackPressed();
cancelEnrollment();
}
});
} }
@Nullable @Nullable
@@ -198,8 +202,7 @@ public class FingerprintEnrollEnrollingRfpsFragment extends Fragment {
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); containView.getMixin(FooterBarMixin.class).setSecondaryButton(
mFooterBarMixin.setSecondaryButton(
new FooterButton.Builder(activity) new FooterButton.Builder(activity)
.setText(R.string.security_settings_fingerprint_enroll_enrolling_skip) .setText(R.string.security_settings_fingerprint_enroll_enrolling_skip)
.setListener(mOnSkipClickListener) .setListener(mOnSkipClickListener)
@@ -263,39 +266,28 @@ public class FingerprintEnrollEnrollingRfpsFragment extends Fragment {
} }
} }
private void onCancelEnrollment(@IdRes int errorMsgId) {
// TODO
// showErrorDialog() will cause onWindowFocusChanged(false), set mIsCanceled to false
// before showErrorDialog() to prevent that another error dialog is triggered again.
// TODO mIsCanceled = true;
// TODO mIsOrientationChanged = false;
mEnrollingViewModel.showErrorDialog(new FingerprintEnrollEnrollingViewModel.ErrorDialogData(
mView.getContext().getString(FingerprintErrorDialog.getErrorMessage(errorMsgId)),
mView.getContext().getString(FingerprintErrorDialog.getErrorTitle(errorMsgId)),
errorMsgId
));
cancelEnrollment();
stopIconAnimation();
}
@Override @Override
public void onStop() { public void onStop() {
stopIconAnimation(); stopIconAnimation();
removeEnrollmentObserver(); removeEnrollmentObservers();
if (!getActivity().isChangingConfigurations()) { if (!getActivity().isChangingConfigurations() && mProgressViewModel.isEnrolling()) {
mProgressViewModel.cancelEnrollment(); mProgressViewModel.cancelEnrollment();
} }
super.onStop(); super.onStop();
} }
private void removeEnrollmentObserver() { private void removeEnrollmentObservers() {
mProgressViewModel.getProgressLiveData().removeObserver(mProgressObserver); preRemoveEnrollmentObservers();
mProgressViewModel.getHelpMessageLiveData().removeObserver(mHelpMessageObserver);
mProgressViewModel.getErrorMessageLiveData().removeObserver(mErrorMessageObserver); mProgressViewModel.getErrorMessageLiveData().removeObserver(mErrorMessageObserver);
} }
private void preRemoveEnrollmentObservers() {
mProgressViewModel.getProgressLiveData().removeObserver(mProgressObserver);
mProgressViewModel.getHelpMessageLiveData().removeObserver(mHelpMessageObserver);
}
private void cancelEnrollment() { private void cancelEnrollment() {
removeEnrollmentObserver(); preRemoveEnrollmentObservers();
mProgressViewModel.cancelEnrollment(); mProgressViewModel.cancelEnrollment();
} }
@@ -318,7 +310,27 @@ public class FingerprintEnrollEnrollingRfpsFragment extends Fragment {
} }
private void onEnrollmentError(@NonNull EnrollmentStatusMessage errorMessage) { private void onEnrollmentError(@NonNull EnrollmentStatusMessage errorMessage) {
onCancelEnrollment(errorMessage.getMsgId()); stopIconAnimation();
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(
mView.getContext().getString(
FingerprintErrorDialog.getErrorMessage(errMsgId)),
mView.getContext().getString(
FingerprintErrorDialog.getErrorTitle(errMsgId)),
errMsgId
));
mProgressViewModel.cancelEnrollment();
}
} }
private void onEnrollmentProgressChange(@NonNull EnrollmentProgress progress) { private void onEnrollmentProgressChange(@NonNull EnrollmentProgress progress) {
@@ -398,7 +410,6 @@ public class FingerprintEnrollEnrollingRfpsFragment extends Fragment {
} }
} }
@Override @Override
public void onDestroy() { public void onDestroy() {
// TODO stopListenOrientationEvent(); // TODO stopListenOrientationEvent();
@@ -444,7 +455,6 @@ public class FingerprintEnrollEnrollingRfpsFragment extends Fragment {
private void showIconTouchDialog() { private void showIconTouchDialog() {
mIconTouchCount = 0; mIconTouchCount = 0;
//TODO EnrollingActivity should observe live data and add dialog fragment
mEnrollingViewModel.onIconTouchDialogShow(); mEnrollingViewModel.onIconTouchDialogShow();
} }

View File

@@ -113,7 +113,7 @@ public class FingerprintEnrollEnrollingSfpsFragment extends Fragment {
private boolean mHaveShownSfpsRightEdgeLottie; private boolean mHaveShownSfpsRightEdgeLottie;
private final View.OnClickListener mOnSkipClickListener = private final View.OnClickListener mOnSkipClickListener =
(v) -> mEnrollingViewModel.onSkipButtonClick(); (v) -> mEnrollingViewModel.onCancelledDueToOnSkipPressed();
private final Observer<EnrollmentProgress> mProgressObserver = progress -> { private final Observer<EnrollmentProgress> mProgressObserver = progress -> {
// TODO // TODO
}; };

View File

@@ -107,7 +107,7 @@ public class FingerprintEnrollEnrollingUdfpsFragment extends Fragment {
private boolean mIsAccessibilityEnabled; private boolean mIsAccessibilityEnabled;
private final View.OnClickListener mOnSkipClickListener = private final View.OnClickListener mOnSkipClickListener =
(v) -> mEnrollingViewModel.onSkipButtonClick(); (v) -> mEnrollingViewModel.onCancelledDueToOnSkipPressed();
private final Observer<EnrollmentProgress> mProgressObserver = progress -> { private final Observer<EnrollmentProgress> mProgressObserver = progress -> {
// TODO // TODO
}; };

View File

@@ -31,6 +31,7 @@ import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnr
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_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_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_ENROLL_ENROLLING_ACTION_SKIP;
import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ENROLL_ENROLLING_CANCELED_BECAUSE_BACK_PRESSED;
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_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.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.FingerprintEnrollEnrollingAction;
@@ -453,8 +454,7 @@ public class FingerprintEnrollmentActivity extends FragmentActivity {
private void onFindSensorAction(@FingerprintEnrollFindSensorAction int action) { private void onFindSensorAction(@FingerprintEnrollFindSensorAction int action) {
switch (action) { switch (action) {
case FINGERPRINT_ENROLL_FIND_SENSOR_ACTION_SKIP: { case FINGERPRINT_ENROLL_FIND_SENSOR_ACTION_SKIP: {
onSetActivityResult( onSetActivityResult(new ActivityResult(BiometricEnrollBase.RESULT_SKIP, null));
new ActivityResult(BiometricEnrollBase.RESULT_SKIP, null));
return; return;
} }
case FINGERPRINT_ENROLL_FIND_SENSOR_ACTION_DIALOG: { case FINGERPRINT_ENROLL_FIND_SENSOR_ACTION_DIALOG: {
@@ -487,6 +487,10 @@ public class FingerprintEnrollmentActivity extends FragmentActivity {
onSetActivityResult(new ActivityResult(BiometricEnrollBase.RESULT_TIMEOUT, null)); onSetActivityResult(new ActivityResult(BiometricEnrollBase.RESULT_TIMEOUT, null));
break; break;
} }
case FINGERPRINT_ENROLL_ENROLLING_CANCELED_BECAUSE_BACK_PRESSED: {
getSupportFragmentManager().popBackStack();
break;
}
} }
} }

View File

@@ -71,11 +71,17 @@ public class FingerprintEnrollEnrollingViewModel extends AndroidViewModel {
*/ */
public static final int FINGERPRINT_ENROLL_ENROLLING_ACTION_DISMISS_ICON_TOUCH_DIALOG = 3; public static final int FINGERPRINT_ENROLL_ENROLLING_ACTION_DISMISS_ICON_TOUCH_DIALOG = 3;
/**
* Has got latest cancelled event due to back key
*/
public static final int FINGERPRINT_ENROLL_ENROLLING_CANCELED_BECAUSE_BACK_PRESSED = 4;
@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_ICON_TOUCH_DIALOG, FINGERPRINT_ENROLL_ENROLLING_ACTION_SHOW_ICON_TOUCH_DIALOG,
FINGERPRINT_ENROLL_ENROLLING_ACTION_DISMISS_ICON_TOUCH_DIALOG FINGERPRINT_ENROLL_ENROLLING_ACTION_DISMISS_ICON_TOUCH_DIALOG,
FINGERPRINT_ENROLL_ENROLLING_CANCELED_BECAUSE_BACK_PRESSED
}) })
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
public @interface FingerprintEnrollEnrollingAction {} public @interface FingerprintEnrollEnrollingAction {}
@@ -103,8 +109,9 @@ public class FingerprintEnrollEnrollingViewModel extends AndroidViewModel {
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
public @interface FingerprintErrorDialogAction {} public @interface FingerprintErrorDialogAction {}
private final int mUserId; private final int mUserId;
private boolean mOnBackPressed;
private boolean mOnSkipPressed;
private final FingerprintRepository mFingerprintRepository; private final FingerprintRepository mFingerprintRepository;
private final AccessibilityRepository mAccessibilityRepository; private final AccessibilityRepository mAccessibilityRepository;
private final VibratorRepository mVibratorRepository; private final VibratorRepository mVibratorRepository;
@@ -162,14 +169,26 @@ public class FingerprintEnrollEnrollingViewModel extends AndroidViewModel {
mErrorDialogActionLiveData.postValue(action); mErrorDialogActionLiveData.postValue(action);
} }
public boolean getOnSkipPressed() {
return mOnSkipPressed;
}
/** /**
* User clicks skip button * User clicks skip button
*/ */
public void onSkipButtonClick() { public void setOnSkipPressed() {
mOnSkipPressed = true;
}
/**
* Enrolling is cacelled because user clicks skip
*/
public void onCancelledDueToOnSkipPressed() {
final int action = FINGERPRINT_ENROLL_ENROLLING_ACTION_SKIP; final int action = FINGERPRINT_ENROLL_ENROLLING_ACTION_SKIP;
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "onSkipButtonClick, post action " + action); Log.d(TAG, "onSkipButtonClick, post action " + action);
} }
mOnSkipPressed = false;
mActionLiveData.postValue(action); mActionLiveData.postValue(action);
} }
@@ -184,6 +203,29 @@ public class FingerprintEnrollEnrollingViewModel extends AndroidViewModel {
mActionLiveData.postValue(action); mActionLiveData.postValue(action);
} }
public boolean getOnBackPressed() {
return mOnBackPressed;
}
/**
* Back key is pressed.
*/
public void setOnBackPressed() {
mOnBackPressed = true;
}
/**
* Enrollment is cancelled because back key is pressed.
*/
public void onCancelledDueToOnBackPressed() {
final int action = FINGERPRINT_ENROLL_ENROLLING_CANCELED_BECAUSE_BACK_PRESSED;
if (DEBUG) {
Log.d(TAG, "onCancelledEventReceivedAfterOnBackPressed, post action " + action);
}
mOnBackPressed = false;
mActionLiveData.postValue(action);
}
/** /**
* Icon touch dialog show * Icon touch dialog show
*/ */