Show Choose/ConfirmLock before showing BiometricEnrollIntroduction
Skip button is now shown when ChooseLock is launched by BiometricEnroll, otherwise users are forced to use passwords (maybe good thing?) Bug: 111548033 Test: Pin/pattern/pass must be set/confirmed before enrollment Test: Able to enroll FP in SUW and Settings Change-Id: Ic4bbeb539e4bf01c1c402dec308943292b43406d
This commit is contained in:
@@ -67,8 +67,11 @@ public abstract class BiometricEnrollBase extends InstrumentedActivity
|
|||||||
*/
|
*/
|
||||||
public static final int RESULT_TIMEOUT = RESULT_FIRST_USER + 2;
|
public static final int RESULT_TIMEOUT = RESULT_FIRST_USER + 2;
|
||||||
|
|
||||||
public static final int CONFIRM_REQUEST = 1;
|
public static final int CHOOSE_LOCK_GENERIC_REQUEST = 1;
|
||||||
public static final int ENROLLING = 2;
|
public static final int BIOMETRIC_FIND_SENSOR_REQUEST = 2;
|
||||||
|
public static final int LEARN_MORE_REQUEST = 3;
|
||||||
|
public static final int CONFIRM_REQUEST = 4;
|
||||||
|
public static final int ENROLLING = 5;
|
||||||
|
|
||||||
protected boolean mLaunchedConfirmLock;
|
protected boolean mLaunchedConfirmLock;
|
||||||
protected byte[] mToken;
|
protected byte[] mToken;
|
||||||
@@ -105,10 +108,6 @@ public abstract class BiometricEnrollBase extends InstrumentedActivity
|
|||||||
initViews();
|
initViews();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean shouldLaunchConfirmLock() {
|
|
||||||
return mToken == null && !mLaunchedConfirmLock;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void initViews() {
|
protected void initViews() {
|
||||||
getWindow().setStatusBarColor(Color.TRANSPARENT);
|
getWindow().setStatusBarColor(Color.TRANSPARENT);
|
||||||
Button nextButton = getNextButton();
|
Button nextButton = getNextButton();
|
||||||
|
@@ -37,10 +37,6 @@ import com.google.android.setupdesign.span.LinkSpan;
|
|||||||
public abstract class BiometricEnrollIntroduction extends BiometricEnrollBase
|
public abstract class BiometricEnrollIntroduction extends BiometricEnrollBase
|
||||||
implements LinkSpan.OnClickListener {
|
implements LinkSpan.OnClickListener {
|
||||||
|
|
||||||
public static final int CHOOSE_LOCK_GENERIC_REQUEST = 1;
|
|
||||||
public static final int BIOMETRIC_FIND_SENSOR_REQUEST = 2;
|
|
||||||
public static final int LEARN_MORE_REQUEST = 3;
|
|
||||||
|
|
||||||
private UserManager mUserManager;
|
private UserManager mUserManager;
|
||||||
private boolean mHasPassword;
|
private boolean mHasPassword;
|
||||||
private boolean mBiometricUnlockDisabledByAdmin;
|
private boolean mBiometricUnlockDisabledByAdmin;
|
||||||
@@ -109,6 +105,11 @@ public abstract class BiometricEnrollIntroduction extends BiometricEnrollBase
|
|||||||
*/
|
*/
|
||||||
protected abstract Intent getEnrollingIntent();
|
protected abstract Intent getEnrollingIntent();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the title to be shown on the ConfirmLock screen.
|
||||||
|
*/
|
||||||
|
protected abstract int getConfirmLockTitleResId();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param span
|
* @param span
|
||||||
*/
|
*/
|
||||||
@@ -133,6 +134,13 @@ public abstract class BiometricEnrollIntroduction extends BiometricEnrollBase
|
|||||||
|
|
||||||
mUserManager = UserManager.get(this);
|
mUserManager = UserManager.get(this);
|
||||||
updatePasswordQuality();
|
updatePasswordQuality();
|
||||||
|
|
||||||
|
if (!mHasPassword) {
|
||||||
|
// No password registered, launch into enrollment wizard.
|
||||||
|
launchChooseLock();
|
||||||
|
} else {
|
||||||
|
launchConfirmLock(getConfirmLockTitleResId(), getChallenge());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -157,13 +165,8 @@ public abstract class BiometricEnrollIntroduction extends BiometricEnrollBase
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onNextButtonClick() {
|
protected void onNextButtonClick() {
|
||||||
if (!mHasPassword) {
|
// Lock thingy is already set up, launch directly to the next page
|
||||||
// No biometrics registered, launch into enrollment wizard.
|
launchNextEnrollingActivity(mToken);
|
||||||
launchChooseLock();
|
|
||||||
} else {
|
|
||||||
// Lock thingy is already set up, launch directly into find sensor step from wizard.
|
|
||||||
launchFindSensor(null);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void launchChooseLock() {
|
private void launchChooseLock() {
|
||||||
@@ -181,7 +184,7 @@ public abstract class BiometricEnrollIntroduction extends BiometricEnrollBase
|
|||||||
startActivityForResult(intent, CHOOSE_LOCK_GENERIC_REQUEST);
|
startActivityForResult(intent, CHOOSE_LOCK_GENERIC_REQUEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void launchFindSensor(byte[] token) {
|
private void launchNextEnrollingActivity(byte[] token) {
|
||||||
Intent intent = getEnrollingIntent();
|
Intent intent = getEnrollingIntent();
|
||||||
if (token != null) {
|
if (token != null) {
|
||||||
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, token);
|
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, token);
|
||||||
@@ -199,9 +202,9 @@ public abstract class BiometricEnrollIntroduction extends BiometricEnrollBase
|
|||||||
@Override
|
@Override
|
||||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
final boolean isResultFinished = resultCode == RESULT_FINISHED;
|
final boolean isResultFinished = resultCode == RESULT_FINISHED;
|
||||||
|
final int result = isResultFinished ? RESULT_OK : RESULT_SKIP;
|
||||||
if (requestCode == BIOMETRIC_FIND_SENSOR_REQUEST) {
|
if (requestCode == BIOMETRIC_FIND_SENSOR_REQUEST) {
|
||||||
if (isResultFinished || resultCode == RESULT_SKIP) {
|
if (isResultFinished || resultCode == RESULT_SKIP) {
|
||||||
final int result = isResultFinished ? RESULT_OK : RESULT_SKIP;
|
|
||||||
setResult(result, data);
|
setResult(result, data);
|
||||||
finish();
|
finish();
|
||||||
return;
|
return;
|
||||||
@@ -209,10 +212,21 @@ public abstract class BiometricEnrollIntroduction extends BiometricEnrollBase
|
|||||||
} else if (requestCode == CHOOSE_LOCK_GENERIC_REQUEST) {
|
} else if (requestCode == CHOOSE_LOCK_GENERIC_REQUEST) {
|
||||||
if (isResultFinished) {
|
if (isResultFinished) {
|
||||||
updatePasswordQuality();
|
updatePasswordQuality();
|
||||||
byte[] token = data.getByteArrayExtra(
|
mToken = data.getByteArrayExtra(
|
||||||
ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN);
|
ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN);
|
||||||
launchFindSensor(token);
|
overridePendingTransition(R.anim.suw_slide_next_in, R.anim.suw_slide_next_out);
|
||||||
return;
|
return;
|
||||||
|
} else {
|
||||||
|
setResult(result, data);
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
} else if (requestCode == CONFIRM_REQUEST) {
|
||||||
|
if (resultCode == RESULT_OK && data != null) {
|
||||||
|
mToken = data.getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN);
|
||||||
|
overridePendingTransition(R.anim.suw_slide_next_in, R.anim.suw_slide_next_out);
|
||||||
|
} else {
|
||||||
|
setResult(result, data);
|
||||||
|
finish();
|
||||||
}
|
}
|
||||||
} else if (requestCode == LEARN_MORE_REQUEST) {
|
} else if (requestCode == LEARN_MORE_REQUEST) {
|
||||||
overridePendingTransition(R.anim.suw_slide_back_in, R.anim.suw_slide_back_out);
|
overridePendingTransition(R.anim.suw_slide_back_in, R.anim.suw_slide_back_out);
|
||||||
|
@@ -48,13 +48,6 @@ public abstract class BiometricsEnrollEnrolling extends BiometricEnrollBase
|
|||||||
*/
|
*/
|
||||||
protected abstract boolean shouldStartAutomatically();
|
protected abstract boolean shouldStartAutomatically();
|
||||||
|
|
||||||
/**
|
|
||||||
* @return true if enrollment should finish when onStop is called.
|
|
||||||
*/
|
|
||||||
protected boolean shouldFinishOnStop() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStart() {
|
protected void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
@@ -70,7 +63,7 @@ public abstract class BiometricsEnrollEnrolling extends BiometricEnrollBase
|
|||||||
mSidecar.setListener(null);
|
mSidecar.setListener(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shouldFinishOnStop() && !isChangingConfigurations()) {
|
if (!isChangingConfigurations()) {
|
||||||
if (mSidecar != null) {
|
if (mSidecar != null) {
|
||||||
mSidecar.cancelEnrollment();
|
mSidecar.cancelEnrollment();
|
||||||
getSupportFragmentManager()
|
getSupportFragmentManager()
|
||||||
|
@@ -44,7 +44,6 @@ public class FaceEnrollEnrolling extends BiometricsEnrollEnrolling {
|
|||||||
|
|
||||||
private TextView mErrorText;
|
private TextView mErrorText;
|
||||||
private Interpolator mLinearOutSlowInInterpolator;
|
private Interpolator mLinearOutSlowInInterpolator;
|
||||||
private boolean mShouldFinishOnStop = true;
|
|
||||||
private FaceEnrollPreviewFragment mPreviewFragment;
|
private FaceEnrollPreviewFragment mPreviewFragment;
|
||||||
|
|
||||||
private FaceFeatureProvider.Listener mListener = new FaceFeatureProvider.Listener() {
|
private FaceFeatureProvider.Listener mListener = new FaceFeatureProvider.Listener() {
|
||||||
@@ -92,13 +91,7 @@ public class FaceEnrollEnrolling extends BiometricsEnrollEnrolling {
|
|||||||
Button skipButton = findViewById(R.id.skip_button);
|
Button skipButton = findViewById(R.id.skip_button);
|
||||||
skipButton.setOnClickListener(this);
|
skipButton.setOnClickListener(this);
|
||||||
|
|
||||||
if (shouldLaunchConfirmLock()) {
|
startEnrollment();
|
||||||
launchConfirmLock(R.string.security_settings_face_preference_title,
|
|
||||||
Utils.getFaceManagerOrNull(this).generateChallenge());
|
|
||||||
mShouldFinishOnStop = false;
|
|
||||||
} else {
|
|
||||||
startEnrollment();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -129,11 +122,6 @@ public class FaceEnrollEnrolling extends BiometricsEnrollEnrolling {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean shouldFinishOnStop() {
|
|
||||||
return mShouldFinishOnStop;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMetricsCategory() {
|
public int getMetricsCategory() {
|
||||||
return MetricsProto.MetricsEvent.FACE_ENROLL_ENROLLING;
|
return MetricsProto.MetricsEvent.FACE_ENROLL_ENROLLING;
|
||||||
@@ -178,23 +166,6 @@ public class FaceEnrollEnrolling extends BiometricsEnrollEnrolling {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
|
||||||
if (requestCode == CONFIRM_REQUEST) {
|
|
||||||
if (resultCode == RESULT_OK && data != null) {
|
|
||||||
mShouldFinishOnStop = true;
|
|
||||||
mToken = data.getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN);
|
|
||||||
overridePendingTransition(R.anim.suw_slide_next_in, R.anim.suw_slide_next_out);
|
|
||||||
getIntent().putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, mToken);
|
|
||||||
startEnrollment();
|
|
||||||
} else {
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
super.onActivityResult(requestCode, resultCode, data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void showErrorDialog(CharSequence msg, int msgId) {
|
private void showErrorDialog(CharSequence msg, int msgId) {
|
||||||
BiometricErrorDialog dialog = FaceErrorDialog.newInstance(msg, msgId);
|
BiometricErrorDialog dialog = FaceErrorDialog.newInstance(msg, msgId);
|
||||||
dialog.show(getSupportFragmentManager(), FaceErrorDialog.class.getName());
|
dialog.show(getSupportFragmentManager(), FaceErrorDialog.class.getName());
|
||||||
|
@@ -102,6 +102,7 @@ public class FaceEnrollIntroduction extends BiometricEnrollIntroduction {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected long getChallenge() {
|
protected long getChallenge() {
|
||||||
|
mFaceManager = Utils.getFaceManagerOrNull(this);
|
||||||
if (mFaceManager == null) {
|
if (mFaceManager == null) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -118,6 +119,11 @@ public class FaceEnrollIntroduction extends BiometricEnrollIntroduction {
|
|||||||
return new Intent(this, FaceEnrollEnrolling.class);
|
return new Intent(this, FaceEnrollEnrolling.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getConfirmLockTitleResId() {
|
||||||
|
return R.string.security_settings_face_preference_title;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMetricsCategory() {
|
public int getMetricsCategory() {
|
||||||
return MetricsProto.MetricsEvent.FACE_ENROLL_INTRO;
|
return MetricsProto.MetricsEvent.FACE_ENROLL_INTRO;
|
||||||
|
@@ -51,12 +51,9 @@ public class FingerprintEnrollFindSensor extends BiometricEnrollBase {
|
|||||||
|
|
||||||
setHeaderText(R.string.security_settings_fingerprint_enroll_find_sensor_title);
|
setHeaderText(R.string.security_settings_fingerprint_enroll_find_sensor_title);
|
||||||
|
|
||||||
if (shouldLaunchConfirmLock()) {
|
|
||||||
launchConfirmLock(R.string.security_settings_fingerprint_preference_title,
|
startLookingForFingerprint(); // already confirmed, so start looking for fingerprint
|
||||||
Utils.getFingerprintManagerOrNull(this).preEnroll());
|
|
||||||
} else if (mToken != null) {
|
|
||||||
startLookingForFingerprint(); // already confirmed, so start looking for fingerprint
|
|
||||||
}
|
|
||||||
View animationView = findViewById(R.id.fingerprint_sensor_location_animation);
|
View animationView = findViewById(R.id.fingerprint_sensor_location_animation);
|
||||||
if (animationView instanceof FingerprintFindSensorAnimation) {
|
if (animationView instanceof FingerprintFindSensorAnimation) {
|
||||||
mAnimation = (FingerprintFindSensorAnimation) animationView;
|
mAnimation = (FingerprintFindSensorAnimation) animationView;
|
||||||
|
@@ -106,6 +106,7 @@ public class FingerprintEnrollIntroduction extends BiometricEnrollIntroduction {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected long getChallenge() {
|
protected long getChallenge() {
|
||||||
|
mFingerprintManager = Utils.getFingerprintManagerOrNull(this);
|
||||||
if (mFingerprintManager == null) {
|
if (mFingerprintManager == null) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -122,6 +123,11 @@ public class FingerprintEnrollIntroduction extends BiometricEnrollIntroduction {
|
|||||||
return new Intent(this, FingerprintEnrollFindSensor.class);
|
return new Intent(this, FingerprintEnrollFindSensor.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getConfirmLockTitleResId() {
|
||||||
|
return R.string.security_settings_fingerprint_preference_title;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMetricsCategory() {
|
public int getMetricsCategory() {
|
||||||
return MetricsProto.MetricsEvent.FINGERPRINT_ENROLL_INTRO;
|
return MetricsProto.MetricsEvent.FINGERPRINT_ENROLL_INTRO;
|
||||||
|
@@ -135,8 +135,9 @@ public class SetupChooseLockPassword extends ChooseLockPassword {
|
|||||||
@Override
|
@Override
|
||||||
protected void updateUi() {
|
protected void updateUi() {
|
||||||
super.updateUi();
|
super.updateUi();
|
||||||
mSkipButton.setVisibility(mForFingerprint ? View.GONE : View.VISIBLE);
|
|
||||||
|
|
||||||
|
// Show the skip button during SUW but not during Settings > Biometric Enrollment
|
||||||
|
mSkipButton.setVisibility(View.VISIBLE);
|
||||||
if (mOptionsButton != null) {
|
if (mOptionsButton != null) {
|
||||||
mOptionsButton.setVisibility(
|
mOptionsButton.setVisibility(
|
||||||
mUiStage == Stage.Introduction ? View.VISIBLE : View.GONE);
|
mUiStage == Stage.Introduction ? View.VISIBLE : View.GONE);
|
||||||
|
@@ -70,17 +70,15 @@ public class SetupChooseLockPattern extends ChooseLockPattern {
|
|||||||
ChooseLockTypeDialogFragment.newInstance(mUserId)
|
ChooseLockTypeDialogFragment.newInstance(mUserId)
|
||||||
.show(getChildFragmentManager(), null));
|
.show(getChildFragmentManager(), null));
|
||||||
}
|
}
|
||||||
// enable skip button only during setup wizard and not with fingerprint flow.
|
// Show the skip button during SUW but not during Settings > Biometric Enrollment
|
||||||
if (!mForFingerprint) {
|
Button skipButton = view.findViewById(R.id.skip_button);
|
||||||
Button skipButton = view.findViewById(R.id.skip_button);
|
skipButton.setVisibility(View.VISIBLE);
|
||||||
skipButton.setVisibility(View.VISIBLE);
|
skipButton.setOnClickListener(v -> {
|
||||||
skipButton.setOnClickListener(v -> {
|
SetupSkipDialog dialog = SetupSkipDialog.newInstance(
|
||||||
SetupSkipDialog dialog = SetupSkipDialog.newInstance(
|
getActivity().getIntent()
|
||||||
getActivity().getIntent()
|
.getBooleanExtra(SetupSkipDialog.EXTRA_FRP_SUPPORTED, false));
|
||||||
.getBooleanExtra(SetupSkipDialog.EXTRA_FRP_SUPPORTED, false));
|
dialog.show(getFragmentManager());
|
||||||
dialog.show(getFragmentManager());
|
|
||||||
});
|
});
|
||||||
}
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -164,23 +164,6 @@ public class SetupChooseLockPatternTest {
|
|||||||
assertThat(findFragment(mActivity).mChosenPattern).isNull();
|
assertThat(findFragment(mActivity).mChosenPattern).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void skipButton_shouldNotBeVisible_duringFingerprintFlow() {
|
|
||||||
final Intent intent =
|
|
||||||
SetupChooseLockPattern.modifyIntentForSetup(
|
|
||||||
application,
|
|
||||||
new IntentBuilder(application)
|
|
||||||
.setUserId(UserHandle.myUserId())
|
|
||||||
.setForFingerprint(true)
|
|
||||||
.build());
|
|
||||||
|
|
||||||
mActivity = ActivityController.of(new SetupChooseLockPattern(), intent).setup().get();
|
|
||||||
Button skipButton = mActivity.findViewById(R.id.skip_button);
|
|
||||||
|
|
||||||
assertThat(skipButton).isNotNull();
|
|
||||||
assertThat(skipButton.getVisibility()).isEqualTo(View.GONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
private ChooseLockPatternFragment findFragment(FragmentActivity activity) {
|
private ChooseLockPatternFragment findFragment(FragmentActivity activity) {
|
||||||
return (ChooseLockPatternFragment)
|
return (ChooseLockPatternFragment)
|
||||||
activity.getSupportFragmentManager().findFragmentById(R.id.main_content);
|
activity.getSupportFragmentManager().findFragmentById(R.id.main_content);
|
||||||
|
Reference in New Issue
Block a user