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