1 /* 2 * Copyright (C) 2018 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.Manifest.permission.USE_BIOMETRIC_INTERNAL; 20 import static android.hardware.biometrics.BiometricManager.Authenticators; 21 22 import static com.android.server.biometrics.BiometricServiceStateProto.STATE_AUTH_IDLE; 23 24 import android.annotation.NonNull; 25 import android.annotation.Nullable; 26 import android.app.ActivityManager; 27 import android.app.IActivityManager; 28 import android.app.UserSwitchObserver; 29 import android.app.admin.DevicePolicyManager; 30 import android.app.trust.ITrustManager; 31 import android.content.ContentResolver; 32 import android.content.Context; 33 import android.content.pm.PackageManager; 34 import android.database.ContentObserver; 35 import android.hardware.biometrics.BiometricAuthenticator; 36 import android.hardware.biometrics.BiometricConstants; 37 import android.hardware.biometrics.BiometricPrompt; 38 import android.hardware.biometrics.IBiometricAuthenticator; 39 import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback; 40 import android.hardware.biometrics.IBiometricSensorReceiver; 41 import android.hardware.biometrics.IBiometricService; 42 import android.hardware.biometrics.IBiometricServiceReceiver; 43 import android.hardware.biometrics.IBiometricSysuiReceiver; 44 import android.hardware.biometrics.IInvalidationCallback; 45 import android.hardware.biometrics.ITestSession; 46 import android.hardware.biometrics.ITestSessionCallback; 47 import android.hardware.biometrics.PromptInfo; 48 import android.hardware.biometrics.SensorPropertiesInternal; 49 import android.hardware.fingerprint.FingerprintManager; 50 import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; 51 import android.net.Uri; 52 import android.os.Binder; 53 import android.os.Build; 54 import android.os.DeadObjectException; 55 import android.os.Handler; 56 import android.os.IBinder; 57 import android.os.Looper; 58 import android.os.Message; 59 import android.os.RemoteException; 60 import android.os.ServiceManager; 61 import android.os.UserHandle; 62 import android.provider.Settings; 63 import android.security.KeyStore; 64 import android.text.TextUtils; 65 import android.util.ArraySet; 66 import android.util.Pair; 67 import android.util.Slog; 68 import android.util.proto.ProtoOutputStream; 69 70 import com.android.internal.R; 71 import com.android.internal.annotations.VisibleForTesting; 72 import com.android.internal.os.SomeArgs; 73 import com.android.internal.statusbar.IStatusBarService; 74 import com.android.internal.util.DumpUtils; 75 import com.android.server.SystemService; 76 import com.android.server.biometrics.sensors.CoexCoordinator; 77 78 import java.io.FileDescriptor; 79 import java.io.PrintWriter; 80 import java.util.ArrayList; 81 import java.util.HashMap; 82 import java.util.List; 83 import java.util.Map; 84 import java.util.Random; 85 import java.util.Set; 86 87 /** 88 * System service that arbitrates the modality for BiometricPrompt to use. 89 */ 90 public class BiometricService extends SystemService { 91 92 static final String TAG = "BiometricService"; 93 94 private static final int MSG_ON_AUTHENTICATION_SUCCEEDED = 2; 95 private static final int MSG_ON_AUTHENTICATION_REJECTED = 3; 96 private static final int MSG_ON_ERROR = 4; 97 private static final int MSG_ON_ACQUIRED = 5; 98 private static final int MSG_ON_DISMISSED = 6; 99 private static final int MSG_ON_TRY_AGAIN_PRESSED = 7; 100 private static final int MSG_ON_READY_FOR_AUTHENTICATION = 8; 101 private static final int MSG_AUTHENTICATE = 9; 102 private static final int MSG_CANCEL_AUTHENTICATION = 10; 103 private static final int MSG_ON_AUTHENTICATION_TIMED_OUT = 11; 104 private static final int MSG_ON_DEVICE_CREDENTIAL_PRESSED = 12; 105 private static final int MSG_ON_SYSTEM_EVENT = 13; 106 private static final int MSG_CLIENT_DIED = 14; 107 private static final int MSG_ON_DIALOG_ANIMATED_IN = 15; 108 private static final int MSG_ON_START_FINGERPRINT_NOW = 16; 109 110 private final Injector mInjector; 111 private final DevicePolicyManager mDevicePolicyManager; 112 @VisibleForTesting 113 final IBiometricService.Stub mImpl; 114 @VisibleForTesting 115 final SettingObserver mSettingObserver; 116 private final List<EnabledOnKeyguardCallback> mEnabledOnKeyguardCallbacks; 117 private final Random mRandom = new Random(); 118 119 @VisibleForTesting 120 IStatusBarService mStatusBarService; 121 @VisibleForTesting 122 KeyStore mKeyStore; 123 @VisibleForTesting 124 ITrustManager mTrustManager; 125 126 // Get and cache the available biometric authenticators and their associated info. 127 final ArrayList<BiometricSensor> mSensors = new ArrayList<>(); 128 129 BiometricStrengthController mBiometricStrengthController; 130 131 // The current authentication session, null if idle/done. 132 @VisibleForTesting 133 AuthSession mCurrentAuthSession; 134 135 @VisibleForTesting 136 final Handler mHandler = new Handler(Looper.getMainLooper()) { 137 @Override 138 public void handleMessage(Message msg) { 139 switch (msg.what) { 140 case MSG_ON_AUTHENTICATION_SUCCEEDED: { 141 SomeArgs args = (SomeArgs) msg.obj; 142 handleAuthenticationSucceeded( 143 args.argi1 /* sensorId */, 144 (byte[]) args.arg1 /* token */); 145 args.recycle(); 146 break; 147 } 148 149 case MSG_ON_AUTHENTICATION_REJECTED: { 150 handleAuthenticationRejected(); 151 break; 152 } 153 154 case MSG_ON_ERROR: { 155 SomeArgs args = (SomeArgs) msg.obj; 156 handleOnError( 157 args.argi1 /* sensorId */, 158 args.argi2 /* cookie */, 159 args.argi3 /* error */, 160 args.argi4 /* vendorCode */); 161 args.recycle(); 162 break; 163 } 164 165 case MSG_ON_ACQUIRED: { 166 SomeArgs args = (SomeArgs) msg.obj; 167 handleOnAcquired( 168 args.argi1 /* sensorId */, 169 args.argi2 /* acquiredInfo */, 170 args.argi3 /* vendorCode */); 171 args.recycle(); 172 break; 173 } 174 175 case MSG_ON_DISMISSED: { 176 handleOnDismissed(msg.arg1, (byte[]) msg.obj); 177 break; 178 } 179 180 case MSG_ON_TRY_AGAIN_PRESSED: { 181 handleOnTryAgainPressed(); 182 break; 183 } 184 185 case MSG_ON_READY_FOR_AUTHENTICATION: { 186 SomeArgs args = (SomeArgs) msg.obj; 187 handleOnReadyForAuthentication( 188 args.argi1 /* cookie */); 189 args.recycle(); 190 break; 191 } 192 193 case MSG_AUTHENTICATE: { 194 SomeArgs args = (SomeArgs) msg.obj; 195 handleAuthenticate( 196 (IBinder) args.arg1 /* token */, 197 (long) args.arg2 /* operationId */, 198 args.argi1 /* userid */, 199 (IBiometricServiceReceiver) args.arg3 /* receiver */, 200 (String) args.arg4 /* opPackageName */, 201 (PromptInfo) args.arg5 /* promptInfo */); 202 args.recycle(); 203 break; 204 } 205 206 case MSG_CANCEL_AUTHENTICATION: { 207 handleCancelAuthentication(); 208 break; 209 } 210 211 case MSG_ON_AUTHENTICATION_TIMED_OUT: { 212 SomeArgs args = (SomeArgs) msg.obj; 213 handleAuthenticationTimedOut( 214 args.argi1 /* sensorId */, 215 args.argi2 /* cookie */, 216 args.argi3 /* error */, 217 args.argi4 /* vendorCode */); 218 args.recycle(); 219 break; 220 } 221 222 case MSG_ON_DEVICE_CREDENTIAL_PRESSED: { 223 handleOnDeviceCredentialPressed(); 224 break; 225 } 226 227 case MSG_ON_SYSTEM_EVENT: { 228 handleOnSystemEvent((int) msg.obj); 229 break; 230 } 231 232 case MSG_CLIENT_DIED: { 233 handleClientDied(); 234 break; 235 } 236 237 case MSG_ON_DIALOG_ANIMATED_IN: { 238 handleOnDialogAnimatedIn(); 239 break; 240 } 241 242 case MSG_ON_START_FINGERPRINT_NOW: { 243 handleOnStartFingerprintNow(); 244 break; 245 } 246 247 default: 248 Slog.e(TAG, "Unknown message: " + msg); 249 break; 250 } 251 } 252 }; 253 254 /** 255 * Tracks authenticatorId invalidation. For more details, see 256 * {@link com.android.server.biometrics.sensors.InvalidationRequesterClient}. 257 */ 258 @VisibleForTesting 259 static class InvalidationTracker { 260 @NonNull private final IInvalidationCallback mClientCallback; 261 @NonNull private final Set<Integer> mSensorsPendingInvalidation; 262 start(@onNull Context context, @NonNull ArrayList<BiometricSensor> sensors, int userId, int fromSensorId, @NonNull IInvalidationCallback clientCallback)263 public static InvalidationTracker start(@NonNull Context context, 264 @NonNull ArrayList<BiometricSensor> sensors, 265 int userId, int fromSensorId, @NonNull IInvalidationCallback clientCallback) { 266 return new InvalidationTracker(context, sensors, userId, fromSensorId, clientCallback); 267 } 268 InvalidationTracker(@onNull Context context, @NonNull ArrayList<BiometricSensor> sensors, int userId, int fromSensorId, @NonNull IInvalidationCallback clientCallback)269 private InvalidationTracker(@NonNull Context context, 270 @NonNull ArrayList<BiometricSensor> sensors, int userId, 271 int fromSensorId, @NonNull IInvalidationCallback clientCallback) { 272 mClientCallback = clientCallback; 273 mSensorsPendingInvalidation = new ArraySet<>(); 274 275 for (BiometricSensor sensor : sensors) { 276 if (sensor.id == fromSensorId) { 277 continue; 278 } 279 280 if (!Utils.isAtLeastStrength(sensor.oemStrength, Authenticators.BIOMETRIC_STRONG)) { 281 continue; 282 } 283 284 try { 285 if (!sensor.impl.hasEnrolledTemplates(userId, context.getOpPackageName())) { 286 continue; 287 } 288 } catch (RemoteException e) { 289 Slog.e(TAG, "Remote Exception", e); 290 } 291 292 Slog.d(TAG, "Requesting authenticatorId invalidation for sensor: " + sensor.id); 293 294 synchronized (this) { 295 mSensorsPendingInvalidation.add(sensor.id); 296 } 297 298 try { 299 sensor.impl.invalidateAuthenticatorId(userId, new IInvalidationCallback.Stub() { 300 @Override 301 public void onCompleted() { 302 onInvalidated(sensor.id); 303 } 304 }); 305 } catch (RemoteException e) { 306 Slog.d(TAG, "RemoteException", e); 307 } 308 } 309 310 synchronized (this) { 311 if (mSensorsPendingInvalidation.isEmpty()) { 312 try { 313 Slog.d(TAG, "No sensors require invalidation"); 314 mClientCallback.onCompleted(); 315 } catch (RemoteException e) { 316 Slog.e(TAG, "Remote Exception", e); 317 } 318 } 319 } 320 } 321 322 @VisibleForTesting onInvalidated(int sensorId)323 void onInvalidated(int sensorId) { 324 synchronized (this) { 325 mSensorsPendingInvalidation.remove(sensorId); 326 327 Slog.d(TAG, "Sensor " + sensorId + " invalidated, remaining size: " 328 + mSensorsPendingInvalidation.size()); 329 330 if (mSensorsPendingInvalidation.isEmpty()) { 331 try { 332 mClientCallback.onCompleted(); 333 } catch (RemoteException e) { 334 Slog.e(TAG, "Remote Exception", e); 335 } 336 } 337 } 338 } 339 } 340 341 @VisibleForTesting 342 public static class SettingObserver extends ContentObserver { 343 344 private static final boolean DEFAULT_KEYGUARD_ENABLED = true; 345 private static final boolean DEFAULT_APP_ENABLED = true; 346 private static final boolean DEFAULT_ALWAYS_REQUIRE_CONFIRMATION = false; 347 348 // Some devices that shipped before S already have face-specific settings. Instead of 349 // migrating, which is complicated, let's just keep using the existing settings. 350 private final boolean mUseLegacyFaceOnlySettings; 351 352 // Only used for legacy face-only devices 353 private final Uri FACE_UNLOCK_KEYGUARD_ENABLED = 354 Settings.Secure.getUriFor(Settings.Secure.FACE_UNLOCK_KEYGUARD_ENABLED); 355 private final Uri FACE_UNLOCK_APP_ENABLED = 356 Settings.Secure.getUriFor(Settings.Secure.FACE_UNLOCK_APP_ENABLED); 357 358 // Continues to be used, even though it's face-specific. 359 private final Uri FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION = 360 Settings.Secure.getUriFor(Settings.Secure.FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION); 361 362 // Used for all devices other than legacy face-only devices 363 private final Uri BIOMETRIC_KEYGUARD_ENABLED = 364 Settings.Secure.getUriFor(Settings.Secure.BIOMETRIC_KEYGUARD_ENABLED); 365 private final Uri BIOMETRIC_APP_ENABLED = 366 Settings.Secure.getUriFor(Settings.Secure.BIOMETRIC_APP_ENABLED); 367 368 private final ContentResolver mContentResolver; 369 private final List<BiometricService.EnabledOnKeyguardCallback> mCallbacks; 370 371 private final Map<Integer, Boolean> mBiometricEnabledOnKeyguard = new HashMap<>(); 372 private final Map<Integer, Boolean> mBiometricEnabledForApps = new HashMap<>(); 373 private final Map<Integer, Boolean> mFaceAlwaysRequireConfirmation = new HashMap<>(); 374 375 /** 376 * Creates a content observer. 377 * 378 * @param handler The handler to run {@link #onChange} on, or null if none. 379 */ SettingObserver(Context context, Handler handler, List<BiometricService.EnabledOnKeyguardCallback> callbacks)380 public SettingObserver(Context context, Handler handler, 381 List<BiometricService.EnabledOnKeyguardCallback> callbacks) { 382 super(handler); 383 mContentResolver = context.getContentResolver(); 384 mCallbacks = callbacks; 385 386 final boolean hasFingerprint = context.getPackageManager() 387 .hasSystemFeature(PackageManager.FEATURE_FINGERPRINT); 388 final boolean hasFace = context.getPackageManager() 389 .hasSystemFeature(PackageManager.FEATURE_FACE); 390 391 // Use the legacy setting on face-only devices that shipped on or before Q 392 mUseLegacyFaceOnlySettings = 393 Build.VERSION.DEVICE_INITIAL_SDK_INT <= Build.VERSION_CODES.Q 394 && hasFace && !hasFingerprint; 395 396 updateContentObserver(); 397 } 398 updateContentObserver()399 public void updateContentObserver() { 400 mContentResolver.unregisterContentObserver(this); 401 402 if (mUseLegacyFaceOnlySettings) { 403 mContentResolver.registerContentObserver(FACE_UNLOCK_KEYGUARD_ENABLED, 404 false /* notifyForDescendants */, 405 this /* observer */, 406 UserHandle.USER_ALL); 407 mContentResolver.registerContentObserver(FACE_UNLOCK_APP_ENABLED, 408 false /* notifyForDescendants */, 409 this /* observer */, 410 UserHandle.USER_ALL); 411 } else { 412 mContentResolver.registerContentObserver(BIOMETRIC_KEYGUARD_ENABLED, 413 false /* notifyForDescendants */, 414 this /* observer */, 415 UserHandle.USER_ALL); 416 mContentResolver.registerContentObserver(BIOMETRIC_APP_ENABLED, 417 false /* notifyForDescendants */, 418 this /* observer */, 419 UserHandle.USER_ALL); 420 } 421 mContentResolver.registerContentObserver(FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION, 422 false /* notifyForDescendants */, 423 this /* observer */, 424 UserHandle.USER_ALL); 425 } 426 427 @Override onChange(boolean selfChange, Uri uri, int userId)428 public void onChange(boolean selfChange, Uri uri, int userId) { 429 if (FACE_UNLOCK_KEYGUARD_ENABLED.equals(uri)) { 430 mBiometricEnabledOnKeyguard.put(userId, Settings.Secure.getIntForUser( 431 mContentResolver, 432 Settings.Secure.FACE_UNLOCK_KEYGUARD_ENABLED, 433 DEFAULT_KEYGUARD_ENABLED ? 1 : 0 /* default */, 434 userId) != 0); 435 436 if (userId == ActivityManager.getCurrentUser() && !selfChange) { 437 notifyEnabledOnKeyguardCallbacks(userId); 438 } 439 } else if (FACE_UNLOCK_APP_ENABLED.equals(uri)) { 440 mBiometricEnabledForApps.put(userId, Settings.Secure.getIntForUser( 441 mContentResolver, 442 Settings.Secure.FACE_UNLOCK_APP_ENABLED, 443 DEFAULT_APP_ENABLED ? 1 : 0 /* default */, 444 userId) != 0); 445 } else if (FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION.equals(uri)) { 446 mFaceAlwaysRequireConfirmation.put(userId, Settings.Secure.getIntForUser( 447 mContentResolver, 448 Settings.Secure.FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION, 449 DEFAULT_ALWAYS_REQUIRE_CONFIRMATION ? 1 : 0 /* default */, 450 userId) != 0); 451 } else if (BIOMETRIC_KEYGUARD_ENABLED.equals(uri)) { 452 mBiometricEnabledOnKeyguard.put(userId, Settings.Secure.getIntForUser( 453 mContentResolver, 454 Settings.Secure.BIOMETRIC_KEYGUARD_ENABLED, 455 DEFAULT_KEYGUARD_ENABLED ? 1 : 0 /* default */, 456 userId) != 0); 457 458 if (userId == ActivityManager.getCurrentUser() && !selfChange) { 459 notifyEnabledOnKeyguardCallbacks(userId); 460 } 461 } else if (BIOMETRIC_APP_ENABLED.equals(uri)) { 462 mBiometricEnabledForApps.put(userId, Settings.Secure.getIntForUser( 463 mContentResolver, 464 Settings.Secure.BIOMETRIC_APP_ENABLED, 465 DEFAULT_APP_ENABLED ? 1 : 0 /* default */, 466 userId) != 0); 467 } 468 } 469 getEnabledOnKeyguard(int userId)470 public boolean getEnabledOnKeyguard(int userId) { 471 if (!mBiometricEnabledOnKeyguard.containsKey(userId)) { 472 if (mUseLegacyFaceOnlySettings) { 473 onChange(true /* selfChange */, FACE_UNLOCK_KEYGUARD_ENABLED, userId); 474 } else { 475 onChange(true /* selfChange */, BIOMETRIC_KEYGUARD_ENABLED, userId); 476 } 477 } 478 return mBiometricEnabledOnKeyguard.get(userId); 479 } 480 getEnabledForApps(int userId)481 public boolean getEnabledForApps(int userId) { 482 if (!mBiometricEnabledForApps.containsKey(userId)) { 483 if (mUseLegacyFaceOnlySettings) { 484 onChange(true /* selfChange */, FACE_UNLOCK_APP_ENABLED, userId); 485 } else { 486 onChange(true /* selfChange */, BIOMETRIC_APP_ENABLED, userId); 487 } 488 } 489 return mBiometricEnabledForApps.getOrDefault(userId, DEFAULT_APP_ENABLED); 490 } 491 getConfirmationAlwaysRequired(@iometricAuthenticator.Modality int modality, int userId)492 public boolean getConfirmationAlwaysRequired(@BiometricAuthenticator.Modality int modality, 493 int userId) { 494 switch (modality) { 495 case BiometricAuthenticator.TYPE_FACE: 496 if (!mFaceAlwaysRequireConfirmation.containsKey(userId)) { 497 onChange(true /* selfChange */, 498 FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION, 499 userId); 500 } 501 return mFaceAlwaysRequireConfirmation.get(userId); 502 503 default: 504 return false; 505 } 506 } 507 notifyEnabledOnKeyguardCallbacks(int userId)508 void notifyEnabledOnKeyguardCallbacks(int userId) { 509 List<EnabledOnKeyguardCallback> callbacks = mCallbacks; 510 for (int i = 0; i < callbacks.size(); i++) { 511 callbacks.get(i).notify( 512 mBiometricEnabledOnKeyguard.getOrDefault(userId, DEFAULT_KEYGUARD_ENABLED), 513 userId); 514 } 515 } 516 } 517 518 final class EnabledOnKeyguardCallback implements IBinder.DeathRecipient { 519 520 private final IBiometricEnabledOnKeyguardCallback mCallback; 521 EnabledOnKeyguardCallback(IBiometricEnabledOnKeyguardCallback callback)522 EnabledOnKeyguardCallback(IBiometricEnabledOnKeyguardCallback callback) { 523 mCallback = callback; 524 try { 525 mCallback.asBinder().linkToDeath(EnabledOnKeyguardCallback.this, 0); 526 } catch (RemoteException e) { 527 Slog.w(TAG, "Unable to linkToDeath", e); 528 } 529 } 530 notify(boolean enabled, int userId)531 void notify(boolean enabled, int userId) { 532 try { 533 mCallback.onChanged(enabled, userId); 534 } catch (DeadObjectException e) { 535 Slog.w(TAG, "Death while invoking notify", e); 536 mEnabledOnKeyguardCallbacks.remove(this); 537 } catch (RemoteException e) { 538 Slog.w(TAG, "Failed to invoke onChanged", e); 539 } 540 } 541 542 @Override binderDied()543 public void binderDied() { 544 Slog.e(TAG, "Enabled callback binder died"); 545 mEnabledOnKeyguardCallbacks.remove(this); 546 } 547 } 548 549 // Receives events from individual biometric sensors. 550 @VisibleForTesting 551 final IBiometricSensorReceiver mBiometricSensorReceiver = new IBiometricSensorReceiver.Stub() { 552 @Override 553 public void onAuthenticationSucceeded(int sensorId, byte[] token) { 554 SomeArgs args = SomeArgs.obtain(); 555 args.argi1 = sensorId; 556 args.arg1 = token; 557 mHandler.obtainMessage(MSG_ON_AUTHENTICATION_SUCCEEDED, args).sendToTarget(); 558 } 559 560 @Override 561 public void onAuthenticationFailed(int sensorId) { 562 Slog.v(TAG, "onAuthenticationFailed"); 563 mHandler.obtainMessage(MSG_ON_AUTHENTICATION_REJECTED).sendToTarget(); 564 } 565 566 @Override 567 public void onError(int sensorId, int cookie, @BiometricConstants.Errors int error, 568 int vendorCode) { 569 // Determine if error is hard or soft error. Certain errors (such as TIMEOUT) are 570 // soft errors and we should allow the user to try authenticating again instead of 571 // dismissing BiometricPrompt. 572 if (error == BiometricConstants.BIOMETRIC_ERROR_TIMEOUT) { 573 SomeArgs args = SomeArgs.obtain(); 574 args.argi1 = sensorId; 575 args.argi2 = cookie; 576 args.argi3 = error; 577 args.argi4 = vendorCode; 578 mHandler.obtainMessage(MSG_ON_AUTHENTICATION_TIMED_OUT, args).sendToTarget(); 579 } else { 580 SomeArgs args = SomeArgs.obtain(); 581 args.argi1 = sensorId; 582 args.argi2 = cookie; 583 args.argi3 = error; 584 args.argi4 = vendorCode; 585 mHandler.obtainMessage(MSG_ON_ERROR, args).sendToTarget(); 586 } 587 } 588 589 @Override 590 public void onAcquired(int sensorId, int acquiredInfo, int vendorCode) { 591 SomeArgs args = SomeArgs.obtain(); 592 args.argi1 = sensorId; 593 args.argi2 = acquiredInfo; 594 args.argi3 = vendorCode; 595 mHandler.obtainMessage(MSG_ON_ACQUIRED, args).sendToTarget(); 596 } 597 }; 598 599 final IBiometricSysuiReceiver mSysuiReceiver = new IBiometricSysuiReceiver.Stub() { 600 @Override 601 public void onDialogDismissed(@BiometricPrompt.DismissedReason int reason, 602 @Nullable byte[] credentialAttestation) { 603 mHandler.obtainMessage(MSG_ON_DISMISSED, 604 reason, 605 0 /* arg2 */, 606 credentialAttestation /* obj */).sendToTarget(); 607 } 608 609 @Override 610 public void onTryAgainPressed() { 611 mHandler.sendEmptyMessage(MSG_ON_TRY_AGAIN_PRESSED); 612 } 613 614 @Override 615 public void onDeviceCredentialPressed() { 616 mHandler.sendEmptyMessage(MSG_ON_DEVICE_CREDENTIAL_PRESSED); 617 } 618 619 @Override 620 public void onSystemEvent(int event) { 621 mHandler.obtainMessage(MSG_ON_SYSTEM_EVENT, event).sendToTarget(); 622 } 623 624 @Override 625 public void onDialogAnimatedIn() { 626 mHandler.obtainMessage(MSG_ON_DIALOG_ANIMATED_IN).sendToTarget(); 627 } 628 629 @Override 630 public void onStartFingerprintNow() { 631 mHandler.obtainMessage(MSG_ON_START_FINGERPRINT_NOW).sendToTarget(); 632 } 633 }; 634 635 private final AuthSession.ClientDeathReceiver mClientDeathReceiver = () -> { 636 mHandler.sendEmptyMessage(MSG_CLIENT_DIED); 637 }; 638 639 /** 640 * Implementation of the BiometricPrompt/BiometricManager APIs. Handles client requests, 641 * sensor arbitration, threading, etc. 642 */ 643 private final class BiometricServiceWrapper extends IBiometricService.Stub { 644 @Override // Binder call createTestSession(int sensorId, @NonNull ITestSessionCallback callback, @NonNull String opPackageName)645 public ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback, 646 @NonNull String opPackageName) throws RemoteException { 647 checkInternalPermission(); 648 649 for (BiometricSensor sensor : mSensors) { 650 if (sensor.id == sensorId) { 651 return sensor.impl.createTestSession(callback, opPackageName); 652 } 653 } 654 655 Slog.e(TAG, "Unknown sensor for createTestSession: " + sensorId); 656 return null; 657 } 658 659 @Override // Binder call getSensorProperties(String opPackageName)660 public List<SensorPropertiesInternal> getSensorProperties(String opPackageName) 661 throws RemoteException { 662 checkInternalPermission(); 663 664 final List<SensorPropertiesInternal> sensors = new ArrayList<>(); 665 for (BiometricSensor sensor : mSensors) { 666 // Explicitly re-create as the super class, since AIDL doesn't play nicely with 667 // "List<? extends SensorPropertiesInternal> ... 668 final SensorPropertiesInternal prop = SensorPropertiesInternal 669 .from(sensor.impl.getSensorProperties(opPackageName)); 670 sensors.add(prop); 671 } 672 673 return sensors; 674 } 675 676 @Override // Binder call onReadyForAuthentication(int cookie)677 public void onReadyForAuthentication(int cookie) { 678 checkInternalPermission(); 679 680 SomeArgs args = SomeArgs.obtain(); 681 args.argi1 = cookie; 682 mHandler.obtainMessage(MSG_ON_READY_FOR_AUTHENTICATION, args).sendToTarget(); 683 } 684 685 @Override // Binder call authenticate(IBinder token, long operationId, int userId, IBiometricServiceReceiver receiver, String opPackageName, PromptInfo promptInfo)686 public void authenticate(IBinder token, long operationId, int userId, 687 IBiometricServiceReceiver receiver, String opPackageName, PromptInfo promptInfo) { 688 checkInternalPermission(); 689 690 if (token == null || receiver == null || opPackageName == null || promptInfo == null) { 691 Slog.e(TAG, "Unable to authenticate, one or more null arguments"); 692 return; 693 } 694 695 if (!Utils.isValidAuthenticatorConfig(promptInfo)) { 696 throw new SecurityException("Invalid authenticator configuration"); 697 } 698 699 Utils.combineAuthenticatorBundles(promptInfo); 700 701 // Set the default title if necessary. 702 if (promptInfo.isUseDefaultTitle()) { 703 if (TextUtils.isEmpty(promptInfo.getTitle())) { 704 promptInfo.setTitle(getContext() 705 .getString(R.string.biometric_dialog_default_title)); 706 } 707 } 708 709 SomeArgs args = SomeArgs.obtain(); 710 args.arg1 = token; 711 args.arg2 = operationId; 712 args.argi1 = userId; 713 args.arg3 = receiver; 714 args.arg4 = opPackageName; 715 args.arg5 = promptInfo; 716 717 mHandler.obtainMessage(MSG_AUTHENTICATE, args).sendToTarget(); 718 } 719 720 @Override // Binder call cancelAuthentication(IBinder token, String opPackageName)721 public void cancelAuthentication(IBinder token, String opPackageName) { 722 checkInternalPermission(); 723 724 mHandler.obtainMessage(MSG_CANCEL_AUTHENTICATION).sendToTarget(); 725 } 726 727 @Override // Binder call canAuthenticate(String opPackageName, int userId, int callingUserId, @Authenticators.Types int authenticators)728 public int canAuthenticate(String opPackageName, int userId, int callingUserId, 729 @Authenticators.Types int authenticators) { 730 checkInternalPermission(); 731 732 Slog.d(TAG, "canAuthenticate: User=" + userId 733 + ", Caller=" + callingUserId 734 + ", Authenticators=" + authenticators); 735 736 if (!Utils.isValidAuthenticatorConfig(authenticators)) { 737 throw new SecurityException("Invalid authenticator configuration"); 738 } 739 740 try { 741 final PreAuthInfo preAuthInfo = 742 createPreAuthInfo(opPackageName, userId, authenticators); 743 return preAuthInfo.getCanAuthenticateResult(); 744 } catch (RemoteException e) { 745 Slog.e(TAG, "Remote exception", e); 746 return BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE; 747 } 748 } 749 750 @Override hasEnrolledBiometrics(int userId, String opPackageName)751 public boolean hasEnrolledBiometrics(int userId, String opPackageName) { 752 checkInternalPermission(); 753 754 try { 755 for (BiometricSensor sensor : mSensors) { 756 if (sensor.impl.hasEnrolledTemplates(userId, opPackageName)) { 757 return true; 758 } 759 } 760 } catch (RemoteException e) { 761 Slog.e(TAG, "Remote exception", e); 762 } 763 764 return false; 765 } 766 767 @Override registerAuthenticator(int id, int modality, @Authenticators.Types int strength, @NonNull IBiometricAuthenticator authenticator)768 public synchronized void registerAuthenticator(int id, int modality, 769 @Authenticators.Types int strength, 770 @NonNull IBiometricAuthenticator authenticator) { 771 checkInternalPermission(); 772 773 Slog.d(TAG, "Registering ID: " + id 774 + " Modality: " + modality 775 + " Strength: " + strength); 776 777 if (authenticator == null) { 778 throw new IllegalArgumentException("Authenticator must not be null." 779 + " Did you forget to modify the core/res/res/values/xml overlay for" 780 + " config_biometric_sensors?"); 781 } 782 783 // Note that we allow BIOMETRIC_CONVENIENCE to register because BiometricService 784 // also does / will do other things such as keep track of lock screen timeout, etc. 785 // Just because a biometric is registered does not mean it can participate in 786 // the android.hardware.biometrics APIs. 787 if (strength != Authenticators.BIOMETRIC_STRONG 788 && strength != Authenticators.BIOMETRIC_WEAK 789 && strength != Authenticators.BIOMETRIC_CONVENIENCE) { 790 throw new IllegalStateException("Unsupported strength"); 791 } 792 793 for (BiometricSensor sensor : mSensors) { 794 if (sensor.id == id) { 795 throw new IllegalStateException("Cannot register duplicate authenticator"); 796 } 797 } 798 799 mSensors.add(new BiometricSensor(getContext(), id, modality, strength, authenticator) { 800 @Override 801 boolean confirmationAlwaysRequired(int userId) { 802 return mSettingObserver.getConfirmationAlwaysRequired(modality, userId); 803 } 804 805 @Override 806 boolean confirmationSupported() { 807 return Utils.isConfirmationSupported(modality); 808 } 809 }); 810 811 mBiometricStrengthController.updateStrengths(); 812 } 813 814 @Override // Binder call registerEnabledOnKeyguardCallback( IBiometricEnabledOnKeyguardCallback callback, int callingUserId)815 public void registerEnabledOnKeyguardCallback( 816 IBiometricEnabledOnKeyguardCallback callback, int callingUserId) { 817 checkInternalPermission(); 818 819 mEnabledOnKeyguardCallbacks.add(new EnabledOnKeyguardCallback(callback)); 820 try { 821 callback.onChanged(mSettingObserver.getEnabledOnKeyguard(callingUserId), 822 callingUserId); 823 } catch (RemoteException e) { 824 Slog.w(TAG, "Remote exception", e); 825 } 826 } 827 828 @Override // Binder call invalidateAuthenticatorIds(int userId, int fromSensorId, IInvalidationCallback callback)829 public void invalidateAuthenticatorIds(int userId, int fromSensorId, 830 IInvalidationCallback callback) { 831 checkInternalPermission(); 832 833 InvalidationTracker.start(getContext(), mSensors, userId, fromSensorId, callback); 834 } 835 836 @Override // Binder call getAuthenticatorIds(int callingUserId)837 public long[] getAuthenticatorIds(int callingUserId) { 838 checkInternalPermission(); 839 840 final List<Long> authenticatorIds = new ArrayList<>(); 841 for (BiometricSensor sensor : mSensors) { 842 try { 843 final boolean hasEnrollments = sensor.impl.hasEnrolledTemplates(callingUserId, 844 getContext().getOpPackageName()); 845 final long authenticatorId = sensor.impl.getAuthenticatorId(callingUserId); 846 if (hasEnrollments && Utils.isAtLeastStrength(sensor.getCurrentStrength(), 847 Authenticators.BIOMETRIC_STRONG)) { 848 authenticatorIds.add(authenticatorId); 849 } else { 850 Slog.d(TAG, "Sensor " + sensor + ", sensorId " + sensor.id 851 + ", hasEnrollments: " + hasEnrollments 852 + " cannot participate in Keystore operations"); 853 } 854 } catch (RemoteException e) { 855 Slog.e(TAG, "RemoteException", e); 856 } 857 } 858 859 long[] result = new long[authenticatorIds.size()]; 860 for (int i = 0; i < authenticatorIds.size(); i++) { 861 result[i] = authenticatorIds.get(i); 862 } 863 return result; 864 } 865 866 @Override // Binder call resetLockoutTimeBound(IBinder token, String opPackageName, int fromSensorId, int userId, byte[] hardwareAuthToken)867 public void resetLockoutTimeBound(IBinder token, String opPackageName, int fromSensorId, 868 int userId, byte[] hardwareAuthToken) { 869 checkInternalPermission(); 870 871 // Check originating strength 872 if (!Utils.isAtLeastStrength(getSensorForId(fromSensorId).getCurrentStrength(), 873 Authenticators.BIOMETRIC_STRONG)) { 874 Slog.w(TAG, "Sensor: " + fromSensorId + " is does not meet the required strength to" 875 + " request resetLockout"); 876 return; 877 } 878 879 // Request resetLockout for applicable sensors 880 for (BiometricSensor sensor : mSensors) { 881 if (sensor.id == fromSensorId) { 882 continue; 883 } 884 try { 885 final SensorPropertiesInternal props = sensor.impl 886 .getSensorProperties(getContext().getOpPackageName()); 887 final boolean supportsChallengelessHat = 888 props.resetLockoutRequiresHardwareAuthToken 889 && !props.resetLockoutRequiresChallenge; 890 final boolean doesNotRequireHat = !props.resetLockoutRequiresHardwareAuthToken; 891 892 if (supportsChallengelessHat || doesNotRequireHat) { 893 Slog.d(TAG, "resetLockout from: " + fromSensorId 894 + ", for: " + sensor.id 895 + ", userId: " + userId); 896 sensor.impl.resetLockout(token, opPackageName, userId, 897 hardwareAuthToken); 898 } 899 } catch (RemoteException e) { 900 Slog.e(TAG, "Remote exception", e); 901 } 902 } 903 } 904 905 @Override // Binder call getCurrentStrength(int sensorId)906 public int getCurrentStrength(int sensorId) { 907 checkInternalPermission(); 908 909 for (BiometricSensor sensor : mSensors) { 910 if (sensor.id == sensorId) { 911 return sensor.getCurrentStrength(); 912 } 913 } 914 Slog.e(TAG, "Unknown sensorId: " + sensorId); 915 return Authenticators.EMPTY_SET; 916 } 917 918 @Override // Binder call getCurrentModality( String opPackageName, int userId, int callingUserId, @Authenticators.Types int authenticators)919 public int getCurrentModality( 920 String opPackageName, 921 int userId, 922 int callingUserId, 923 @Authenticators.Types int authenticators) { 924 925 checkInternalPermission(); 926 927 Slog.d(TAG, "getCurrentModality: User=" + userId 928 + ", Caller=" + callingUserId 929 + ", Authenticators=" + authenticators); 930 931 if (!Utils.isValidAuthenticatorConfig(authenticators)) { 932 throw new SecurityException("Invalid authenticator configuration"); 933 } 934 935 try { 936 final PreAuthInfo preAuthInfo = 937 createPreAuthInfo(opPackageName, userId, authenticators); 938 return preAuthInfo.getPreAuthenticateStatus().first; 939 } catch (RemoteException e) { 940 Slog.e(TAG, "Remote exception", e); 941 return BiometricAuthenticator.TYPE_NONE; 942 } 943 } 944 945 @Override // Binder call getSupportedModalities(@uthenticators.Types int authenticators)946 public int getSupportedModalities(@Authenticators.Types int authenticators) { 947 checkInternalPermission(); 948 949 Slog.d(TAG, "getSupportedModalities: Authenticators=" + authenticators); 950 951 if (!Utils.isValidAuthenticatorConfig(authenticators)) { 952 throw new SecurityException("Invalid authenticator configuration"); 953 } 954 955 @BiometricAuthenticator.Modality int modality = 956 Utils.isCredentialRequested(authenticators) 957 ? BiometricAuthenticator.TYPE_CREDENTIAL 958 : BiometricAuthenticator.TYPE_NONE; 959 960 if (Utils.isBiometricRequested(authenticators)) { 961 @Authenticators.Types final int requestedStrength = 962 Utils.getPublicBiometricStrength(authenticators); 963 964 // Add modalities of all biometric sensors that meet the authenticator requirements. 965 for (final BiometricSensor sensor : mSensors) { 966 @Authenticators.Types final int sensorStrength = sensor.getCurrentStrength(); 967 if (Utils.isAtLeastStrength(sensorStrength, requestedStrength)) { 968 modality |= sensor.modality; 969 } 970 } 971 } 972 973 return modality; 974 } 975 976 @Override dump(@onNull FileDescriptor fd, @NonNull PrintWriter pw, String[] args)977 protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, String[] args) { 978 if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) { 979 return; 980 } 981 982 final long ident = Binder.clearCallingIdentity(); 983 try { 984 if (args.length > 0 && "--proto".equals(args[0])) { 985 final boolean clearSchedulerBuffer = args.length > 1 986 && "--clear-scheduler-buffer".equals(args[1]); 987 Slog.d(TAG, "ClearSchedulerBuffer: " + clearSchedulerBuffer); 988 final ProtoOutputStream proto = new ProtoOutputStream(fd); 989 proto.write(BiometricServiceStateProto.AUTH_SESSION_STATE, 990 mCurrentAuthSession != null ? mCurrentAuthSession.getState() 991 : STATE_AUTH_IDLE); 992 for (BiometricSensor sensor : mSensors) { 993 byte[] serviceState = sensor.impl 994 .dumpSensorServiceStateProto(clearSchedulerBuffer); 995 proto.write(BiometricServiceStateProto.SENSOR_SERVICE_STATES, serviceState); 996 } 997 proto.flush(); 998 } else { 999 dumpInternal(pw); 1000 } 1001 } catch (RemoteException e) { 1002 Slog.e(TAG, "Remote exception", e); 1003 } finally { 1004 Binder.restoreCallingIdentity(ident); 1005 } 1006 } 1007 } 1008 checkInternalPermission()1009 private void checkInternalPermission() { 1010 getContext().enforceCallingOrSelfPermission(USE_BIOMETRIC_INTERNAL, 1011 "Must have USE_BIOMETRIC_INTERNAL permission"); 1012 } 1013 1014 @NonNull createPreAuthInfo( @onNull String opPackageName, int userId, @Authenticators.Types int authenticators)1015 private PreAuthInfo createPreAuthInfo( 1016 @NonNull String opPackageName, 1017 int userId, 1018 @Authenticators.Types int authenticators) throws RemoteException { 1019 1020 final PromptInfo promptInfo = new PromptInfo(); 1021 promptInfo.setAuthenticators(authenticators); 1022 1023 return PreAuthInfo.create(mTrustManager, mDevicePolicyManager, mSettingObserver, mSensors, 1024 userId, promptInfo, opPackageName, false /* checkDevicePolicyManager */); 1025 } 1026 1027 /** 1028 * Class for injecting dependencies into BiometricService. 1029 * TODO(b/141025588): Replace with a dependency injection framework (e.g. Guice, Dagger). 1030 */ 1031 @VisibleForTesting 1032 public static class Injector { 1033 getActivityManagerService()1034 public IActivityManager getActivityManagerService() { 1035 return ActivityManager.getService(); 1036 } 1037 getTrustManager()1038 public ITrustManager getTrustManager() { 1039 return ITrustManager.Stub.asInterface(ServiceManager.getService(Context.TRUST_SERVICE)); 1040 } 1041 getStatusBarService()1042 public IStatusBarService getStatusBarService() { 1043 return IStatusBarService.Stub.asInterface( 1044 ServiceManager.getService(Context.STATUS_BAR_SERVICE)); 1045 } 1046 1047 /** 1048 * Allows to mock SettingObserver for testing. 1049 */ getSettingObserver(Context context, Handler handler, List<EnabledOnKeyguardCallback> callbacks)1050 public SettingObserver getSettingObserver(Context context, Handler handler, 1051 List<EnabledOnKeyguardCallback> callbacks) { 1052 return new SettingObserver(context, handler, callbacks); 1053 } 1054 getKeyStore()1055 public KeyStore getKeyStore() { 1056 return KeyStore.getInstance(); 1057 } 1058 1059 /** 1060 * Allows to enable/disable debug logs. 1061 */ isDebugEnabled(Context context, int userId)1062 public boolean isDebugEnabled(Context context, int userId) { 1063 return Utils.isDebugEnabled(context, userId); 1064 } 1065 1066 /** 1067 * Allows to stub publishBinderService(...) for testing. 1068 */ publishBinderService(BiometricService service, IBiometricService.Stub impl)1069 public void publishBinderService(BiometricService service, IBiometricService.Stub impl) { 1070 service.publishBinderService(Context.BIOMETRIC_SERVICE, impl); 1071 } 1072 1073 /** 1074 * Allows to mock BiometricStrengthController for testing. 1075 */ getBiometricStrengthController( BiometricService service)1076 public BiometricStrengthController getBiometricStrengthController( 1077 BiometricService service) { 1078 return new BiometricStrengthController(service); 1079 } 1080 1081 /** 1082 * Allows to test with various device sensor configurations. 1083 * @param context System Server context 1084 * @return the sensor configuration from core/res/res/values/config.xml 1085 */ getConfiguration(Context context)1086 public String[] getConfiguration(Context context) { 1087 return context.getResources().getStringArray(R.array.config_biometric_sensors); 1088 } 1089 getDevicePolicyManager(Context context)1090 public DevicePolicyManager getDevicePolicyManager(Context context) { 1091 return context.getSystemService(DevicePolicyManager.class); 1092 } 1093 getFingerprintSensorProperties( Context context)1094 public List<FingerprintSensorPropertiesInternal> getFingerprintSensorProperties( 1095 Context context) { 1096 if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) { 1097 final FingerprintManager fpm = context.getSystemService(FingerprintManager.class); 1098 if (fpm != null) { 1099 return fpm.getSensorPropertiesInternal(); 1100 } 1101 } 1102 return new ArrayList<>(); 1103 } 1104 isAdvancedCoexLogicEnabled(Context context)1105 public boolean isAdvancedCoexLogicEnabled(Context context) { 1106 return Settings.Secure.getInt(context.getContentResolver(), 1107 CoexCoordinator.SETTING_ENABLE_NAME, 1) != 0; 1108 } 1109 isCoexFaceNonBypassHapticsDisabled(Context context)1110 public boolean isCoexFaceNonBypassHapticsDisabled(Context context) { 1111 return Settings.Secure.getInt(context.getContentResolver(), 1112 CoexCoordinator.FACE_HAPTIC_DISABLE, 1) != 0; 1113 } 1114 } 1115 1116 /** 1117 * Initializes the system service. 1118 * <p> 1119 * Subclasses must define a single argument constructor that accepts the context 1120 * and passes it to super. 1121 * </p> 1122 * 1123 * @param context The system server context. 1124 */ BiometricService(Context context)1125 public BiometricService(Context context) { 1126 this(context, new Injector()); 1127 } 1128 1129 @VisibleForTesting BiometricService(Context context, Injector injector)1130 BiometricService(Context context, Injector injector) { 1131 super(context); 1132 1133 mInjector = injector; 1134 mDevicePolicyManager = mInjector.getDevicePolicyManager(context); 1135 mImpl = new BiometricServiceWrapper(); 1136 mEnabledOnKeyguardCallbacks = new ArrayList<>(); 1137 mSettingObserver = mInjector.getSettingObserver(context, mHandler, 1138 mEnabledOnKeyguardCallbacks); 1139 1140 // TODO(b/193089985) This logic lives here (outside of CoexCoordinator) so that it doesn't 1141 // need to depend on context. We can remove this code once the advanced logic is enabled 1142 // by default. 1143 CoexCoordinator coexCoordinator = CoexCoordinator.getInstance(); 1144 coexCoordinator.setAdvancedLogicEnabled(injector.isAdvancedCoexLogicEnabled(context)); 1145 coexCoordinator.setFaceHapticDisabledWhenNonBypass( 1146 injector.isCoexFaceNonBypassHapticsDisabled(context)); 1147 1148 try { 1149 injector.getActivityManagerService().registerUserSwitchObserver( 1150 new UserSwitchObserver() { 1151 @Override 1152 public void onUserSwitchComplete(int newUserId) { 1153 mSettingObserver.updateContentObserver(); 1154 mSettingObserver.notifyEnabledOnKeyguardCallbacks(newUserId); 1155 } 1156 }, BiometricService.class.getName() 1157 ); 1158 } catch (RemoteException e) { 1159 Slog.e(TAG, "Failed to register user switch observer", e); 1160 } 1161 } 1162 1163 @Override onStart()1164 public void onStart() { 1165 mKeyStore = mInjector.getKeyStore(); 1166 mStatusBarService = mInjector.getStatusBarService(); 1167 mTrustManager = mInjector.getTrustManager(); 1168 mInjector.publishBinderService(this, mImpl); 1169 mBiometricStrengthController = mInjector.getBiometricStrengthController(this); 1170 mBiometricStrengthController.startListening(); 1171 } 1172 isStrongBiometric(int id)1173 private boolean isStrongBiometric(int id) { 1174 for (BiometricSensor sensor : mSensors) { 1175 if (sensor.id == id) { 1176 return Utils.isAtLeastStrength(sensor.getCurrentStrength(), 1177 Authenticators.BIOMETRIC_STRONG); 1178 } 1179 } 1180 Slog.e(TAG, "Unknown sensorId: " + id); 1181 return false; 1182 } 1183 handleAuthenticationSucceeded(int sensorId, byte[] token)1184 private void handleAuthenticationSucceeded(int sensorId, byte[] token) { 1185 Slog.v(TAG, "handleAuthenticationSucceeded(), sensorId: " + sensorId); 1186 // Should never happen, log this to catch bad HAL behavior (e.g. auth succeeded 1187 // after user dismissed/canceled dialog). 1188 if (mCurrentAuthSession == null) { 1189 Slog.e(TAG, "handleAuthenticationSucceeded: AuthSession is null"); 1190 return; 1191 } 1192 1193 mCurrentAuthSession.onAuthenticationSucceeded(sensorId, isStrongBiometric(sensorId), token); 1194 } 1195 handleAuthenticationRejected()1196 private void handleAuthenticationRejected() { 1197 Slog.v(TAG, "handleAuthenticationRejected()"); 1198 1199 // Should never happen, log this to catch bad HAL behavior (e.g. auth rejected 1200 // after user dismissed/canceled dialog). 1201 if (mCurrentAuthSession == null) { 1202 Slog.e(TAG, "handleAuthenticationRejected: AuthSession is null"); 1203 return; 1204 } 1205 1206 mCurrentAuthSession.onAuthenticationRejected(); 1207 } 1208 handleAuthenticationTimedOut(int sensorId, int cookie, int error, int vendorCode)1209 private void handleAuthenticationTimedOut(int sensorId, int cookie, int error, int vendorCode) { 1210 Slog.v(TAG, "handleAuthenticationTimedOut(), sensorId: " + sensorId 1211 + ", cookie: " + cookie 1212 + ", error: " + error 1213 + ", vendorCode: " + vendorCode); 1214 // Should never happen, log this to catch bad HAL behavior (e.g. auth succeeded 1215 // after user dismissed/canceled dialog). 1216 if (mCurrentAuthSession == null) { 1217 Slog.e(TAG, "handleAuthenticationTimedOut: AuthSession is null"); 1218 return; 1219 } 1220 1221 mCurrentAuthSession.onAuthenticationTimedOut(sensorId, cookie, error, vendorCode); 1222 } 1223 handleOnError(int sensorId, int cookie, @BiometricConstants.Errors int error, int vendorCode)1224 private void handleOnError(int sensorId, int cookie, @BiometricConstants.Errors int error, 1225 int vendorCode) { 1226 Slog.d(TAG, "handleOnError() sensorId: " + sensorId 1227 + ", cookie: " + cookie 1228 + ", error: " + error 1229 + ", vendorCode: " + vendorCode); 1230 1231 if (mCurrentAuthSession == null) { 1232 Slog.e(TAG, "handleOnError: AuthSession is null"); 1233 return; 1234 } 1235 1236 try { 1237 final boolean finished = mCurrentAuthSession 1238 .onErrorReceived(sensorId, cookie, error, vendorCode); 1239 if (finished) { 1240 Slog.d(TAG, "handleOnError: AuthSession finished"); 1241 mCurrentAuthSession = null; 1242 } 1243 } catch (RemoteException e) { 1244 Slog.e(TAG, "RemoteException", e); 1245 } 1246 } 1247 handleOnAcquired(int sensorId, int acquiredInfo, int vendorCode)1248 private void handleOnAcquired(int sensorId, int acquiredInfo, int vendorCode) { 1249 // Should never happen, log this to catch bad HAL behavior (e.g. auth succeeded 1250 // after user dismissed/canceled dialog). 1251 if (mCurrentAuthSession == null) { 1252 Slog.e(TAG, "onAcquired: AuthSession is null"); 1253 return; 1254 } 1255 1256 mCurrentAuthSession.onAcquired(sensorId, acquiredInfo, vendorCode); 1257 } 1258 handleOnDismissed(@iometricPrompt.DismissedReason int reason, @Nullable byte[] credentialAttestation)1259 private void handleOnDismissed(@BiometricPrompt.DismissedReason int reason, 1260 @Nullable byte[] credentialAttestation) { 1261 if (mCurrentAuthSession == null) { 1262 Slog.e(TAG, "onDismissed: " + reason + ", AuthSession is null"); 1263 return; 1264 } 1265 1266 mCurrentAuthSession.onDialogDismissed(reason, credentialAttestation); 1267 mCurrentAuthSession = null; 1268 } 1269 handleOnTryAgainPressed()1270 private void handleOnTryAgainPressed() { 1271 Slog.d(TAG, "onTryAgainPressed"); 1272 // No need to check permission, since it can only be invoked by SystemUI 1273 // (or system server itself). 1274 if (mCurrentAuthSession == null) { 1275 Slog.e(TAG, "handleOnTryAgainPressed: AuthSession is null"); 1276 return; 1277 } 1278 1279 mCurrentAuthSession.onTryAgainPressed(); 1280 } 1281 handleOnDeviceCredentialPressed()1282 private void handleOnDeviceCredentialPressed() { 1283 Slog.d(TAG, "onDeviceCredentialPressed"); 1284 if (mCurrentAuthSession == null) { 1285 Slog.e(TAG, "handleOnDeviceCredentialPressed: AuthSession is null"); 1286 return; 1287 } 1288 1289 mCurrentAuthSession.onDeviceCredentialPressed(); 1290 } 1291 handleOnSystemEvent(int event)1292 private void handleOnSystemEvent(int event) { 1293 Slog.d(TAG, "onSystemEvent: " + event); 1294 1295 if (mCurrentAuthSession == null) { 1296 Slog.e(TAG, "handleOnSystemEvent: AuthSession is null"); 1297 return; 1298 } 1299 1300 mCurrentAuthSession.onSystemEvent(event); 1301 } 1302 handleClientDied()1303 private void handleClientDied() { 1304 if (mCurrentAuthSession == null) { 1305 Slog.e(TAG, "handleClientDied: AuthSession is null"); 1306 return; 1307 } 1308 1309 Slog.e(TAG, "Session: " + mCurrentAuthSession); 1310 final boolean finished = mCurrentAuthSession.onClientDied(); 1311 if (finished) { 1312 mCurrentAuthSession = null; 1313 } 1314 } 1315 handleOnDialogAnimatedIn()1316 private void handleOnDialogAnimatedIn() { 1317 Slog.d(TAG, "handleOnDialogAnimatedIn"); 1318 if (mCurrentAuthSession == null) { 1319 Slog.e(TAG, "handleOnDialogAnimatedIn: AuthSession is null"); 1320 return; 1321 } 1322 1323 mCurrentAuthSession.onDialogAnimatedIn(); 1324 } 1325 handleOnStartFingerprintNow()1326 private void handleOnStartFingerprintNow() { 1327 Slog.d(TAG, "handleOnStartFingerprintNow"); 1328 if (mCurrentAuthSession == null) { 1329 Slog.e(TAG, "handleOnStartFingerprintNow: AuthSession is null"); 1330 return; 1331 } 1332 1333 mCurrentAuthSession.onStartFingerprint(); 1334 } 1335 1336 /** 1337 * Invoked when each service has notified that its client is ready to be started. When 1338 * all biometrics are ready, this invokes the SystemUI dialog through StatusBar. 1339 */ handleOnReadyForAuthentication(int cookie)1340 private void handleOnReadyForAuthentication(int cookie) { 1341 if (mCurrentAuthSession == null) { 1342 // Only should happen if a biometric was locked out when authenticate() was invoked. 1343 // In that case, if device credentials are allowed, the UI is already showing. If not 1344 // allowed, the error has already been returned to the caller. 1345 Slog.w(TAG, "handleOnReadyForAuthentication: AuthSession is null"); 1346 return; 1347 } 1348 1349 mCurrentAuthSession.onCookieReceived(cookie); 1350 } 1351 handleAuthenticate(IBinder token, long operationId, int userId, IBiometricServiceReceiver receiver, String opPackageName, PromptInfo promptInfo)1352 private void handleAuthenticate(IBinder token, long operationId, int userId, 1353 IBiometricServiceReceiver receiver, String opPackageName, PromptInfo promptInfo) { 1354 mHandler.post(() -> { 1355 try { 1356 final PreAuthInfo preAuthInfo = PreAuthInfo.create(mTrustManager, 1357 mDevicePolicyManager, mSettingObserver, mSensors, userId, promptInfo, 1358 opPackageName, promptInfo.isDisallowBiometricsIfPolicyExists()); 1359 1360 final Pair<Integer, Integer> preAuthStatus = preAuthInfo.getPreAuthenticateStatus(); 1361 1362 Slog.d(TAG, "handleAuthenticate: modality(" + preAuthStatus.first 1363 + "), status(" + preAuthStatus.second + "), preAuthInfo: " + preAuthInfo); 1364 1365 if (preAuthStatus.second == BiometricConstants.BIOMETRIC_SUCCESS) { 1366 // If BIOMETRIC_WEAK or BIOMETRIC_STRONG are allowed, but not enrolled, but 1367 // CREDENTIAL is requested and available, set the bundle to only request 1368 // CREDENTIAL. 1369 // TODO: We should clean this up, as well as the interface with SystemUI 1370 if (preAuthInfo.credentialRequested && preAuthInfo.credentialAvailable 1371 && preAuthInfo.eligibleSensors.isEmpty()) { 1372 promptInfo.setAuthenticators(Authenticators.DEVICE_CREDENTIAL); 1373 } 1374 1375 authenticateInternal(token, operationId, userId, receiver, opPackageName, 1376 promptInfo, preAuthInfo); 1377 } else { 1378 receiver.onError(preAuthStatus.first /* modality */, 1379 preAuthStatus.second /* errorCode */, 1380 0 /* vendorCode */); 1381 } 1382 } catch (RemoteException e) { 1383 Slog.e(TAG, "Remote exception", e); 1384 } 1385 }); 1386 } 1387 1388 /** 1389 * handleAuthenticate() (above) which is called from BiometricPrompt determines which 1390 * modality/modalities to start authenticating with. authenticateInternal() should only be 1391 * used for preparing <Biometric>Services for authentication when BiometricPrompt#authenticate 1392 * is invoked, shortly after which BiometricPrompt is shown and authentication starts. 1393 * 1394 * Note that this path is NOT invoked when the BiometricPrompt "Try again" button is pressed. 1395 * In that case, see {@link #handleOnTryAgainPressed()}. 1396 */ authenticateInternal(IBinder token, long operationId, int userId, IBiometricServiceReceiver receiver, String opPackageName, PromptInfo promptInfo, PreAuthInfo preAuthInfo)1397 private void authenticateInternal(IBinder token, long operationId, int userId, 1398 IBiometricServiceReceiver receiver, String opPackageName, PromptInfo promptInfo, 1399 PreAuthInfo preAuthInfo) { 1400 Slog.d(TAG, "Creating authSession with authRequest: " + preAuthInfo); 1401 1402 // No need to dismiss dialog / send error yet if we're continuing authentication, e.g. 1403 // "Try again" is showing due to something like ERROR_TIMEOUT. 1404 if (mCurrentAuthSession != null) { 1405 // Forcefully cancel authentication. Dismiss the UI, and immediately send 1406 // ERROR_CANCELED to the client. Note that we should/will ignore HAL ERROR_CANCELED. 1407 // Expect to see some harmless "unknown cookie" errors. 1408 Slog.w(TAG, "Existing AuthSession: " + mCurrentAuthSession); 1409 mCurrentAuthSession.onCancelAuthSession(true /* force */); 1410 mCurrentAuthSession = null; 1411 } 1412 1413 final boolean debugEnabled = mInjector.isDebugEnabled(getContext(), userId); 1414 mCurrentAuthSession = new AuthSession(getContext(), mStatusBarService, mSysuiReceiver, 1415 mKeyStore, mRandom, mClientDeathReceiver, preAuthInfo, token, operationId, userId, 1416 mBiometricSensorReceiver, receiver, opPackageName, promptInfo, debugEnabled, 1417 mInjector.getFingerprintSensorProperties(getContext())); 1418 try { 1419 mCurrentAuthSession.goToInitialState(); 1420 } catch (RemoteException e) { 1421 Slog.e(TAG, "RemoteException", e); 1422 } 1423 } 1424 handleCancelAuthentication()1425 private void handleCancelAuthentication() { 1426 if (mCurrentAuthSession == null) { 1427 Slog.e(TAG, "handleCancelAuthentication: AuthSession is null"); 1428 return; 1429 } 1430 1431 final boolean finished = mCurrentAuthSession.onCancelAuthSession(false /* force */); 1432 if (finished) { 1433 Slog.d(TAG, "handleCancelAuthentication: AuthSession finished"); 1434 mCurrentAuthSession = null; 1435 } 1436 } 1437 1438 @Nullable getSensorForId(int sensorId)1439 private BiometricSensor getSensorForId(int sensorId) { 1440 for (BiometricSensor sensor : mSensors) { 1441 if (sensor.id == sensorId) { 1442 return sensor; 1443 } 1444 } 1445 return null; 1446 } 1447 dumpInternal(PrintWriter pw)1448 private void dumpInternal(PrintWriter pw) { 1449 pw.println("Legacy Settings: " + mSettingObserver.mUseLegacyFaceOnlySettings); 1450 pw.println(); 1451 1452 pw.println("Sensors:"); 1453 for (BiometricSensor sensor : mSensors) { 1454 pw.println(" " + sensor); 1455 } 1456 pw.println(); 1457 pw.println("CurrentSession: " + mCurrentAuthSession); 1458 pw.println(); 1459 pw.println("CoexCoordinator: " + CoexCoordinator.getInstance().toString()); 1460 pw.println(); 1461 } 1462 } 1463