• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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_ANY_BIOMETRIC;
20 import static android.hardware.biometrics.BiometricAuthenticator.TYPE_CREDENTIAL;
21 import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE;
22 import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
23 import static android.hardware.biometrics.BiometricManager.Authenticators;
24 import static android.view.DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS;
25 
26 import static com.android.server.biometrics.BiometricServiceStateProto.STATE_AUTHENTICATED_PENDING_SYSUI;
27 import static com.android.server.biometrics.BiometricServiceStateProto.STATE_AUTH_CALLED;
28 import static com.android.server.biometrics.BiometricServiceStateProto.STATE_AUTH_PAUSED;
29 import static com.android.server.biometrics.BiometricServiceStateProto.STATE_AUTH_PAUSED_RESUMING;
30 import static com.android.server.biometrics.BiometricServiceStateProto.STATE_AUTH_PENDING_CONFIRM;
31 import static com.android.server.biometrics.BiometricServiceStateProto.STATE_AUTH_STARTED;
32 import static com.android.server.biometrics.BiometricServiceStateProto.STATE_CLIENT_DIED_CANCELLING;
33 import static com.android.server.biometrics.BiometricServiceStateProto.STATE_ERROR_PENDING_SYSUI;
34 import static com.android.server.biometrics.BiometricServiceStateProto.STATE_SHOWING_DEVICE_CREDENTIAL;
35 
36 import static junit.framework.Assert.assertEquals;
37 import static junit.framework.Assert.assertFalse;
38 import static junit.framework.Assert.assertTrue;
39 import static junit.framework.TestCase.assertNotNull;
40 
41 import static org.junit.Assert.assertNotEquals;
42 import static org.junit.Assert.assertNull;
43 import static org.mockito.ArgumentMatchers.any;
44 import static org.mockito.ArgumentMatchers.anyBoolean;
45 import static org.mockito.ArgumentMatchers.anyInt;
46 import static org.mockito.ArgumentMatchers.anyLong;
47 import static org.mockito.ArgumentMatchers.anyString;
48 import static org.mockito.ArgumentMatchers.eq;
49 import static org.mockito.Mockito.mock;
50 import static org.mockito.Mockito.never;
51 import static org.mockito.Mockito.verify;
52 import static org.mockito.Mockito.verifyNoMoreInteractions;
53 import static org.mockito.Mockito.when;
54 
55 import android.app.IActivityManager;
56 import android.app.admin.DevicePolicyManager;
57 import android.app.trust.ITrustManager;
58 import android.content.ContentResolver;
59 import android.content.Context;
60 import android.content.pm.UserInfo;
61 import android.content.res.Resources;
62 import android.hardware.biometrics.BiometricAuthenticator;
63 import android.hardware.biometrics.BiometricConstants;
64 import android.hardware.biometrics.BiometricManager;
65 import android.hardware.biometrics.BiometricPrompt;
66 import android.hardware.biometrics.BiometricStateListener;
67 import android.hardware.biometrics.Flags;
68 import android.hardware.biometrics.IBiometricAuthenticator;
69 import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback;
70 import android.hardware.biometrics.IBiometricSensorReceiver;
71 import android.hardware.biometrics.IBiometricService;
72 import android.hardware.biometrics.IBiometricServiceReceiver;
73 import android.hardware.biometrics.IBiometricSysuiReceiver;
74 import android.hardware.biometrics.PromptInfo;
75 import android.hardware.biometrics.SensorProperties;
76 import android.hardware.display.DisplayManagerGlobal;
77 import android.hardware.face.FaceManager;
78 import android.hardware.face.FaceSensorProperties;
79 import android.hardware.face.FaceSensorPropertiesInternal;
80 import android.hardware.face.IFaceAuthenticatorsRegisteredCallback;
81 import android.hardware.fingerprint.FingerprintManager;
82 import android.hardware.fingerprint.FingerprintSensorProperties;
83 import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
84 import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback;
85 import android.hardware.keymaster.HardwareAuthenticatorType;
86 import android.os.Binder;
87 import android.os.Handler;
88 import android.os.IBinder;
89 import android.os.RemoteException;
90 import android.os.UserManager;
91 import android.platform.test.annotations.Presubmit;
92 import android.platform.test.annotations.RequiresFlagsDisabled;
93 import android.platform.test.annotations.RequiresFlagsEnabled;
94 import android.platform.test.flag.junit.CheckFlagsRule;
95 import android.platform.test.flag.junit.DeviceFlagsValueProvider;
96 import android.platform.test.flag.junit.SetFlagsRule;
97 import android.provider.Settings;
98 import android.security.GateKeeper;
99 import android.security.KeyStoreAuthorization;
100 import android.service.gatekeeper.IGateKeeperService;
101 import android.testing.AndroidTestingRunner;
102 import android.testing.TestableLooper;
103 import android.view.Display;
104 import android.view.DisplayInfo;
105 import android.view.WindowManager;
106 
107 import androidx.test.core.app.ApplicationProvider;
108 import androidx.test.filters.SmallTest;
109 
110 import com.android.internal.R;
111 import com.android.internal.statusbar.ISessionListener;
112 import com.android.internal.statusbar.IStatusBarService;
113 import com.android.server.biometrics.log.BiometricContextProvider;
114 import com.android.server.biometrics.sensors.AuthSessionCoordinator;
115 import com.android.server.biometrics.sensors.LockoutTracker;
116 
117 import org.junit.Before;
118 import org.junit.Rule;
119 import org.junit.Test;
120 import org.junit.runner.RunWith;
121 import org.mockito.AdditionalMatchers;
122 import org.mockito.ArgumentCaptor;
123 import org.mockito.Mock;
124 import org.mockito.MockitoAnnotations;
125 
126 import java.util.ArrayList;
127 import java.util.List;
128 import java.util.Random;
129 
130 @Presubmit
131 @SmallTest
132 @RunWith(AndroidTestingRunner.class)
133 @TestableLooper.RunWithLooper()
134 public class BiometricServiceTest {
135 
136     @Rule
137     public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
138     @Rule
139     public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
140 
141     private static final String TEST_PACKAGE_NAME = "test_package";
142     private static final long TEST_REQUEST_ID = 44;
143 
144     private static final String ERROR_HW_UNAVAILABLE = "hw_unavailable";
145     private static final String ERROR_NOT_RECOGNIZED = "not_recognized";
146     private static final String ERROR_TIMEOUT = "error_timeout";
147     private static final String ERROR_CANCELED = "error_canceled";
148     private static final String ERROR_UNABLE_TO_PROCESS = "error_unable_to_process";
149     private static final String ERROR_USER_CANCELED = "error_user_canceled";
150     private static final String ERROR_LOCKOUT = "error_lockout";
151     private static final String FACE_SUBTITLE = "face_subtitle";
152     private static final String FINGERPRINT_SUBTITLE = "fingerprint_subtitle";
153     private static final String CREDENTIAL_SUBTITLE = "credential_subtitle";
154     private static final String DEFAULT_SUBTITLE = "default_subtitle";
155 
156     private static final String FINGERPRINT_ACQUIRED_SENSOR_DIRTY = "sensor_dirty";
157 
158     private static final int SENSOR_ID_FINGERPRINT = 0;
159     private static final int SENSOR_ID_FACE = 1;
160     private final ArgumentCaptor<IFingerprintAuthenticatorsRegisteredCallback.Stub>
161             mFingerprintAuthenticatorRegisteredCallbackCaptor = ArgumentCaptor.forClass(
162             IFingerprintAuthenticatorsRegisteredCallback.Stub.class);
163     private final ArgumentCaptor<IFaceAuthenticatorsRegisteredCallback.Stub>
164             mFaceAuthenticatorRegisteredCallbackCaptor = ArgumentCaptor.forClass(
165             IFaceAuthenticatorsRegisteredCallback.Stub.class);
166     private final ArgumentCaptor<BiometricStateListener> mBiometricStateListenerArgumentCaptor =
167             ArgumentCaptor.forClass(BiometricStateListener.class);
168     private final List<FingerprintSensorPropertiesInternal>
169             mFingerprintSensorPropertiesInternals = List.of(
170                     new FingerprintSensorPropertiesInternal(SENSOR_ID_FINGERPRINT,
171                             SensorProperties.STRENGTH_STRONG, 5 /* maxEnrollmentsPerUser */,
172                             List.of(), FingerprintSensorProperties.TYPE_UNKNOWN,
173                             true /* resetLockoutRequiresHardwareAuthToken */));
174     private final List<FaceSensorPropertiesInternal>
175             mFaceSensorPropertiesInternals = List.of(
176                     new FaceSensorPropertiesInternal(SENSOR_ID_FACE,
177                             SensorProperties.STRENGTH_STRONG, 5 /* maxEnrollmentsPerUser */,
178                             List.of(), FaceSensorProperties.TYPE_UNKNOWN,
179                             false /* supportsFaceDetection */, false /* supportsSelfIllumination */,
180                             false /* resetLockoutRequiresChallenge */));
181 
182     private BiometricService mBiometricService;
183 
184     @Mock
185     private Context mContext;
186     @Mock
187     private ContentResolver mContentResolver;
188     @Mock
189     private Resources mResources;
190     @Mock
191     IBiometricServiceReceiver mReceiver1;
192     @Mock
193     IBiometricServiceReceiver mReceiver2;
194     @Mock
195     BiometricService.Injector mInjector;
196     @Mock
197     IBiometricAuthenticator mFingerprintAuthenticator;
198     @Mock
199     IBiometricAuthenticator mFaceAuthenticator;
200     @Mock
201     IBiometricAuthenticator mCredentialAuthenticator;
202     @Mock
203     ITrustManager mTrustManager;
204     @Mock
205     DevicePolicyManager mDevicePolicyManager;
206     @Mock
207     private WindowManager mWindowManager;
208     @Mock
209     private IStatusBarService mStatusBarService;
210     @Mock
211     private ISessionListener mSessionListener;
212     @Mock
213     private AuthSessionCoordinator mAuthSessionCoordinator;
214     @Mock
215     private UserManager mUserManager;
216     @Mock
217     private BiometricCameraManager mBiometricCameraManager;
218     @Mock
219     private BiometricHandlerProvider mBiometricHandlerProvider;
220 
221     @Mock
222     private KeyStoreAuthorization mKeyStoreAuthorization;
223 
224     @Mock
225     private IGateKeeperService mGateKeeperService;
226 
227     @Mock
228     private BiometricNotificationLogger mNotificationLogger;
229     @Mock
230     private FingerprintManager mFingerprintManager;
231     @Mock
232     private FaceManager mFaceManager;
233 
234     BiometricContextProvider mBiometricContextProvider;
235 
236     @Before
setUp()237     public void setUp() throws RemoteException {
238         MockitoAnnotations.initMocks(this);
239 
240         resetReceivers();
241 
242         when(mContext.getContentResolver()).thenReturn(mContentResolver);
243         when(mContext.getResources()).thenReturn(mResources);
244         when(mContext.getSystemService(Context.DEVICE_POLICY_SERVICE))
245                 .thenReturn(mDevicePolicyManager);
246 
247         when(mInjector.getActivityManagerService()).thenReturn(mock(IActivityManager.class));
248         when(mInjector.getStatusBarService()).thenReturn(mock(IStatusBarService.class));
249         when(mInjector.getSettingObserver(any(), any(), any()))
250                 .thenReturn(mock(BiometricService.SettingObserver.class));
251         when(mInjector.getKeyStoreAuthorization()).thenReturn(mock(KeyStoreAuthorization.class));
252         when(mInjector.isDebugEnabled(any(), anyInt())).thenReturn(false);
253         when(mInjector.getBiometricStrengthController(any()))
254                 .thenReturn(mock(BiometricStrengthController.class));
255         when(mInjector.getTrustManager()).thenReturn(mTrustManager);
256         when(mInjector.getDevicePolicyManager(any())).thenReturn(mDevicePolicyManager);
257         when(mInjector.getRequestGenerator()).thenReturn(() -> TEST_REQUEST_ID);
258         when(mInjector.getUserManager(any())).thenReturn(mUserManager);
259         when(mInjector.getBiometricCameraManager(any())).thenReturn(mBiometricCameraManager);
260 
261         when(mResources.getString(R.string.biometric_error_hw_unavailable))
262                 .thenReturn(ERROR_HW_UNAVAILABLE);
263         when(mResources.getString(R.string.biometric_not_recognized))
264                 .thenReturn(ERROR_NOT_RECOGNIZED);
265         when(mResources.getString(R.string.biometric_face_not_recognized))
266                 .thenReturn(ERROR_NOT_RECOGNIZED);
267         when(mResources.getString(R.string.fingerprint_error_not_match))
268                 .thenReturn(ERROR_NOT_RECOGNIZED);
269         when(mResources.getString(R.string.biometric_error_user_canceled))
270                 .thenReturn(ERROR_USER_CANCELED);
271         when(mContext.getString(R.string.face_dialog_default_subtitle))
272                 .thenReturn(FACE_SUBTITLE);
273         when(mContext.getString(R.string.fingerprint_dialog_default_subtitle))
274                 .thenReturn(FINGERPRINT_SUBTITLE);
275         when(mContext.getString(R.string.screen_lock_dialog_default_subtitle))
276                 .thenReturn(CREDENTIAL_SUBTITLE);
277         when(mContext.getString(R.string.biometric_dialog_default_subtitle))
278                 .thenReturn(DEFAULT_SUBTITLE);
279 
280         when(mWindowManager.getDefaultDisplay()).thenReturn(
281                 new Display(DisplayManagerGlobal.getInstance(), Display.DEFAULT_DISPLAY,
282                         new DisplayInfo(), DEFAULT_DISPLAY_ADJUSTMENTS));
283         mBiometricContextProvider = new BiometricContextProvider(mContext, mWindowManager,
284                 mStatusBarService, null /* handler */,
285                 mAuthSessionCoordinator);
286         when(mInjector.getBiometricContext(any())).thenReturn(mBiometricContextProvider);
287         when(mInjector.getKeyStoreAuthorization()).thenReturn(mKeyStoreAuthorization);
288         when(mInjector.getGateKeeperService()).thenReturn(mGateKeeperService);
289         when(mInjector.getNotificationLogger()).thenReturn(mNotificationLogger);
290         when(mGateKeeperService.getSecureUserId(anyInt())).thenReturn(42L);
291         when(mBiometricHandlerProvider.getBiometricCallbackHandler()).thenReturn(
292                 new Handler(TestableLooper.get(this).getLooper()));
293 
294         final String[] config = {
295                 "0:2:15",  // ID0:Fingerprint:Strong
296                 "1:8:15",  // ID1:Face:Strong
297                 "2:4:255", // ID2:Iris:Weak
298         };
299 
300         when(mInjector.getConfiguration(any())).thenReturn(config);
301     }
302 
303     @Test
testClientBinderDied_whenPaused()304     public void testClientBinderDied_whenPaused() throws Exception {
305         setupAuthForOnly(TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
306 
307         invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
308                 true /* requireConfirmation */, null /* authenticators */);
309         waitForIdle();
310         verify(mReceiver1.asBinder()).linkToDeath(eq(mBiometricService.mAuthSession),
311                 anyInt());
312 
313         mBiometricService.mAuthSession.mSensorReceiver.onError(
314                 SENSOR_ID_FACE,
315                 getCookieForCurrentSession(mBiometricService.mAuthSession),
316                 BiometricConstants.BIOMETRIC_ERROR_TIMEOUT,
317                 0 /* vendorCode */);
318         waitForIdle();
319 
320         assertEquals(STATE_AUTH_PAUSED, mBiometricService.mAuthSession.getState());
321 
322         mBiometricService.mAuthSession.binderDied();
323         waitForIdle();
324 
325         assertNull(mBiometricService.mAuthSession);
326         verify(mBiometricService.mStatusBarService).hideAuthenticationDialog(eq(TEST_REQUEST_ID));
327         verify(mReceiver1, never()).onError(anyInt(), anyInt(), anyInt());
328     }
329 
330     @Test
testClientBinderDied_whenAuthenticating()331     public void testClientBinderDied_whenAuthenticating() throws Exception {
332         setupAuthForOnly(TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
333 
334         invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
335                 true /* requireConfirmation */, null /* authenticators */);
336         waitForIdle();
337         verify(mReceiver1.asBinder()).linkToDeath(eq(mBiometricService.mAuthSession),
338                 anyInt());
339 
340         assertEquals(STATE_AUTH_STARTED, mBiometricService.mAuthSession.getState());
341         mBiometricService.mAuthSession.binderDied();
342         waitForIdle();
343 
344         assertNotNull(mBiometricService.mAuthSession);
345         verify(mBiometricService.mStatusBarService, never())
346                 .hideAuthenticationDialog(eq(TEST_REQUEST_ID));
347         assertEquals(STATE_CLIENT_DIED_CANCELLING,
348                 mBiometricService.mAuthSession.getState());
349 
350         verify(mBiometricService.mAuthSession.mPreAuthInfo.eligibleSensors.get(0).impl)
351                 .cancelAuthenticationFromService(any(), any(), anyLong());
352 
353         // Simulate ERROR_CANCELED received from HAL
354         mBiometricService.mAuthSession.mSensorReceiver.onError(
355                 SENSOR_ID_FACE,
356                 getCookieForCurrentSession(mBiometricService.mAuthSession),
357                 BiometricConstants.BIOMETRIC_ERROR_CANCELED,
358                 0 /* vendorCode */);
359         waitForIdle();
360         verify(mBiometricService.mStatusBarService).hideAuthenticationDialog(eq(TEST_REQUEST_ID));
361         verify(mReceiver1, never()).onError(anyInt(), anyInt(), anyInt());
362         assertNull(mBiometricService.mAuthSession);
363     }
364 
365     @Test
testAuthenticate_credentialAllowedButNotSetup_returnsNoDeviceCredential()366     public void testAuthenticate_credentialAllowedButNotSetup_returnsNoDeviceCredential()
367             throws Exception {
368         when(mTrustManager.isDeviceSecure(anyInt(), anyInt()))
369                 .thenReturn(false);
370 
371         mBiometricService = new BiometricService(mContext, mInjector, mBiometricHandlerProvider);
372         mBiometricService.onStart();
373 
374         invokeAuthenticate(mBiometricService.mImpl, mReceiver1, false /* requireConfirmation */,
375                 Authenticators.DEVICE_CREDENTIAL, false /* useDefaultSubtitle */,
376                 false /* deviceCredentialAllowed */);
377         waitForIdle();
378         verify(mReceiver1).onError(
379                 eq(BiometricAuthenticator.TYPE_CREDENTIAL),
380                 eq(BiometricConstants.BIOMETRIC_ERROR_NO_DEVICE_CREDENTIAL),
381                 eq(0 /* vendorCode */));
382     }
383 
384     @Test
testAuthenticate_credentialAllowedAndSetup_callsSystemUI()385     public void testAuthenticate_credentialAllowedAndSetup_callsSystemUI() throws Exception {
386         // When no biometrics are enrolled, but credentials are set up, status bar should be
387         // invoked right away with showAuthenticationDialog
388 
389         when(mTrustManager.isDeviceSecure(anyInt(), anyInt()))
390                 .thenReturn(true);
391 
392         mBiometricService = new BiometricService(mContext, mInjector, mBiometricHandlerProvider);
393         mBiometricService.onStart();
394 
395         invokeAuthenticate(mBiometricService.mImpl, mReceiver1, false /* requireConfirmation */,
396                 Authenticators.DEVICE_CREDENTIAL, false /* useDefaultSubtitle */,
397                 false /* deviceCredentialAllowed */);
398         waitForIdle();
399 
400         assertNotNull(mBiometricService.mAuthSession);
401         assertEquals(STATE_SHOWING_DEVICE_CREDENTIAL,
402                 mBiometricService.mAuthSession.getState());
403         // StatusBar showBiometricDialog invoked
404         verify(mBiometricService.mStatusBarService).showAuthenticationDialog(
405                 eq(mBiometricService.mAuthSession.mPromptInfo),
406                 any(IBiometricSysuiReceiver.class),
407                 AdditionalMatchers.aryEq(new int[0]) /* sensorIds */,
408                 eq(true) /* credentialAllowed */,
409                 anyBoolean() /* requireConfirmation */,
410                 anyInt() /* userId */,
411                 anyLong() /* operationId */,
412                 eq(TEST_PACKAGE_NAME),
413                 eq(TEST_REQUEST_ID));
414     }
415 
416     @Test
testAuthenticate_withoutHardware_returnsErrorHardwareNotPresent()417     public void testAuthenticate_withoutHardware_returnsErrorHardwareNotPresent() throws
418             Exception {
419         mBiometricService = new BiometricService(mContext, mInjector, mBiometricHandlerProvider);
420         mBiometricService.onStart();
421 
422         invokeAuthenticate(mBiometricService.mImpl, mReceiver1, false /* requireConfirmation */,
423                 null /* authenticators */, false /* useDefaultSubtitle */,
424                 false /* deviceCredentialAllowed */);
425         waitForIdle();
426         verify(mReceiver1).onError(
427                 eq(BiometricAuthenticator.TYPE_NONE),
428                 eq(BiometricConstants.BIOMETRIC_ERROR_HW_NOT_PRESENT),
429                 eq(0 /* vendorCode */));
430     }
431 
432     @Test
testAuthenticate_withoutEnrolled_returnsErrorNoBiometrics()433     public void testAuthenticate_withoutEnrolled_returnsErrorNoBiometrics() throws Exception {
434         when(mFingerprintAuthenticator.isHardwareDetected(any())).thenReturn(true);
435 
436         mBiometricService = new BiometricService(mContext, mInjector, mBiometricHandlerProvider);
437         mBiometricService.onStart();
438         mBiometricService.mImpl.registerAuthenticator(0 /* id */,
439                 TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG,
440                 mFingerprintAuthenticator);
441 
442         invokeAuthenticate(mBiometricService.mImpl, mReceiver1, false /* requireConfirmation */,
443                 null /* authenticators */, false /* useDefaultSubtitle */,
444                 false /* deviceCredentialAllowed */);
445         waitForIdle();
446         verify(mReceiver1).onError(
447                 eq(TYPE_FINGERPRINT),
448                 eq(BiometricConstants.BIOMETRIC_ERROR_NO_BIOMETRICS),
449                 eq(0 /* vendorCode */));
450     }
451 
452     @Test
testAuthenticate_notStrongEnough_returnsHardwareNotPresent()453     public void testAuthenticate_notStrongEnough_returnsHardwareNotPresent() throws Exception {
454         setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_WEAK);
455 
456         invokeAuthenticate(mBiometricService.mImpl, mReceiver1, false /* requireConfirmation */,
457                 Authenticators.BIOMETRIC_STRONG, false /* useDefaultSubtitle */,
458                 false /* deviceCredentialAllowed */);
459         waitForIdle();
460         verify(mReceiver1).onError(
461                 eq(BiometricAuthenticator.TYPE_NONE),
462                 eq(BiometricConstants.BIOMETRIC_ERROR_HW_NOT_PRESENT),
463                 eq(0 /* vendorCode */));
464     }
465 
466     @Test
testAuthenticate_picksStrongIfAvailable()467     public void testAuthenticate_picksStrongIfAvailable() throws Exception {
468         // If both strong and weak are available, and the caller requires STRONG, authentication
469         // is able to proceed.
470 
471         final int[] modalities = new int[] {
472                 TYPE_FINGERPRINT,
473                 TYPE_FACE,
474         };
475 
476         final int[] strengths = new int[] {
477                 Authenticators.BIOMETRIC_WEAK,
478                 Authenticators.BIOMETRIC_STRONG,
479         };
480 
481         setupAuthForMultiple(modalities, strengths);
482 
483         invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
484                 false /* requireConfirmation */, Authenticators.BIOMETRIC_STRONG);
485         waitForIdle();
486         verify(mReceiver1, never()).onError(
487                 anyInt(),
488                 anyInt(),
489                 anyInt() /* vendorCode */);
490 
491         // StatusBar showBiometricDialog invoked with face, which was set up to be STRONG
492         verify(mBiometricService.mStatusBarService).showAuthenticationDialog(
493                 eq(mBiometricService.mAuthSession.mPromptInfo),
494                 any(IBiometricSysuiReceiver.class),
495                 AdditionalMatchers.aryEq(new int[] {SENSOR_ID_FACE}),
496                 eq(false) /* credentialAllowed */,
497                 eq(false) /* requireConfirmation */,
498                 anyInt() /* userId */,
499                 anyLong() /* operationId */,
500                 eq(TEST_PACKAGE_NAME),
501                 eq(TEST_REQUEST_ID));
502     }
503 
504     @Test
testAuthenticate_whenHalIsDead_returnsErrorHardwareUnavailable()505     public void testAuthenticate_whenHalIsDead_returnsErrorHardwareUnavailable() throws
506             Exception {
507         when(mFingerprintAuthenticator.hasEnrolledTemplates(anyInt(), any())).thenReturn(true);
508         when(mFingerprintAuthenticator.isHardwareDetected(any())).thenReturn(false);
509 
510         mBiometricService = new BiometricService(mContext, mInjector, mBiometricHandlerProvider);
511         mBiometricService.onStart();
512         mBiometricService.mImpl.registerAuthenticator(0 /* id */,
513                 TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG,
514                 mFingerprintAuthenticator);
515 
516         invokeAuthenticate(mBiometricService.mImpl, mReceiver1, false /* requireConfirmation */,
517                 null /* authenticators */, false /* useDefaultSubtitle */,
518                 false /* deviceCredentialAllowed */);
519         waitForIdle();
520         verify(mReceiver1).onError(
521                 eq(TYPE_FINGERPRINT),
522                 eq(BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE),
523                 eq(0 /* vendorCode */));
524     }
525 
526     @Test
testAuthenticateFace_shouldShowSubtitleForFace()527     public void testAuthenticateFace_shouldShowSubtitleForFace() throws Exception {
528         setupAuthForOnly(TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
529 
530         invokeAuthenticate(mBiometricService.mImpl, mReceiver1, false /* requireConfirmation */,
531                 null /* authenticators */, true /* useDefaultSubtitle */,
532                 false /* deviceCredentialAllowed */);
533         waitForIdle();
534 
535         assertEquals(FACE_SUBTITLE, mBiometricService.mAuthSession.mPromptInfo.getSubtitle());
536     }
537 
538     @Test
testAuthenticateFingerprint_shouldShowSubtitleForFingerprint()539     public void testAuthenticateFingerprint_shouldShowSubtitleForFingerprint() throws Exception {
540         setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
541 
542         invokeAuthenticate(mBiometricService.mImpl, mReceiver1, false /* requireConfirmation */,
543                 null /* authenticators */, true /* useDefaultSubtitle */,
544                 false /* deviceCredentialAllowed */);
545         waitForIdle();
546 
547         assertEquals(FINGERPRINT_SUBTITLE,
548                 mBiometricService.mAuthSession.mPromptInfo.getSubtitle());
549     }
550 
551     @Test
testAuthenticateFingerprint_shouldShowSubtitleForCredential()552     public void testAuthenticateFingerprint_shouldShowSubtitleForCredential() throws Exception {
553         setupAuthForOnly(TYPE_CREDENTIAL, Authenticators.DEVICE_CREDENTIAL);
554 
555         invokeAuthenticate(mBiometricService.mImpl, mReceiver1, false /* requireConfirmation */,
556                 null /* authenticators */, true /* useDefaultSubtitle */,
557                 true /* deviceCredentialAllowed */);
558         waitForIdle();
559 
560         assertEquals(CREDENTIAL_SUBTITLE,
561                 mBiometricService.mAuthSession.mPromptInfo.getSubtitle());
562     }
563 
564     @Test
testAuthenticateBothFpAndFace_shouldShowDefaultSubtitle()565     public void testAuthenticateBothFpAndFace_shouldShowDefaultSubtitle() throws Exception {
566         final int[] modalities = new int[] {
567                 TYPE_FINGERPRINT,
568                 TYPE_FACE,
569         };
570 
571         final int[] strengths = new int[] {
572                 Authenticators.BIOMETRIC_WEAK,
573                 Authenticators.BIOMETRIC_STRONG,
574         };
575 
576         setupAuthForMultiple(modalities, strengths);
577 
578         invokeAuthenticate(mBiometricService.mImpl, mReceiver1, false /* requireConfirmation */,
579                 null /* authenticators */, true /* useDefaultSubtitle */,
580                 false /* deviceCredentialAllowed */);
581         waitForIdle();
582 
583         assertEquals(DEFAULT_SUBTITLE, mBiometricService.mAuthSession.mPromptInfo.getSubtitle());
584     }
585 
586     @Test
testAuthenticateFace_respectsUserSetting()587     public void testAuthenticateFace_respectsUserSetting()
588             throws Exception {
589         setupAuthForOnly(TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
590 
591         // Disabled in user settings receives onError
592         when(mBiometricService.mSettingObserver.getEnabledForApps(anyInt(), anyInt()))
593                 .thenReturn(false);
594         invokeAuthenticate(mBiometricService.mImpl, mReceiver1, false /* requireConfirmation */,
595                 null /* authenticators */, false /* useDefaultSubtitle */,
596                 false /* deviceCredentialAllowed */);
597         waitForIdle();
598         verify(mReceiver1).onError(
599                 eq(BiometricAuthenticator.TYPE_NONE),
600                 eq(Flags.mandatoryBiometrics()
601                         ? BiometricConstants.BIOMETRIC_ERROR_NOT_ENABLED_FOR_APPS
602                         : BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE),
603                 eq(0 /* vendorCode */));
604 
605         // Enrolled, not disabled in settings, user requires confirmation in settings
606         resetReceivers();
607         when(mBiometricService.mSettingObserver.getEnabledForApps(anyInt(), anyInt()))
608                 .thenReturn(true);
609         when(mBiometricService.mSettingObserver.getConfirmationAlwaysRequired(
610                 anyInt() /* modality */, anyInt() /* userId */))
611                 .thenReturn(true);
612         invokeAuthenticate(mBiometricService.mImpl, mReceiver1, false /* requireConfirmation */,
613                 null /* authenticators */, false /* useDefaultSubtitle */,
614                 false /* deviceCredentialAllowed */);
615         waitForIdle();
616         verify(mReceiver1, never()).onError(anyInt(), anyInt(), anyInt());
617         final byte[] HAT = generateRandomHAT();
618         mBiometricService.mAuthSession.mSensorReceiver.onAuthenticationSucceeded(
619                 SENSOR_ID_FACE,
620                 HAT);
621         waitForIdle();
622         // Confirmation is required
623         assertEquals(STATE_AUTH_PENDING_CONFIRM,
624                 mBiometricService.mAuthSession.getState());
625 
626         // Enrolled, not disabled in settings, user doesn't require confirmation in settings
627         resetReceivers();
628         when(mBiometricService.mSettingObserver.getConfirmationAlwaysRequired(
629                 anyInt() /* modality */, anyInt() /* userId */))
630                 .thenReturn(false);
631         invokeAuthenticate(mBiometricService.mImpl, mReceiver1, false /* requireConfirmation */,
632                 null /* authenticators */, false /* useDefaultSubtitle */,
633                 false /* deviceCredentialAllowed */);
634         waitForIdle();
635         mBiometricService.mAuthSession.mSensorReceiver.onAuthenticationSucceeded(
636                 SENSOR_ID_FACE,
637                 HAT);
638         waitForIdle();
639         // Confirmation not required, waiting for dialog to dismiss
640         assertEquals(STATE_AUTHENTICATED_PENDING_SYSUI,
641                 mBiometricService.mAuthSession.getState());
642 
643     }
644 
645     @Test
testAuthenticate_happyPathWithoutConfirmation_strongBiometric()646     public void testAuthenticate_happyPathWithoutConfirmation_strongBiometric() throws Exception {
647         setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
648         testAuthenticate_happyPathWithoutConfirmation(true /* isStrongBiometric */);
649     }
650 
651     @Test
testAuthenticate_happyPathWithoutConfirmation_weakBiometric()652     public void testAuthenticate_happyPathWithoutConfirmation_weakBiometric() throws Exception {
653         setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_WEAK);
654         testAuthenticate_happyPathWithoutConfirmation(false /* isStrongBiometric */);
655     }
656 
testAuthenticate_happyPathWithoutConfirmation(boolean isStrongBiometric)657     private void testAuthenticate_happyPathWithoutConfirmation(boolean isStrongBiometric)
658             throws Exception {
659         // Start testing the happy path
660         invokeAuthenticate(mBiometricService.mImpl, mReceiver1, false /* requireConfirmation */,
661                 null /* authenticators */, false /* useDefaultSubtitle */,
662                 false /* deviceCredentialAllowed */);
663         waitForIdle();
664 
665         // Creates a pending auth session with the correct initial states
666         assertEquals(STATE_AUTH_CALLED, mBiometricService.mAuthSession.getState());
667 
668         // Invokes <Modality>Service#prepareForAuthentication
669         ArgumentCaptor<Integer> cookieCaptor = ArgumentCaptor.forClass(Integer.class);
670         verify(mReceiver1, never()).onError(anyInt(), anyInt(), anyInt());
671         verify(mBiometricService.mSensors.get(0).impl).prepareForAuthentication(
672                 eq(false) /* requireConfirmation */,
673                 any(IBinder.class),
674                 anyLong() /* sessionId */,
675                 anyInt() /* userId */,
676                 any(IBiometricSensorReceiver.class),
677                 anyString() /* opPackageName */,
678                 eq(TEST_REQUEST_ID),
679                 cookieCaptor.capture() /* cookie */,
680                 anyBoolean() /* allowBackgroundAuthentication */,
681                 anyBoolean() /* isForLegacyFingerprintManager */,
682                 eq(false) /* isMandatoryBiometrics */);
683 
684         // onReadyForAuthentication, mAuthSession state OK
685         mBiometricService.mImpl.onReadyForAuthentication(TEST_REQUEST_ID, cookieCaptor.getValue());
686         waitForIdle();
687         assertEquals(STATE_AUTH_STARTED, mBiometricService.mAuthSession.getState());
688 
689         // startPreparedClient invoked
690         mBiometricService.mAuthSession.onDialogAnimatedIn(true /* startFingerprintNow */);
691         verify(mBiometricService.mSensors.get(0).impl)
692                 .startPreparedClient(cookieCaptor.getValue());
693 
694         // StatusBar showBiometricDialog invoked
695         verify(mBiometricService.mStatusBarService).showAuthenticationDialog(
696                 eq(mBiometricService.mAuthSession.mPromptInfo),
697                 any(IBiometricSysuiReceiver.class),
698                 any(),
699                 eq(false) /* credentialAllowed */,
700                 anyBoolean() /* requireConfirmation */,
701                 anyInt() /* userId */,
702                 anyLong() /* operationId */,
703                 eq(TEST_PACKAGE_NAME),
704                 eq(TEST_REQUEST_ID));
705 
706         // Hardware authenticated
707         final byte[] HAT = generateRandomHAT();
708         mBiometricService.mAuthSession.mSensorReceiver.onAuthenticationSucceeded(
709                 SENSOR_ID_FINGERPRINT,
710                 HAT);
711         waitForIdle();
712         // Waiting for SystemUI to send dismissed callback
713         assertEquals(STATE_AUTHENTICATED_PENDING_SYSUI,
714                 mBiometricService.mAuthSession.getState());
715         // Notify SystemUI hardware authenticated
716         verify(mBiometricService.mStatusBarService).onBiometricAuthenticated(TYPE_FINGERPRINT);
717 
718         // SystemUI sends callback with dismissed reason
719         mBiometricService.mAuthSession.mSysuiReceiver.onDialogDismissed(
720                 BiometricPrompt.DISMISSED_REASON_BIOMETRIC_CONFIRM_NOT_REQUIRED,
721                 null /* credentialAttestation */);
722         waitForIdle();
723         // HAT sent to keystore
724         if (isStrongBiometric) {
725             verify(mKeyStoreAuthorization).addAuthToken(AdditionalMatchers.aryEq(HAT));
726         } else {
727             verify(mKeyStoreAuthorization, never()).addAuthToken(any(byte[].class));
728         }
729         // Send onAuthenticated to client
730         verify(mReceiver1).onAuthenticationSucceeded(
731                 BiometricPrompt.AUTHENTICATION_RESULT_TYPE_BIOMETRIC);
732         // Current session becomes null
733         assertNull(mBiometricService.mAuthSession);
734     }
735 
736     @Test
testAuthenticate_noBiometrics_credentialAllowed()737     public void testAuthenticate_noBiometrics_credentialAllowed() throws Exception {
738         setupAuthForOnly(TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
739         when(mFaceAuthenticator.hasEnrolledTemplates(anyInt(), any())).thenReturn(false);
740         when(mTrustManager.isDeviceSecure(anyInt(), anyInt()))
741                 .thenReturn(true);
742         invokeAuthenticate(mBiometricService.mImpl, mReceiver1,
743                 true /* requireConfirmation */,
744                 Authenticators.DEVICE_CREDENTIAL | Authenticators.BIOMETRIC_WEAK,
745                 false /* useDefaultSubtitle*/, false /* deviceCredentialAllowed */);
746         waitForIdle();
747 
748         assertEquals(STATE_SHOWING_DEVICE_CREDENTIAL,
749                 mBiometricService.mAuthSession.getState());
750         assertEquals(Authenticators.DEVICE_CREDENTIAL,
751                 mBiometricService.mAuthSession.mPromptInfo.getAuthenticators());
752         verify(mBiometricService.mStatusBarService).showAuthenticationDialog(
753                 eq(mBiometricService.mAuthSession.mPromptInfo),
754                 any(IBiometricSysuiReceiver.class),
755                 AdditionalMatchers.aryEq(new int[0]) /* sensorIds */,
756                 eq(true) /* credentialAllowed */,
757                 anyBoolean() /* requireConfirmation */,
758                 anyInt() /* userId */,
759                 anyLong() /* operationId */,
760                 eq(TEST_PACKAGE_NAME),
761                 eq(TEST_REQUEST_ID));
762     }
763 
764     @Test
testAuthenticate_happyPathWithConfirmation_strongBiometric()765     public void testAuthenticate_happyPathWithConfirmation_strongBiometric() throws Exception {
766         setupAuthForOnly(TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
767         testAuthenticate_happyPathWithConfirmation(true /* isStrongBiometric */);
768     }
769 
770     @Test
testAuthenticate_happyPathWithConfirmation_weakBiometric()771     public void testAuthenticate_happyPathWithConfirmation_weakBiometric() throws Exception {
772         setupAuthForOnly(TYPE_FACE, Authenticators.BIOMETRIC_WEAK);
773         testAuthenticate_happyPathWithConfirmation(false /* isStrongBiometric */);
774     }
775 
testAuthenticate_happyPathWithConfirmation(boolean isStrongBiometric)776     private void testAuthenticate_happyPathWithConfirmation(boolean isStrongBiometric)
777             throws Exception {
778         invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
779                 true /* requireConfirmation */, null /* authenticators */);
780 
781         // Test authentication succeeded goes to PENDING_CONFIRMATION and that the HAT is not
782         // sent to KeyStore yet
783         final byte[] HAT = generateRandomHAT();
784         mBiometricService.mAuthSession.mSensorReceiver.onAuthenticationSucceeded(
785                 SENSOR_ID_FACE,
786                 HAT);
787         waitForIdle();
788         // Waiting for SystemUI to send confirmation callback
789         assertEquals(STATE_AUTH_PENDING_CONFIRM, mBiometricService.mAuthSession.getState());
790         verify(mKeyStoreAuthorization, never()).addAuthToken(any(byte[].class));
791 
792         // SystemUI sends confirm, HAT is sent to keystore and client is notified.
793         mBiometricService.mAuthSession.mSysuiReceiver.onDialogDismissed(
794                 BiometricPrompt.DISMISSED_REASON_BIOMETRIC_CONFIRMED,
795                 null /* credentialAttestation */);
796         waitForIdle();
797         if (isStrongBiometric) {
798             verify(mKeyStoreAuthorization).addAuthToken(AdditionalMatchers.aryEq(HAT));
799         } else {
800             verify(mKeyStoreAuthorization, never()).addAuthToken(any(byte[].class));
801         }
802         verify(mReceiver1).onAuthenticationSucceeded(
803                 BiometricPrompt.AUTHENTICATION_RESULT_TYPE_BIOMETRIC);
804     }
805 
806     @Test
testAuthenticate_no_Biometrics_noCredential()807     public void testAuthenticate_no_Biometrics_noCredential() throws Exception {
808         setupAuthForOnly(TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
809         when(mFaceAuthenticator.hasEnrolledTemplates(anyInt(), any())).thenReturn(false);
810         when(mTrustManager.isDeviceSecure(anyInt(), anyInt()))
811                 .thenReturn(false);
812 
813         invokeAuthenticate(mBiometricService.mImpl, mReceiver1,
814                 true /* requireConfirmation */,
815                 Authenticators.DEVICE_CREDENTIAL | Authenticators.BIOMETRIC_STRONG,
816                 false /* useDefaultSubtitle */, false /* deviceCredentialAllowed */);
817         waitForIdle();
818 
819         verify(mReceiver1).onError(anyInt() /* modality */,
820                 eq(BiometricConstants.BIOMETRIC_ERROR_NO_BIOMETRICS)/* error */,
821                 eq(0) /* vendorCode */);
822     }
823 
824     @Test
testRejectFace_whenAuthenticating_notifiesSystemUIAndClient_thenPaused()825     public void testRejectFace_whenAuthenticating_notifiesSystemUIAndClient_thenPaused()
826             throws Exception {
827         setupAuthForOnly(TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
828         invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
829                 false /* requireConfirmation */, null /* authenticators */);
830 
831         mBiometricService.mAuthSession.mSensorReceiver.onAuthenticationFailed(SENSOR_ID_FACE);
832         waitForIdle();
833 
834         verify(mBiometricService.mStatusBarService).onBiometricError(
835                 eq(TYPE_FACE),
836                 eq(BiometricConstants.BIOMETRIC_PAUSED_REJECTED),
837                 eq(0 /* vendorCode */));
838         verify(mReceiver1).onAuthenticationFailed();
839         assertEquals(STATE_AUTH_PAUSED, mBiometricService.mAuthSession.getState());
840     }
841 
842     @Test
testRejectFingerprint_whenAuthenticating_notifiesAndKeepsAuthenticating()843     public void testRejectFingerprint_whenAuthenticating_notifiesAndKeepsAuthenticating()
844             throws Exception {
845         setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
846         invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
847                 false /* requireConfirmation */, null /* authenticators */);
848 
849         mBiometricService.mAuthSession.mSensorReceiver
850                 .onAuthenticationFailed(SENSOR_ID_FINGERPRINT);
851         waitForIdle();
852 
853         verify(mBiometricService.mStatusBarService).onBiometricError(
854                 eq(TYPE_FINGERPRINT),
855                 eq(BiometricConstants.BIOMETRIC_PAUSED_REJECTED),
856                 eq(0 /* vendorCode */));
857         verify(mReceiver1).onAuthenticationFailed();
858         assertEquals(STATE_AUTH_STARTED, mBiometricService.mAuthSession.getState());
859     }
860 
861     @Test
testRequestAuthentication_whenAlreadyAuthenticating()862     public void testRequestAuthentication_whenAlreadyAuthenticating() throws Exception {
863         setupAuthForOnly(TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
864         invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
865                 false /* requireConfirmation */, null /* authenticators */);
866 
867         invokeAuthenticate(mBiometricService.mImpl, mReceiver2, false /* requireConfirmation */,
868                 null /* authenticators */, false /* useDefaultSubtitle */,
869                 false /* deviceCredentialAllowed */);
870         waitForIdle();
871 
872         verify(mReceiver1).onError(
873                 eq(TYPE_FACE),
874                 eq(BiometricPrompt.BIOMETRIC_ERROR_CANCELED),
875                 eq(0) /* vendorCode */);
876         verify(mBiometricService.mStatusBarService).hideAuthenticationDialog(eq(TEST_REQUEST_ID));
877 
878         verify(mReceiver2, never()).onError(anyInt(), anyInt(), anyInt());
879     }
880 
881     @Test
testErrorHalTimeout_whenAuthenticating_entersPausedState()882     public void testErrorHalTimeout_whenAuthenticating_entersPausedState() throws Exception {
883         setupAuthForOnly(TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
884         invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
885                 false /* requireConfirmation */, null /* authenticators */);
886 
887         mBiometricService.mAuthSession.mSensorReceiver.onError(
888                 SENSOR_ID_FACE,
889                 getCookieForCurrentSession(mBiometricService.mAuthSession),
890                 BiometricConstants.BIOMETRIC_ERROR_TIMEOUT,
891                 0 /* vendorCode */);
892         waitForIdle();
893 
894         assertEquals(STATE_AUTH_PAUSED, mBiometricService.mAuthSession.getState());
895         verify(mBiometricService.mStatusBarService).onBiometricError(
896                 eq(TYPE_FACE),
897                 eq(BiometricConstants.BIOMETRIC_ERROR_TIMEOUT),
898                 eq(0 /* vendorCode */));
899         // Timeout does not count as fail as per BiometricPrompt documentation.
900         verify(mReceiver1, never()).onAuthenticationFailed();
901 
902         // No auth session. Pressing try again will create one.
903         assertEquals(STATE_AUTH_PAUSED, mBiometricService.mAuthSession.getState());
904 
905         // Pressing "Try again" on SystemUI
906         mBiometricService.mAuthSession.mSysuiReceiver.onTryAgainPressed();
907         waitForIdle();
908         verify(mReceiver1, never()).onError(anyInt(), anyInt(), anyInt());
909 
910         // AuthSession is now resuming
911         assertEquals(STATE_AUTH_PAUSED_RESUMING, mBiometricService.mAuthSession.getState());
912 
913         // Test resuming when hardware becomes ready. SystemUI should not be requested to
914         // show another dialog since it's already showing.
915         resetStatusBar();
916         startPendingAuthSession(mBiometricService);
917         waitForIdle();
918         verify(mBiometricService.mStatusBarService, never()).showAuthenticationDialog(
919                 any(PromptInfo.class),
920                 any(IBiometricSysuiReceiver.class),
921                 any() /* sensorIds */,
922                 anyBoolean() /* credentialAllowed */,
923                 anyBoolean() /* requireConfirmation */,
924                 anyInt() /* userId */,
925                 anyLong() /* operationId */,
926                 anyString(),
927                 anyLong() /* requestId */);
928     }
929 
930     @Test
testErrorFromHal_whenPaused_notifiesSystemUIAndClient()931     public void testErrorFromHal_whenPaused_notifiesSystemUIAndClient() throws Exception {
932         setupAuthForOnly(TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
933         invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
934                 false /* requireConfirmation */, null /* authenticators */);
935 
936         mBiometricService.mAuthSession.mSensorReceiver.onError(
937                 SENSOR_ID_FACE,
938                 getCookieForCurrentSession(mBiometricService.mAuthSession),
939                 BiometricConstants.BIOMETRIC_ERROR_TIMEOUT,
940                 0 /* vendorCode */);
941         mBiometricService.mAuthSession.mSensorReceiver.onError(
942                 SENSOR_ID_FACE,
943                 getCookieForCurrentSession(mBiometricService.mAuthSession),
944                 BiometricConstants.BIOMETRIC_ERROR_CANCELED,
945                 0 /* vendorCode */);
946         waitForIdle();
947 
948         // Client receives error immediately
949         verify(mReceiver1).onError(
950                 eq(TYPE_FACE),
951                 eq(BiometricConstants.BIOMETRIC_ERROR_CANCELED),
952                 eq(0 /* vendorCode */));
953         // Dialog is hidden immediately
954         verify(mBiometricService.mStatusBarService).hideAuthenticationDialog(eq(TEST_REQUEST_ID));
955         // Auth session is over
956         assertNull(mBiometricService.mAuthSession);
957     }
958 
959     @Test
testErrorFromHal_whileAuthenticating_waitsForSysUIBeforeNotifyingClient()960     public void testErrorFromHal_whileAuthenticating_waitsForSysUIBeforeNotifyingClient()
961             throws Exception {
962         // For errors that show in SystemUI, BiometricService stays in STATE_ERROR_PENDING_SYSUI
963         // until SystemUI notifies us that the dialog is dismissed at which point the current
964         // session is done.
965         setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
966         invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
967                 false /* requireConfirmation */, null /* authenticators */);
968 
969         mBiometricService.mAuthSession.mSensorReceiver.onError(
970                 SENSOR_ID_FINGERPRINT,
971                 getCookieForCurrentSession(mBiometricService.mAuthSession),
972                 BiometricConstants.BIOMETRIC_ERROR_UNABLE_TO_PROCESS,
973                 0 /* vendorCode */);
974         waitForIdle();
975 
976         // Sends error to SystemUI and does not notify client yet
977         assertEquals(STATE_ERROR_PENDING_SYSUI, mBiometricService.mAuthSession.getState());
978         verify(mBiometricService.mStatusBarService).onBiometricError(
979                 eq(TYPE_FINGERPRINT),
980                 eq(BiometricConstants.BIOMETRIC_ERROR_UNABLE_TO_PROCESS),
981                 eq(0 /* vendorCode */));
982         verify(mBiometricService.mStatusBarService, never())
983                 .hideAuthenticationDialog(eq(TEST_REQUEST_ID));
984         verify(mReceiver1, never()).onError(anyInt(), anyInt(), anyInt());
985 
986         // SystemUI animation completed, client is notified, auth session is over
987         mBiometricService.mAuthSession.mSysuiReceiver.onDialogDismissed(
988                 BiometricPrompt.DISMISSED_REASON_ERROR, null /* credentialAttestation */);
989         waitForIdle();
990         verify(mReceiver1).onError(
991                 eq(TYPE_FINGERPRINT),
992                 eq(BiometricConstants.BIOMETRIC_ERROR_UNABLE_TO_PROCESS),
993                 eq(0 /* vendorCode */));
994         assertNull(mBiometricService.mAuthSession);
995     }
996 
997     @Test
testErrorFromHal_whilePreparingAuthentication_credentialAllowed()998     public void testErrorFromHal_whilePreparingAuthentication_credentialAllowed() throws Exception {
999         setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
1000         invokeAuthenticate(mBiometricService.mImpl, mReceiver1,
1001                 false /* requireConfirmation */,
1002                 Authenticators.DEVICE_CREDENTIAL | Authenticators.BIOMETRIC_WEAK,
1003                 false /* useDefaultSubtitle */, false /* deviceCredentialAllowed */);
1004         waitForIdle();
1005 
1006         assertEquals(STATE_AUTH_CALLED, mBiometricService.mAuthSession.getState());
1007         mBiometricService.mAuthSession.mSensorReceiver.onError(
1008                 SENSOR_ID_FINGERPRINT,
1009                 getCookieForPendingSession(mBiometricService.mAuthSession),
1010                 BiometricConstants.BIOMETRIC_ERROR_LOCKOUT,
1011                 0 /* vendorCode */);
1012         waitForIdle();
1013 
1014         // We should be showing device credential now
1015         assertNotNull(mBiometricService.mAuthSession);
1016         assertEquals(STATE_SHOWING_DEVICE_CREDENTIAL,
1017                 mBiometricService.mAuthSession.getState());
1018         assertEquals(Authenticators.DEVICE_CREDENTIAL,
1019                 mBiometricService.mAuthSession.mPromptInfo.getAuthenticators());
1020         verify(mBiometricService.mStatusBarService).showAuthenticationDialog(
1021                 eq(mBiometricService.mAuthSession.mPromptInfo),
1022                 any(IBiometricSysuiReceiver.class),
1023                 AdditionalMatchers.aryEq(new int[0]) /* sensorIds */,
1024                 eq(true) /* credentialAllowed */,
1025                 anyBoolean() /* requireConfirmation */,
1026                 anyInt() /* userId */,
1027                 anyLong() /* operationId */,
1028                 eq(TEST_PACKAGE_NAME),
1029                 eq(TEST_REQUEST_ID));
1030     }
1031 
1032     @Test
testErrorFromHal_whilePreparingAuthentication_credentialNotAllowed()1033     public void testErrorFromHal_whilePreparingAuthentication_credentialNotAllowed()
1034             throws Exception {
1035         setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
1036         invokeAuthenticate(mBiometricService.mImpl, mReceiver1, false /* requireConfirmation */,
1037                 null /* authenticators */, false /* useDefaultSubtitle */,
1038                 false /* deviceCredentialAllowed */);
1039         waitForIdle();
1040 
1041         mBiometricService.mAuthSession.mSensorReceiver.onError(
1042                 SENSOR_ID_FINGERPRINT,
1043                 getCookieForPendingSession(mBiometricService.mAuthSession),
1044                 BiometricConstants.BIOMETRIC_ERROR_LOCKOUT,
1045                 0 /* vendorCode */);
1046         waitForIdle();
1047 
1048         // Error is sent to client
1049         verify(mReceiver1).onError(eq(TYPE_FINGERPRINT),
1050                 eq(BiometricConstants.BIOMETRIC_ERROR_LOCKOUT),
1051                 eq(0) /* vendorCode */);
1052         assertNull(mBiometricService.mAuthSession);
1053     }
1054 
1055     @Test
testBiometricAuth_whenBiometricLockoutTimed_sendsErrorAndModality()1056     public void testBiometricAuth_whenBiometricLockoutTimed_sendsErrorAndModality()
1057             throws Exception {
1058         testBiometricAuth_whenLockout(LockoutTracker.LOCKOUT_TIMED,
1059                 BiometricPrompt.BIOMETRIC_ERROR_LOCKOUT);
1060     }
1061 
1062     @Test
testBiometricAuth_whenBiometricLockoutPermanent_sendsErrorAndModality()1063     public void testBiometricAuth_whenBiometricLockoutPermanent_sendsErrorAndModality()
1064             throws Exception {
1065         testBiometricAuth_whenLockout(LockoutTracker.LOCKOUT_PERMANENT,
1066                 BiometricPrompt.BIOMETRIC_ERROR_LOCKOUT_PERMANENT);
1067     }
1068 
testBiometricAuth_whenLockout(@ockoutTracker.LockoutMode int lockoutMode, int biometricPromptError)1069     private void testBiometricAuth_whenLockout(@LockoutTracker.LockoutMode int lockoutMode,
1070             int biometricPromptError) throws Exception {
1071         setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
1072         when(mFingerprintAuthenticator.getLockoutModeForUser(anyInt()))
1073                 .thenReturn(lockoutMode);
1074         invokeAuthenticate(mBiometricService.mImpl, mReceiver1, false /* requireConfirmation */,
1075                 null /* authenticators */, false /* useDefaultSubtitle */,
1076                 false /* deviceCredentialAllowed */);
1077         waitForIdle();
1078 
1079         // Modality and error are sent
1080         verify(mReceiver1).onError(eq(TYPE_FINGERPRINT),
1081                 eq(biometricPromptError), eq(0) /* vendorCode */);
1082     }
1083 
1084     @Test
testMultiBiometricAuth_whenLockoutTimed_sendsErrorAndModality()1085     public void testMultiBiometricAuth_whenLockoutTimed_sendsErrorAndModality()
1086             throws Exception {
1087         testMultiBiometricAuth_whenLockout(LockoutTracker.LOCKOUT_TIMED,
1088                 BiometricPrompt.BIOMETRIC_ERROR_LOCKOUT);
1089     }
1090 
1091     @Test
testMultiBiometricAuth_whenLockoutPermanent_sendsErrorAndModality()1092     public void testMultiBiometricAuth_whenLockoutPermanent_sendsErrorAndModality()
1093             throws Exception {
1094         testMultiBiometricAuth_whenLockout(LockoutTracker.LOCKOUT_PERMANENT,
1095                 BiometricPrompt.BIOMETRIC_ERROR_LOCKOUT_PERMANENT);
1096     }
1097 
testMultiBiometricAuth_whenLockout(@ockoutTracker.LockoutMode int lockoutMode, int biometricPromptError)1098     private void testMultiBiometricAuth_whenLockout(@LockoutTracker.LockoutMode int lockoutMode,
1099             int biometricPromptError) throws Exception {
1100         final int[] modalities = new int[] {
1101                 TYPE_FINGERPRINT,
1102                 TYPE_FACE,
1103         };
1104 
1105         final int[] strengths = new int[] {
1106                 Authenticators.BIOMETRIC_STRONG,
1107                 Authenticators.BIOMETRIC_STRONG,
1108         };
1109         setupAuthForMultiple(modalities, strengths);
1110 
1111         when(mFingerprintAuthenticator.getLockoutModeForUser(anyInt()))
1112                 .thenReturn(lockoutMode);
1113         when(mFaceAuthenticator.hasEnrolledTemplates(anyInt(), any())).thenReturn(false);
1114         invokeAuthenticate(mBiometricService.mImpl, mReceiver1, false /* requireConfirmation */,
1115                 null /* authenticators */, false /* useDefaultSubtitle */,
1116                 false /* deviceCredentialAllowed */);
1117         waitForIdle();
1118 
1119         // The lockout error should be sent, instead of ERROR_NONE_ENROLLED. See b/286923477.
1120         verify(mReceiver1).onError(eq(TYPE_FINGERPRINT),
1121                 eq(biometricPromptError), eq(0) /* vendorCode */);
1122     }
1123 
1124     @Test
testBiometricOrCredentialAuth_whenBiometricLockout_showsCredential()1125     public void testBiometricOrCredentialAuth_whenBiometricLockout_showsCredential()
1126             throws Exception {
1127         when(mTrustManager.isDeviceSecure(anyInt(), anyInt())).thenReturn(true);
1128         setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
1129         when(mFingerprintAuthenticator.getLockoutModeForUser(anyInt()))
1130                 .thenReturn(LockoutTracker.LOCKOUT_PERMANENT);
1131         invokeAuthenticate(mBiometricService.mImpl, mReceiver1,
1132                 false /* requireConfirmation */,
1133                 Authenticators.DEVICE_CREDENTIAL | Authenticators.BIOMETRIC_STRONG,
1134                 false /* useDefaultSubtitle */, false /* deviceCredentialAllowed */);
1135         waitForIdle();
1136 
1137         verify(mReceiver1, never()).onError(anyInt(), anyInt(), anyInt());
1138         assertNotNull(mBiometricService.mAuthSession);
1139         assertEquals(STATE_SHOWING_DEVICE_CREDENTIAL,
1140                 mBiometricService.mAuthSession.getState());
1141         assertEquals(Authenticators.DEVICE_CREDENTIAL,
1142                 mBiometricService.mAuthSession.mPromptInfo.getAuthenticators());
1143         verify(mBiometricService.mStatusBarService).showAuthenticationDialog(
1144                 eq(mBiometricService.mAuthSession.mPromptInfo),
1145                 any(IBiometricSysuiReceiver.class),
1146                 AdditionalMatchers.aryEq(new int[0]) /* sensorIds */,
1147                 eq(true) /* credentialAllowed */,
1148                 anyBoolean() /* requireConfirmation */,
1149                 anyInt() /* userId */,
1150                 anyLong() /* operationId */,
1151                 eq(TEST_PACKAGE_NAME),
1152                 eq(TEST_REQUEST_ID));
1153     }
1154 
1155     @Test
testCombineAuthenticatorBundles_withKeyDeviceCredential_andKeyAuthenticators()1156     public void testCombineAuthenticatorBundles_withKeyDeviceCredential_andKeyAuthenticators() {
1157         final boolean allowDeviceCredential = false;
1158         final @Authenticators.Types int authenticators =
1159                 Authenticators.DEVICE_CREDENTIAL | Authenticators.BIOMETRIC_WEAK;
1160         final PromptInfo promptInfo = new PromptInfo();
1161 
1162         promptInfo.setDeviceCredentialAllowed(allowDeviceCredential);
1163         promptInfo.setAuthenticators(authenticators);
1164         Utils.combineAuthenticatorBundles(promptInfo);
1165 
1166         assertFalse(promptInfo.isDeviceCredentialAllowed());
1167         assertEquals(authenticators, promptInfo.getAuthenticators());
1168     }
1169 
1170     @Test
testCombineAuthenticatorBundles_withNoKeyDeviceCredential_andKeyAuthenticators()1171     public void testCombineAuthenticatorBundles_withNoKeyDeviceCredential_andKeyAuthenticators() {
1172         final @Authenticators.Types int authenticators =
1173                 Authenticators.DEVICE_CREDENTIAL | Authenticators.BIOMETRIC_WEAK;
1174         final PromptInfo promptInfo = new PromptInfo();
1175 
1176         promptInfo.setAuthenticators(authenticators);
1177         Utils.combineAuthenticatorBundles(promptInfo);
1178 
1179         assertFalse(promptInfo.isDeviceCredentialAllowed());
1180         assertEquals(authenticators, promptInfo.getAuthenticators());
1181     }
1182 
1183     @Test
testCombineAuthenticatorBundles_withKeyDeviceCredential_andNoKeyAuthenticators()1184     public void testCombineAuthenticatorBundles_withKeyDeviceCredential_andNoKeyAuthenticators() {
1185         final boolean allowDeviceCredential = true;
1186         final PromptInfo promptInfo = new PromptInfo();
1187 
1188         promptInfo.setDeviceCredentialAllowed(allowDeviceCredential);
1189         Utils.combineAuthenticatorBundles(promptInfo);
1190 
1191         assertFalse(promptInfo.isDeviceCredentialAllowed());
1192         assertEquals(Authenticators.DEVICE_CREDENTIAL | Authenticators.BIOMETRIC_WEAK,
1193                 promptInfo.getAuthenticators());
1194     }
1195 
1196     @Test
testCombineAuthenticatorBundles_withNoKeyDeviceCredential_andNoKeyAuthenticators()1197     public void testCombineAuthenticatorBundles_withNoKeyDeviceCredential_andNoKeyAuthenticators() {
1198         final PromptInfo promptInfo = new PromptInfo();
1199 
1200         Utils.combineAuthenticatorBundles(promptInfo);
1201 
1202         assertFalse(promptInfo.isDeviceCredentialAllowed());
1203         assertEquals(Authenticators.BIOMETRIC_WEAK, promptInfo.getAuthenticators());
1204     }
1205 
1206     @Test
testErrorFromHal_whileShowingDeviceCredential_doesntNotifySystemUI()1207     public void testErrorFromHal_whileShowingDeviceCredential_doesntNotifySystemUI()
1208             throws Exception {
1209         setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
1210         invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
1211                 false /* requireConfirmation */,
1212                 Authenticators.DEVICE_CREDENTIAL | Authenticators.BIOMETRIC_WEAK);
1213 
1214         mBiometricService.mAuthSession.mSysuiReceiver.onDeviceCredentialPressed();
1215         waitForIdle();
1216 
1217         assertEquals(STATE_SHOWING_DEVICE_CREDENTIAL,
1218                 mBiometricService.mAuthSession.getState());
1219         verify(mReceiver1, never()).onError(anyInt(), anyInt(), anyInt());
1220 
1221         mBiometricService.mAuthSession.mSensorReceiver.onError(
1222                 SENSOR_ID_FINGERPRINT,
1223                 getCookieForCurrentSession(mBiometricService.mAuthSession),
1224                 BiometricConstants.BIOMETRIC_ERROR_CANCELED,
1225                 0 /* vendorCode */);
1226         waitForIdle();
1227 
1228         assertEquals(STATE_SHOWING_DEVICE_CREDENTIAL,
1229                 mBiometricService.mAuthSession.getState());
1230         verify(mReceiver1, never()).onError(anyInt(), anyInt(), anyInt());
1231     }
1232 
1233     @Test
testLockout_whileAuthenticating_credentialAllowed()1234     public void testLockout_whileAuthenticating_credentialAllowed() throws Exception {
1235         setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
1236         invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
1237                 false /* requireConfirmation */,
1238                 Authenticators.DEVICE_CREDENTIAL | Authenticators.BIOMETRIC_WEAK);
1239 
1240         assertEquals(STATE_AUTH_STARTED, mBiometricService.mAuthSession.getState());
1241 
1242         mBiometricService.mAuthSession.mSensorReceiver.onError(
1243                 SENSOR_ID_FINGERPRINT,
1244                 getCookieForCurrentSession(mBiometricService.mAuthSession),
1245                 BiometricConstants.BIOMETRIC_ERROR_LOCKOUT,
1246                 0 /* vendorCode */);
1247         waitForIdle();
1248 
1249         assertEquals(STATE_SHOWING_DEVICE_CREDENTIAL,
1250                 mBiometricService.mAuthSession.getState());
1251         verify(mBiometricService.mStatusBarService).onBiometricError(
1252                 eq(TYPE_FINGERPRINT),
1253                 eq(BiometricConstants.BIOMETRIC_ERROR_LOCKOUT),
1254                 eq(0 /* vendorCode */));
1255     }
1256 
1257     @Test
testLockout_whenAuthenticating_credentialNotAllowed()1258     public void testLockout_whenAuthenticating_credentialNotAllowed() throws Exception {
1259         setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
1260         invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
1261                 false /* requireConfirmation */, null /* authenticators */);
1262 
1263         assertEquals(STATE_AUTH_STARTED, mBiometricService.mAuthSession.getState());
1264 
1265         mBiometricService.mAuthSession.mSensorReceiver.onError(
1266                 SENSOR_ID_FINGERPRINT,
1267                 getCookieForCurrentSession(mBiometricService.mAuthSession),
1268                 BiometricConstants.BIOMETRIC_ERROR_UNABLE_TO_PROCESS,
1269                 0 /* vendorCode */);
1270         waitForIdle();
1271 
1272         assertEquals(STATE_ERROR_PENDING_SYSUI,
1273                 mBiometricService.mAuthSession.getState());
1274         verify(mBiometricService.mStatusBarService).onBiometricError(
1275                 eq(TYPE_FINGERPRINT),
1276                 eq(BiometricConstants.BIOMETRIC_ERROR_UNABLE_TO_PROCESS),
1277                 eq(0 /* vendorCode */));
1278     }
1279 
1280     @Test
testDismissedReasonUserCancel_whileAuthenticating_cancelsHalAuthentication()1281     public void testDismissedReasonUserCancel_whileAuthenticating_cancelsHalAuthentication()
1282             throws Exception {
1283         setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
1284         invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
1285                 false /* requireConfirmation */, null /* authenticators */);
1286 
1287         mBiometricService.mAuthSession.mSysuiReceiver.onDialogDismissed(
1288                 BiometricPrompt.DISMISSED_REASON_USER_CANCEL, null /* credentialAttestation */);
1289         waitForIdle();
1290         verify(mReceiver1).onError(
1291                 eq(TYPE_FINGERPRINT),
1292                 eq(BiometricConstants.BIOMETRIC_ERROR_USER_CANCELED),
1293                 eq(0 /* vendorCode */));
1294         verify(mBiometricService.mSensors.get(0).impl).cancelAuthenticationFromService(
1295                 any(), any(), anyLong());
1296         assertNull(mBiometricService.mAuthSession);
1297     }
1298 
1299     @Test
testDismissedReasonNegative_whilePaused_invokeHalCancel()1300     public void testDismissedReasonNegative_whilePaused_invokeHalCancel() throws Exception {
1301         setupAuthForOnly(TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
1302         invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
1303                 false /* requireConfirmation */, null /* authenticators */);
1304 
1305         mBiometricService.mAuthSession.mSensorReceiver.onError(
1306                 SENSOR_ID_FACE,
1307                 getCookieForCurrentSession(mBiometricService.mAuthSession),
1308                 BiometricConstants.BIOMETRIC_ERROR_TIMEOUT,
1309                 0 /* vendorCode */);
1310         mBiometricService.mAuthSession.mSysuiReceiver.onDialogDismissed(
1311                 BiometricPrompt.DISMISSED_REASON_NEGATIVE, null /* credentialAttestation */);
1312         waitForIdle();
1313 
1314         verify(mBiometricService.mSensors.get(0).impl)
1315                 .cancelAuthenticationFromService(any(), any(), anyLong());
1316     }
1317 
1318     @Test
testDismissedReasonUserCancel_whilePaused_invokesHalCancel()1319     public void testDismissedReasonUserCancel_whilePaused_invokesHalCancel() throws Exception {
1320         setupAuthForOnly(TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
1321         invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
1322                 false /* requireConfirmation */, null /* authenticators */);
1323 
1324         mBiometricService.mAuthSession.mSensorReceiver.onError(
1325                 SENSOR_ID_FACE,
1326                 getCookieForCurrentSession(mBiometricService.mAuthSession),
1327                 BiometricConstants.BIOMETRIC_ERROR_TIMEOUT,
1328                 0 /* vendorCode */);
1329         mBiometricService.mAuthSession.mSysuiReceiver.onDialogDismissed(
1330                 BiometricPrompt.DISMISSED_REASON_USER_CANCEL, null /* credentialAttestation */);
1331         waitForIdle();
1332 
1333         verify(mBiometricService.mSensors.get(0).impl)
1334                 .cancelAuthenticationFromService(any(), any(), anyLong());
1335     }
1336 
1337     @Test
testDismissedReasonUserCancel_whenPendingConfirmation()1338     public void testDismissedReasonUserCancel_whenPendingConfirmation() throws Exception {
1339         setupAuthForOnly(TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
1340         invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
1341                 true /* requireConfirmation */, null /* authenticators */);
1342 
1343         mBiometricService.mAuthSession.mSensorReceiver.onAuthenticationSucceeded(
1344                 SENSOR_ID_FACE,
1345                 new byte[69] /* HAT */);
1346         mBiometricService.mAuthSession.mSysuiReceiver.onDialogDismissed(
1347                 BiometricPrompt.DISMISSED_REASON_USER_CANCEL, null /* credentialAttestation */);
1348         waitForIdle();
1349 
1350         verify(mBiometricService.mSensors.get(0).impl)
1351                 .cancelAuthenticationFromService(any(), any(), anyLong());
1352         verify(mReceiver1).onError(
1353                 eq(TYPE_FACE),
1354                 eq(BiometricConstants.BIOMETRIC_ERROR_USER_CANCELED),
1355                 eq(0 /* vendorCode */));
1356         verify(mKeyStoreAuthorization, never()).addAuthToken(any(byte[].class));
1357         assertNull(mBiometricService.mAuthSession);
1358     }
1359 
1360     @Test
testDismissedReasonMoreOptions_whilePaused_invokeHalCancel()1361     public void testDismissedReasonMoreOptions_whilePaused_invokeHalCancel() throws Exception {
1362         setupAuthForOnly(TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
1363         invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
1364                 false /* requireConfirmation */, null /* authenticators */);
1365 
1366         mBiometricService.mAuthSession.mSensorReceiver.onError(
1367                 SENSOR_ID_FACE,
1368                 getCookieForCurrentSession(mBiometricService.mAuthSession),
1369                 BiometricConstants.BIOMETRIC_ERROR_TIMEOUT,
1370                 0 /* vendorCode */);
1371         mBiometricService.mAuthSession.mSysuiReceiver.onDialogDismissed(
1372                 BiometricPrompt.DISMISSED_REASON_CONTENT_VIEW_MORE_OPTIONS,
1373                 null /* credentialAttestation */);
1374         waitForIdle();
1375 
1376         verify(mReceiver1).onDialogDismissed(
1377                 eq(BiometricPrompt.DISMISSED_REASON_CONTENT_VIEW_MORE_OPTIONS));
1378         verify(mBiometricService.mSensors.get(0).impl)
1379                 .cancelAuthenticationFromService(any(), any(), anyLong());
1380     }
1381 
1382     @Test
testAcquire_whenAuthenticating_sentToSystemUI()1383     public void testAcquire_whenAuthenticating_sentToSystemUI() throws Exception {
1384         when(mContext.getResources().getString(anyInt())).thenReturn("test string");
1385 
1386         final int modality = TYPE_FINGERPRINT;
1387         setupAuthForOnly(modality, Authenticators.BIOMETRIC_STRONG);
1388         invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
1389                 false /* requireConfirmation */, null /* authenticators */);
1390 
1391         mBiometricService.mAuthSession.mSensorReceiver.onAcquired(
1392                 SENSOR_ID_FINGERPRINT,
1393                 FingerprintManager.FINGERPRINT_ACQUIRED_IMAGER_DIRTY,
1394                 0 /* vendorCode */);
1395         waitForIdle();
1396 
1397         // Sends to SysUI and stays in authenticating state. We don't test that the correct
1398         // string is retrieved for now, but it's also very unlikely to break anyway.
1399         verify(mBiometricService.mStatusBarService)
1400                 .onBiometricHelp(eq(modality), anyString());
1401         assertEquals(STATE_AUTH_STARTED, mBiometricService.mAuthSession.getState());
1402     }
1403 
1404     @Test
testCancel_whenAuthenticating()1405     public void testCancel_whenAuthenticating() throws Exception {
1406         setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
1407         invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
1408                 false /* requireConfirmation */, null /* authenticators */);
1409 
1410         mBiometricService.mImpl.cancelAuthentication(mBiometricService.mAuthSession.mToken,
1411                 TEST_PACKAGE_NAME, TEST_REQUEST_ID);
1412         waitForIdle();
1413 
1414         // Pretend that the HAL has responded to cancel with ERROR_CANCELED
1415         mBiometricService.mAuthSession.mSensorReceiver.onError(
1416                 SENSOR_ID_FINGERPRINT,
1417                 getCookieForCurrentSession(mBiometricService.mAuthSession),
1418                 BiometricConstants.BIOMETRIC_ERROR_CANCELED,
1419                 0 /* vendorCode */);
1420         waitForIdle();
1421 
1422         // Hides system dialog and invokes the onError callback
1423         verify(mReceiver1).onError(eq(TYPE_FINGERPRINT),
1424                 eq(BiometricConstants.BIOMETRIC_ERROR_CANCELED),
1425                 eq(0 /* vendorCode */));
1426         verify(mBiometricService.mStatusBarService).hideAuthenticationDialog(eq(TEST_REQUEST_ID));
1427     }
1428 
1429     @Test
testCanAuthenticate_whenDeviceHasRequestedBiometricStrength()1430     public void testCanAuthenticate_whenDeviceHasRequestedBiometricStrength() throws Exception {
1431         // When only biometric is requested, and sensor is strong enough
1432         setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
1433 
1434         assertEquals(BiometricManager.BIOMETRIC_SUCCESS,
1435                 invokeCanAuthenticate(mBiometricService, Authenticators.BIOMETRIC_STRONG));
1436     }
1437 
1438     @Test
testCanAuthenticate_whenDeviceDoesNotHaveRequestedBiometricStrength()1439     public void testCanAuthenticate_whenDeviceDoesNotHaveRequestedBiometricStrength()
1440             throws Exception {
1441         setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_WEAK);
1442 
1443         // When only biometric is requested, and sensor is not strong enough
1444         when(mTrustManager.isDeviceSecure(anyInt(), anyInt()))
1445                 .thenReturn(false);
1446         int authenticators = Authenticators.BIOMETRIC_STRONG;
1447         assertEquals(BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE,
1448                 invokeCanAuthenticate(mBiometricService, authenticators));
1449 
1450         // When credential and biometric are requested, and sensor is not strong enough
1451         when(mTrustManager.isDeviceSecure(anyInt(), anyInt()))
1452                 .thenReturn(true);
1453         authenticators = Authenticators.BIOMETRIC_STRONG | Authenticators.DEVICE_CREDENTIAL;
1454         assertEquals(BiometricManager.BIOMETRIC_SUCCESS,
1455                 invokeCanAuthenticate(mBiometricService, authenticators));
1456     }
1457 
1458     @Test
testCanAuthenticate_onlyCredentialRequested()1459     public void testCanAuthenticate_onlyCredentialRequested() throws Exception {
1460         mBiometricService = new BiometricService(mContext, mInjector, mBiometricHandlerProvider);
1461         mBiometricService.onStart();
1462 
1463         // Credential requested but not set up
1464         when(mTrustManager.isDeviceSecure(anyInt(), anyInt()))
1465                 .thenReturn(false);
1466         assertEquals(BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED,
1467                 invokeCanAuthenticate(mBiometricService, Authenticators.DEVICE_CREDENTIAL));
1468 
1469         // Credential requested and set up
1470         when(mTrustManager.isDeviceSecure(anyInt(), anyInt()))
1471                 .thenReturn(true);
1472         assertEquals(BiometricManager.BIOMETRIC_SUCCESS,
1473                 invokeCanAuthenticate(mBiometricService, Authenticators.DEVICE_CREDENTIAL));
1474     }
1475 
1476     @Test
testCanAuthenticate_whenNoBiometricsEnrolled()1477     public void testCanAuthenticate_whenNoBiometricsEnrolled() throws Exception {
1478         // With credential set up, test the following.
1479         when(mTrustManager.isDeviceSecure(anyInt(), anyInt())).thenReturn(true);
1480         setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG,
1481                 false /* enrolled */);
1482 
1483         // When only biometric is requested
1484         int authenticators = Authenticators.BIOMETRIC_STRONG;
1485         assertEquals(BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED,
1486                 invokeCanAuthenticate(mBiometricService, authenticators));
1487 
1488         // When credential and biometric are requested
1489         authenticators = Authenticators.BIOMETRIC_STRONG | Authenticators.DEVICE_CREDENTIAL;
1490         assertEquals(BiometricManager.BIOMETRIC_SUCCESS,
1491                 invokeCanAuthenticate(mBiometricService, authenticators));
1492     }
1493 
1494     @Test
1495     @RequiresFlagsDisabled(Flags.FLAG_MANDATORY_BIOMETRICS)
testCanAuthenticate_whenBiometricsNotEnabledForApps_returnsHardwareUnavailable()1496     public void testCanAuthenticate_whenBiometricsNotEnabledForApps_returnsHardwareUnavailable()
1497             throws Exception {
1498         setupAuthForOnly(TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
1499         when(mBiometricService.mSettingObserver.getEnabledForApps(anyInt(), anyInt()))
1500                 .thenReturn(false);
1501         when(mTrustManager.isDeviceSecure(anyInt(), anyInt()))
1502                 .thenReturn(true);
1503 
1504         // When only biometric is requested
1505         int authenticators = Authenticators.BIOMETRIC_STRONG;
1506         assertEquals(BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE,
1507                 invokeCanAuthenticate(mBiometricService, authenticators));
1508 
1509         // When credential and biometric are requested
1510         authenticators = Authenticators.BIOMETRIC_STRONG | Authenticators.DEVICE_CREDENTIAL;
1511         assertEquals(BiometricManager.BIOMETRIC_SUCCESS,
1512                 invokeCanAuthenticate(mBiometricService, authenticators));
1513     }
1514 
1515     @Test
1516     @RequiresFlagsEnabled(Flags.FLAG_MANDATORY_BIOMETRICS)
testCanAuthenticate_whenBiometricsNotEnabledForApps()1517     public void testCanAuthenticate_whenBiometricsNotEnabledForApps() throws Exception {
1518         setupAuthForOnly(TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
1519         when(mBiometricService.mSettingObserver.getEnabledForApps(anyInt(), anyInt()))
1520                 .thenReturn(false);
1521         when(mTrustManager.isDeviceSecure(anyInt(), anyInt()))
1522                 .thenReturn(true);
1523 
1524         // When only biometric is requested
1525         int authenticators = Authenticators.BIOMETRIC_STRONG;
1526         assertEquals(BiometricManager.BIOMETRIC_ERROR_NOT_ENABLED_FOR_APPS,
1527                 invokeCanAuthenticate(mBiometricService, authenticators));
1528 
1529         // When credential and biometric are requested
1530         authenticators = Authenticators.BIOMETRIC_STRONG | Authenticators.DEVICE_CREDENTIAL;
1531         assertEquals(BiometricManager.BIOMETRIC_SUCCESS,
1532                 invokeCanAuthenticate(mBiometricService, authenticators));
1533     }
1534 
1535     @Test
testCanAuthenticate_whenNoBiometricSensor()1536     public void testCanAuthenticate_whenNoBiometricSensor() throws Exception {
1537         mBiometricService = new BiometricService(mContext, mInjector, mBiometricHandlerProvider);
1538         mBiometricService.onStart();
1539 
1540         // When only biometric is requested
1541         int authenticators = Authenticators.BIOMETRIC_STRONG;
1542         assertEquals(BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE,
1543                 invokeCanAuthenticate(mBiometricService, authenticators));
1544 
1545         // When credential and biometric are requested, and credential is not set up
1546         authenticators = Authenticators.BIOMETRIC_STRONG | Authenticators.DEVICE_CREDENTIAL;
1547         assertEquals(BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED,
1548                 invokeCanAuthenticate(mBiometricService, authenticators));
1549 
1550         // When credential and biometric are requested, and credential is set up
1551         when(mTrustManager.isDeviceSecure(anyInt(), anyInt()))
1552                 .thenReturn(true);
1553         assertEquals(BiometricManager.BIOMETRIC_SUCCESS,
1554                 invokeCanAuthenticate(mBiometricService, authenticators));
1555     }
1556 
1557     @Test
1558     @RequiresFlagsDisabled(Flags.FLAG_MANDATORY_BIOMETRICS)
testCanAuthenticate_whenLockoutTimed()1559     public void testCanAuthenticate_whenLockoutTimed() throws Exception {
1560         testCanAuthenticate_whenLockedOut(LockoutTracker.LOCKOUT_TIMED);
1561     }
1562 
1563     @Test
1564     @RequiresFlagsDisabled(Flags.FLAG_MANDATORY_BIOMETRICS)
testCanAuthenticate_whenLockoutPermanent()1565     public void testCanAuthenticate_whenLockoutPermanent() throws Exception {
1566         testCanAuthenticate_whenLockedOut(LockoutTracker.LOCKOUT_PERMANENT);
1567     }
1568 
1569     @Test
1570     @RequiresFlagsEnabled(Flags.FLAG_MANDATORY_BIOMETRICS)
testCanAuthenticate_whenLockoutTimed_returnsLockoutError()1571     public void testCanAuthenticate_whenLockoutTimed_returnsLockoutError() throws Exception {
1572         testCanAuthenticate_whenLockedOut_returnLockoutError(LockoutTracker.LOCKOUT_TIMED);
1573     }
1574 
1575     @Test
1576     @RequiresFlagsEnabled(Flags.FLAG_MANDATORY_BIOMETRICS)
testCanAuthenticate_whenLockoutPermanent_returnsLockoutError()1577     public void testCanAuthenticate_whenLockoutPermanent_returnsLockoutError() throws Exception {
1578         testCanAuthenticate_whenLockedOut_returnLockoutError(LockoutTracker.LOCKOUT_PERMANENT);
1579     }
1580 
1581     @RequiresFlagsDisabled(Flags.FLAG_MANDATORY_BIOMETRICS)
testCanAuthenticate_whenLockedOut(@ockoutTracker.LockoutMode int lockoutMode)1582     private void testCanAuthenticate_whenLockedOut(@LockoutTracker.LockoutMode int lockoutMode)
1583             throws Exception {
1584         // When only biometric is requested, and sensor is strong enough
1585         setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
1586 
1587         when(mFingerprintAuthenticator.getLockoutModeForUser(anyInt()))
1588                 .thenReturn(lockoutMode);
1589 
1590         // Lockout is not considered an error for BiometricManager#canAuthenticate
1591         assertEquals(BiometricManager.BIOMETRIC_SUCCESS,
1592                 invokeCanAuthenticate(mBiometricService, Authenticators.BIOMETRIC_STRONG));
1593     }
1594 
1595     @RequiresFlagsEnabled(Flags.FLAG_MANDATORY_BIOMETRICS)
testCanAuthenticate_whenLockedOut_returnLockoutError( @ockoutTracker.LockoutMode int lockoutMode)1596     private void testCanAuthenticate_whenLockedOut_returnLockoutError(
1597             @LockoutTracker.LockoutMode int lockoutMode)
1598             throws Exception {
1599         // When only biometric is requested, and sensor is strong enough
1600         setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
1601 
1602         when(mFingerprintAuthenticator.getLockoutModeForUser(anyInt()))
1603                 .thenReturn(lockoutMode);
1604 
1605         // Lockout is not considered an error for BiometricManager#canAuthenticate
1606         assertEquals(BiometricManager.BIOMETRIC_ERROR_LOCKOUT,
1607                 invokeCanAuthenticate(mBiometricService, Authenticators.BIOMETRIC_STRONG));
1608     }
1609 
1610     @Test
1611     @RequiresFlagsEnabled(Flags.FLAG_MANDATORY_BIOMETRICS)
testCanAuthenticate_whenMandatoryBiometricsRequested()1612     public void testCanAuthenticate_whenMandatoryBiometricsRequested()
1613             throws Exception {
1614         mBiometricService = new BiometricService(mContext, mInjector, mBiometricHandlerProvider);
1615         mBiometricService.onStart();
1616 
1617         when(mTrustManager.isInSignificantPlace()).thenReturn(false);
1618         when(mBiometricService.mSettingObserver
1619                 .getMandatoryBiometricsEnabledAndRequirementsSatisfiedForUser(anyInt()))
1620                 .thenReturn(true);
1621 
1622         setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
1623 
1624         assertEquals(BiometricManager.BIOMETRIC_SUCCESS,
1625                 invokeCanAuthenticate(mBiometricService, Authenticators.IDENTITY_CHECK));
1626 
1627         when(mTrustManager.isInSignificantPlace()).thenReturn(true);
1628 
1629         assertEquals(BiometricManager.BIOMETRIC_ERROR_IDENTITY_CHECK_NOT_ACTIVE,
1630                 invokeCanAuthenticate(mBiometricService, Authenticators.IDENTITY_CHECK));
1631     }
1632 
1633     @Test
1634     @RequiresFlagsEnabled(Flags.FLAG_MANDATORY_BIOMETRICS)
testCanAuthenticate_whenMandatoryBiometricsAndStrongAuthenticatorsRequested()1635     public void testCanAuthenticate_whenMandatoryBiometricsAndStrongAuthenticatorsRequested()
1636             throws Exception {
1637         mBiometricService = new BiometricService(mContext, mInjector, mBiometricHandlerProvider);
1638         mBiometricService.onStart();
1639 
1640         when(mTrustManager.isInSignificantPlace()).thenReturn(false);
1641         when(mBiometricService.mSettingObserver
1642                 .getMandatoryBiometricsEnabledAndRequirementsSatisfiedForUser(anyInt()))
1643                 .thenReturn(true);
1644 
1645         setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
1646 
1647         assertEquals(BiometricManager.BIOMETRIC_SUCCESS,
1648                 invokeCanAuthenticate(mBiometricService, Authenticators.IDENTITY_CHECK
1649                         | Authenticators.BIOMETRIC_STRONG));
1650 
1651         when(mTrustManager.isInSignificantPlace()).thenReturn(true);
1652 
1653         assertEquals(BiometricManager.BIOMETRIC_SUCCESS,
1654                 invokeCanAuthenticate(mBiometricService, Authenticators.IDENTITY_CHECK
1655                         | Authenticators.BIOMETRIC_STRONG));
1656     }
1657 
1658     @Test
1659     @RequiresFlagsEnabled(Flags.FLAG_MANDATORY_BIOMETRICS)
testCanAuthenticate_whenMandatoryBiometricsRequestedAndDeviceCredentialAvailable()1660     public void testCanAuthenticate_whenMandatoryBiometricsRequestedAndDeviceCredentialAvailable()
1661             throws Exception {
1662         mBiometricService = new BiometricService(mContext, mInjector, mBiometricHandlerProvider);
1663         mBiometricService.onStart();
1664 
1665         when(mTrustManager.isInSignificantPlace()).thenReturn(false);
1666         when(mBiometricService.mSettingObserver
1667                 .getMandatoryBiometricsEnabledAndRequirementsSatisfiedForUser(anyInt()))
1668                 .thenReturn(true);
1669 
1670         setupAuthForOnly(TYPE_CREDENTIAL, Authenticators.DEVICE_CREDENTIAL);
1671 
1672         assertEquals(BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE,
1673                 invokeCanAuthenticate(mBiometricService, Authenticators.IDENTITY_CHECK));
1674 
1675         when(mTrustManager.isInSignificantPlace()).thenReturn(true);
1676 
1677         assertEquals(BiometricManager.BIOMETRIC_SUCCESS,
1678                 invokeCanAuthenticate(mBiometricService, Authenticators.IDENTITY_CHECK
1679                         | Authenticators.DEVICE_CREDENTIAL));
1680     }
1681 
1682     @Test
testAuthenticatorActualStrength()1683     public void testAuthenticatorActualStrength() {
1684         // Tuple of OEM config, updatedStrength, and expectedStrength
1685         final int[][] testCases = {
1686                 // Downgrades to the specified strength
1687                 {Authenticators.BIOMETRIC_STRONG, Authenticators.BIOMETRIC_WEAK,
1688                         Authenticators.BIOMETRIC_WEAK},
1689 
1690                 // Cannot be upgraded
1691                 {Authenticators.BIOMETRIC_WEAK, Authenticators.BIOMETRIC_STRONG,
1692                         Authenticators.BIOMETRIC_WEAK},
1693 
1694                 // Downgrades to convenience
1695                 {Authenticators.BIOMETRIC_WEAK, Authenticators.BIOMETRIC_CONVENIENCE,
1696                         Authenticators.BIOMETRIC_CONVENIENCE},
1697 
1698                 // EMPTY_SET does not modify specified strength
1699                 {Authenticators.BIOMETRIC_WEAK, Authenticators.EMPTY_SET,
1700                         Authenticators.BIOMETRIC_WEAK},
1701         };
1702 
1703         for (int i = 0; i < testCases.length; i++) {
1704             final BiometricSensor sensor =
1705                     new BiometricSensor(mContext, 0 /* id */,
1706                             TYPE_FINGERPRINT,
1707                             testCases[i][0],
1708                             mock(IBiometricAuthenticator.class)) {
1709                         @Override
1710                         boolean confirmationAlwaysRequired(int userId) {
1711                             return false;
1712                         }
1713 
1714                         @Override
1715                         boolean confirmationSupported() {
1716                             return false;
1717                         }
1718                     };
1719             sensor.updateStrength(testCases[i][1]);
1720             assertEquals(testCases[i][2], sensor.getCurrentStrength());
1721         }
1722     }
1723 
1724     @Test
testRegisterAuthenticator_updatesStrengths()1725     public void testRegisterAuthenticator_updatesStrengths() throws Exception {
1726         mBiometricService = new BiometricService(mContext, mInjector, mBiometricHandlerProvider);
1727         mBiometricService.onStart();
1728 
1729         verify(mBiometricService.mBiometricStrengthController).startListening();
1730         verify(mBiometricService.mBiometricStrengthController, never()).updateStrengths();
1731 
1732         when(mFingerprintAuthenticator.hasEnrolledTemplates(anyInt(), any()))
1733                 .thenReturn(true);
1734         when(mFingerprintAuthenticator.isHardwareDetected(any())).thenReturn(true);
1735         mBiometricService.mImpl.registerAuthenticator(0 /* testId */,
1736                 TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG,
1737                 mFingerprintAuthenticator);
1738 
1739         verify(mBiometricService.mBiometricStrengthController).updateStrengths();
1740     }
1741 
1742     @Test
testWithDowngradedAuthenticator()1743     public void testWithDowngradedAuthenticator() throws Exception {
1744         mBiometricService = new BiometricService(mContext, mInjector, mBiometricHandlerProvider);
1745         mBiometricService.onStart();
1746 
1747         final int testId = 0;
1748 
1749         when(mBiometricService.mSettingObserver.getEnabledForApps(anyInt(), anyInt()))
1750                 .thenReturn(true);
1751 
1752         when(mFingerprintAuthenticator.hasEnrolledTemplates(anyInt(), any()))
1753                 .thenReturn(true);
1754         when(mFingerprintAuthenticator.isHardwareDetected(any())).thenReturn(true);
1755         mBiometricService.mImpl.registerAuthenticator(testId /* id */,
1756                 TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG,
1757                 mFingerprintAuthenticator);
1758 
1759         // Downgrade the authenticator
1760         for (BiometricSensor sensor : mBiometricService.mSensors) {
1761             if (sensor.id == testId) {
1762                 sensor.updateStrength(Authenticators.BIOMETRIC_WEAK);
1763             }
1764         }
1765 
1766         // STRONG-only auth is not available
1767         int authenticators = Authenticators.BIOMETRIC_STRONG;
1768         assertEquals(BiometricManager.BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED,
1769                 invokeCanAuthenticate(mBiometricService, authenticators));
1770         long requestId = invokeAuthenticate(mBiometricService.mImpl, mReceiver1,
1771                 false /* requireConfirmation */, authenticators, false /* useDefaultSubtitle */,
1772                 false /* deviceCredentialAllowed */);
1773         waitForIdle();
1774         verify(mReceiver1).onError(
1775                 eq(TYPE_FINGERPRINT),
1776                 eq(BiometricPrompt.BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED),
1777                 eq(0) /* vendorCode */);
1778 
1779         // Request for weak auth works
1780         resetReceivers();
1781         authenticators = Authenticators.BIOMETRIC_WEAK;
1782         assertEquals(BiometricManager.BIOMETRIC_SUCCESS,
1783                 invokeCanAuthenticate(mBiometricService, authenticators));
1784         requestId = invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
1785                 false /* requireConfirmation */,
1786                 authenticators);
1787         waitForIdle();
1788         verify(mBiometricService.mStatusBarService).showAuthenticationDialog(
1789                 eq(mBiometricService.mAuthSession.mPromptInfo),
1790                 any(IBiometricSysuiReceiver.class),
1791                 AdditionalMatchers.aryEq(new int[] {testId}),
1792                 eq(false) /* credentialAllowed */,
1793                 anyBoolean() /* requireConfirmation */,
1794                 anyInt() /* userId */,
1795                 anyLong() /* operationId */,
1796                 eq(TEST_PACKAGE_NAME),
1797                 eq(requestId));
1798 
1799         // Requesting strong and credential, when credential is setup
1800         resetReceivers();
1801         authenticators = Authenticators.BIOMETRIC_STRONG | Authenticators.DEVICE_CREDENTIAL;
1802         when(mTrustManager.isDeviceSecure(anyInt(), anyInt()))
1803                 .thenReturn(true);
1804         assertEquals(BiometricManager.BIOMETRIC_SUCCESS,
1805                 invokeCanAuthenticate(mBiometricService, authenticators));
1806         requestId = invokeAuthenticate(mBiometricService.mImpl, mReceiver1,
1807                 false /* requireConfirmation */,
1808                 authenticators, false /* useDefaultSubtitle */,
1809                 false /* deviceCredentialAllowed */);
1810         waitForIdle();
1811         assertTrue(Utils.isCredentialRequested(mBiometricService.mAuthSession.mPromptInfo));
1812         verify(mBiometricService.mStatusBarService).showAuthenticationDialog(
1813                 eq(mBiometricService.mAuthSession.mPromptInfo),
1814                 any(IBiometricSysuiReceiver.class),
1815                 AdditionalMatchers.aryEq(new int[0]) /* sensorIds */,
1816                 eq(true) /* credentialAllowed */,
1817                 anyBoolean() /* requireConfirmation */,
1818                 anyInt() /* userId */,
1819                 anyLong() /* operationId */,
1820                 eq(TEST_PACKAGE_NAME),
1821                 eq(requestId));
1822 
1823         // Un-downgrading the authenticator allows successful strong auth
1824         for (BiometricSensor sensor : mBiometricService.mSensors) {
1825             if (sensor.id == testId) {
1826                 sensor.updateStrength(Authenticators.BIOMETRIC_STRONG);
1827             }
1828         }
1829 
1830         resetReceivers();
1831         authenticators = Authenticators.BIOMETRIC_STRONG;
1832         assertEquals(BiometricManager.BIOMETRIC_SUCCESS,
1833                 invokeCanAuthenticate(mBiometricService, authenticators));
1834         requestId = invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
1835                 false /* requireConfirmation */, authenticators);
1836         waitForIdle();
1837         verify(mBiometricService.mStatusBarService).showAuthenticationDialog(
1838                 eq(mBiometricService.mAuthSession.mPromptInfo),
1839                 any(IBiometricSysuiReceiver.class),
1840                 AdditionalMatchers.aryEq(new int[] {testId}) /* sensorIds */,
1841                 eq(false) /* credentialAllowed */,
1842                 anyBoolean() /* requireConfirmation */,
1843                 anyInt() /* userId */,
1844                 anyLong() /* operationId */,
1845                 eq(TEST_PACKAGE_NAME),
1846                 eq(requestId));
1847     }
1848 
1849     @Test(expected = IllegalStateException.class)
testRegistrationWithDuplicateId_throwsIllegalStateException()1850     public void testRegistrationWithDuplicateId_throwsIllegalStateException() throws Exception {
1851         mBiometricService = new BiometricService(mContext, mInjector, mBiometricHandlerProvider);
1852         mBiometricService.onStart();
1853 
1854         mBiometricService.mImpl.registerAuthenticator(
1855                 0 /* id */, 2 /* modality */, 15 /* strength */,
1856                 mFingerprintAuthenticator);
1857         mBiometricService.mImpl.registerAuthenticator(
1858                 0 /* id */, 2 /* modality */, 15 /* strength */,
1859                 mFingerprintAuthenticator);
1860     }
1861 
1862     @Test(expected = IllegalArgumentException.class)
testRegistrationWithNullAuthenticator_throwsIllegalArgumentException()1863     public void testRegistrationWithNullAuthenticator_throwsIllegalArgumentException()
1864             throws Exception {
1865         mBiometricService = new BiometricService(mContext, mInjector, mBiometricHandlerProvider);
1866         mBiometricService.onStart();
1867 
1868         mBiometricService.mImpl.registerAuthenticator(
1869                 0 /* id */, 2 /* modality */,
1870                 Authenticators.BIOMETRIC_STRONG /* strength */,
1871                 null /* authenticator */);
1872     }
1873 
1874     @Test
testRegistrationHappyPath_isOk()1875     public void testRegistrationHappyPath_isOk() throws Exception {
1876         // This is being tested in many of the other cases, but here's the base case.
1877         mBiometricService = new BiometricService(mContext, mInjector, mBiometricHandlerProvider);
1878         mBiometricService.onStart();
1879 
1880         for (String s : mInjector.getConfiguration(null)) {
1881             SensorConfig config = new SensorConfig(s);
1882             mBiometricService.mImpl.registerAuthenticator(config.id, config.modality,
1883                 config.strength, mFingerprintAuthenticator);
1884         }
1885     }
1886 
1887     @Test
testWorkAuthentication_fingerprintWorksIfNotDisabledByDevicePolicyManager()1888     public void testWorkAuthentication_fingerprintWorksIfNotDisabledByDevicePolicyManager()
1889             throws Exception {
1890         setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
1891         when(mDevicePolicyManager
1892                 .getKeyguardDisabledFeatures(any() /* admin */, anyInt() /* userHandle */))
1893                 .thenReturn(~DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT);
1894         invokeAuthenticateForWorkApp(mBiometricService.mImpl, mReceiver1,
1895                 Authenticators.BIOMETRIC_STRONG);
1896         waitForIdle();
1897         assertEquals(STATE_AUTH_CALLED, mBiometricService.mAuthSession.getState());
1898         startPendingAuthSession(mBiometricService);
1899         waitForIdle();
1900         assertEquals(STATE_AUTH_STARTED, mBiometricService.mAuthSession.getState());
1901     }
1902 
1903     @Test
testAuthentication_normalAppIgnoresDevicePolicy()1904     public void testAuthentication_normalAppIgnoresDevicePolicy() throws Exception {
1905         setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
1906         when(mDevicePolicyManager
1907                 .getKeyguardDisabledFeatures(any() /* admin */, anyInt() /* userHandle */))
1908                 .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT);
1909         invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
1910                 false /* requireConfirmation */, Authenticators.BIOMETRIC_STRONG);
1911         waitForIdle();
1912         assertEquals(STATE_AUTH_STARTED, mBiometricService.mAuthSession.getState());
1913     }
1914 
1915     @Test
testWorkAuthentication_faceWorksIfNotDisabledByDevicePolicyManager()1916     public void testWorkAuthentication_faceWorksIfNotDisabledByDevicePolicyManager()
1917             throws Exception {
1918         setupAuthForOnly(TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
1919         when(mDevicePolicyManager
1920                 .getKeyguardDisabledFeatures(any() /* admin*/, anyInt() /* userHandle */))
1921                 .thenReturn(~DevicePolicyManager.KEYGUARD_DISABLE_FACE);
1922         invokeAuthenticateForWorkApp(mBiometricService.mImpl, mReceiver1,
1923                 Authenticators.BIOMETRIC_STRONG);
1924         waitForIdle();
1925         assertEquals(STATE_AUTH_CALLED, mBiometricService.mAuthSession.getState());
1926         startPendingAuthSession(mBiometricService);
1927         waitForIdle();
1928         assertEquals(STATE_AUTH_STARTED, mBiometricService.mAuthSession.getState());
1929     }
1930 
1931     @Test
testWorkAuthentication_fingerprintFailsIfDisabledByDevicePolicyManager()1932     public void testWorkAuthentication_fingerprintFailsIfDisabledByDevicePolicyManager()
1933             throws Exception {
1934         setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
1935         when(mTrustManager.isDeviceSecure(anyInt(), anyInt())).thenReturn(true);
1936         when(mDevicePolicyManager
1937                 .getKeyguardDisabledFeatures(any() /* admin */, anyInt() /* userHandle */))
1938                 .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT);
1939 
1940         invokeAuthenticateForWorkApp(mBiometricService.mImpl, mReceiver1,
1941                 Authenticators.BIOMETRIC_STRONG);
1942         waitForIdle();
1943         verify(mReceiver1).onError(eq(BiometricAuthenticator.TYPE_NONE),
1944                 eq(BiometricPrompt.BIOMETRIC_ERROR_HW_UNAVAILABLE), eq(0) /* vendorCode */);
1945 
1946         invokeAuthenticateForWorkApp(mBiometricService.mImpl, mReceiver2,
1947                 Authenticators.BIOMETRIC_STRONG | Authenticators.DEVICE_CREDENTIAL);
1948         waitForIdle();
1949         assertNotNull(mBiometricService.mAuthSession);
1950         assertEquals(STATE_SHOWING_DEVICE_CREDENTIAL,
1951                 mBiometricService.mAuthSession.getState());
1952         verify(mReceiver2, never()).onError(anyInt(), anyInt(), anyInt());
1953     }
1954 
1955     @Test
1956     @RequiresFlagsDisabled(com.android.settings.flags.Flags.FLAG_BIOMETRICS_ONBOARDING_EDUCATION)
testRegisterEnabledOnKeyguardCallback_flagDisabled()1957     public void testRegisterEnabledOnKeyguardCallback_flagDisabled() throws RemoteException {
1958         final UserInfo userInfo1 = new UserInfo(0 /* userId */, "user1" /* name */, 0 /* flags */);
1959         final UserInfo userInfo2 = new UserInfo(10 /* userId */, "user2" /* name */, 0 /* flags */);
1960         final List<UserInfo> aliveUsers = List.of(userInfo1, userInfo2);
1961         final IBiometricEnabledOnKeyguardCallback callback =
1962                 mock(IBiometricEnabledOnKeyguardCallback.class);
1963 
1964         mBiometricService = new BiometricService(mContext, mInjector, mBiometricHandlerProvider);
1965 
1966         when(mUserManager.getAliveUsers()).thenReturn(aliveUsers);
1967         when(mBiometricService.mSettingObserver
1968                 .getEnabledOnKeyguard(userInfo1.id, TYPE_ANY_BIOMETRIC)).thenReturn(true);
1969         when(mBiometricService.mSettingObserver
1970                 .getEnabledOnKeyguard(userInfo2.id, TYPE_ANY_BIOMETRIC)).thenReturn(false);
1971         when(callback.asBinder()).thenReturn(mock(IBinder.class));
1972 
1973         mBiometricService.mImpl.registerEnabledOnKeyguardCallback(callback);
1974 
1975         waitForIdle();
1976 
1977         verify(callback).asBinder();
1978         verify(callback).onChanged(true, userInfo1.id, TYPE_ANY_BIOMETRIC);
1979         verify(callback).onChanged(false, userInfo2.id, TYPE_ANY_BIOMETRIC);
1980         verifyNoMoreInteractions(callback);
1981     }
1982 
1983     @Test
1984     @RequiresFlagsEnabled(com.android.settings.flags.Flags.FLAG_BIOMETRICS_ONBOARDING_EDUCATION)
testRegisterEnabledOnKeyguardCallback_flagEnabled()1985     public void testRegisterEnabledOnKeyguardCallback_flagEnabled() throws RemoteException {
1986         final UserInfo userInfo1 = new UserInfo(0 /* userId */, "user1" /* name */, 0 /* flags */);
1987         final UserInfo userInfo2 = new UserInfo(10 /* userId */, "user2" /* name */, 0 /* flags */);
1988         final List<UserInfo> aliveUsers = List.of(userInfo1, userInfo2);
1989         final IBiometricEnabledOnKeyguardCallback callback =
1990                 mock(IBiometricEnabledOnKeyguardCallback.class);
1991 
1992         mBiometricService = new BiometricService(mContext, mInjector, mBiometricHandlerProvider);
1993 
1994         when(mUserManager.getAliveUsers()).thenReturn(aliveUsers);
1995         when(mBiometricService.mSettingObserver.getEnabledOnKeyguard(userInfo1.id, TYPE_FACE))
1996                 .thenReturn(true);
1997         when(mBiometricService.mSettingObserver.getEnabledOnKeyguard(userInfo1.id,
1998                 TYPE_FINGERPRINT)).thenReturn(true);
1999         when(mBiometricService.mSettingObserver.getEnabledOnKeyguard(userInfo2.id, TYPE_FACE))
2000                 .thenReturn(false);
2001         when(mBiometricService.mSettingObserver.getEnabledOnKeyguard(userInfo2.id,
2002                 TYPE_FINGERPRINT)).thenReturn(false);
2003         when(callback.asBinder()).thenReturn(mock(IBinder.class));
2004 
2005         mBiometricService.mImpl.registerEnabledOnKeyguardCallback(callback);
2006 
2007         waitForIdle();
2008 
2009         verify(callback).asBinder();
2010         verify(callback).onChanged(true, userInfo1.id, TYPE_FACE);
2011         verify(callback).onChanged(true, userInfo1.id, TYPE_FINGERPRINT);
2012         verify(callback).onChanged(false, userInfo2.id, TYPE_FACE);
2013         verify(callback).onChanged(false, userInfo2.id, TYPE_FINGERPRINT);
2014         verifyNoMoreInteractions(callback);
2015     }
2016 
2017     @Test
testGetLastAuthenticationTime_callsKeystoreAuthorization()2018     public void testGetLastAuthenticationTime_callsKeystoreAuthorization()
2019             throws RemoteException {
2020         final int[] hardwareAuthenticators = new int[] {
2021                 HardwareAuthenticatorType.PASSWORD,
2022                 HardwareAuthenticatorType.FINGERPRINT
2023         };
2024 
2025         final int userId = 0;
2026         final long secureUserId = mGateKeeperService.getSecureUserId(userId);
2027 
2028         assertNotEquals(GateKeeper.INVALID_SECURE_USER_ID, secureUserId);
2029 
2030         final long expectedResult = 31337L;
2031 
2032         when(mKeyStoreAuthorization.getLastAuthTime(eq(secureUserId), eq(hardwareAuthenticators)))
2033                 .thenReturn(expectedResult);
2034 
2035         mBiometricService = new BiometricService(mContext, mInjector, mBiometricHandlerProvider);
2036 
2037         final long result = mBiometricService.mImpl.getLastAuthenticationTime(userId,
2038                 Authenticators.BIOMETRIC_STRONG | Authenticators.DEVICE_CREDENTIAL);
2039 
2040         assertEquals(expectedResult, result);
2041         verify(mKeyStoreAuthorization).getLastAuthTime(eq(secureUserId),
2042                 eq(hardwareAuthenticators));
2043     }
2044 
2045     @Test
testMandatoryBiometricsValue_whenParentProfileEnabled()2046     public void testMandatoryBiometricsValue_whenParentProfileEnabled() throws RemoteException {
2047         final Context context = ApplicationProvider.getApplicationContext();
2048         final int profileParentId = context.getContentResolver().getUserId();
2049         final int userId = profileParentId + 1;
2050         final BiometricService.SettingObserver settingObserver =
2051                 new BiometricService.SettingObserver(
2052                         context, mBiometricHandlerProvider.getBiometricCallbackHandler(),
2053                         new ArrayList<>(), mUserManager, mFingerprintManager, mFaceManager);
2054 
2055         verify(mFingerprintManager).addAuthenticatorsRegisteredCallback(
2056                 mFingerprintAuthenticatorRegisteredCallbackCaptor.capture());
2057         verify(mFaceManager).addAuthenticatorsRegisteredCallback(
2058                 mFaceAuthenticatorRegisteredCallbackCaptor.capture());
2059 
2060         mFingerprintAuthenticatorRegisteredCallbackCaptor.getValue().onAllAuthenticatorsRegistered(
2061                 mFingerprintSensorPropertiesInternals);
2062         mFaceAuthenticatorRegisteredCallbackCaptor.getValue().onAllAuthenticatorsRegistered(
2063                 mFaceSensorPropertiesInternals);
2064 
2065         verify(mFingerprintManager).registerBiometricStateListener(
2066                 mBiometricStateListenerArgumentCaptor.capture());
2067 
2068         mBiometricStateListenerArgumentCaptor.getValue().onEnrollmentsChanged(userId,
2069                 SENSOR_ID_FINGERPRINT, true /* hasEnrollments */);
2070 
2071         verify(mFaceManager).registerBiometricStateListener(
2072                 mBiometricStateListenerArgumentCaptor.capture());
2073 
2074         mBiometricStateListenerArgumentCaptor.getValue().onEnrollmentsChanged(userId,
2075                 SENSOR_ID_FACE, true /* hasEnrollments */);
2076 
2077         when(mUserManager.getProfileParent(userId)).thenReturn(new UserInfo(profileParentId,
2078                 "", 0));
2079         when(mUserManager.getEnabledProfileIds(profileParentId)).thenReturn(new int[]{userId});
2080 
2081         //Disable Identity Check for profile user
2082         Settings.Secure.putIntForUser(context.getContentResolver(),
2083                 Settings.Secure.MANDATORY_BIOMETRICS, 0, userId);
2084         Settings.Secure.putIntForUser(context.getContentResolver(),
2085                 Settings.Secure.MANDATORY_BIOMETRICS_REQUIREMENTS_SATISFIED, 0,
2086                 userId);
2087         //Enable Identity Check for parent user
2088         Settings.Secure.putIntForUser(context.getContentResolver(),
2089                 Settings.Secure.MANDATORY_BIOMETRICS, 1, profileParentId);
2090         Settings.Secure.putIntForUser(context.getContentResolver(),
2091                 Settings.Secure.MANDATORY_BIOMETRICS_REQUIREMENTS_SATISFIED, 1,
2092                 profileParentId);
2093 
2094         assertTrue(settingObserver.getMandatoryBiometricsEnabledAndRequirementsSatisfiedForUser(
2095                 userId));
2096     }
2097 
2098     @Test
2099     @RequiresFlagsEnabled(com.android.settings.flags.Flags.FLAG_BIOMETRICS_ONBOARDING_EDUCATION)
testCanAuthenticate_faceEnabledForApps()2100     public void testCanAuthenticate_faceEnabledForApps() throws Exception {
2101         setupAuthForOnly(TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
2102         when(mBiometricService.mSettingObserver.getEnabledForApps(0 /* userId */, TYPE_FACE))
2103                 .thenReturn(true);
2104         when(mTrustManager.isDeviceSecure(anyInt(), anyInt()))
2105                 .thenReturn(true);
2106 
2107         assertEquals(BiometricManager.BIOMETRIC_SUCCESS,
2108                 invokeCanAuthenticate(mBiometricService, Authenticators.BIOMETRIC_STRONG));
2109     }
2110 
2111     @Test
2112     @RequiresFlagsEnabled(com.android.settings.flags.Flags.FLAG_BIOMETRICS_ONBOARDING_EDUCATION)
testCanAuthenticate_faceDisabledForApps()2113     public void testCanAuthenticate_faceDisabledForApps() throws Exception {
2114         setupAuthForOnly(TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
2115         when(mBiometricService.mSettingObserver.getEnabledForApps(0 /* userId */, TYPE_FACE))
2116                 .thenReturn(false);
2117         when(mTrustManager.isDeviceSecure(anyInt(), anyInt()))
2118                 .thenReturn(true);
2119 
2120         assertEquals(BiometricManager.BIOMETRIC_ERROR_NOT_ENABLED_FOR_APPS,
2121                 invokeCanAuthenticate(mBiometricService, Authenticators.BIOMETRIC_STRONG));
2122     }
2123 
2124     @Test
2125     @RequiresFlagsEnabled(com.android.settings.flags.Flags.FLAG_BIOMETRICS_ONBOARDING_EDUCATION)
testCanAuthenticate_fingerprintsEnabledForApps()2126     public void testCanAuthenticate_fingerprintsEnabledForApps() throws Exception {
2127         setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
2128         when(mBiometricService.mSettingObserver.getEnabledForApps(0 /* userId */, TYPE_FINGERPRINT))
2129                 .thenReturn(true);
2130         when(mTrustManager.isDeviceSecure(anyInt(), anyInt()))
2131                 .thenReturn(true);
2132 
2133         assertEquals(BiometricManager.BIOMETRIC_SUCCESS,
2134                 invokeCanAuthenticate(mBiometricService, Authenticators.BIOMETRIC_STRONG));
2135     }
2136 
2137     @Test
2138     @RequiresFlagsEnabled(com.android.settings.flags.Flags.FLAG_BIOMETRICS_ONBOARDING_EDUCATION)
testCanAuthenticate_fingerprintsDisabledForApps()2139     public void testCanAuthenticate_fingerprintsDisabledForApps() throws Exception {
2140         setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
2141         when(mBiometricService.mSettingObserver.getEnabledForApps(0 /* userId */, TYPE_FINGERPRINT))
2142                 .thenReturn(false);
2143         when(mTrustManager.isDeviceSecure(anyInt(), anyInt()))
2144                 .thenReturn(true);
2145 
2146         assertEquals(BiometricManager.BIOMETRIC_ERROR_NOT_ENABLED_FOR_APPS,
2147                 invokeCanAuthenticate(mBiometricService, Authenticators.BIOMETRIC_STRONG));
2148     }
2149 
2150     // Helper methods
2151 
invokeCanAuthenticate(BiometricService service, int authenticators)2152     private int invokeCanAuthenticate(BiometricService service, int authenticators)
2153             throws Exception {
2154         return service.mImpl.canAuthenticate(
2155                 TEST_PACKAGE_NAME, 0 /* userId */, 0 /* callingUserId */, authenticators);
2156     }
2157 
setupAuthForOnly(int modality, int strength)2158     private void setupAuthForOnly(int modality, int strength) throws Exception {
2159         setupAuthForOnly(modality, strength, true /* enrolled */);
2160     }
2161 
2162     // TODO: Reconcile the registration strength with the injector
setupAuthForOnly(int modality, int strength, boolean enrolled)2163     private void setupAuthForOnly(int modality, int strength, boolean enrolled) throws Exception {
2164         mBiometricService = new BiometricService(mContext, mInjector, mBiometricHandlerProvider);
2165         mBiometricService.onStart();
2166 
2167         when(mBiometricService.mSettingObserver.getEnabledForApps(anyInt(), anyInt()))
2168                 .thenReturn(true);
2169 
2170         if ((modality & TYPE_FINGERPRINT) != 0) {
2171             when(mFingerprintAuthenticator.hasEnrolledTemplates(anyInt(), any()))
2172                     .thenReturn(enrolled);
2173             when(mFingerprintAuthenticator.isHardwareDetected(any())).thenReturn(true);
2174             when(mFingerprintAuthenticator.getLockoutModeForUser(anyInt()))
2175                     .thenReturn(LockoutTracker.LOCKOUT_NONE);
2176             mBiometricService.mImpl.registerAuthenticator(SENSOR_ID_FINGERPRINT, modality, strength,
2177                     mFingerprintAuthenticator);
2178         }
2179 
2180         if ((modality & TYPE_FACE) != 0) {
2181             when(mFaceAuthenticator.hasEnrolledTemplates(anyInt(), any())).thenReturn(enrolled);
2182             when(mFaceAuthenticator.isHardwareDetected(any())).thenReturn(true);
2183             when(mFaceAuthenticator.getLockoutModeForUser(anyInt()))
2184                     .thenReturn(LockoutTracker.LOCKOUT_NONE);
2185             mBiometricService.mImpl.registerAuthenticator(SENSOR_ID_FACE, modality, strength,
2186                     mFaceAuthenticator);
2187         }
2188 
2189         if ((modality & TYPE_CREDENTIAL) != 0) {
2190             when(mTrustManager.isDeviceSecure(anyInt(), anyInt()))
2191                     .thenReturn(true);
2192         }
2193     }
2194 
2195     // TODO: Reduce duplicated code, currently we cannot start the BiometricService in setUp() for
2196     // all tests.
setupAuthForMultiple(int[] modalities, int[] strengths)2197     private void setupAuthForMultiple(int[] modalities, int[] strengths) throws RemoteException {
2198         mBiometricService = new BiometricService(mContext, mInjector, mBiometricHandlerProvider);
2199         mBiometricService.onStart();
2200 
2201         when(mBiometricService.mSettingObserver.getEnabledForApps(anyInt(), anyInt()))
2202                 .thenReturn(true);
2203 
2204         assertEquals(modalities.length, strengths.length);
2205 
2206         for (int i = 0; i < modalities.length; i++) {
2207             final int modality = modalities[i];
2208             final int strength = strengths[i];
2209 
2210             if ((modality & TYPE_FINGERPRINT) != 0) {
2211                 when(mFingerprintAuthenticator.hasEnrolledTemplates(anyInt(), any()))
2212                         .thenReturn(true);
2213                 when(mFingerprintAuthenticator.isHardwareDetected(any())).thenReturn(true);
2214                 mBiometricService.mImpl.registerAuthenticator(SENSOR_ID_FINGERPRINT, modality,
2215                         strength, mFingerprintAuthenticator);
2216             }
2217 
2218             if ((modality & TYPE_FACE) != 0) {
2219                 when(mFaceAuthenticator.hasEnrolledTemplates(anyInt(), any())).thenReturn(true);
2220                 when(mFaceAuthenticator.isHardwareDetected(any())).thenReturn(true);
2221                 mBiometricService.mImpl.registerAuthenticator(SENSOR_ID_FACE, modality,
2222                         strength, mFaceAuthenticator);
2223             }
2224         }
2225     }
2226 
resetReceivers()2227     private void resetReceivers() {
2228         mReceiver1 = mock(IBiometricServiceReceiver.class);
2229         mReceiver2 = mock(IBiometricServiceReceiver.class);
2230 
2231         when(mReceiver1.asBinder()).thenReturn(mock(Binder.class));
2232         when(mReceiver2.asBinder()).thenReturn(mock(Binder.class));
2233     }
2234 
resetStatusBar()2235     private void resetStatusBar() {
2236         mBiometricService.mStatusBarService = mock(IStatusBarService.class);
2237     }
2238 
invokeAuthenticateAndStart(IBiometricService.Stub service, IBiometricServiceReceiver receiver, boolean requireConfirmation, Integer authenticators)2239     private long invokeAuthenticateAndStart(IBiometricService.Stub service,
2240             IBiometricServiceReceiver receiver, boolean requireConfirmation,
2241             Integer authenticators) throws Exception {
2242         // Request auth, creates a pending session
2243         final long requestId = invokeAuthenticate(
2244                 service, receiver, requireConfirmation, authenticators,
2245                 false /* useDefaultSubtitle */, false /* deviceCredentialAllowed */);
2246         waitForIdle();
2247 
2248         startPendingAuthSession(mBiometricService);
2249         waitForIdle();
2250 
2251         assertNotNull(mBiometricService.mAuthSession);
2252         assertEquals(TEST_REQUEST_ID, mBiometricService.mAuthSession.getRequestId());
2253         assertEquals(STATE_AUTH_STARTED, mBiometricService.mAuthSession.getState());
2254 
2255         return requestId;
2256     }
2257 
startPendingAuthSession(BiometricService service)2258     private static void startPendingAuthSession(BiometricService service) throws Exception {
2259         // Get the cookie so we can pretend the hardware is ready to authenticate
2260         // Currently we only support single modality per auth
2261         final PreAuthInfo preAuthInfo = service.mAuthSession.mPreAuthInfo;
2262         assertEquals(preAuthInfo.eligibleSensors.size(), 1);
2263         assertEquals(preAuthInfo.numSensorsWaitingForCookie(), 1);
2264 
2265         final int cookie = preAuthInfo.eligibleSensors.get(0).getCookie();
2266         assertNotEquals(cookie, 0);
2267 
2268         service.mImpl.onReadyForAuthentication(TEST_REQUEST_ID, cookie);
2269     }
2270 
invokeAuthenticate(IBiometricService.Stub service, IBiometricServiceReceiver receiver, boolean requireConfirmation, Integer authenticators, boolean useDefaultSubtitle, boolean deviceCredentialAllowed)2271     private static long invokeAuthenticate(IBiometricService.Stub service,
2272             IBiometricServiceReceiver receiver, boolean requireConfirmation,
2273             Integer authenticators, boolean useDefaultSubtitle,
2274             boolean deviceCredentialAllowed) throws Exception {
2275         return service.authenticate(
2276                 new Binder() /* token */,
2277                 0 /* operationId */,
2278                 0 /* userId */,
2279                 receiver,
2280                 TEST_PACKAGE_NAME /* packageName */,
2281                 createTestPromptInfo(requireConfirmation, authenticators,
2282                         false /* checkDevicePolicy */, useDefaultSubtitle,
2283                         deviceCredentialAllowed));
2284     }
2285 
invokeAuthenticateForWorkApp(IBiometricService.Stub service, IBiometricServiceReceiver receiver, Integer authenticators)2286     private static long invokeAuthenticateForWorkApp(IBiometricService.Stub service,
2287             IBiometricServiceReceiver receiver, Integer authenticators) throws Exception {
2288         return service.authenticate(
2289                 new Binder() /* token */,
2290                 0 /* operationId */,
2291                 0 /* userId */,
2292                 receiver,
2293                 TEST_PACKAGE_NAME /* packageName */,
2294                 createTestPromptInfo(false /* requireConfirmation */, authenticators,
2295                         true /* checkDevicePolicy */, false /* useDefaultSubtitle */,
2296                         false /* deviceCredentialAllowed */));
2297     }
2298 
createTestPromptInfo( boolean requireConfirmation, Integer authenticators, boolean checkDevicePolicy, boolean useDefaultSubtitle, boolean deviceCredentialAllowed)2299     private static PromptInfo createTestPromptInfo(
2300             boolean requireConfirmation,
2301             Integer authenticators,
2302             boolean checkDevicePolicy,
2303             boolean useDefaultSubtitle,
2304             boolean deviceCredentialAllowed) {
2305         final PromptInfo promptInfo = new PromptInfo();
2306         promptInfo.setConfirmationRequested(requireConfirmation);
2307         promptInfo.setUseDefaultSubtitle(useDefaultSubtitle);
2308 
2309         if (authenticators != null) {
2310             promptInfo.setAuthenticators(authenticators);
2311         }
2312         if (checkDevicePolicy) {
2313             promptInfo.setDisallowBiometricsIfPolicyExists(checkDevicePolicy);
2314         }
2315         promptInfo.setDeviceCredentialAllowed(deviceCredentialAllowed);
2316         return promptInfo;
2317     }
2318 
getCookieForCurrentSession(AuthSession session)2319     private static int getCookieForCurrentSession(AuthSession session) {
2320         // Currently only tests authentication with a single sensor
2321         final PreAuthInfo preAuthInfo = session.mPreAuthInfo;
2322 
2323         assertEquals(preAuthInfo.eligibleSensors.size(), 1);
2324         return preAuthInfo.eligibleSensors.get(0).getCookie();
2325     }
2326 
getCookieForPendingSession(AuthSession session)2327     private static int getCookieForPendingSession(AuthSession session) {
2328         // Currently only tests authentication with a single sensor
2329         final PreAuthInfo requestWrapper = session.mPreAuthInfo;
2330 
2331         assertEquals(requestWrapper.eligibleSensors.size(), 1);
2332         assertEquals(requestWrapper.eligibleSensors.get(0).getSensorState(),
2333                 BiometricSensor.STATE_WAITING_FOR_COOKIE);
2334         return requestWrapper.eligibleSensors.get(0).getCookie();
2335     }
2336 
waitForIdle()2337     private void waitForIdle() {
2338         TestableLooper.get(this).processAllMessages();
2339     }
2340 
generateRandomHAT()2341     private byte[] generateRandomHAT() {
2342         byte[] HAT = new byte[69];
2343         Random random = new Random();
2344         random.nextBytes(HAT);
2345         return HAT;
2346     }
2347 }
2348