Loading src/com/android/settings/biometrics/MultiBiometricEnrollHelper.java +51 −29 Original line number Diff line number Diff line Loading @@ -24,8 +24,11 @@ import android.hardware.fingerprint.FingerprintManager; import androidx.annotation.NonNull; import androidx.fragment.app.FragmentActivity; import com.android.internal.annotations.VisibleForTesting; import com.android.settings.password.ChooseLockSettingsHelper; import java.util.function.Function; /** * Helper for {@link BiometricEnrollActivity} when multiple sensors exist on a device. */ Loading @@ -45,14 +48,39 @@ public class MultiBiometricEnrollHelper { private final int mUserId; private final boolean mRequestEnrollFace; private final boolean mRequestEnrollFingerprint; private final FingerprintManager mFingerprintManager; private final FaceManager mFaceManager; private final Intent mFingerprintEnrollIntroductionIntent; private final Intent mFaceEnrollIntroductionIntent; private Function<Long, byte[]> mGatekeeperHatSupplier; @VisibleForTesting MultiBiometricEnrollHelper(@NonNull FragmentActivity activity, int userId, boolean enrollFace, boolean enrollFingerprint, long gkPwHandle) { boolean enrollFace, boolean enrollFingerprint, long gkPwHandle, FingerprintManager fingerprintManager, FaceManager faceManager, Intent fingerprintEnrollIntroductionIntent, Intent faceEnrollIntroductionIntent, Function<Long, byte[]> gatekeeperHatSupplier) { mActivity = activity; mUserId = userId; mGkPwHandle = gkPwHandle; mRequestEnrollFace = enrollFace; mRequestEnrollFingerprint = enrollFingerprint; mFingerprintManager = fingerprintManager; mFaceManager = faceManager; mFingerprintEnrollIntroductionIntent = fingerprintEnrollIntroductionIntent; mFaceEnrollIntroductionIntent = faceEnrollIntroductionIntent; mGatekeeperHatSupplier = gatekeeperHatSupplier; } MultiBiometricEnrollHelper(@NonNull FragmentActivity activity, int userId, boolean enrollFace, boolean enrollFingerprint, long gkPwHandle) { this(activity, userId, enrollFace, enrollFingerprint, gkPwHandle, activity.getSystemService(FingerprintManager.class), activity.getSystemService(FaceManager.class), BiometricUtils.getFingerprintIntroIntent(activity, activity.getIntent()), BiometricUtils.getFaceIntroIntent(activity, activity.getIntent()), (challenge) -> BiometricUtils.requestGatekeeperHat(activity, gkPwHandle, userId, challenge)); } void startNextStep() { Loading @@ -67,45 +95,39 @@ public class MultiBiometricEnrollHelper { } private void launchFaceEnroll() { final FaceManager faceManager = mActivity.getSystemService(FaceManager.class); faceManager.generateChallenge(mUserId, (sensorId, userId, challenge) -> { final byte[] hardwareAuthToken = BiometricUtils.requestGatekeeperHat(mActivity, mGkPwHandle, mUserId, challenge); final Intent faceIntent = BiometricUtils.getFaceIntroIntent(mActivity, mActivity.getIntent()); faceIntent.putExtra(BiometricEnrollBase.EXTRA_KEY_SENSOR_ID, sensorId); faceIntent.putExtra(BiometricEnrollBase.EXTRA_KEY_CHALLENGE, challenge); BiometricUtils.launchEnrollForResult(mActivity, faceIntent, REQUEST_FACE_ENROLL, hardwareAuthToken, mGkPwHandle, mUserId); mFaceManager.generateChallenge(mUserId, (sensorId, userId, challenge) -> { final byte[] hardwareAuthToken = mGatekeeperHatSupplier.apply(challenge); mFaceEnrollIntroductionIntent.putExtra( BiometricEnrollBase.EXTRA_KEY_SENSOR_ID, sensorId); mFaceEnrollIntroductionIntent.putExtra( BiometricEnrollBase.EXTRA_KEY_CHALLENGE, challenge); BiometricUtils.launchEnrollForResult(mActivity, mFaceEnrollIntroductionIntent, REQUEST_FACE_ENROLL, hardwareAuthToken, mGkPwHandle, mUserId); }); } private void launchFingerprintEnroll() { final FingerprintManager fingerprintManager = mActivity .getSystemService(FingerprintManager.class); fingerprintManager.generateChallenge(mUserId, ((sensorId, userId, challenge) -> { final byte[] hardwareAuthToken = BiometricUtils.requestGatekeeperHat(mActivity, mGkPwHandle, mUserId, challenge); final Intent intent = BiometricUtils.getFingerprintIntroIntent(mActivity, mActivity.getIntent()); intent.putExtra(BiometricEnrollBase.EXTRA_KEY_SENSOR_ID, sensorId); intent.putExtra(BiometricEnrollBase.EXTRA_KEY_CHALLENGE, challenge); mFingerprintManager.generateChallenge(mUserId, ((sensorId, userId, challenge) -> { final byte[] hardwareAuthToken = mGatekeeperHatSupplier.apply(challenge); mFingerprintEnrollIntroductionIntent.putExtra( BiometricEnrollBase.EXTRA_KEY_SENSOR_ID, sensorId); mFingerprintEnrollIntroductionIntent.putExtra( BiometricEnrollBase.EXTRA_KEY_CHALLENGE, challenge); if (mRequestEnrollFace) { // Give FingerprintEnroll a pendingIntent pointing to face enrollment, so that it // can be started when user skips or finishes fingerprint enrollment. // FLAG_UPDATE_CURRENT ensures it is launched with the most recent values. final Intent faceIntent = BiometricUtils.getFaceIntroIntent(mActivity, mActivity.getIntent()); faceIntent.putExtra(Intent.EXTRA_USER_ID, mUserId); faceIntent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE, mGkPwHandle); mFaceEnrollIntroductionIntent.putExtra(Intent.EXTRA_USER_ID, mUserId); mFaceEnrollIntroductionIntent.putExtra( ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE, mGkPwHandle); final PendingIntent faceAfterFp = PendingIntent.getActivity(mActivity, 0 /* requestCode */, faceIntent, 0 /* requestCode */, mFaceEnrollIntroductionIntent, PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT); intent.putExtra(EXTRA_ENROLL_AFTER_FINGERPRINT, faceAfterFp); mFingerprintEnrollIntroductionIntent.putExtra(EXTRA_ENROLL_AFTER_FINGERPRINT, faceAfterFp); } BiometricUtils.launchEnrollForResult(mActivity, intent, REQUEST_FINGERPRINT_ENROLL, hardwareAuthToken, mGkPwHandle, mUserId); BiometricUtils.launchEnrollForResult(mActivity, mFingerprintEnrollIntroductionIntent, REQUEST_FINGERPRINT_ENROLL, hardwareAuthToken, mGkPwHandle, mUserId); })); } } tests/robotests/src/com/android/settings/biometrics/MultiBiometricEnrollHelperTest.java 0 → 100644 +148 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.settings.biometrics; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.verify; import static org.robolectric.Shadows.shadowOf; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.hardware.face.FaceManager; import android.hardware.fingerprint.FingerprintManager; import android.os.RemoteException; import androidx.fragment.app.FragmentActivity; import com.android.settings.biometrics.face.FaceEnrollIntroduction; import com.android.settings.biometrics.fingerprint.FingerprintEnrollIntroduction; import com.android.settings.password.ChooseLockSettingsHelper; import com.android.settings.testutils.shadow.ShadowLockPatternUtils; import com.android.settings.testutils.shadow.ShadowRestrictedLockUtilsInternal; import com.android.settings.testutils.shadow.ShadowSensorPrivacyManager; import com.android.settings.testutils.shadow.ShadowUserManager; import com.android.settings.testutils.shadow.ShadowUtils; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import org.robolectric.android.controller.ActivityController; import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowPackageManager; @RunWith(RobolectricTestRunner.class) @Config(shadows = { ShadowUtils.class, ShadowUserManager.class, ShadowRestrictedLockUtilsInternal.class, ShadowSensorPrivacyManager.class, ShadowLockPatternUtils.class }) public class MultiBiometricEnrollHelperTest { @Rule public final MockitoRule mockito = MockitoJUnit.rule(); @Mock private FragmentActivity mActivity; @Mock private FingerprintManager mFingerprintManager; @Mock private FaceManager mFaceManager; private Context mContext; @Captor private ArgumentCaptor<FingerprintManager.GenerateChallengeCallback> mFingerprintCaptor; private final int mUserId = 10; private final long mChallenge = 0L; private final int mSensorId = 0; private final long mGkPwHandle = 0L; private MultiBiometricEnrollHelper mMultiBiometricEnrollHelper; private Intent mFingerprintIntent; private Intent mFaceIntent; @Before public void setUp() throws RemoteException { mContext = RuntimeEnvironment.application.getApplicationContext(); mFingerprintIntent = new Intent(mContext, FingerprintEnrollIntroduction.class); mFaceIntent = new Intent(mContext, FaceEnrollIntroduction.class); mMultiBiometricEnrollHelper = new MultiBiometricEnrollHelper( mActivity, mUserId, true /* enrollFace */, true /* enrollFingerprint */, mGkPwHandle, mFingerprintManager, mFaceManager, mFingerprintIntent, mFaceIntent, (challenge) -> null); } @Test public void launchFaceAndFingerprintEnroll_testFingerprint() { mMultiBiometricEnrollHelper.startNextStep(); verify(mFingerprintManager).generateChallenge(anyInt(), mFingerprintCaptor.capture()); FingerprintManager.GenerateChallengeCallback generateChallengeCallback = mFingerprintCaptor.getValue(); generateChallengeCallback.onChallengeGenerated(mSensorId, mUserId, mChallenge); assertThat(mFingerprintIntent.hasExtra( MultiBiometricEnrollHelper.EXTRA_ENROLL_AFTER_FINGERPRINT)).isTrue(); assertThat(mFingerprintIntent.getExtra(BiometricEnrollBase.EXTRA_KEY_SENSOR_ID, -1 /* defaultValue */)).isEqualTo(mSensorId); assertThat(mFingerprintIntent.getExtra(BiometricEnrollBase.EXTRA_KEY_CHALLENGE, -1 /* defaultValue */)).isEqualTo(mChallenge); assertThat(mFingerprintIntent.getExtra(ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE, -1 /* defaultValue */)).isEqualTo(mGkPwHandle); } @Test public void launchFaceAndFingerprintEnroll_testFace() { mMultiBiometricEnrollHelper.startNextStep(); verify(mFingerprintManager).generateChallenge(anyInt(), mFingerprintCaptor.capture()); FingerprintManager.GenerateChallengeCallback fingerprintGenerateChallengeCallback = mFingerprintCaptor.getValue(); fingerprintGenerateChallengeCallback.onChallengeGenerated( mSensorId, mUserId, mChallenge); assertThat(mFaceIntent.getExtra(ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE, -1 /* defaultValue */)).isEqualTo(mGkPwHandle); assertThat(mFaceIntent.getIntExtra(Intent.EXTRA_USER_ID, -1 /* defaultValue */)) .isEqualTo(mUserId); final ShadowPackageManager shadowPackageManager = shadowOf(mContext.getPackageManager()); shadowPackageManager.setSystemFeature(PackageManager.FEATURE_FACE, true); ShadowUtils.setFaceManager(mFaceManager); ActivityController.of(new FaceEnrollIntroduction(), mFaceIntent) .create(mFaceIntent.getExtras()).get(); verify(mFaceManager).generateChallenge(eq(mUserId), any()); } } Loading
src/com/android/settings/biometrics/MultiBiometricEnrollHelper.java +51 −29 Original line number Diff line number Diff line Loading @@ -24,8 +24,11 @@ import android.hardware.fingerprint.FingerprintManager; import androidx.annotation.NonNull; import androidx.fragment.app.FragmentActivity; import com.android.internal.annotations.VisibleForTesting; import com.android.settings.password.ChooseLockSettingsHelper; import java.util.function.Function; /** * Helper for {@link BiometricEnrollActivity} when multiple sensors exist on a device. */ Loading @@ -45,14 +48,39 @@ public class MultiBiometricEnrollHelper { private final int mUserId; private final boolean mRequestEnrollFace; private final boolean mRequestEnrollFingerprint; private final FingerprintManager mFingerprintManager; private final FaceManager mFaceManager; private final Intent mFingerprintEnrollIntroductionIntent; private final Intent mFaceEnrollIntroductionIntent; private Function<Long, byte[]> mGatekeeperHatSupplier; @VisibleForTesting MultiBiometricEnrollHelper(@NonNull FragmentActivity activity, int userId, boolean enrollFace, boolean enrollFingerprint, long gkPwHandle) { boolean enrollFace, boolean enrollFingerprint, long gkPwHandle, FingerprintManager fingerprintManager, FaceManager faceManager, Intent fingerprintEnrollIntroductionIntent, Intent faceEnrollIntroductionIntent, Function<Long, byte[]> gatekeeperHatSupplier) { mActivity = activity; mUserId = userId; mGkPwHandle = gkPwHandle; mRequestEnrollFace = enrollFace; mRequestEnrollFingerprint = enrollFingerprint; mFingerprintManager = fingerprintManager; mFaceManager = faceManager; mFingerprintEnrollIntroductionIntent = fingerprintEnrollIntroductionIntent; mFaceEnrollIntroductionIntent = faceEnrollIntroductionIntent; mGatekeeperHatSupplier = gatekeeperHatSupplier; } MultiBiometricEnrollHelper(@NonNull FragmentActivity activity, int userId, boolean enrollFace, boolean enrollFingerprint, long gkPwHandle) { this(activity, userId, enrollFace, enrollFingerprint, gkPwHandle, activity.getSystemService(FingerprintManager.class), activity.getSystemService(FaceManager.class), BiometricUtils.getFingerprintIntroIntent(activity, activity.getIntent()), BiometricUtils.getFaceIntroIntent(activity, activity.getIntent()), (challenge) -> BiometricUtils.requestGatekeeperHat(activity, gkPwHandle, userId, challenge)); } void startNextStep() { Loading @@ -67,45 +95,39 @@ public class MultiBiometricEnrollHelper { } private void launchFaceEnroll() { final FaceManager faceManager = mActivity.getSystemService(FaceManager.class); faceManager.generateChallenge(mUserId, (sensorId, userId, challenge) -> { final byte[] hardwareAuthToken = BiometricUtils.requestGatekeeperHat(mActivity, mGkPwHandle, mUserId, challenge); final Intent faceIntent = BiometricUtils.getFaceIntroIntent(mActivity, mActivity.getIntent()); faceIntent.putExtra(BiometricEnrollBase.EXTRA_KEY_SENSOR_ID, sensorId); faceIntent.putExtra(BiometricEnrollBase.EXTRA_KEY_CHALLENGE, challenge); BiometricUtils.launchEnrollForResult(mActivity, faceIntent, REQUEST_FACE_ENROLL, hardwareAuthToken, mGkPwHandle, mUserId); mFaceManager.generateChallenge(mUserId, (sensorId, userId, challenge) -> { final byte[] hardwareAuthToken = mGatekeeperHatSupplier.apply(challenge); mFaceEnrollIntroductionIntent.putExtra( BiometricEnrollBase.EXTRA_KEY_SENSOR_ID, sensorId); mFaceEnrollIntroductionIntent.putExtra( BiometricEnrollBase.EXTRA_KEY_CHALLENGE, challenge); BiometricUtils.launchEnrollForResult(mActivity, mFaceEnrollIntroductionIntent, REQUEST_FACE_ENROLL, hardwareAuthToken, mGkPwHandle, mUserId); }); } private void launchFingerprintEnroll() { final FingerprintManager fingerprintManager = mActivity .getSystemService(FingerprintManager.class); fingerprintManager.generateChallenge(mUserId, ((sensorId, userId, challenge) -> { final byte[] hardwareAuthToken = BiometricUtils.requestGatekeeperHat(mActivity, mGkPwHandle, mUserId, challenge); final Intent intent = BiometricUtils.getFingerprintIntroIntent(mActivity, mActivity.getIntent()); intent.putExtra(BiometricEnrollBase.EXTRA_KEY_SENSOR_ID, sensorId); intent.putExtra(BiometricEnrollBase.EXTRA_KEY_CHALLENGE, challenge); mFingerprintManager.generateChallenge(mUserId, ((sensorId, userId, challenge) -> { final byte[] hardwareAuthToken = mGatekeeperHatSupplier.apply(challenge); mFingerprintEnrollIntroductionIntent.putExtra( BiometricEnrollBase.EXTRA_KEY_SENSOR_ID, sensorId); mFingerprintEnrollIntroductionIntent.putExtra( BiometricEnrollBase.EXTRA_KEY_CHALLENGE, challenge); if (mRequestEnrollFace) { // Give FingerprintEnroll a pendingIntent pointing to face enrollment, so that it // can be started when user skips or finishes fingerprint enrollment. // FLAG_UPDATE_CURRENT ensures it is launched with the most recent values. final Intent faceIntent = BiometricUtils.getFaceIntroIntent(mActivity, mActivity.getIntent()); faceIntent.putExtra(Intent.EXTRA_USER_ID, mUserId); faceIntent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE, mGkPwHandle); mFaceEnrollIntroductionIntent.putExtra(Intent.EXTRA_USER_ID, mUserId); mFaceEnrollIntroductionIntent.putExtra( ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE, mGkPwHandle); final PendingIntent faceAfterFp = PendingIntent.getActivity(mActivity, 0 /* requestCode */, faceIntent, 0 /* requestCode */, mFaceEnrollIntroductionIntent, PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT); intent.putExtra(EXTRA_ENROLL_AFTER_FINGERPRINT, faceAfterFp); mFingerprintEnrollIntroductionIntent.putExtra(EXTRA_ENROLL_AFTER_FINGERPRINT, faceAfterFp); } BiometricUtils.launchEnrollForResult(mActivity, intent, REQUEST_FINGERPRINT_ENROLL, hardwareAuthToken, mGkPwHandle, mUserId); BiometricUtils.launchEnrollForResult(mActivity, mFingerprintEnrollIntroductionIntent, REQUEST_FINGERPRINT_ENROLL, hardwareAuthToken, mGkPwHandle, mUserId); })); } }
tests/robotests/src/com/android/settings/biometrics/MultiBiometricEnrollHelperTest.java 0 → 100644 +148 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.settings.biometrics; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.verify; import static org.robolectric.Shadows.shadowOf; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.hardware.face.FaceManager; import android.hardware.fingerprint.FingerprintManager; import android.os.RemoteException; import androidx.fragment.app.FragmentActivity; import com.android.settings.biometrics.face.FaceEnrollIntroduction; import com.android.settings.biometrics.fingerprint.FingerprintEnrollIntroduction; import com.android.settings.password.ChooseLockSettingsHelper; import com.android.settings.testutils.shadow.ShadowLockPatternUtils; import com.android.settings.testutils.shadow.ShadowRestrictedLockUtilsInternal; import com.android.settings.testutils.shadow.ShadowSensorPrivacyManager; import com.android.settings.testutils.shadow.ShadowUserManager; import com.android.settings.testutils.shadow.ShadowUtils; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import org.robolectric.android.controller.ActivityController; import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowPackageManager; @RunWith(RobolectricTestRunner.class) @Config(shadows = { ShadowUtils.class, ShadowUserManager.class, ShadowRestrictedLockUtilsInternal.class, ShadowSensorPrivacyManager.class, ShadowLockPatternUtils.class }) public class MultiBiometricEnrollHelperTest { @Rule public final MockitoRule mockito = MockitoJUnit.rule(); @Mock private FragmentActivity mActivity; @Mock private FingerprintManager mFingerprintManager; @Mock private FaceManager mFaceManager; private Context mContext; @Captor private ArgumentCaptor<FingerprintManager.GenerateChallengeCallback> mFingerprintCaptor; private final int mUserId = 10; private final long mChallenge = 0L; private final int mSensorId = 0; private final long mGkPwHandle = 0L; private MultiBiometricEnrollHelper mMultiBiometricEnrollHelper; private Intent mFingerprintIntent; private Intent mFaceIntent; @Before public void setUp() throws RemoteException { mContext = RuntimeEnvironment.application.getApplicationContext(); mFingerprintIntent = new Intent(mContext, FingerprintEnrollIntroduction.class); mFaceIntent = new Intent(mContext, FaceEnrollIntroduction.class); mMultiBiometricEnrollHelper = new MultiBiometricEnrollHelper( mActivity, mUserId, true /* enrollFace */, true /* enrollFingerprint */, mGkPwHandle, mFingerprintManager, mFaceManager, mFingerprintIntent, mFaceIntent, (challenge) -> null); } @Test public void launchFaceAndFingerprintEnroll_testFingerprint() { mMultiBiometricEnrollHelper.startNextStep(); verify(mFingerprintManager).generateChallenge(anyInt(), mFingerprintCaptor.capture()); FingerprintManager.GenerateChallengeCallback generateChallengeCallback = mFingerprintCaptor.getValue(); generateChallengeCallback.onChallengeGenerated(mSensorId, mUserId, mChallenge); assertThat(mFingerprintIntent.hasExtra( MultiBiometricEnrollHelper.EXTRA_ENROLL_AFTER_FINGERPRINT)).isTrue(); assertThat(mFingerprintIntent.getExtra(BiometricEnrollBase.EXTRA_KEY_SENSOR_ID, -1 /* defaultValue */)).isEqualTo(mSensorId); assertThat(mFingerprintIntent.getExtra(BiometricEnrollBase.EXTRA_KEY_CHALLENGE, -1 /* defaultValue */)).isEqualTo(mChallenge); assertThat(mFingerprintIntent.getExtra(ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE, -1 /* defaultValue */)).isEqualTo(mGkPwHandle); } @Test public void launchFaceAndFingerprintEnroll_testFace() { mMultiBiometricEnrollHelper.startNextStep(); verify(mFingerprintManager).generateChallenge(anyInt(), mFingerprintCaptor.capture()); FingerprintManager.GenerateChallengeCallback fingerprintGenerateChallengeCallback = mFingerprintCaptor.getValue(); fingerprintGenerateChallengeCallback.onChallengeGenerated( mSensorId, mUserId, mChallenge); assertThat(mFaceIntent.getExtra(ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE, -1 /* defaultValue */)).isEqualTo(mGkPwHandle); assertThat(mFaceIntent.getIntExtra(Intent.EXTRA_USER_ID, -1 /* defaultValue */)) .isEqualTo(mUserId); final ShadowPackageManager shadowPackageManager = shadowOf(mContext.getPackageManager()); shadowPackageManager.setSystemFeature(PackageManager.FEATURE_FACE, true); ShadowUtils.setFaceManager(mFaceManager); ActivityController.of(new FaceEnrollIntroduction(), mFaceIntent) .create(mFaceIntent.getExtras()).get(); verify(mFaceManager).generateChallenge(eq(mUserId), any()); } }