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