• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.biometrics;
18 
19 import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE;
20 import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
21 import static android.hardware.biometrics.BiometricPrompt.DISMISSED_REASON_NEGATIVE;
22 
23 import static com.android.server.biometrics.BiometricServiceStateProto.STATE_AUTH_CALLED;
24 import static com.android.server.biometrics.BiometricServiceStateProto.STATE_AUTH_STARTED;
25 import static com.android.server.biometrics.BiometricServiceStateProto.STATE_AUTH_STARTED_UI_SHOWING;
26 
27 import static junit.framework.Assert.assertEquals;
28 import static junit.framework.Assert.assertFalse;
29 import static junit.framework.Assert.assertTrue;
30 
31 import static org.mockito.ArgumentMatchers.any;
32 import static org.mockito.ArgumentMatchers.anyBoolean;
33 import static org.mockito.ArgumentMatchers.anyInt;
34 import static org.mockito.ArgumentMatchers.anyLong;
35 import static org.mockito.ArgumentMatchers.eq;
36 import static org.mockito.Mockito.mock;
37 import static org.mockito.Mockito.never;
38 import static org.mockito.Mockito.times;
39 import static org.mockito.Mockito.verify;
40 import static org.mockito.Mockito.when;
41 
42 import android.annotation.NonNull;
43 import android.app.admin.DevicePolicyManager;
44 import android.app.trust.ITrustManager;
45 import android.content.Context;
46 import android.hardware.biometrics.BiometricManager.Authenticators;
47 import android.hardware.biometrics.ComponentInfoInternal;
48 import android.hardware.biometrics.IBiometricAuthenticator;
49 import android.hardware.biometrics.IBiometricSensorReceiver;
50 import android.hardware.biometrics.IBiometricServiceReceiver;
51 import android.hardware.biometrics.IBiometricSysuiReceiver;
52 import android.hardware.biometrics.PromptInfo;
53 import android.hardware.biometrics.SensorProperties;
54 import android.hardware.fingerprint.FingerprintSensorProperties;
55 import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
56 import android.os.Binder;
57 import android.os.IBinder;
58 import android.os.RemoteException;
59 import android.platform.test.annotations.Presubmit;
60 import android.security.KeyStore;
61 
62 import androidx.test.filters.SmallTest;
63 
64 import com.android.internal.statusbar.IStatusBarService;
65 
66 import org.junit.Before;
67 import org.junit.Test;
68 import org.mockito.Mock;
69 import org.mockito.MockitoAnnotations;
70 
71 import java.util.ArrayList;
72 import java.util.List;
73 import java.util.Random;
74 import java.util.function.Consumer;
75 
76 @Presubmit
77 @SmallTest
78 public class AuthSessionTest {
79 
80     private static final String TEST_PACKAGE = "test_package";
81     private static final long TEST_REQUEST_ID = 22;
82 
83     @Mock private Context mContext;
84     @Mock private ITrustManager mTrustManager;
85     @Mock private DevicePolicyManager mDevicePolicyManager;
86     @Mock private BiometricService.SettingObserver mSettingObserver;
87     @Mock private IBiometricSensorReceiver mSensorReceiver;
88     @Mock private IBiometricServiceReceiver mClientReceiver;
89     @Mock private IStatusBarService mStatusBarService;
90     @Mock private IBiometricSysuiReceiver mSysuiReceiver;
91     @Mock private KeyStore mKeyStore;
92     @Mock private AuthSession.ClientDeathReceiver mClientDeathReceiver;
93 
94     private Random mRandom;
95     private IBinder mToken;
96 
97     // Assume all tests can be done with the same set of sensors for now.
98     @NonNull private List<BiometricSensor> mSensors;
99     @NonNull private List<FingerprintSensorPropertiesInternal> mFingerprintSensorProps;
100 
101     @Before
setUp()102     public void setUp() throws Exception {
103         MockitoAnnotations.initMocks(this);
104         when(mClientReceiver.asBinder()).thenReturn(mock(Binder.class));
105         mRandom = new Random();
106         mToken = new Binder();
107         mSensors = new ArrayList<>();
108         mFingerprintSensorProps = new ArrayList<>();
109     }
110 
111     @Test
testNewAuthSession_eligibleSensorsSetToStateUnknown()112     public void testNewAuthSession_eligibleSensorsSetToStateUnknown() throws RemoteException {
113         setupFingerprint(0 /* id */, FingerprintSensorProperties.TYPE_REAR);
114         setupFace(1 /* id */, false /* confirmationAlwaysRequired */,
115                 mock(IBiometricAuthenticator.class));
116 
117         final AuthSession session = createAuthSession(mSensors,
118                 false /* checkDevicePolicyManager */,
119                 Authenticators.BIOMETRIC_STRONG,
120                 TEST_REQUEST_ID,
121                 0 /* operationId */,
122                 0 /* userId */);
123 
124         for (BiometricSensor sensor : session.mPreAuthInfo.eligibleSensors) {
125             assertEquals(BiometricSensor.STATE_UNKNOWN, sensor.getSensorState());
126         }
127     }
128 
129     @Test
testStartNewAuthSession()130     public void testStartNewAuthSession() throws RemoteException {
131         setupFace(0 /* id */, false /* confirmationAlwaysRequired */,
132                 mock(IBiometricAuthenticator.class));
133         setupFingerprint(1 /* id */, FingerprintSensorProperties.TYPE_REAR);
134 
135         final boolean requireConfirmation = true;
136         final long operationId = 123;
137         final int userId = 10;
138 
139         final AuthSession session = createAuthSession(mSensors,
140                 false /* checkDevicePolicyManager */,
141                 Authenticators.BIOMETRIC_STRONG,
142                 TEST_REQUEST_ID,
143                 operationId,
144                 userId);
145         assertEquals(mSensors.size(), session.mPreAuthInfo.eligibleSensors.size());
146 
147         for (BiometricSensor sensor : session.mPreAuthInfo.eligibleSensors) {
148             assertEquals(BiometricSensor.STATE_UNKNOWN, sensor.getSensorState());
149             assertEquals(0, sensor.getCookie());
150         }
151 
152         session.goToInitialState();
153         for (BiometricSensor sensor : session.mPreAuthInfo.eligibleSensors) {
154             assertEquals(BiometricSensor.STATE_WAITING_FOR_COOKIE, sensor.getSensorState());
155             assertTrue("Cookie must be >0", sensor.getCookie() > 0);
156             verify(sensor.impl).prepareForAuthentication(
157                     eq(sensor.confirmationSupported() && requireConfirmation),
158                     eq(mToken),
159                     eq(operationId),
160                     eq(userId),
161                     eq(mSensorReceiver),
162                     eq(TEST_PACKAGE),
163                     eq(TEST_REQUEST_ID),
164                     eq(sensor.getCookie()),
165                     anyBoolean() /* allowBackgroundAuthentication */);
166         }
167 
168         final int cookie1 = session.mPreAuthInfo.eligibleSensors.get(0).getCookie();
169         session.onCookieReceived(cookie1);
170         for (BiometricSensor sensor : session.mPreAuthInfo.eligibleSensors) {
171             if (cookie1 == sensor.getCookie()) {
172                 assertEquals(BiometricSensor.STATE_COOKIE_RETURNED, sensor.getSensorState());
173             } else {
174                 assertEquals(BiometricSensor.STATE_WAITING_FOR_COOKIE, sensor.getSensorState());
175             }
176         }
177         assertFalse(session.allCookiesReceived());
178 
179         final int cookie2 = session.mPreAuthInfo.eligibleSensors.get(1).getCookie();
180         session.onCookieReceived(cookie2);
181         assertTrue(session.allCookiesReceived());
182 
183 
184         // for multi-sensor face then fingerprint is the default policy
185         for (BiometricSensor sensor : session.mPreAuthInfo.eligibleSensors) {
186             if (sensor.modality == TYPE_FACE) {
187                 verify(sensor.impl).startPreparedClient(eq(sensor.getCookie()));
188                 assertEquals(BiometricSensor.STATE_AUTHENTICATING, sensor.getSensorState());
189             } else if (sensor.modality == TYPE_FINGERPRINT) {
190                 assertEquals(BiometricSensor.STATE_COOKIE_RETURNED, sensor.getSensorState());
191             }
192         }
193     }
194 
195     @Test
testCancelReducesAppetiteForCookies()196     public void testCancelReducesAppetiteForCookies() throws Exception {
197         setupFace(0 /* id */, false /* confirmationAlwaysRequired */,
198                 mock(IBiometricAuthenticator.class));
199         setupFingerprint(1 /* id */, FingerprintSensorProperties.TYPE_UDFPS_OPTICAL);
200 
201         final AuthSession session = createAuthSession(mSensors,
202                 false /* checkDevicePolicyManager */,
203                 Authenticators.BIOMETRIC_STRONG,
204                 TEST_REQUEST_ID,
205                 44 /* operationId */,
206                 2 /* userId */);
207 
208         session.goToInitialState();
209 
210         for (BiometricSensor sensor : session.mPreAuthInfo.eligibleSensors) {
211             assertEquals(BiometricSensor.STATE_WAITING_FOR_COOKIE, sensor.getSensorState());
212         }
213 
214         session.onCancelAuthSession(false /* force */);
215 
216         for (BiometricSensor sensor : session.mPreAuthInfo.eligibleSensors) {
217             session.onCookieReceived(sensor.getCookie());
218             assertEquals(BiometricSensor.STATE_CANCELING, sensor.getSensorState());
219         }
220     }
221 
222     @Test
testMultiAuth_singleSensor_fingerprintSensorStartsAfterDialogAnimationCompletes()223     public void testMultiAuth_singleSensor_fingerprintSensorStartsAfterDialogAnimationCompletes()
224             throws Exception {
225         setupFingerprint(0 /* id */, FingerprintSensorProperties.TYPE_UDFPS_OPTICAL);
226         testMultiAuth_fingerprintSensorStartsAfterUINotifies();
227     }
228 
229     @Test
testMultiAuth_fingerprintSensorStartsAfterDialogAnimationCompletes()230     public void testMultiAuth_fingerprintSensorStartsAfterDialogAnimationCompletes()
231             throws Exception {
232         setupFingerprint(0 /* id */, FingerprintSensorProperties.TYPE_UDFPS_OPTICAL);
233         setupFace(1 /* id */, false, mock(IBiometricAuthenticator.class));
234         testMultiAuth_fingerprintSensorStartsAfterUINotifies();
235     }
236 
testMultiAuth_fingerprintSensorStartsAfterUINotifies()237     public void testMultiAuth_fingerprintSensorStartsAfterUINotifies()
238             throws Exception {
239         final long operationId = 123;
240         final int userId = 10;
241         final int fingerprintSensorId = mSensors.stream()
242                 .filter(s -> s.modality == TYPE_FINGERPRINT)
243                 .map(s -> s.id)
244                 .findFirst()
245                 .orElse(-1);
246 
247         final AuthSession session = createAuthSession(mSensors,
248                 false /* checkDevicePolicyManager */,
249                 Authenticators.BIOMETRIC_STRONG,
250                 TEST_REQUEST_ID,
251                 operationId,
252                 userId);
253         assertEquals(mSensors.size(), session.mPreAuthInfo.eligibleSensors.size());
254 
255         for (BiometricSensor sensor : session.mPreAuthInfo.eligibleSensors) {
256             assertEquals(BiometricSensor.STATE_UNKNOWN, sensor.getSensorState());
257             assertEquals(0, sensor.getCookie());
258         }
259 
260         session.goToInitialState();
261 
262         for (BiometricSensor sensor : session.mPreAuthInfo.eligibleSensors) {
263             assertEquals(BiometricSensor.STATE_WAITING_FOR_COOKIE, sensor.getSensorState());
264             session.onCookieReceived(
265                     session.mPreAuthInfo.eligibleSensors.get(sensor.id).getCookie());
266             if (fingerprintSensorId == sensor.id) {
267                 assertEquals(BiometricSensor.STATE_COOKIE_RETURNED, sensor.getSensorState());
268             } else {
269                 assertEquals(BiometricSensor.STATE_AUTHENTICATING, sensor.getSensorState());
270             }
271         }
272         assertTrue(session.allCookiesReceived());
273 
274         // fingerprint sensor does not start even if all cookies are received
275         assertEquals(STATE_AUTH_STARTED, session.getState());
276         verify(mStatusBarService).showAuthenticationDialog(any(), any(), any(),
277                 anyBoolean(), anyBoolean(), anyInt(), anyLong(), any(), anyLong(), anyInt());
278 
279         // Notify AuthSession that the UI is shown. Then, fingerprint sensor should be started.
280         session.onDialogAnimatedIn();
281         assertEquals(STATE_AUTH_STARTED_UI_SHOWING, session.getState());
282         assertEquals(BiometricSensor.STATE_AUTHENTICATING,
283                 session.mPreAuthInfo.eligibleSensors.get(fingerprintSensorId).getSensorState());
284     }
285 
286     @Test
testOnDialogAnimatedInDoesNothingDuringInvalidState()287     public void testOnDialogAnimatedInDoesNothingDuringInvalidState() throws Exception {
288         setupFingerprint(0 /* id */, FingerprintSensorProperties.TYPE_UDFPS_OPTICAL);
289         final long operationId = 123;
290         final int userId = 10;
291 
292         final AuthSession session = createAuthSession(mSensors,
293                 false /* checkDevicePolicyManager */,
294                 Authenticators.BIOMETRIC_STRONG,
295                 TEST_REQUEST_ID,
296                 operationId,
297                 userId);
298         final IBiometricAuthenticator impl = session.mPreAuthInfo.eligibleSensors.get(0).impl;
299 
300         session.goToInitialState();
301         for (BiometricSensor sensor : session.mPreAuthInfo.eligibleSensors) {
302             assertEquals(BiometricSensor.STATE_WAITING_FOR_COOKIE, sensor.getSensorState());
303             session.onCookieReceived(
304                     session.mPreAuthInfo.eligibleSensors.get(sensor.id).getCookie());
305         }
306         assertTrue(session.allCookiesReceived());
307         assertEquals(STATE_AUTH_STARTED, session.getState());
308         verify(impl, never()).startPreparedClient(anyInt());
309 
310         // First invocation should start the client monitor.
311         session.onDialogAnimatedIn();
312         assertEquals(STATE_AUTH_STARTED_UI_SHOWING, session.getState());
313         verify(impl).startPreparedClient(anyInt());
314 
315         // Subsequent invocations should not start the client monitor again.
316         session.onDialogAnimatedIn();
317         session.onDialogAnimatedIn();
318         session.onDialogAnimatedIn();
319         assertEquals(STATE_AUTH_STARTED_UI_SHOWING, session.getState());
320         verify(impl, times(1)).startPreparedClient(anyInt());
321     }
322 
323     @Test
testCancelAuthentication_whenStateAuthCalled_invokesCancel()324     public void testCancelAuthentication_whenStateAuthCalled_invokesCancel()
325             throws RemoteException {
326         testInvokesCancel(session -> session.onCancelAuthSession(false /* force */));
327     }
328 
329     @Test
testCancelAuthentication_whenStateAuthForcedCalled_invokesCancel()330     public void testCancelAuthentication_whenStateAuthForcedCalled_invokesCancel()
331             throws RemoteException {
332         testInvokesCancel(session -> session.onCancelAuthSession(true /* force */));
333     }
334 
335     @Test
testCancelAuthentication_whenDialogDismissed()336     public void testCancelAuthentication_whenDialogDismissed() throws RemoteException {
337         testInvokesCancel(session -> session.onDialogDismissed(DISMISSED_REASON_NEGATIVE, null));
338     }
339 
340     // TODO (b/208484275) : Enable these tests
341     // @Test
342     // public void testPreAuth_canAuthAndPrivacyDisabled() throws Exception {
343     //     SensorPrivacyManager manager = ExtendedMockito.mock(SensorPrivacyManager.class);
344     //     when(manager
345     //             .isSensorPrivacyEnabled(SensorPrivacyManager.Sensors.CAMERA, anyInt()))
346     //             .thenReturn(false);
347     //     when(mContext.getSystemService(SensorPrivacyManager.class))
348     //             .thenReturn(manager);
349     //     setupFace(1 /* id */, false /* confirmationAlwaysRequired */,
350     //             mock(IBiometricAuthenticator.class));
351     //     final PromptInfo promptInfo = createPromptInfo(Authenticators.BIOMETRIC_STRONG);
352     //     final PreAuthInfo preAuthInfo = createPreAuthInfo(mSensors, 0, promptInfo, false);
353     //     assertEquals(BiometricManager.BIOMETRIC_SUCCESS, preAuthInfo.getCanAuthenticateResult());
354     //     for (BiometricSensor sensor : preAuthInfo.eligibleSensors) {
355     //         assertEquals(BiometricSensor.STATE_UNKNOWN, sensor.getSensorState());
356     //     }
357     // }
358 
359     // @Test
360     // public void testPreAuth_cannotAuthAndPrivacyEnabled() throws Exception {
361     //     SensorPrivacyManager manager = ExtendedMockito.mock(SensorPrivacyManager.class);
362     //     when(manager
363     //             .isSensorPrivacyEnabled(SensorPrivacyManager.Sensors.CAMERA, anyInt()))
364     //             .thenReturn(true);
365     //     when(mContext.getSystemService(SensorPrivacyManager.class))
366     //             .thenReturn(manager);
367     //     setupFace(1 /* id */, false /* confirmationAlwaysRequired */,
368     //             mock(IBiometricAuthenticator.class));
369     //     final PromptInfo promptInfo = createPromptInfo(Authenticators.BIOMETRIC_STRONG);
370     //     final PreAuthInfo preAuthInfo = createPreAuthInfo(mSensors, 0, promptInfo, false);
371     //     assertEquals(BiometricManager.BIOMETRIC_ERROR_SENSOR_PRIVACY_ENABLED,
372     //             preAuthInfo.getCanAuthenticateResult());
373     //     // Even though canAuth returns privacy enabled, we should still be able to authenticate.
374     //     for (BiometricSensor sensor : preAuthInfo.eligibleSensors) {
375     //         assertEquals(BiometricSensor.STATE_UNKNOWN, sensor.getSensorState());
376     //     }
377     // }
378 
379     // @Test
380     // public void testPreAuth_canAuthAndPrivacyEnabledCredentialEnabled() throws Exception {
381     //     SensorPrivacyManager manager = ExtendedMockito.mock(SensorPrivacyManager.class);
382     //     when(manager
383     //             .isSensorPrivacyEnabled(SensorPrivacyManager.Sensors.CAMERA, anyInt()))
384     //             .thenReturn(true);
385     //     when(mContext.getSystemService(SensorPrivacyManager.class))
386     //             .thenReturn(manager);
387     //     setupFace(1 /* id */, false /* confirmationAlwaysRequired */,
388     //             mock(IBiometricAuthenticator.class));
389     //     final PromptInfo promptInfo =
390     //             createPromptInfo(Authenticators.BIOMETRIC_STRONG
391     //             | Authenticators. DEVICE_CREDENTIAL);
392     //     final PreAuthInfo preAuthInfo = createPreAuthInfo(mSensors, 0, promptInfo, false);
393     //     assertEquals(BiometricManager.BIOMETRIC_SUCCESS, preAuthInfo.getCanAuthenticateResult());
394     //     for (BiometricSensor sensor : preAuthInfo.eligibleSensors) {
395     //         assertEquals(BiometricSensor.STATE_UNKNOWN, sensor.getSensorState());
396     //     }
397     // }
398 
testInvokesCancel(Consumer<AuthSession> sessionConsumer)399     private void testInvokesCancel(Consumer<AuthSession> sessionConsumer) throws RemoteException {
400         final IBiometricAuthenticator faceAuthenticator = mock(IBiometricAuthenticator.class);
401 
402         setupFace(0 /* id */, false /* confirmationAlwaysRequired */, faceAuthenticator);
403         final AuthSession session = createAuthSession(mSensors,
404                 false /* checkDevicePolicyManager */,
405                 Authenticators.BIOMETRIC_STRONG,
406                 TEST_REQUEST_ID,
407                 0 /* operationId */,
408                 0 /* userId */);
409 
410         session.goToInitialState();
411         assertEquals(STATE_AUTH_CALLED, session.getState());
412 
413         sessionConsumer.accept(session);
414 
415         verify(faceAuthenticator).cancelAuthenticationFromService(
416                 eq(mToken), eq(TEST_PACKAGE), eq(TEST_REQUEST_ID));
417     }
418 
createPreAuthInfo(List<BiometricSensor> sensors, int userId, PromptInfo promptInfo, boolean checkDevicePolicyManager)419     private PreAuthInfo createPreAuthInfo(List<BiometricSensor> sensors, int userId,
420             PromptInfo promptInfo, boolean checkDevicePolicyManager) throws RemoteException {
421         return PreAuthInfo.create(mTrustManager,
422                 mDevicePolicyManager,
423                 mSettingObserver,
424                 sensors,
425                 userId,
426                 promptInfo,
427                 TEST_PACKAGE,
428                 checkDevicePolicyManager,
429                 mContext);
430     }
431 
createAuthSession(List<BiometricSensor> sensors, boolean checkDevicePolicyManager, @Authenticators.Types int authenticators, long requestId, long operationId, int userId)432     private AuthSession createAuthSession(List<BiometricSensor> sensors,
433             boolean checkDevicePolicyManager, @Authenticators.Types int authenticators,
434             long requestId, long operationId, int userId) throws RemoteException {
435 
436         final PromptInfo promptInfo = createPromptInfo(authenticators);
437 
438         final PreAuthInfo preAuthInfo = createPreAuthInfo(sensors, userId, promptInfo,
439                 checkDevicePolicyManager);
440         return new AuthSession(mContext, mStatusBarService, mSysuiReceiver, mKeyStore,
441                 mRandom, mClientDeathReceiver, preAuthInfo, mToken, requestId, operationId, userId,
442                 mSensorReceiver, mClientReceiver, TEST_PACKAGE, promptInfo,
443                 false /* debugEnabled */, mFingerprintSensorProps);
444     }
445 
createPromptInfo(@uthenticators.Types int authenticators)446     private PromptInfo createPromptInfo(@Authenticators.Types int authenticators) {
447         PromptInfo promptInfo = new PromptInfo();
448         promptInfo.setAuthenticators(authenticators);
449         return promptInfo;
450     }
451 
setupFingerprint(int id, @FingerprintSensorProperties.SensorType int type)452     private void setupFingerprint(int id, @FingerprintSensorProperties.SensorType int type)
453             throws RemoteException {
454         IBiometricAuthenticator fingerprintAuthenticator = mock(IBiometricAuthenticator.class);
455         when(fingerprintAuthenticator.isHardwareDetected(any())).thenReturn(true);
456         when(fingerprintAuthenticator.hasEnrolledTemplates(anyInt(), any())).thenReturn(true);
457         mSensors.add(new BiometricSensor(mContext, id,
458                 TYPE_FINGERPRINT /* modality */,
459                 Authenticators.BIOMETRIC_STRONG /* strength */,
460                 fingerprintAuthenticator) {
461             @Override
462             boolean confirmationAlwaysRequired(int userId) {
463                 return false; // no-op / unsupported
464             }
465 
466             @Override
467             boolean confirmationSupported() {
468                 return false; // fingerprint does not support confirmation
469             }
470         });
471 
472         final List<ComponentInfoInternal> componentInfo = new ArrayList<>();
473         componentInfo.add(new ComponentInfoInternal("faceSensor" /* componentId */,
474                 "vendor/model/revision" /* hardwareVersion */, "1.01" /* firmwareVersion */,
475                 "00000001" /* serialNumber */, "" /* softwareVersion */));
476         componentInfo.add(new ComponentInfoInternal("matchingAlgorithm" /* componentId */,
477                 "" /* hardwareVersion */, "" /* firmwareVersion */, "" /* serialNumber */,
478                 "vendor/version/revision" /* softwareVersion */));
479 
480         mFingerprintSensorProps.add(new FingerprintSensorPropertiesInternal(id,
481                 SensorProperties.STRENGTH_STRONG,
482                 5 /* maxEnrollmentsPerUser */,
483                 componentInfo,
484                 type,
485                 false /* resetLockoutRequiresHardwareAuthToken */));
486 
487         when(mSettingObserver.getEnabledForApps(anyInt())).thenReturn(true);
488     }
489 
setupFace(int id, boolean confirmationAlwaysRequired, IBiometricAuthenticator authenticator)490     private void setupFace(int id, boolean confirmationAlwaysRequired,
491             IBiometricAuthenticator authenticator) throws RemoteException {
492         when(authenticator.isHardwareDetected(any())).thenReturn(true);
493         when(authenticator.hasEnrolledTemplates(anyInt(), any())).thenReturn(true);
494         mSensors.add(new BiometricSensor(mContext, id,
495                 TYPE_FACE /* modality */,
496                 Authenticators.BIOMETRIC_STRONG /* strength */,
497                 authenticator) {
498             @Override
499             boolean confirmationAlwaysRequired(int userId) {
500                 return confirmationAlwaysRequired;
501             }
502 
503             @Override
504             boolean confirmationSupported() {
505                 return true;
506             }
507         });
508 
509         when(mSettingObserver.getEnabledForApps(anyInt())).thenReturn(true);
510     }
511 }
512