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.BiometricAuthenticator.TYPE_ANY_BIOMETRIC; 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.hardware.biometrics.BiometricManager.BIOMETRIC_NO_AUTHENTICATION; 25 import static android.hardware.biometrics.SensorProperties.STRENGTH_STRONG; 26 27 import static com.android.server.biometrics.BiometricServiceStateProto.STATE_AUTH_IDLE; 28 29 import android.annotation.NonNull; 30 import android.annotation.Nullable; 31 import android.app.ActivityManager; 32 import android.app.IActivityManager; 33 import android.app.UserSwitchObserver; 34 import android.app.admin.DevicePolicyManager; 35 import android.app.trust.ITrustManager; 36 import android.content.ComponentName; 37 import android.content.ContentResolver; 38 import android.content.Context; 39 import android.content.pm.PackageManager; 40 import android.content.pm.UserInfo; 41 import android.database.ContentObserver; 42 import android.hardware.SensorPrivacyManager; 43 import android.hardware.biometrics.BiometricAuthenticator; 44 import android.hardware.biometrics.BiometricConstants; 45 import android.hardware.biometrics.BiometricPrompt; 46 import android.hardware.biometrics.BiometricStateListener; 47 import android.hardware.biometrics.IBiometricAuthenticator; 48 import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback; 49 import android.hardware.biometrics.IBiometricSensorReceiver; 50 import android.hardware.biometrics.IBiometricService; 51 import android.hardware.biometrics.IBiometricServiceReceiver; 52 import android.hardware.biometrics.IBiometricSysuiReceiver; 53 import android.hardware.biometrics.IInvalidationCallback; 54 import android.hardware.biometrics.ITestSession; 55 import android.hardware.biometrics.ITestSessionCallback; 56 import android.hardware.biometrics.PromptInfo; 57 import android.hardware.biometrics.SensorPropertiesInternal; 58 import android.hardware.camera2.CameraManager; 59 import android.hardware.face.FaceManager; 60 import android.hardware.face.FaceSensorPropertiesInternal; 61 import android.hardware.face.IFaceAuthenticatorsRegisteredCallback; 62 import android.hardware.fingerprint.FingerprintManager; 63 import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; 64 import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback; 65 import android.hardware.security.keymint.HardwareAuthenticatorType; 66 import android.net.Uri; 67 import android.os.Binder; 68 import android.os.Build; 69 import android.os.DeadObjectException; 70 import android.os.Handler; 71 import android.os.IBinder; 72 import android.os.RemoteException; 73 import android.os.ServiceManager; 74 import android.os.UserHandle; 75 import android.os.UserManager; 76 import android.provider.Settings; 77 import android.security.GateKeeper; 78 import android.security.KeyStoreAuthorization; 79 import android.service.gatekeeper.IGateKeeperService; 80 import android.text.TextUtils; 81 import android.util.ArraySet; 82 import android.util.Pair; 83 import android.util.Slog; 84 import android.util.SparseBooleanArray; 85 import android.util.proto.ProtoOutputStream; 86 87 import com.android.internal.R; 88 import com.android.internal.annotations.VisibleForTesting; 89 import com.android.internal.os.SomeArgs; 90 import com.android.internal.statusbar.IStatusBarService; 91 import com.android.internal.util.DumpUtils; 92 import com.android.server.SystemService; 93 import com.android.server.biometrics.log.BiometricContext; 94 import com.android.server.utils.Slogf; 95 96 import java.io.FileDescriptor; 97 import java.io.PrintWriter; 98 import java.util.ArrayList; 99 import java.util.HashMap; 100 import java.util.List; 101 import java.util.Map; 102 import java.util.Random; 103 import java.util.Set; 104 import java.util.concurrent.CopyOnWriteArrayList; 105 import java.util.concurrent.atomic.AtomicLong; 106 import java.util.function.Supplier; 107 108 /** 109 * System service that arbitrates the modality for BiometricPrompt to use. 110 */ 111 public class BiometricService extends SystemService { 112 113 static final String TAG = "BiometricService"; 114 115 private final Injector mInjector; 116 private final DevicePolicyManager mDevicePolicyManager; 117 @VisibleForTesting 118 final IBiometricService.Stub mImpl; 119 @VisibleForTesting 120 final SettingObserver mSettingObserver; 121 private final List<EnabledOnKeyguardCallback> mEnabledOnKeyguardCallbacks; 122 private final Random mRandom = new Random(); 123 @NonNull private final Supplier<Long> mRequestCounter; 124 @NonNull private final BiometricContext mBiometricContext; 125 private final UserManager mUserManager; 126 127 @VisibleForTesting 128 IStatusBarService mStatusBarService; 129 @VisibleForTesting 130 ITrustManager mTrustManager; 131 @VisibleForTesting 132 KeyStoreAuthorization mKeyStoreAuthorization; 133 @VisibleForTesting 134 IGateKeeperService mGateKeeper; 135 136 // Get and cache the available biometric authenticators and their associated info. 137 final CopyOnWriteArrayList<BiometricSensor> mSensors = new CopyOnWriteArrayList<>(); 138 139 @VisibleForTesting 140 BiometricStrengthController mBiometricStrengthController; 141 142 // The current authentication session, null if idle/done. 143 @VisibleForTesting 144 AuthSession mAuthSession; 145 private final Handler mHandler; 146 147 private final BiometricCameraManager mBiometricCameraManager; 148 149 private final BiometricNotificationLogger mBiometricNotificationLogger; 150 151 /** 152 * Tracks authenticatorId invalidation. For more details, see 153 * {@link com.android.server.biometrics.sensors.InvalidationRequesterClient}. 154 */ 155 @VisibleForTesting 156 static class InvalidationTracker { 157 @NonNull private final IInvalidationCallback mClientCallback; 158 @NonNull private final Set<Integer> mSensorsPendingInvalidation; 159 start(@onNull Context context, @NonNull List<BiometricSensor> sensors, int userId, int fromSensorId, @NonNull IInvalidationCallback clientCallback)160 public static InvalidationTracker start(@NonNull Context context, 161 @NonNull List<BiometricSensor> sensors, int userId, 162 int fromSensorId, @NonNull IInvalidationCallback clientCallback) { 163 return new InvalidationTracker(context, sensors, userId, fromSensorId, clientCallback); 164 } 165 InvalidationTracker(@onNull Context context, @NonNull List<BiometricSensor> sensors, int userId, int fromSensorId, @NonNull IInvalidationCallback clientCallback)166 private InvalidationTracker(@NonNull Context context, 167 @NonNull List<BiometricSensor> sensors, int userId, 168 int fromSensorId, @NonNull IInvalidationCallback clientCallback) { 169 mClientCallback = clientCallback; 170 mSensorsPendingInvalidation = new ArraySet<>(); 171 172 for (BiometricSensor sensor : sensors) { 173 if (sensor.id == fromSensorId) { 174 continue; 175 } 176 177 if (!Utils.isAtLeastStrength(sensor.oemStrength, Authenticators.BIOMETRIC_STRONG)) { 178 continue; 179 } 180 181 try { 182 if (!sensor.impl.hasEnrolledTemplates(userId, context.getOpPackageName())) { 183 continue; 184 } 185 } catch (RemoteException e) { 186 Slog.e(TAG, "Remote Exception", e); 187 } 188 189 Slog.d(TAG, "Requesting authenticatorId invalidation for sensor: " + sensor.id); 190 191 synchronized (this) { 192 mSensorsPendingInvalidation.add(sensor.id); 193 } 194 195 try { 196 sensor.impl.invalidateAuthenticatorId(userId, new IInvalidationCallback.Stub() { 197 @Override 198 public void onCompleted() { 199 onInvalidated(sensor.id); 200 } 201 }); 202 } catch (RemoteException e) { 203 Slog.d(TAG, "RemoteException", e); 204 } 205 } 206 207 synchronized (this) { 208 if (mSensorsPendingInvalidation.isEmpty()) { 209 try { 210 Slog.d(TAG, "No sensors require invalidation"); 211 mClientCallback.onCompleted(); 212 } catch (RemoteException e) { 213 Slog.e(TAG, "Remote Exception", e); 214 } 215 } 216 } 217 } 218 219 @VisibleForTesting onInvalidated(int sensorId)220 void onInvalidated(int sensorId) { 221 synchronized (this) { 222 mSensorsPendingInvalidation.remove(sensorId); 223 224 Slog.d(TAG, "Sensor " + sensorId + " invalidated, remaining size: " 225 + mSensorsPendingInvalidation.size()); 226 227 if (mSensorsPendingInvalidation.isEmpty()) { 228 try { 229 mClientCallback.onCompleted(); 230 } catch (RemoteException e) { 231 Slog.e(TAG, "Remote Exception", e); 232 } 233 } 234 } 235 } 236 } 237 238 @VisibleForTesting 239 public static class SettingObserver extends ContentObserver { 240 241 private static final boolean DEFAULT_KEYGUARD_ENABLED = true; 242 private static final boolean DEFAULT_APP_ENABLED = true; 243 private static final boolean DEFAULT_ALWAYS_REQUIRE_CONFIRMATION = false; 244 private static final boolean DEFAULT_MANDATORY_BIOMETRICS_STATUS = false; 245 private static final boolean DEFAULT_MANDATORY_BIOMETRICS_REQUIREMENTS_SATISFIED_STATUS = 246 true; 247 248 // Some devices that shipped before S already have face-specific settings. Instead of 249 // migrating, which is complicated, let's just keep using the existing settings. 250 private final boolean mUseLegacyFaceOnlySettings; 251 252 // Only used for legacy face-only devices 253 private final Uri FACE_UNLOCK_KEYGUARD_ENABLED = 254 Settings.Secure.getUriFor(Settings.Secure.FACE_UNLOCK_KEYGUARD_ENABLED); 255 private final Uri FACE_UNLOCK_APP_ENABLED = 256 Settings.Secure.getUriFor(Settings.Secure.FACE_UNLOCK_APP_ENABLED); 257 258 // Continues to be used, even though it's face-specific. 259 private final Uri FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION = 260 Settings.Secure.getUriFor(Settings.Secure.FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION); 261 262 // Used for all devices other than legacy face-only devices 263 private final Uri BIOMETRIC_KEYGUARD_ENABLED = 264 Settings.Secure.getUriFor(Settings.Secure.BIOMETRIC_KEYGUARD_ENABLED); 265 private final Uri BIOMETRIC_APP_ENABLED = 266 Settings.Secure.getUriFor(Settings.Secure.BIOMETRIC_APP_ENABLED); 267 private final Uri FACE_KEYGUARD_ENABLED = 268 Settings.Secure.getUriFor(Settings.Secure.FACE_KEYGUARD_ENABLED); 269 private final Uri FACE_APP_ENABLED = 270 Settings.Secure.getUriFor(Settings.Secure.FACE_APP_ENABLED); 271 private final Uri FINGERPRINT_KEYGUARD_ENABLED = 272 Settings.Secure.getUriFor(Settings.Secure.FINGERPRINT_KEYGUARD_ENABLED); 273 private final Uri FINGERPRINT_APP_ENABLED = 274 Settings.Secure.getUriFor(Settings.Secure.FINGERPRINT_APP_ENABLED); 275 private final Uri MANDATORY_BIOMETRICS_ENABLED = 276 Settings.Secure.getUriFor(Settings.Secure.MANDATORY_BIOMETRICS); 277 private final Uri MANDATORY_BIOMETRICS_REQUIREMENTS_SATISFIED = Settings.Secure.getUriFor( 278 Settings.Secure.MANDATORY_BIOMETRICS_REQUIREMENTS_SATISFIED); 279 280 private final ContentResolver mContentResolver; 281 private final List<BiometricService.EnabledOnKeyguardCallback> mCallbacks; 282 private final UserManager mUserManager; 283 284 private final Map<Integer, Boolean> mBiometricEnabledOnKeyguard = new HashMap<>(); 285 private final Map<Integer, Boolean> mBiometricEnabledForApps = new HashMap<>(); 286 private final SparseBooleanArray mFaceEnabledOnKeyguard = new SparseBooleanArray(); 287 private final SparseBooleanArray mFaceEnabledForApps = new SparseBooleanArray(); 288 private final SparseBooleanArray mFingerprintEnabledOnKeyguard = new SparseBooleanArray(); 289 private final SparseBooleanArray mFingerprintEnabledForApps = new SparseBooleanArray(); 290 private final Map<Integer, Boolean> mFaceAlwaysRequireConfirmation = new HashMap<>(); 291 private final Map<Integer, Boolean> mMandatoryBiometricsEnabled = new HashMap<>(); 292 private final Map<Integer, Boolean> mMandatoryBiometricsRequirementsSatisfied = 293 new HashMap<>(); 294 private final Map<Integer, Boolean> mFingerprintEnrolledForUser = 295 new HashMap<>(); 296 private final Map<Integer, Boolean> mFaceEnrolledForUser = 297 new HashMap<>(); 298 299 /** 300 * Creates a content observer. 301 * 302 * @param handler The handler to run {@link #onChange} on, or null if none. 303 */ SettingObserver(Context context, Handler handler, List<BiometricService.EnabledOnKeyguardCallback> callbacks, UserManager userManager, FingerprintManager fingerprintManager, FaceManager faceManager)304 public SettingObserver(Context context, Handler handler, 305 List<BiometricService.EnabledOnKeyguardCallback> callbacks, 306 UserManager userManager, FingerprintManager fingerprintManager, 307 FaceManager faceManager) { 308 super(handler); 309 mContentResolver = context.getContentResolver(); 310 mCallbacks = callbacks; 311 mUserManager = userManager; 312 313 final boolean hasFingerprint = context.getPackageManager() 314 .hasSystemFeature(PackageManager.FEATURE_FINGERPRINT); 315 final boolean hasFace = context.getPackageManager() 316 .hasSystemFeature(PackageManager.FEATURE_FACE); 317 318 // Use the legacy setting on face-only devices that shipped on or before Q 319 mUseLegacyFaceOnlySettings = 320 Build.VERSION.DEVICE_INITIAL_SDK_INT <= Build.VERSION_CODES.Q 321 && hasFace && !hasFingerprint; 322 323 addBiometricListenersForMandatoryBiometrics(context, fingerprintManager, faceManager); 324 updateContentObserver(); 325 } 326 updateContentObserver()327 public void updateContentObserver() { 328 mContentResolver.unregisterContentObserver(this); 329 330 if (mUseLegacyFaceOnlySettings) { 331 mContentResolver.registerContentObserver(FACE_UNLOCK_KEYGUARD_ENABLED, 332 false /* notifyForDescendants */, 333 this /* observer */, 334 UserHandle.USER_ALL); 335 mContentResolver.registerContentObserver(FACE_UNLOCK_APP_ENABLED, 336 false /* notifyForDescendants */, 337 this /* observer */, 338 UserHandle.USER_ALL); 339 } else if (com.android.settings.flags.Flags.biometricsOnboardingEducation()) { 340 mContentResolver.registerContentObserver(FINGERPRINT_KEYGUARD_ENABLED, 341 false /* notifyForDescendants */, 342 this /* observer */, 343 UserHandle.USER_ALL); 344 mContentResolver.registerContentObserver(FACE_KEYGUARD_ENABLED, 345 false /* notifyForDescendants */, 346 this /* observer */, 347 UserHandle.USER_ALL); 348 mContentResolver.registerContentObserver(FINGERPRINT_APP_ENABLED, 349 false /* notifyForDescendants */, 350 this /* observer */, 351 UserHandle.USER_ALL); 352 mContentResolver.registerContentObserver(FACE_APP_ENABLED, 353 false /* notifyForDescendants */, 354 this /* observer */, 355 UserHandle.USER_ALL); 356 } else { 357 mContentResolver.registerContentObserver(BIOMETRIC_KEYGUARD_ENABLED, 358 false /* notifyForDescendants */, 359 this /* observer */, 360 UserHandle.USER_ALL); 361 mContentResolver.registerContentObserver(BIOMETRIC_APP_ENABLED, 362 false /* notifyForDescendants */, 363 this /* observer */, 364 UserHandle.USER_ALL); 365 } 366 mContentResolver.registerContentObserver(FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION, 367 false /* notifyForDescendants */, 368 this /* observer */, 369 UserHandle.USER_ALL); 370 mContentResolver.registerContentObserver(MANDATORY_BIOMETRICS_ENABLED, 371 false /* notifyForDescendants */, 372 this /* observer */, 373 UserHandle.USER_ALL); 374 mContentResolver.registerContentObserver(MANDATORY_BIOMETRICS_REQUIREMENTS_SATISFIED, 375 false /* notifyForDescendants */, 376 this /* observer */, 377 UserHandle.USER_ALL); 378 } 379 380 @Override onChange(boolean selfChange, Uri uri, int userId)381 public void onChange(boolean selfChange, Uri uri, int userId) { 382 if (FACE_UNLOCK_KEYGUARD_ENABLED.equals(uri)) { 383 mBiometricEnabledOnKeyguard.put(userId, Settings.Secure.getIntForUser( 384 mContentResolver, 385 Settings.Secure.FACE_UNLOCK_KEYGUARD_ENABLED, 386 DEFAULT_KEYGUARD_ENABLED ? 1 : 0 /* default */, 387 userId) != 0); 388 389 if (userId == ActivityManager.getCurrentUser() && !selfChange) { 390 notifyEnabledOnKeyguardCallbacks(userId, TYPE_FACE); 391 } 392 } else if (FACE_UNLOCK_APP_ENABLED.equals(uri)) { 393 mBiometricEnabledForApps.put(userId, Settings.Secure.getIntForUser( 394 mContentResolver, 395 Settings.Secure.FACE_UNLOCK_APP_ENABLED, 396 DEFAULT_APP_ENABLED ? 1 : 0 /* default */, 397 userId) != 0); 398 } else if (FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION.equals(uri)) { 399 mFaceAlwaysRequireConfirmation.put(userId, Settings.Secure.getIntForUser( 400 mContentResolver, 401 Settings.Secure.FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION, 402 DEFAULT_ALWAYS_REQUIRE_CONFIRMATION ? 1 : 0 /* default */, 403 userId) != 0); 404 } else if (BIOMETRIC_KEYGUARD_ENABLED.equals(uri)) { 405 mBiometricEnabledOnKeyguard.put(userId, Settings.Secure.getIntForUser( 406 mContentResolver, 407 Settings.Secure.BIOMETRIC_KEYGUARD_ENABLED, 408 DEFAULT_KEYGUARD_ENABLED ? 1 : 0 /* default */, 409 userId) != 0); 410 411 if (userId == ActivityManager.getCurrentUser() && !selfChange) { 412 notifyEnabledOnKeyguardCallbacks(userId, TYPE_ANY_BIOMETRIC); 413 } 414 } else if (FACE_KEYGUARD_ENABLED.equals(uri)) { 415 mFaceEnabledOnKeyguard.put(userId, Settings.Secure.getIntForUser( 416 mContentResolver, 417 Settings.Secure.FACE_KEYGUARD_ENABLED, 418 DEFAULT_KEYGUARD_ENABLED ? 1 : 0 /* default */, 419 userId) != 0); 420 421 if (userId == ActivityManager.getCurrentUser() && !selfChange) { 422 notifyEnabledOnKeyguardCallbacks(userId, TYPE_FACE); 423 } 424 } else if (FINGERPRINT_KEYGUARD_ENABLED.equals(uri)) { 425 mFingerprintEnabledOnKeyguard.put(userId, Settings.Secure.getIntForUser( 426 mContentResolver, 427 Settings.Secure.FINGERPRINT_KEYGUARD_ENABLED, 428 DEFAULT_KEYGUARD_ENABLED ? 1 : 0 /* default */, 429 userId) != 0); 430 431 if (userId == ActivityManager.getCurrentUser() && !selfChange) { 432 notifyEnabledOnKeyguardCallbacks(userId, TYPE_FINGERPRINT); 433 } 434 } else if (BIOMETRIC_APP_ENABLED.equals(uri)) { 435 mBiometricEnabledForApps.put(userId, Settings.Secure.getIntForUser( 436 mContentResolver, 437 Settings.Secure.BIOMETRIC_APP_ENABLED, 438 DEFAULT_APP_ENABLED ? 1 : 0 /* default */, 439 userId) != 0); 440 } else if (FACE_APP_ENABLED.equals(uri)) { 441 mFaceEnabledForApps.put(userId, Settings.Secure.getIntForUser( 442 mContentResolver, 443 Settings.Secure.FACE_APP_ENABLED, 444 DEFAULT_APP_ENABLED ? 1 : 0 /* default */, 445 userId) != 0); 446 } else if (FINGERPRINT_APP_ENABLED.equals(uri)) { 447 mFingerprintEnabledForApps.put(userId, Settings.Secure.getIntForUser( 448 mContentResolver, 449 Settings.Secure.FINGERPRINT_APP_ENABLED, 450 DEFAULT_APP_ENABLED ? 1 : 0 /* default */, 451 userId) != 0); 452 } else if (MANDATORY_BIOMETRICS_ENABLED.equals(uri)) { 453 updateMandatoryBiometricsForAllProfiles(userId); 454 } else if (MANDATORY_BIOMETRICS_REQUIREMENTS_SATISFIED.equals(uri)) { 455 updateMandatoryBiometricsRequirementsForAllProfiles(userId); 456 } 457 } 458 getEnabledOnKeyguard(int userId, int modality)459 public boolean getEnabledOnKeyguard(int userId, int modality) { 460 if (com.android.settings.flags.Flags.biometricsOnboardingEducation()) { 461 if (modality == TYPE_FACE) { 462 if (mFaceEnabledOnKeyguard.indexOfKey(userId) < 0) { 463 onChange(true /* selfChange */, FACE_KEYGUARD_ENABLED, userId); 464 } 465 return mFaceEnabledOnKeyguard.get(userId, DEFAULT_KEYGUARD_ENABLED); 466 } else if (modality == TYPE_FINGERPRINT) { 467 if (mFingerprintEnabledOnKeyguard.indexOfKey(userId) < 0) { 468 onChange(true /* selfChange */, FINGERPRINT_KEYGUARD_ENABLED, userId); 469 } 470 return mFingerprintEnabledOnKeyguard.get(userId, DEFAULT_KEYGUARD_ENABLED); 471 } else { // modality == TYPE_ANY_BIOMETRIC 472 return mFingerprintEnabledOnKeyguard.get(userId, DEFAULT_KEYGUARD_ENABLED) 473 || mFaceEnabledOnKeyguard.get(userId, DEFAULT_KEYGUARD_ENABLED); 474 } 475 } else { 476 if (!mBiometricEnabledOnKeyguard.containsKey(userId)) { 477 if (mUseLegacyFaceOnlySettings) { 478 onChange(true /* selfChange */, FACE_UNLOCK_KEYGUARD_ENABLED, userId); 479 } else { 480 onChange(true /* selfChange */, BIOMETRIC_KEYGUARD_ENABLED, userId); 481 } 482 } 483 return mBiometricEnabledOnKeyguard.get(userId); 484 } 485 } 486 getEnabledForApps(int userId, int modality)487 public boolean getEnabledForApps(int userId, int modality) { 488 if (com.android.settings.flags.Flags.biometricsOnboardingEducation()) { 489 if (modality == TYPE_FACE) { 490 if (mFaceEnabledForApps.indexOfKey(userId) < 0) { 491 onChange(true /* selfChange */, FACE_APP_ENABLED, userId); 492 } 493 return mFaceEnabledForApps.get(userId, DEFAULT_APP_ENABLED); 494 } else if (modality == TYPE_FINGERPRINT) { 495 if (mFingerprintEnabledForApps.indexOfKey(userId) < 0) { 496 onChange(true /* selfChange */, FINGERPRINT_APP_ENABLED, userId); 497 } 498 return mFingerprintEnabledForApps.get(userId, DEFAULT_APP_ENABLED); 499 } else { // modality == TYPE_ANY_BIOMETRIC 500 return mFingerprintEnabledForApps.get(userId, DEFAULT_APP_ENABLED) 501 || mFaceEnabledForApps.get(userId, DEFAULT_APP_ENABLED); 502 } 503 } else { 504 if (!mBiometricEnabledForApps.containsKey(userId)) { 505 if (mUseLegacyFaceOnlySettings) { 506 onChange(true /* selfChange */, FACE_UNLOCK_APP_ENABLED, userId); 507 } else { 508 onChange(true /* selfChange */, BIOMETRIC_APP_ENABLED, userId); 509 } 510 } 511 return mBiometricEnabledForApps.getOrDefault(userId, DEFAULT_APP_ENABLED); 512 } 513 } 514 getConfirmationAlwaysRequired(@iometricAuthenticator.Modality int modality, int userId)515 public boolean getConfirmationAlwaysRequired(@BiometricAuthenticator.Modality int modality, 516 int userId) { 517 switch (modality) { 518 case TYPE_FACE: 519 if (!mFaceAlwaysRequireConfirmation.containsKey(userId)) { 520 onChange(true /* selfChange */, 521 FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION, 522 userId); 523 } 524 return mFaceAlwaysRequireConfirmation.get(userId); 525 526 default: 527 return false; 528 } 529 } 530 getMandatoryBiometricsEnabledAndRequirementsSatisfiedForUser(int userId)531 public boolean getMandatoryBiometricsEnabledAndRequirementsSatisfiedForUser(int userId) { 532 if (!mMandatoryBiometricsEnabled.containsKey(userId)) { 533 updateMandatoryBiometricsForAllProfiles(userId); 534 } 535 if (!mMandatoryBiometricsRequirementsSatisfied.containsKey(userId)) { 536 updateMandatoryBiometricsRequirementsForAllProfiles(userId); 537 } 538 539 return mMandatoryBiometricsEnabled.getOrDefault(userId, 540 DEFAULT_MANDATORY_BIOMETRICS_STATUS) 541 && mMandatoryBiometricsRequirementsSatisfied.getOrDefault(userId, 542 DEFAULT_MANDATORY_BIOMETRICS_REQUIREMENTS_SATISFIED_STATUS) 543 && getBiometricStatusForIdentityCheck(userId); 544 } 545 getBiometricStatusForIdentityCheck(int userId)546 private boolean getBiometricStatusForIdentityCheck(int userId) { 547 if (com.android.settings.flags.Flags.biometricsOnboardingEducation()) { 548 if (mFingerprintEnrolledForUser.getOrDefault(userId, false /* default */) 549 && getEnabledForApps(userId, TYPE_FINGERPRINT)) { 550 return true; 551 } else { 552 return mFaceEnrolledForUser.getOrDefault(userId, false /* default */) 553 && getEnabledForApps(userId, TYPE_FACE); 554 } 555 } else { 556 return (mFingerprintEnrolledForUser.getOrDefault(userId, false /* default */) 557 || mFaceEnrolledForUser.getOrDefault(userId, false /* default */)) 558 && getEnabledForApps(userId, TYPE_ANY_BIOMETRIC); 559 } 560 } 561 notifyEnabledOnKeyguardCallbacks(int userId, int modality)562 void notifyEnabledOnKeyguardCallbacks(int userId, int modality) { 563 List<EnabledOnKeyguardCallback> callbacks = mCallbacks; 564 final boolean enabled = getEnabledOnKeyguard(userId, modality); 565 for (int i = 0; i < callbacks.size(); i++) { 566 callbacks.get(i).notify(enabled, userId, modality); 567 } 568 } 569 updateMandatoryBiometricsForAllProfiles(int userId)570 private void updateMandatoryBiometricsForAllProfiles(int userId) { 571 int effectiveUserId = userId; 572 final UserInfo parentProfile = mUserManager.getProfileParent(userId); 573 574 if (parentProfile != null) { 575 effectiveUserId = parentProfile.id; 576 } 577 578 final int[] enabledProfileIds = mUserManager.getEnabledProfileIds(effectiveUserId); 579 if (enabledProfileIds != null) { 580 for (int profileUserId : enabledProfileIds) { 581 mMandatoryBiometricsEnabled.put(profileUserId, 582 Settings.Secure.getIntForUser( 583 mContentResolver, Settings.Secure.MANDATORY_BIOMETRICS, 584 DEFAULT_MANDATORY_BIOMETRICS_STATUS ? 1 : 0, 585 effectiveUserId) != 0); 586 } 587 } else { 588 mMandatoryBiometricsEnabled.put(userId, 589 Settings.Secure.getIntForUser( 590 mContentResolver, Settings.Secure.MANDATORY_BIOMETRICS, 591 DEFAULT_MANDATORY_BIOMETRICS_STATUS ? 1 : 0, 592 effectiveUserId) != 0); 593 } 594 } 595 updateMandatoryBiometricsRequirementsForAllProfiles(int userId)596 private void updateMandatoryBiometricsRequirementsForAllProfiles(int userId) { 597 int effectiveUserId = userId; 598 final UserInfo parentProfile = mUserManager.getProfileParent(userId); 599 600 if (parentProfile != null) { 601 effectiveUserId = parentProfile.id; 602 } 603 604 final int[] enabledProfileIds = mUserManager.getEnabledProfileIds(effectiveUserId); 605 if (enabledProfileIds != null) { 606 for (int profileUserId : enabledProfileIds) { 607 mMandatoryBiometricsRequirementsSatisfied.put(profileUserId, 608 Settings.Secure.getIntForUser(mContentResolver, 609 Settings.Secure.MANDATORY_BIOMETRICS_REQUIREMENTS_SATISFIED, 610 DEFAULT_MANDATORY_BIOMETRICS_REQUIREMENTS_SATISFIED_STATUS 611 ? 1 : 0, 612 effectiveUserId) != 0); 613 } 614 } else { 615 mMandatoryBiometricsRequirementsSatisfied.put(userId, 616 Settings.Secure.getIntForUser(mContentResolver, 617 Settings.Secure.MANDATORY_BIOMETRICS_REQUIREMENTS_SATISFIED, 618 DEFAULT_MANDATORY_BIOMETRICS_REQUIREMENTS_SATISFIED_STATUS ? 1 : 0, 619 effectiveUserId) != 0); 620 } 621 } 622 addBiometricListenersForMandatoryBiometrics(Context context, FingerprintManager fingerprintManager, FaceManager faceManager)623 private void addBiometricListenersForMandatoryBiometrics(Context context, 624 FingerprintManager fingerprintManager, FaceManager faceManager) { 625 if (fingerprintManager != null) { 626 fingerprintManager.addAuthenticatorsRegisteredCallback( 627 new IFingerprintAuthenticatorsRegisteredCallback.Stub() { 628 @Override 629 public void onAllAuthenticatorsRegistered( 630 List<FingerprintSensorPropertiesInternal> list) { 631 if (list == null || list.isEmpty()) { 632 Slog.d(TAG, "No fingerprint authenticators registered."); 633 return; 634 } 635 final FingerprintSensorPropertiesInternal 636 fingerprintSensorProperties = list.get(0); 637 if (fingerprintSensorProperties.sensorStrength 638 == STRENGTH_STRONG) { 639 fingerprintManager.registerBiometricStateListener( 640 new BiometricStateListener() { 641 @Override 642 public void onEnrollmentsChanged( 643 int userId, 644 int sensorId, 645 boolean hasEnrollments 646 ) { 647 if (sensorId == fingerprintSensorProperties 648 .sensorId) { 649 mFingerprintEnrolledForUser.put(userId, 650 hasEnrollments); 651 } 652 } 653 }); 654 } 655 } 656 }); 657 } 658 if (faceManager != null) { 659 faceManager.addAuthenticatorsRegisteredCallback( 660 new IFaceAuthenticatorsRegisteredCallback.Stub() { 661 @Override 662 public void onAllAuthenticatorsRegistered( 663 List<FaceSensorPropertiesInternal> list) { 664 if (list == null || list.isEmpty()) { 665 Slog.d(TAG, "No face authenticators registered."); 666 return; 667 } 668 final FaceSensorPropertiesInternal 669 faceSensorPropertiesInternal = list.get(0); 670 if (faceSensorPropertiesInternal.sensorStrength 671 == STRENGTH_STRONG) { 672 faceManager.registerBiometricStateListener( 673 new BiometricStateListener() { 674 @Override 675 public void onEnrollmentsChanged( 676 int userId, 677 int sensorId, 678 boolean hasEnrollments 679 ) { 680 if (sensorId 681 == faceSensorPropertiesInternal 682 .sensorId) { 683 mFaceEnrolledForUser.put(userId, 684 hasEnrollments); 685 } 686 } 687 }); 688 } 689 } 690 }); 691 } 692 } 693 } 694 695 final class EnabledOnKeyguardCallback implements IBinder.DeathRecipient { 696 697 private final IBiometricEnabledOnKeyguardCallback mCallback; 698 EnabledOnKeyguardCallback(IBiometricEnabledOnKeyguardCallback callback)699 EnabledOnKeyguardCallback(IBiometricEnabledOnKeyguardCallback callback) { 700 mCallback = callback; 701 try { 702 mCallback.asBinder().linkToDeath(EnabledOnKeyguardCallback.this, 0); 703 } catch (RemoteException e) { 704 Slog.w(TAG, "Unable to linkToDeath", e); 705 } 706 } 707 notify(boolean enabled, int userId, int modality)708 void notify(boolean enabled, int userId, int modality) { 709 try { 710 mCallback.onChanged(enabled, userId, modality); 711 } catch (DeadObjectException e) { 712 Slog.w(TAG, "Death while invoking notify", e); 713 mEnabledOnKeyguardCallbacks.remove(this); 714 } catch (RemoteException e) { 715 Slog.w(TAG, "Failed to invoke onChanged", e); 716 } 717 } 718 719 @Override binderDied()720 public void binderDied() { 721 Slog.e(TAG, "Enabled callback binder died"); 722 mEnabledOnKeyguardCallbacks.remove(this); 723 } 724 } 725 726 // Receives events from individual biometric sensors. createBiometricSensorReceiver(final long requestId)727 private IBiometricSensorReceiver createBiometricSensorReceiver(final long requestId) { 728 return new IBiometricSensorReceiver.Stub() { 729 @Override 730 public void onAuthenticationSucceeded(int sensorId, byte[] token) { 731 mHandler.post(() -> handleAuthenticationSucceeded(requestId, sensorId, token)); 732 } 733 734 @Override 735 public void onAuthenticationFailed(int sensorId) { 736 Slog.v(TAG, "onAuthenticationFailed"); 737 mHandler.post(() -> handleAuthenticationRejected(requestId, sensorId)); 738 } 739 740 @Override 741 public void onError(int sensorId, int cookie, @BiometricConstants.Errors int error, 742 int vendorCode) { 743 // Determine if error is hard or soft error. Certain errors (such as TIMEOUT) are 744 // soft errors and we should allow the user to try authenticating again instead of 745 // dismissing BiometricPrompt. 746 if (error == BiometricConstants.BIOMETRIC_ERROR_TIMEOUT) { 747 mHandler.post(() -> handleAuthenticationTimedOut( 748 requestId, sensorId, cookie, error, vendorCode)); 749 } else { 750 mHandler.post(() -> handleOnError( 751 requestId, sensorId, cookie, error, vendorCode)); 752 } 753 } 754 755 @Override 756 public void onAcquired(int sensorId, int acquiredInfo, int vendorCode) { 757 mHandler.post(() -> handleOnAcquired( 758 requestId, sensorId, acquiredInfo, vendorCode)); 759 } 760 }; 761 } 762 763 private IBiometricSysuiReceiver createSysuiReceiver(final long requestId) { 764 return new IBiometricSysuiReceiver.Stub() { 765 @Override 766 public void onDialogDismissed(@BiometricPrompt.DismissedReason int reason, 767 @Nullable byte[] credentialAttestation) { 768 mHandler.post(() -> handleOnDismissed(requestId, reason, credentialAttestation)); 769 } 770 771 @Override 772 public void onTryAgainPressed() { 773 mHandler.post(() -> handleOnTryAgainPressed(requestId)); 774 } 775 776 @Override 777 public void onDeviceCredentialPressed() { 778 mHandler.post(() -> handleOnDeviceCredentialPressed(requestId)); 779 } 780 781 @Override 782 public void onSystemEvent(int event) { 783 mHandler.post(() -> handleOnSystemEvent(requestId, event)); 784 } 785 786 @Override 787 public void onDialogAnimatedIn(boolean startFingerprintNow) { 788 mHandler.post(() -> handleOnDialogAnimatedIn(requestId, startFingerprintNow)); 789 } 790 791 @Override 792 public void onStartFingerprintNow() { 793 mHandler.post(() -> handleOnStartFingerprintNow(requestId)); 794 } 795 }; 796 } 797 798 private AuthSession.ClientDeathReceiver createClientDeathReceiver(final long requestId) { 799 return () -> mHandler.post(() -> handleClientDied(requestId)); 800 }; 801 802 /** 803 * Implementation of the BiometricPrompt/BiometricManager APIs. Handles client requests, 804 * sensor arbitration, threading, etc. 805 */ 806 private final class BiometricServiceWrapper extends IBiometricService.Stub { 807 @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL) 808 @Override // Binder call 809 public ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback, 810 @NonNull String opPackageName) throws RemoteException { 811 812 super.createTestSession_enforcePermission(); 813 814 for (BiometricSensor sensor : mSensors) { 815 if (sensor.id == sensorId) { 816 return sensor.impl.createTestSession(callback, opPackageName); 817 } 818 } 819 820 Slog.e(TAG, "Unknown sensor for createTestSession: " + sensorId); 821 return null; 822 } 823 824 @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL) 825 @Override // Binder call 826 public List<SensorPropertiesInternal> getSensorProperties(String opPackageName) 827 throws RemoteException { 828 829 super.getSensorProperties_enforcePermission(); 830 831 final List<SensorPropertiesInternal> sensors = new ArrayList<>(); 832 for (BiometricSensor sensor : mSensors) { 833 // Explicitly re-create as the super class, since AIDL doesn't play nicely with 834 // "List<? extends SensorPropertiesInternal> ... 835 final SensorPropertiesInternal prop = SensorPropertiesInternal 836 .from(sensor.impl.getSensorProperties(opPackageName)); 837 sensors.add(prop); 838 } 839 840 return sensors; 841 } 842 843 @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL) 844 @Override // Binder call 845 public void onReadyForAuthentication(long requestId, int cookie) { 846 847 super.onReadyForAuthentication_enforcePermission(); 848 849 mHandler.post(() -> handleOnReadyForAuthentication(requestId, cookie)); 850 } 851 852 @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL) 853 @Override // Binder call 854 public long authenticate(IBinder token, long operationId, int userId, 855 IBiometricServiceReceiver receiver, String opPackageName, PromptInfo promptInfo) { 856 857 super.authenticate_enforcePermission(); 858 859 if (token == null || receiver == null || opPackageName == null || promptInfo == null) { 860 Slog.e(TAG, "Unable to authenticate, one or more null arguments"); 861 return -1; 862 } 863 864 if (!Utils.isValidAuthenticatorConfig(getContext(), promptInfo)) { 865 throw new SecurityException("Invalid authenticator configuration"); 866 } 867 868 Utils.combineAuthenticatorBundles(promptInfo); 869 870 final long requestId = mRequestCounter.get(); 871 mHandler.post(() -> handleAuthenticate( 872 token, requestId, operationId, userId, receiver, opPackageName, promptInfo)); 873 874 return requestId; 875 } 876 877 @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL) 878 @Override // Binder call 879 public void cancelAuthentication(IBinder token, String opPackageName, long requestId) { 880 881 super.cancelAuthentication_enforcePermission(); 882 883 SomeArgs args = SomeArgs.obtain(); 884 args.arg1 = token; 885 args.arg2 = opPackageName; 886 args.arg3 = requestId; 887 888 mHandler.post(() -> handleCancelAuthentication(requestId)); 889 } 890 891 @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL) 892 @Override // Binder call 893 public int canAuthenticate(String opPackageName, int userId, int callingUserId, 894 @Authenticators.Types int authenticators) { 895 896 super.canAuthenticate_enforcePermission(); 897 898 Slog.d(TAG, "canAuthenticate: User=" + userId 899 + ", Caller=" + callingUserId 900 + ", Authenticators=" + authenticators); 901 902 if (!Utils.isValidAuthenticatorConfig(getContext(), authenticators)) { 903 throw new SecurityException("Invalid authenticator configuration"); 904 } 905 906 try { 907 final PreAuthInfo preAuthInfo = 908 createPreAuthInfo(opPackageName, userId, authenticators); 909 return preAuthInfo.getCanAuthenticateResult(); 910 } catch (RemoteException e) { 911 Slog.e(TAG, "Remote exception", e); 912 return BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE; 913 } 914 } 915 916 @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL) 917 @Override // Binder call 918 public long getLastAuthenticationTime( 919 int userId, @Authenticators.Types int authenticators) { 920 super.getLastAuthenticationTime_enforcePermission(); 921 922 Slogf.d(TAG, "getLastAuthenticationTime(userId=%d, authenticators=0x%x)", 923 userId, authenticators); 924 925 final long secureUserId; 926 try { 927 secureUserId = mGateKeeper.getSecureUserId(userId); 928 } catch (RemoteException e) { 929 Slogf.w(TAG, "Failed to get secure user id for " + userId, e); 930 return BIOMETRIC_NO_AUTHENTICATION; 931 } 932 933 if (secureUserId == GateKeeper.INVALID_SECURE_USER_ID) { 934 Slogf.w(TAG, "No secure user id for " + userId); 935 return BIOMETRIC_NO_AUTHENTICATION; 936 } 937 938 ArrayList<Integer> hardwareAuthenticators = new ArrayList<>(2); 939 940 if ((authenticators & Authenticators.DEVICE_CREDENTIAL) != 0) { 941 hardwareAuthenticators.add(HardwareAuthenticatorType.PASSWORD); 942 } 943 944 if ((authenticators & Authenticators.BIOMETRIC_STRONG) != 0) { 945 hardwareAuthenticators.add(HardwareAuthenticatorType.FINGERPRINT); 946 } 947 948 if (hardwareAuthenticators.isEmpty()) { 949 throw new IllegalArgumentException("authenticators must not be empty"); 950 } 951 952 int[] authTypesArray = hardwareAuthenticators.stream() 953 .mapToInt(Integer::intValue) 954 .toArray(); 955 return mKeyStoreAuthorization.getLastAuthTime(secureUserId, authTypesArray); 956 } 957 958 @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL) 959 @Override 960 public boolean hasEnrolledBiometrics(int userId, String opPackageName) { 961 962 super.hasEnrolledBiometrics_enforcePermission(); 963 964 try { 965 for (BiometricSensor sensor : mSensors) { 966 if (sensor.impl.hasEnrolledTemplates(userId, opPackageName)) { 967 return true; 968 } 969 } 970 } catch (RemoteException e) { 971 Slog.e(TAG, "Remote exception", e); 972 } 973 974 return false; 975 } 976 977 @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL) 978 @Override 979 public void registerAuthenticator(int id, int modality, 980 @Authenticators.Types int strength, 981 @NonNull IBiometricAuthenticator authenticator) { 982 983 super.registerAuthenticator_enforcePermission(); 984 985 Slog.d(TAG, "Registering ID: " + id 986 + " Modality: " + modality 987 + " Strength: " + strength); 988 989 if (authenticator == null) { 990 throw new IllegalArgumentException("Authenticator must not be null." 991 + " Did you forget to modify the core/res/res/values/xml overlay for" 992 + " config_biometric_sensors?"); 993 } 994 995 // Note that we allow BIOMETRIC_CONVENIENCE to register because BiometricService 996 // also does / will do other things such as keep track of lock screen timeout, etc. 997 // Just because a biometric is registered does not mean it can participate in 998 // the android.hardware.biometrics APIs. 999 if (strength != Authenticators.BIOMETRIC_STRONG 1000 && strength != Authenticators.BIOMETRIC_WEAK 1001 && strength != Authenticators.BIOMETRIC_CONVENIENCE) { 1002 throw new IllegalStateException("Unsupported strength"); 1003 } 1004 1005 for (BiometricSensor sensor : mSensors) { 1006 if (sensor.id == id) { 1007 throw new IllegalStateException("Cannot register duplicate authenticator"); 1008 } 1009 } 1010 1011 mSensors.add(new BiometricSensor(getContext(), id, modality, strength, authenticator) { 1012 @Override 1013 boolean confirmationAlwaysRequired(int userId) { 1014 return mSettingObserver.getConfirmationAlwaysRequired(modality, userId); 1015 } 1016 1017 @Override 1018 boolean confirmationSupported() { 1019 return Utils.isConfirmationSupported(modality); 1020 } 1021 }); 1022 1023 mBiometricStrengthController.updateStrengths(); 1024 } 1025 1026 @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL) 1027 @Override // Binder call 1028 public void registerEnabledOnKeyguardCallback( 1029 IBiometricEnabledOnKeyguardCallback callback) { 1030 1031 super.registerEnabledOnKeyguardCallback_enforcePermission(); 1032 1033 mEnabledOnKeyguardCallbacks.add(new EnabledOnKeyguardCallback(callback)); 1034 final List<UserInfo> aliveUsers = mUserManager.getAliveUsers(); 1035 try { 1036 for (UserInfo userInfo: aliveUsers) { 1037 final int userId = userInfo.id; 1038 if (com.android.settings.flags.Flags.biometricsOnboardingEducation()) { 1039 callback.onChanged(mSettingObserver.getEnabledOnKeyguard(userId, TYPE_FACE), 1040 userId, TYPE_FACE); 1041 callback.onChanged( 1042 mSettingObserver.getEnabledOnKeyguard(userId, TYPE_FINGERPRINT), 1043 userId, TYPE_FINGERPRINT); 1044 } else { 1045 callback.onChanged(mSettingObserver.getEnabledOnKeyguard(userId, 1046 TYPE_ANY_BIOMETRIC), userId, TYPE_ANY_BIOMETRIC); 1047 } 1048 } 1049 } catch (RemoteException e) { 1050 Slog.w(TAG, "Remote exception", e); 1051 } 1052 } 1053 1054 @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL) 1055 @Override // Binder call 1056 public void invalidateAuthenticatorIds(int userId, int fromSensorId, 1057 IInvalidationCallback callback) { 1058 1059 super.invalidateAuthenticatorIds_enforcePermission(); 1060 1061 InvalidationTracker.start(getContext(), mSensors, userId, fromSensorId, callback); 1062 } 1063 1064 @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL) 1065 @Override // Binder call 1066 public long[] getAuthenticatorIds(int callingUserId) { 1067 1068 super.getAuthenticatorIds_enforcePermission(); 1069 1070 final List<Long> authenticatorIds = new ArrayList<>(); 1071 for (BiometricSensor sensor : mSensors) { 1072 try { 1073 final boolean hasEnrollments = sensor.impl.hasEnrolledTemplates(callingUserId, 1074 getContext().getOpPackageName()); 1075 final long authenticatorId = sensor.impl.getAuthenticatorId(callingUserId); 1076 if (hasEnrollments && Utils.isAtLeastStrength(sensor.getCurrentStrength(), 1077 Authenticators.BIOMETRIC_STRONG)) { 1078 authenticatorIds.add(authenticatorId); 1079 } else { 1080 Slog.d(TAG, "Sensor " + sensor + ", sensorId " + sensor.id 1081 + ", hasEnrollments: " + hasEnrollments 1082 + " cannot participate in Keystore operations"); 1083 } 1084 } catch (RemoteException e) { 1085 Slog.e(TAG, "RemoteException", e); 1086 } 1087 } 1088 1089 long[] result = new long[authenticatorIds.size()]; 1090 for (int i = 0; i < authenticatorIds.size(); i++) { 1091 result[i] = authenticatorIds.get(i); 1092 } 1093 return result; 1094 } 1095 1096 @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL) 1097 @Override // Binder call 1098 public void resetLockoutTimeBound(IBinder token, String opPackageName, int fromSensorId, 1099 int userId, byte[] hardwareAuthToken) { 1100 1101 // Check originating strength 1102 super.resetLockoutTimeBound_enforcePermission(); 1103 1104 if (!Utils.isAtLeastStrength(getSensorForId(fromSensorId).getCurrentStrength(), 1105 Authenticators.BIOMETRIC_STRONG)) { 1106 Slog.w(TAG, "Sensor: " + fromSensorId + " is does not meet the required strength to" 1107 + " request resetLockout"); 1108 return; 1109 } 1110 1111 // Request resetLockout for applicable sensors 1112 for (BiometricSensor sensor : mSensors) { 1113 if (sensor.id == fromSensorId) { 1114 continue; 1115 } 1116 try { 1117 final SensorPropertiesInternal props = sensor.impl 1118 .getSensorProperties(getContext().getOpPackageName()); 1119 final boolean supportsChallengelessHat = 1120 props.resetLockoutRequiresHardwareAuthToken 1121 && !props.resetLockoutRequiresChallenge; 1122 final boolean doesNotRequireHat = !props.resetLockoutRequiresHardwareAuthToken; 1123 1124 if (supportsChallengelessHat || doesNotRequireHat) { 1125 Slog.d(TAG, "resetLockout from: " + fromSensorId 1126 + ", for: " + sensor.id 1127 + ", userId: " + userId); 1128 sensor.impl.resetLockout(token, opPackageName, userId, 1129 hardwareAuthToken); 1130 } 1131 } catch (RemoteException e) { 1132 Slog.e(TAG, "Remote exception", e); 1133 } 1134 } 1135 } 1136 1137 @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL) 1138 @Override // Binder call 1139 public void resetLockout( 1140 int userId, byte[] hardwareAuthToken) { 1141 super.resetLockout_enforcePermission(); 1142 1143 Slog.d(TAG, "resetLockout(userId=" + userId 1144 + ", hat=" + (hardwareAuthToken == null ? "null " : "present") + ")"); 1145 mHandler.post(() -> { 1146 mBiometricContext.getAuthSessionCoordinator() 1147 .resetLockoutFor(userId, Authenticators.BIOMETRIC_STRONG, -1); 1148 }); 1149 } 1150 1151 @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL) 1152 @Override // Binder call 1153 public int getCurrentStrength(int sensorId) { 1154 1155 super.getCurrentStrength_enforcePermission(); 1156 1157 for (BiometricSensor sensor : mSensors) { 1158 if (sensor.id == sensorId) { 1159 return sensor.getCurrentStrength(); 1160 } 1161 } 1162 Slog.e(TAG, "Unknown sensorId: " + sensorId); 1163 return Authenticators.EMPTY_SET; 1164 } 1165 1166 @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL) 1167 @Override // Binder call 1168 public int getCurrentModality( 1169 String opPackageName, 1170 int userId, 1171 int callingUserId, 1172 @Authenticators.Types int authenticators) { 1173 1174 1175 super.getCurrentModality_enforcePermission(); 1176 1177 Slog.d(TAG, "getCurrentModality: User=" + userId 1178 + ", Caller=" + callingUserId 1179 + ", Authenticators=" + authenticators); 1180 1181 if (!Utils.isValidAuthenticatorConfig(getContext(), authenticators)) { 1182 throw new SecurityException("Invalid authenticator configuration"); 1183 } 1184 1185 try { 1186 final PreAuthInfo preAuthInfo = 1187 createPreAuthInfo(opPackageName, userId, authenticators); 1188 return preAuthInfo.getPreAuthenticateStatus().first; 1189 } catch (RemoteException e) { 1190 Slog.e(TAG, "Remote exception", e); 1191 return BiometricAuthenticator.TYPE_NONE; 1192 } 1193 } 1194 1195 @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL) 1196 @Override // Binder call 1197 public int getSupportedModalities(@Authenticators.Types int authenticators) { 1198 1199 super.getSupportedModalities_enforcePermission(); 1200 1201 Slog.d(TAG, "getSupportedModalities: Authenticators=" + authenticators); 1202 1203 if (!Utils.isValidAuthenticatorConfig(getContext(), authenticators)) { 1204 throw new SecurityException("Invalid authenticator configuration"); 1205 } 1206 1207 @BiometricAuthenticator.Modality int modality = 1208 Utils.isCredentialRequested(authenticators) 1209 ? BiometricAuthenticator.TYPE_CREDENTIAL 1210 : BiometricAuthenticator.TYPE_NONE; 1211 1212 if (Utils.isBiometricRequested(authenticators)) { 1213 @Authenticators.Types final int requestedStrength = 1214 Utils.getPublicBiometricStrength(authenticators); 1215 1216 // Add modalities of all biometric sensors that meet the authenticator requirements. 1217 for (final BiometricSensor sensor : mSensors) { 1218 @Authenticators.Types final int sensorStrength = sensor.getCurrentStrength(); 1219 if (Utils.isAtLeastStrength(sensorStrength, requestedStrength)) { 1220 modality |= sensor.modality; 1221 } 1222 } 1223 } 1224 1225 return modality; 1226 } 1227 1228 @Override 1229 protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, String[] args) { 1230 if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) { 1231 return; 1232 } 1233 1234 final long ident = Binder.clearCallingIdentity(); 1235 try { 1236 if (args.length > 0 && "--proto".equals(args[0])) { 1237 final boolean clearSchedulerBuffer = args.length > 1 1238 && "--clear-scheduler-buffer".equals(args[1]); 1239 Slog.d(TAG, "ClearSchedulerBuffer: " + clearSchedulerBuffer); 1240 final ProtoOutputStream proto = new ProtoOutputStream(fd); 1241 proto.write(BiometricServiceStateProto.AUTH_SESSION_STATE, 1242 mAuthSession != null ? mAuthSession.getState() : STATE_AUTH_IDLE); 1243 for (BiometricSensor sensor : mSensors) { 1244 byte[] serviceState = sensor.impl 1245 .dumpSensorServiceStateProto(clearSchedulerBuffer); 1246 proto.write(BiometricServiceStateProto.SENSOR_SERVICE_STATES, serviceState); 1247 } 1248 proto.flush(); 1249 } else { 1250 dumpInternal(pw); 1251 } 1252 } catch (RemoteException e) { 1253 Slog.e(TAG, "Remote exception", e); 1254 } finally { 1255 Binder.restoreCallingIdentity(ident); 1256 } 1257 } 1258 } 1259 1260 private void checkInternalPermission() { 1261 getContext().enforceCallingOrSelfPermission(USE_BIOMETRIC_INTERNAL, 1262 "Must have USE_BIOMETRIC_INTERNAL permission"); 1263 } 1264 1265 @NonNull 1266 private PreAuthInfo createPreAuthInfo( 1267 @NonNull String opPackageName, 1268 int userId, 1269 @Authenticators.Types int authenticators) throws RemoteException { 1270 1271 final PromptInfo promptInfo = new PromptInfo(); 1272 promptInfo.setAuthenticators(authenticators); 1273 1274 return PreAuthInfo.create(mTrustManager, mDevicePolicyManager, mSettingObserver, mSensors, 1275 userId, promptInfo, opPackageName, false /* checkDevicePolicyManager */, 1276 getContext(), mBiometricCameraManager, mUserManager); 1277 } 1278 1279 /** 1280 * Class for injecting dependencies into BiometricService. 1281 * TODO(b/141025588): Replace with a dependency injection framework (e.g. Guice, Dagger). 1282 */ 1283 @VisibleForTesting 1284 public static class Injector { 1285 1286 public IActivityManager getActivityManagerService() { 1287 return ActivityManager.getService(); 1288 } 1289 1290 public KeyStoreAuthorization getKeyStoreAuthorization() { 1291 return KeyStoreAuthorization.getInstance(); 1292 } 1293 1294 public IGateKeeperService getGateKeeperService() { 1295 return GateKeeper.getService(); 1296 } 1297 1298 public ITrustManager getTrustManager() { 1299 return ITrustManager.Stub.asInterface(ServiceManager.getService(Context.TRUST_SERVICE)); 1300 } 1301 1302 public IStatusBarService getStatusBarService() { 1303 return IStatusBarService.Stub.asInterface( 1304 ServiceManager.getService(Context.STATUS_BAR_SERVICE)); 1305 } 1306 1307 /** 1308 * Allows to mock SettingObserver for testing. 1309 */ 1310 public SettingObserver getSettingObserver(Context context, Handler handler, 1311 List<EnabledOnKeyguardCallback> callbacks) { 1312 return new SettingObserver(context, handler, callbacks, context.getSystemService( 1313 UserManager.class), context.getSystemService(FingerprintManager.class), 1314 context.getSystemService(FaceManager.class)); 1315 } 1316 1317 /** 1318 * Allows to enable/disable debug logs. 1319 */ 1320 public boolean isDebugEnabled(Context context, int userId) { 1321 return Utils.isDebugEnabled(context, userId); 1322 } 1323 1324 /** 1325 * Allows to stub publishBinderService(...) for testing. 1326 */ 1327 public void publishBinderService(BiometricService service, IBiometricService.Stub impl) { 1328 service.publishBinderService(Context.BIOMETRIC_SERVICE, impl); 1329 } 1330 1331 /** 1332 * Allows to mock BiometricStrengthController for testing. 1333 */ 1334 public BiometricStrengthController getBiometricStrengthController( 1335 BiometricService service) { 1336 return new BiometricStrengthController(service); 1337 } 1338 1339 /** 1340 * Allows to test with various device sensor configurations. 1341 * @param context System Server context 1342 * @return the sensor configuration from core/res/res/values/config.xml 1343 */ 1344 public String[] getConfiguration(Context context) { 1345 return context.getResources().getStringArray(R.array.config_biometric_sensors); 1346 } 1347 1348 public DevicePolicyManager getDevicePolicyManager(Context context) { 1349 return context.getSystemService(DevicePolicyManager.class); 1350 } 1351 1352 public List<FingerprintSensorPropertiesInternal> getFingerprintSensorProperties( 1353 Context context) { 1354 if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) { 1355 final FingerprintManager fpm = context.getSystemService(FingerprintManager.class); 1356 if (fpm != null) { 1357 return fpm.getSensorPropertiesInternal(); 1358 } 1359 } 1360 return new ArrayList<>(); 1361 } 1362 1363 public Supplier<Long> getRequestGenerator() { 1364 final AtomicLong generator = new AtomicLong(0); 1365 return () -> generator.incrementAndGet(); 1366 } 1367 1368 public BiometricContext getBiometricContext(Context context) { 1369 return BiometricContext.getInstance(context); 1370 } 1371 1372 public UserManager getUserManager(Context context) { 1373 return context.getSystemService(UserManager.class); 1374 } 1375 1376 public BiometricCameraManager getBiometricCameraManager(Context context) { 1377 return new BiometricCameraManagerImpl(context.getSystemService(CameraManager.class), 1378 context.getSystemService(SensorPrivacyManager.class)); 1379 } 1380 1381 public BiometricNotificationLogger getNotificationLogger() { 1382 return new BiometricNotificationLogger(); 1383 } 1384 } 1385 1386 /** 1387 * Initializes the system service. 1388 * <p> 1389 * Subclasses must define a single argument constructor that accepts the context 1390 * and passes it to super. 1391 * </p> 1392 * 1393 * @param context The system server context. 1394 */ 1395 public BiometricService(Context context) { 1396 this(context, new Injector(), BiometricHandlerProvider.getInstance()); 1397 } 1398 1399 @VisibleForTesting 1400 BiometricService(Context context, Injector injector, 1401 BiometricHandlerProvider biometricHandlerProvider) { 1402 super(context); 1403 1404 mInjector = injector; 1405 mHandler = biometricHandlerProvider.getBiometricCallbackHandler(); 1406 mDevicePolicyManager = mInjector.getDevicePolicyManager(context); 1407 mImpl = new BiometricServiceWrapper(); 1408 mEnabledOnKeyguardCallbacks = new ArrayList<>(); 1409 mSettingObserver = mInjector.getSettingObserver(context, mHandler, 1410 mEnabledOnKeyguardCallbacks); 1411 mRequestCounter = mInjector.getRequestGenerator(); 1412 mBiometricContext = injector.getBiometricContext(context); 1413 mUserManager = injector.getUserManager(context); 1414 mBiometricCameraManager = injector.getBiometricCameraManager(context); 1415 mKeyStoreAuthorization = injector.getKeyStoreAuthorization(); 1416 mGateKeeper = injector.getGateKeeperService(); 1417 mBiometricNotificationLogger = injector.getNotificationLogger(); 1418 1419 try { 1420 injector.getActivityManagerService().registerUserSwitchObserver( 1421 new UserSwitchObserver() { 1422 @Override 1423 public void onUserSwitchComplete(int newUserId) { 1424 mSettingObserver.updateContentObserver(); 1425 if (com.android.settings.flags.Flags.biometricsOnboardingEducation()) { 1426 mSettingObserver.notifyEnabledOnKeyguardCallbacks(newUserId, 1427 TYPE_FACE); 1428 mSettingObserver.notifyEnabledOnKeyguardCallbacks( 1429 newUserId, TYPE_FINGERPRINT); 1430 } else { 1431 mSettingObserver.notifyEnabledOnKeyguardCallbacks( 1432 newUserId, TYPE_ANY_BIOMETRIC); 1433 } 1434 } 1435 }, BiometricService.class.getName() 1436 ); 1437 } catch (RemoteException e) { 1438 Slog.e(TAG, "Failed to register user switch observer", e); 1439 } 1440 } 1441 1442 @Override 1443 public void onStart() { 1444 mStatusBarService = mInjector.getStatusBarService(); 1445 mTrustManager = mInjector.getTrustManager(); 1446 mInjector.publishBinderService(this, mImpl); 1447 mBiometricStrengthController = mInjector.getBiometricStrengthController(this); 1448 mBiometricStrengthController.startListening(); 1449 1450 mHandler.post(new Runnable(){ 1451 @Override 1452 public void run() { 1453 try { 1454 mBiometricNotificationLogger.registerAsSystemService(getContext(), 1455 new ComponentName(getContext(), BiometricNotificationLogger.class), 1456 UserHandle.USER_ALL); 1457 } catch (RemoteException e) { 1458 // Intra-process call, should never happen. 1459 } 1460 } 1461 1462 }); 1463 } 1464 1465 private boolean isStrongBiometric(int id) { 1466 for (BiometricSensor sensor : mSensors) { 1467 if (sensor.id == id) { 1468 return Utils.isAtLeastStrength(sensor.getCurrentStrength(), 1469 Authenticators.BIOMETRIC_STRONG); 1470 } 1471 } 1472 Slog.e(TAG, "Unknown sensorId: " + id); 1473 return false; 1474 } 1475 1476 @Nullable 1477 private AuthSession getAuthSessionIfCurrent(long requestId) { 1478 final AuthSession session = mAuthSession; 1479 if (session != null && session.getRequestId() == requestId) { 1480 return session; 1481 } 1482 return null; 1483 } 1484 1485 private void handleAuthenticationSucceeded(long requestId, int sensorId, byte[] token) { 1486 Slog.v(TAG, "handleAuthenticationSucceeded(), sensorId: " + sensorId); 1487 // Should never happen, log this to catch bad HAL behavior (e.g. auth succeeded 1488 // after user dismissed/canceled dialog). 1489 final AuthSession session = getAuthSessionIfCurrent(requestId); 1490 if (session == null) { 1491 Slog.e(TAG, "handleAuthenticationSucceeded: AuthSession is null"); 1492 return; 1493 } 1494 1495 session.onAuthenticationSucceeded(sensorId, isStrongBiometric(sensorId), token); 1496 } 1497 1498 private void handleAuthenticationRejected(long requestId, int sensorId) { 1499 Slog.v(TAG, "handleAuthenticationRejected()"); 1500 1501 // Should never happen, log this to catch bad HAL behavior (e.g. auth rejected 1502 // after user dismissed/canceled dialog). 1503 final AuthSession session = getAuthSessionIfCurrent(requestId); 1504 if (session == null) { 1505 Slog.w(TAG, "handleAuthenticationRejected: AuthSession is not current"); 1506 return; 1507 } 1508 1509 session.onAuthenticationRejected(sensorId); 1510 } 1511 1512 private void handleAuthenticationTimedOut(long requestId, int sensorId, int cookie, int error, 1513 int vendorCode) { 1514 Slog.v(TAG, "handleAuthenticationTimedOut(), sensorId: " + sensorId 1515 + ", cookie: " + cookie 1516 + ", error: " + error 1517 + ", vendorCode: " + vendorCode); 1518 // Should never happen, log this to catch bad HAL behavior (e.g. auth succeeded 1519 // after user dismissed/canceled dialog). 1520 final AuthSession session = getAuthSessionIfCurrent(requestId); 1521 if (session == null) { 1522 Slog.w(TAG, "handleAuthenticationTimedOut: AuthSession is not current"); 1523 return; 1524 } 1525 1526 session.onAuthenticationTimedOut(sensorId, cookie, error, vendorCode); 1527 } 1528 1529 private void handleOnError(long requestId, int sensorId, int cookie, 1530 @BiometricConstants.Errors int error, int vendorCode) { 1531 Slog.d(TAG, "handleOnError() sensorId: " + sensorId 1532 + ", cookie: " + cookie 1533 + ", error: " + error 1534 + ", vendorCode: " + vendorCode); 1535 1536 final AuthSession session = getAuthSessionIfCurrent(requestId); 1537 if (session == null) { 1538 Slog.w(TAG, "handleOnError: AuthSession is not current"); 1539 return; 1540 } 1541 1542 try { 1543 final boolean finished = session.onErrorReceived(sensorId, cookie, error, vendorCode); 1544 if (finished) { 1545 Slog.d(TAG, "handleOnError: AuthSession finished"); 1546 mAuthSession = null; 1547 } 1548 } catch (RemoteException e) { 1549 Slog.e(TAG, "RemoteException", e); 1550 } 1551 } 1552 1553 private void handleOnAcquired(long requestId, int sensorId, int acquiredInfo, int vendorCode) { 1554 // Should never happen, log this to catch bad HAL behavior (e.g. auth succeeded 1555 // after user dismissed/canceled dialog). 1556 final AuthSession session = getAuthSessionIfCurrent(requestId); 1557 if (session == null) { 1558 Slog.w(TAG, "onAcquired: AuthSession is not current"); 1559 return; 1560 } 1561 1562 session.onAcquired(sensorId, acquiredInfo, vendorCode); 1563 } 1564 1565 private void handleOnDismissed(long requestId, @BiometricPrompt.DismissedReason int reason, 1566 @Nullable byte[] credentialAttestation) { 1567 final AuthSession session = getAuthSessionIfCurrent(requestId); 1568 if (session == null) { 1569 Slog.e(TAG, "onDismissed: " + reason + ", AuthSession is not current"); 1570 return; 1571 } 1572 1573 session.onDialogDismissed(reason, credentialAttestation); 1574 mAuthSession = null; 1575 } 1576 1577 private void handleOnTryAgainPressed(long requestId) { 1578 Slog.d(TAG, "onTryAgainPressed"); 1579 // No need to check permission, since it can only be invoked by SystemUI 1580 // (or system server itself). 1581 final AuthSession session = getAuthSessionIfCurrent(requestId); 1582 if (session == null) { 1583 Slog.w(TAG, "handleOnTryAgainPressed: AuthSession is not current"); 1584 return; 1585 } 1586 1587 session.onTryAgainPressed(); 1588 } 1589 1590 private void handleOnDeviceCredentialPressed(long requestId) { 1591 Slog.d(TAG, "onDeviceCredentialPressed"); 1592 final AuthSession session = getAuthSessionIfCurrent(requestId); 1593 if (session == null) { 1594 Slog.w(TAG, "handleOnDeviceCredentialPressed: AuthSession is not current"); 1595 return; 1596 } 1597 1598 session.onDeviceCredentialPressed(); 1599 } 1600 1601 private void handleOnSystemEvent(long requestId, int event) { 1602 Slog.d(TAG, "onSystemEvent: " + event); 1603 1604 final AuthSession session = getAuthSessionIfCurrent(requestId); 1605 if (session == null) { 1606 Slog.w(TAG, "handleOnSystemEvent: AuthSession is not current"); 1607 return; 1608 } 1609 1610 session.onSystemEvent(event); 1611 } 1612 1613 private void handleClientDied(long requestId) { 1614 final AuthSession session = getAuthSessionIfCurrent(requestId); 1615 if (session == null) { 1616 Slog.w(TAG, "handleClientDied: AuthSession is not current"); 1617 return; 1618 } 1619 1620 Slog.e(TAG, "Session: " + session); 1621 final boolean finished = session.onClientDied(); 1622 if (finished) { 1623 mAuthSession = null; 1624 } 1625 } 1626 1627 private void handleOnDialogAnimatedIn(long requestId, boolean startFingerprintNow) { 1628 Slog.d(TAG, "handleOnDialogAnimatedIn"); 1629 1630 final AuthSession session = getAuthSessionIfCurrent(requestId); 1631 if (session == null) { 1632 Slog.w(TAG, "handleOnDialogAnimatedIn: AuthSession is not current"); 1633 return; 1634 } 1635 1636 session.onDialogAnimatedIn(startFingerprintNow); 1637 } 1638 1639 private void handleOnStartFingerprintNow(long requestId) { 1640 Slog.d(TAG, "handleOnStartFingerprintNow"); 1641 1642 final AuthSession session = getAuthSessionIfCurrent(requestId); 1643 if (session == null) { 1644 Slog.w(TAG, "handleOnStartFingerprintNow: AuthSession is not current"); 1645 return; 1646 } 1647 1648 session.onStartFingerprint(); 1649 } 1650 1651 /** 1652 * Invoked when each service has notified that its client is ready to be started. When 1653 * all biometrics are ready, this invokes the SystemUI dialog through StatusBar. 1654 */ 1655 private void handleOnReadyForAuthentication(long requestId, int cookie) { 1656 final AuthSession session = getAuthSessionIfCurrent(requestId); 1657 if (session == null) { 1658 // Only should happen if a biometric was locked out when authenticate() was invoked. 1659 // In that case, if device credentials are allowed, the UI is already showing. If not 1660 // allowed, the error has already been returned to the caller. 1661 Slog.w(TAG, "handleOnReadyForAuthentication: AuthSession is not current"); 1662 return; 1663 } 1664 1665 session.onCookieReceived(cookie); 1666 } 1667 1668 private void handleAuthenticate(IBinder token, long requestId, long operationId, int userId, 1669 IBiometricServiceReceiver receiver, String opPackageName, PromptInfo promptInfo) { 1670 mHandler.post(() -> { 1671 try { 1672 final PreAuthInfo preAuthInfo = PreAuthInfo.create(mTrustManager, 1673 mDevicePolicyManager, mSettingObserver, mSensors, userId, 1674 promptInfo, opPackageName, promptInfo.isDisallowBiometricsIfPolicyExists(), 1675 getContext(), mBiometricCameraManager, mUserManager); 1676 1677 // Set the default title if necessary. 1678 if (promptInfo.isUseDefaultTitle()) { 1679 if (TextUtils.isEmpty(promptInfo.getTitle())) { 1680 promptInfo.setTitle(getContext() 1681 .getString(R.string.biometric_dialog_default_title)); 1682 } 1683 } 1684 1685 final int eligible = preAuthInfo.getEligibleModalities(); 1686 final boolean hasEligibleFingerprintSensor = 1687 (eligible & TYPE_FINGERPRINT) == TYPE_FINGERPRINT; 1688 final boolean hasEligibleFaceSensor = (eligible & TYPE_FACE) == TYPE_FACE; 1689 1690 // Set the subtitle according to the modality. 1691 if (promptInfo.isUseDefaultSubtitle()) { 1692 if (hasEligibleFingerprintSensor && hasEligibleFaceSensor) { 1693 promptInfo.setSubtitle(getContext() 1694 .getString(R.string.biometric_dialog_default_subtitle)); 1695 } else if (hasEligibleFingerprintSensor) { 1696 promptInfo.setSubtitle(getContext() 1697 .getString(R.string.fingerprint_dialog_default_subtitle)); 1698 } else if (hasEligibleFaceSensor) { 1699 promptInfo.setSubtitle(getContext() 1700 .getString(R.string.face_dialog_default_subtitle)); 1701 } else { 1702 promptInfo.setSubtitle(getContext() 1703 .getString(R.string.screen_lock_dialog_default_subtitle)); 1704 } 1705 } 1706 1707 final Pair<Integer, Integer> preAuthStatus = preAuthInfo.getPreAuthenticateStatus(); 1708 1709 Slog.d(TAG, "handleAuthenticate: modality(" + preAuthStatus.first 1710 + "), status(" + preAuthStatus.second + "), preAuthInfo: " + preAuthInfo 1711 + " requestId: " + requestId + " promptInfo.isIgnoreEnrollmentState: " 1712 + promptInfo.isIgnoreEnrollmentState()); 1713 // BIOMETRIC_ERROR_SENSOR_PRIVACY_ENABLED is added so that BiometricPrompt can 1714 // be shown for this case. 1715 if (preAuthStatus.second == BiometricConstants.BIOMETRIC_SUCCESS) { 1716 // If BIOMETRIC_WEAK or BIOMETRIC_STRONG are allowed, but not enrolled, but 1717 // CREDENTIAL is requested and available, set the bundle to only request 1718 // CREDENTIAL. 1719 // TODO: We should clean this up, as well as the interface with SystemUI 1720 if (preAuthInfo.credentialRequested && preAuthInfo.credentialAvailable 1721 && preAuthInfo.eligibleSensors.isEmpty()) { 1722 promptInfo.setAuthenticators(Authenticators.DEVICE_CREDENTIAL); 1723 } 1724 1725 authenticateInternal(token, requestId, operationId, preAuthInfo.userId, 1726 receiver, opPackageName, promptInfo, preAuthInfo); 1727 } else { 1728 receiver.onError(preAuthStatus.first /* modality */, 1729 preAuthStatus.second /* errorCode */, 1730 0 /* vendorCode */); 1731 } 1732 } catch (RemoteException e) { 1733 Slog.e(TAG, "Remote exception", e); 1734 } 1735 }); 1736 } 1737 1738 /** 1739 * handleAuthenticate() (above) which is called from BiometricPrompt determines which 1740 * modality/modalities to start authenticating with. authenticateInternal() should only be 1741 * used for preparing <Biometric>Services for authentication when BiometricPrompt#authenticate 1742 * is invoked, shortly after which BiometricPrompt is shown and authentication starts. 1743 * 1744 * Note that this path is NOT invoked when the BiometricPrompt "Try again" button is pressed. 1745 * In that case, see {@link #handleOnTryAgainPressed()}. 1746 */ 1747 private void authenticateInternal(IBinder token, long requestId, long operationId, int userId, 1748 IBiometricServiceReceiver receiver, String opPackageName, PromptInfo promptInfo, 1749 PreAuthInfo preAuthInfo) { 1750 Slog.d(TAG, "Creating authSession with authRequest: " + preAuthInfo); 1751 1752 // No need to dismiss dialog / send error yet if we're continuing authentication, e.g. 1753 // "Try again" is showing due to something like ERROR_TIMEOUT. 1754 if (mAuthSession != null) { 1755 // Forcefully cancel authentication. Dismiss the UI, and immediately send 1756 // ERROR_CANCELED to the client. Note that we should/will ignore HAL ERROR_CANCELED. 1757 // Expect to see some harmless "unknown cookie" errors. 1758 Slog.w(TAG, "Existing AuthSession: " + mAuthSession); 1759 mAuthSession.onCancelAuthSession(true /* force */); 1760 mAuthSession = null; 1761 } 1762 1763 final boolean debugEnabled = mInjector.isDebugEnabled(getContext(), userId); 1764 mAuthSession = new AuthSession(getContext(), mBiometricContext, mStatusBarService, 1765 createSysuiReceiver(requestId), mKeyStoreAuthorization, mRandom, 1766 createClientDeathReceiver(requestId), preAuthInfo, token, requestId, 1767 operationId, userId, createBiometricSensorReceiver(requestId), receiver, 1768 opPackageName, promptInfo, debugEnabled, 1769 mInjector.getFingerprintSensorProperties(getContext())); 1770 try { 1771 mAuthSession.goToInitialState(); 1772 } catch (RemoteException e) { 1773 Slog.e(TAG, "RemoteException", e); 1774 } 1775 } 1776 1777 private void handleCancelAuthentication(long requestId) { 1778 final AuthSession session = getAuthSessionIfCurrent(requestId); 1779 if (session == null) { 1780 Slog.w(TAG, "handleCancelAuthentication: AuthSession is not current"); 1781 // TODO: actually cancel the operation? 1782 return; 1783 } 1784 1785 final boolean finished = session.onCancelAuthSession(false /* force */); 1786 if (finished) { 1787 Slog.d(TAG, "handleCancelAuthentication: AuthSession finished"); 1788 mAuthSession = null; 1789 } 1790 } 1791 1792 @Nullable 1793 private BiometricSensor getSensorForId(int sensorId) { 1794 for (BiometricSensor sensor : mSensors) { 1795 if (sensor.id == sensorId) { 1796 return sensor; 1797 } 1798 } 1799 return null; 1800 } 1801 1802 private void dumpInternal(PrintWriter pw) { 1803 pw.println("Legacy Settings: " + mSettingObserver.mUseLegacyFaceOnlySettings); 1804 pw.println(); 1805 1806 pw.println("Sensors:"); 1807 for (BiometricSensor sensor : mSensors) { 1808 pw.println(" " + sensor); 1809 } 1810 pw.println(); 1811 pw.println("CurrentSession: " + mAuthSession); 1812 pw.println(); 1813 } 1814 1815 } 1816