Support the ability to enroll face unlock first
Add a new EXTRA value to indicate whehter the face enrollment should be launched first. Bug: 370940762 Test: atest BiometricEnrollActivityTest Flag: com.android.settings.flags.biometrics_onboarding_education Change-Id: I7c85212c7fbcc6fe9dd53a26515412623c80ecbf
This commit is contained in:
@@ -107,7 +107,10 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
|
||||
// intent will include this extra containing a bundle of the form:
|
||||
// "modality" -> consented (boolean).
|
||||
public static final String EXTRA_PARENTAL_CONSENT_STATUS = "consent_status";
|
||||
|
||||
// Whether the face enrollment should be launched first when there are multiple biometrics
|
||||
// supported.
|
||||
public static final String EXTRA_LAUNCH_FACE_ENROLL_FIRST =
|
||||
"launch_face_enroll_first";
|
||||
private static final String SAVED_STATE_CONFIRMING_CREDENTIALS = "confirming_credentials";
|
||||
private static final String SAVED_STATE_IS_SINGLE_ENROLLING =
|
||||
"is_single_enrolling";
|
||||
@@ -130,6 +133,7 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
|
||||
private boolean mIsFingerprintEnrollable = false;
|
||||
private boolean mParentalOptionsRequired = false;
|
||||
private boolean mSkipReturnToParent = false;
|
||||
private boolean mLaunchFaceEnrollFirst = false;
|
||||
private Bundle mParentalOptions;
|
||||
@Nullable private Long mGkPwHandle;
|
||||
@Nullable private ParentalConsentHelper mParentalConsentHelper;
|
||||
@@ -214,6 +218,7 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
|
||||
|
||||
mParentalOptionsRequired = intent.getBooleanExtra(EXTRA_REQUIRE_PARENTAL_CONSENT, false);
|
||||
mSkipReturnToParent = intent.getBooleanExtra(EXTRA_SKIP_RETURN_TO_PARENT, false);
|
||||
mLaunchFaceEnrollFirst = intent.getBooleanExtra(EXTRA_LAUNCH_FACE_ENROLL_FIRST, false);
|
||||
|
||||
// determine what can be enrolled
|
||||
final boolean isSetupWizard = WizardManagerHelper.isAnySetupWizard(getIntent());
|
||||
@@ -221,6 +226,7 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
|
||||
|
||||
Log.d(TAG, "parentalOptionsRequired: " + mParentalOptionsRequired
|
||||
+ ", skipReturnToParent: " + mSkipReturnToParent
|
||||
+ ", launchFaceEnrollFirst: " + mLaunchFaceEnrollFirst
|
||||
+ ", isSetupWizard: " + isSetupWizard
|
||||
+ ", isMultiSensor: " + isMultiSensor);
|
||||
|
||||
@@ -356,7 +362,8 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
|
||||
} else if (canUseFace || canUseFingerprint) {
|
||||
if (mGkPwHandle == null) {
|
||||
setOrConfirmCredentialsNow();
|
||||
} else if (canUseFingerprint && mIsFingerprintEnrollable) {
|
||||
} else if (canUseFingerprint && mIsFingerprintEnrollable
|
||||
&& !(canUseFace && mIsFaceEnrollable && mLaunchFaceEnrollFirst)) {
|
||||
launchFingerprintOnlyEnroll();
|
||||
} else if (canUseFace && mIsFaceEnrollable) {
|
||||
launchFaceOnlyEnroll();
|
||||
@@ -510,7 +517,8 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
|
||||
int requestCode, int resultCode, Intent data) {
|
||||
|
||||
Log.d(TAG, "handleOnActivityResultWhileEnrolling, request = " + requestCode + ""
|
||||
+ ", resultCode = " + resultCode);
|
||||
+ ", resultCode = " + resultCode + ", launchFaceEnrollFirst="
|
||||
+ mLaunchFaceEnrollFirst);
|
||||
switch (requestCode) {
|
||||
case REQUEST_HANDOFF_PARENT:
|
||||
setResult(RESULT_OK, newResultIntent());
|
||||
@@ -526,7 +534,8 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
|
||||
// SetupFingerprintEnrollIntroduction/FingerprintEnrollmentActivity
|
||||
TransitionHelper.applyForwardTransition(this, TRANSITION_FADE_THROUGH);
|
||||
updateGatekeeperPasswordHandle(data);
|
||||
if (mIsFingerprintEnrollable) {
|
||||
if (mIsFingerprintEnrollable
|
||||
&& !(mIsFaceEnrollable && mLaunchFaceEnrollFirst)) {
|
||||
launchFingerprintOnlyEnroll();
|
||||
} else {
|
||||
launchFaceOnlyEnroll();
|
||||
@@ -548,7 +557,7 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
|
||||
}
|
||||
if ((resultCode == BiometricEnrollBase.RESULT_SKIP
|
||||
|| resultCode == BiometricEnrollBase.RESULT_FINISHED)
|
||||
&& mIsFaceEnrollable) {
|
||||
&& mIsFaceEnrollable && !mLaunchFaceEnrollFirst) {
|
||||
// Apply forward animation during the transition from
|
||||
// SetupFingerprintEnroll*/FingerprintEnrollmentActivity to
|
||||
// SetupFaceEnrollIntroduction
|
||||
@@ -556,6 +565,9 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
|
||||
mIsPreviousEnrollmentCanceled =
|
||||
resultCode != BiometricEnrollBase.RESULT_FINISHED;
|
||||
launchFaceOnlyEnroll();
|
||||
} else if (resultCode == Activity.RESULT_CANCELED && mIsFaceEnrollable
|
||||
&& mLaunchFaceEnrollFirst) {
|
||||
launchFaceOnlyEnroll();
|
||||
} else {
|
||||
notifySafetyIssueActionLaunchedIfNeeded(resultCode);
|
||||
finishOrLaunchHandToParent(resultCode);
|
||||
@@ -563,7 +575,14 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
|
||||
break;
|
||||
case REQUEST_SINGLE_ENROLL_FACE:
|
||||
mIsSingleEnrolling = false;
|
||||
if (resultCode == Activity.RESULT_CANCELED && mIsFingerprintEnrollable) {
|
||||
if ((resultCode == BiometricEnrollBase.RESULT_SKIP
|
||||
|| resultCode == BiometricEnrollBase.RESULT_FINISHED)
|
||||
&& mIsFingerprintEnrollable && mLaunchFaceEnrollFirst) {
|
||||
mIsPreviousEnrollmentCanceled =
|
||||
resultCode != BiometricEnrollBase.RESULT_FINISHED;
|
||||
launchFingerprintOnlyEnroll();
|
||||
} else if (resultCode == Activity.RESULT_CANCELED && mIsFingerprintEnrollable
|
||||
&& !mLaunchFaceEnrollFirst) {
|
||||
mIsPreviousEnrollmentCanceled = true;
|
||||
launchFingerprintOnlyEnroll();
|
||||
} else {
|
||||
|
@@ -43,6 +43,7 @@ import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.internal.widget.VerifyCredentialResponse;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SetupWizardUtils;
|
||||
import com.android.settings.biometrics.face.FaceEnroll;
|
||||
import com.android.settings.biometrics.fingerprint.FingerprintEnroll;
|
||||
import com.android.settings.biometrics.fingerprint.FingerprintEnrollFindSensor;
|
||||
import com.android.settings.biometrics.fingerprint.SetupFingerprintEnrollFindSensor;
|
||||
@@ -282,9 +283,7 @@ public class BiometricUtils {
|
||||
*/
|
||||
public static Intent getFaceIntroIntent(@NonNull Context context,
|
||||
@NonNull Intent activityIntent) {
|
||||
final Intent intent = new Intent(context,
|
||||
FeatureFactory.getFeatureFactory().getFaceFeatureProvider()
|
||||
.getEnrollActivityClassProvider().getNext());
|
||||
final Intent intent = new Intent(context, FaceEnroll.class);
|
||||
WizardManagerHelper.copyWizardManagerExtras(activityIntent, intent);
|
||||
return intent;
|
||||
}
|
||||
|
@@ -23,6 +23,7 @@ import static androidx.test.espresso.intent.Intents.intended;
|
||||
import static androidx.test.espresso.intent.matcher.IntentMatchers.hasComponent;
|
||||
import static androidx.test.espresso.intent.matcher.IntentMatchers.hasExtra;
|
||||
|
||||
import static com.android.settings.biometrics.BiometricEnrollActivity.EXTRA_LAUNCH_FACE_ENROLL_FIRST;
|
||||
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_FOR_BIOMETRICS;
|
||||
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_FOR_FACE;
|
||||
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT;
|
||||
@@ -39,6 +40,7 @@ import android.hardware.face.FaceManager;
|
||||
import android.hardware.face.FaceSensorPropertiesInternal;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
|
||||
@@ -145,7 +147,7 @@ public class BiometricEnrollActivityTest {
|
||||
assumeTrue(mHasFace || mHasFingerprint);
|
||||
|
||||
setPin();
|
||||
final Intent intent = getIntent(true /* useInternal */);
|
||||
final Intent intent = getIntent(true /* useInternal */, null);
|
||||
LockPatternChecker.verifyCredential(new LockPatternUtils(mContext),
|
||||
LockscreenCredential.createPin(TEST_PIN), UserHandle.myUserId(),
|
||||
LockPatternUtils.VERIFY_FLAG_REQUEST_GK_PW_HANDLE, (response, timeoutMs) -> {
|
||||
@@ -162,6 +164,26 @@ public class BiometricEnrollActivityTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void launchWithPinAndPwHandle_confirmsPin_firstEnrollmentIsFace() throws Exception {
|
||||
assumeTrue(mHasFace && mHasFingerprint);
|
||||
|
||||
setPin();
|
||||
final Intent intent = getFaceEnrollFirstIntent();
|
||||
LockPatternChecker.verifyCredential(new LockPatternUtils(mContext),
|
||||
LockscreenCredential.createPin(TEST_PIN), UserHandle.myUserId(),
|
||||
LockPatternUtils.VERIFY_FLAG_REQUEST_GK_PW_HANDLE, (response, timeoutMs) -> {
|
||||
assertThat(response.containsGatekeeperPasswordHandle()).isTrue();
|
||||
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE,
|
||||
response.getGatekeeperPasswordHandle());
|
||||
}).get();
|
||||
|
||||
try (ActivityScenario<BiometricEnrollActivity> scenario =
|
||||
ActivityScenario.launch(intent)) {
|
||||
intended(hasComponent(FaceEnroll.class.getName()));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void launchWithStrongBiometricAllowed_doNotEnrollWeak() throws Exception {
|
||||
assumeTrue(mHasFace || mHasFingerprint);
|
||||
@@ -184,13 +206,22 @@ public class BiometricEnrollActivityTest {
|
||||
}
|
||||
|
||||
private Intent getIntent() {
|
||||
return getIntent(false /* useInternal */);
|
||||
return getIntent(false /* useInternal */, null);
|
||||
}
|
||||
|
||||
private Intent getIntent(boolean useInternal) {
|
||||
private Intent getFaceEnrollFirstIntent() {
|
||||
final Bundle bundle = new Bundle();
|
||||
bundle.putBoolean(EXTRA_LAUNCH_FACE_ENROLL_FIRST, true);
|
||||
return getIntent(true /* useInternal */, bundle);
|
||||
}
|
||||
|
||||
private Intent getIntent(boolean useInternal, Bundle bundle) {
|
||||
final Intent intent = new Intent(mContext, useInternal
|
||||
? BiometricEnrollActivity.InternalActivity.class : BiometricEnrollActivity.class);
|
||||
intent.setAction(ACTION_BIOMETRIC_ENROLL);
|
||||
if (bundle != null && !bundle.isEmpty()) {
|
||||
intent.putExtras(bundle);
|
||||
}
|
||||
return intent;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user