1 /* 2 * Copyright (C) 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.biometrics; 18 19 import static android.Manifest.permission.SET_BIOMETRIC_DIALOG_ADVANCED; 20 import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL; 21 import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE; 22 import static android.hardware.biometrics.BiometricManager.Authenticators; 23 24 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT; 25 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW; 26 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN; 27 import static com.android.server.biometrics.PreAuthInfo.AUTHENTICATOR_OK; 28 import static com.android.server.biometrics.PreAuthInfo.BIOMETRIC_DISABLED_BY_DEVICE_POLICY; 29 import static com.android.server.biometrics.PreAuthInfo.BIOMETRIC_HARDWARE_NOT_DETECTED; 30 import static com.android.server.biometrics.PreAuthInfo.BIOMETRIC_INSUFFICIENT_STRENGTH; 31 import static com.android.server.biometrics.PreAuthInfo.BIOMETRIC_INSUFFICIENT_STRENGTH_AFTER_DOWNGRADE; 32 import static com.android.server.biometrics.PreAuthInfo.BIOMETRIC_LOCKOUT_PERMANENT; 33 import static com.android.server.biometrics.PreAuthInfo.BIOMETRIC_LOCKOUT_TIMED; 34 import static com.android.server.biometrics.PreAuthInfo.BIOMETRIC_NOT_ENABLED_FOR_APPS; 35 import static com.android.server.biometrics.PreAuthInfo.BIOMETRIC_NOT_ENROLLED; 36 import static com.android.server.biometrics.PreAuthInfo.BIOMETRIC_NO_HARDWARE; 37 import static com.android.server.biometrics.PreAuthInfo.BIOMETRIC_SENSOR_PRIVACY_ENABLED; 38 import static com.android.server.biometrics.PreAuthInfo.CREDENTIAL_NOT_ENROLLED; 39 import static com.android.server.biometrics.PreAuthInfo.MANDATORY_BIOMETRIC_UNAVAILABLE_ERROR; 40 41 import android.annotation.NonNull; 42 import android.annotation.Nullable; 43 import android.app.ActivityManager; 44 import android.app.ActivityTaskManager; 45 import android.content.ComponentName; 46 import android.content.Context; 47 import android.content.pm.PackageManager; 48 import android.hardware.biometrics.BiometricAuthenticator; 49 import android.hardware.biometrics.BiometricConstants; 50 import android.hardware.biometrics.BiometricManager; 51 import android.hardware.biometrics.BiometricPrompt; 52 import android.hardware.biometrics.BiometricPrompt.AuthenticationResultType; 53 import android.hardware.biometrics.Flags; 54 import android.hardware.biometrics.IBiometricService; 55 import android.hardware.biometrics.PromptInfo; 56 import android.hardware.biometrics.SensorProperties; 57 import android.hardware.biometrics.SensorPropertiesInternal; 58 import android.os.Binder; 59 import android.os.Build; 60 import android.os.Process; 61 import android.os.RemoteException; 62 import android.os.ServiceManager; 63 import android.os.UserHandle; 64 import android.os.UserManager; 65 import android.provider.Settings; 66 import android.util.Slog; 67 68 import com.android.internal.R; 69 import com.android.internal.widget.LockPatternUtils; 70 import com.android.server.biometrics.sensors.BaseClientMonitor; 71 72 import java.util.List; 73 74 public class Utils { 75 76 private static final String TAG = "BiometricUtils"; 77 isDebugEnabled(Context context, int targetUserId)78 public static boolean isDebugEnabled(Context context, int targetUserId) { 79 if (targetUserId == UserHandle.USER_NULL) { 80 return false; 81 } 82 83 if (!(Build.IS_ENG || Build.IS_USERDEBUG)) { 84 return false; 85 } 86 87 if (Settings.Secure.getIntForUser(context.getContentResolver(), 88 Settings.Secure.BIOMETRIC_DEBUG_ENABLED, 0, 89 targetUserId) == 0) { 90 return false; 91 } 92 return true; 93 } 94 95 /** If virtualized fingerprint sensor is supported. */ isFingerprintVirtualEnabled(@onNull Context context)96 public static boolean isFingerprintVirtualEnabled(@NonNull Context context) { 97 return Build.isDebuggable() 98 && (Settings.Secure.getIntForUser(context.getContentResolver(), 99 Settings.Secure.BIOMETRIC_FINGERPRINT_VIRTUAL_ENABLED, 0, 100 UserHandle.USER_CURRENT) == 1 101 || Settings.Secure.getIntForUser(context.getContentResolver(), 102 Settings.Secure.BIOMETRIC_VIRTUAL_ENABLED, 0, UserHandle.USER_CURRENT) == 1); 103 } 104 105 /** If virtualized face sensor is supported. */ isFaceVirtualEnabled(@onNull Context context)106 public static boolean isFaceVirtualEnabled(@NonNull Context context) { 107 return Build.isDebuggable() 108 && (Settings.Secure.getIntForUser(context.getContentResolver(), 109 Settings.Secure.BIOMETRIC_FACE_VIRTUAL_ENABLED, 0, UserHandle.USER_CURRENT) == 1 110 || Settings.Secure.getIntForUser(context.getContentResolver(), 111 Settings.Secure.BIOMETRIC_VIRTUAL_ENABLED, 0, UserHandle.USER_CURRENT) == 1); 112 } 113 114 /** 115 * Combines {@link PromptInfo#setDeviceCredentialAllowed(boolean)} with 116 * {@link PromptInfo#setAuthenticators(int)}, as the former is not flexible enough. 117 */ combineAuthenticatorBundles(PromptInfo promptInfo)118 static void combineAuthenticatorBundles(PromptInfo promptInfo) { 119 // Cache and remove explicit ALLOW_DEVICE_CREDENTIAL boolean flag from the bundle. 120 final boolean deviceCredentialAllowed = promptInfo.isDeviceCredentialAllowed(); 121 promptInfo.setDeviceCredentialAllowed(false); 122 123 final @Authenticators.Types int authenticators; 124 if (promptInfo.getAuthenticators() != 0) { 125 // Ignore ALLOW_DEVICE_CREDENTIAL flag if AUTH_TYPES_ALLOWED is defined. 126 authenticators = promptInfo.getAuthenticators(); 127 } else { 128 // Otherwise, use ALLOW_DEVICE_CREDENTIAL flag along with Weak+ biometrics by default. 129 authenticators = deviceCredentialAllowed 130 ? Authenticators.DEVICE_CREDENTIAL | Authenticators.BIOMETRIC_WEAK 131 : Authenticators.BIOMETRIC_WEAK; 132 } 133 134 promptInfo.setAuthenticators(authenticators); 135 } 136 137 /** 138 * @param authenticators composed of one or more values from {@link Authenticators} 139 * @return true if device credential is allowed. 140 */ isCredentialRequested(@uthenticators.Types int authenticators)141 static boolean isCredentialRequested(@Authenticators.Types int authenticators) { 142 return (authenticators & Authenticators.DEVICE_CREDENTIAL) != 0; 143 } 144 145 /** 146 * @param authenticators composed of one or more values from {@link Authenticators} 147 * @return true if mandatory biometrics is requested 148 */ isMandatoryBiometricsRequested(@uthenticators.Types int authenticators)149 static boolean isMandatoryBiometricsRequested(@Authenticators.Types int authenticators) { 150 return (authenticators & Authenticators.IDENTITY_CHECK) != 0; 151 } 152 153 /** 154 * @param promptInfo should be first processed by 155 * {@link #combineAuthenticatorBundles(PromptInfo)} 156 * @return true if device credential is allowed. 157 */ isCredentialRequested(PromptInfo promptInfo)158 static boolean isCredentialRequested(PromptInfo promptInfo) { 159 return isCredentialRequested(promptInfo.getAuthenticators()); 160 } 161 162 /** 163 * Checks if any of the publicly defined strengths are set. 164 * 165 * @param authenticators composed of one or more values from {@link Authenticators} 166 * @return minimal allowed biometric strength or 0 if biometric authentication is not allowed. 167 */ getPublicBiometricStrength(@uthenticators.Types int authenticators)168 static int getPublicBiometricStrength(@Authenticators.Types int authenticators) { 169 // Only biometrics WEAK and above are allowed to integrate with the public APIs. 170 return authenticators & Authenticators.BIOMETRIC_WEAK; 171 } 172 173 /** 174 * Checks if any of the publicly defined strengths are set. 175 * 176 * @param promptInfo should be first processed by 177 * {@link #combineAuthenticatorBundles(PromptInfo)} 178 * @return minimal allowed biometric strength or 0 if biometric authentication is not allowed. 179 */ getPublicBiometricStrength(PromptInfo promptInfo)180 static int getPublicBiometricStrength(PromptInfo promptInfo) { 181 return getPublicBiometricStrength(promptInfo.getAuthenticators()); 182 } 183 184 /** 185 * Checks if any of the publicly defined strengths are set. 186 * 187 * @param authenticators composed of one or more values from {@link Authenticators} 188 * @return true if biometric authentication is allowed. 189 */ isBiometricRequested(@uthenticators.Types int authenticators)190 static boolean isBiometricRequested(@Authenticators.Types int authenticators) { 191 return getPublicBiometricStrength(authenticators) != 0; 192 } 193 194 /** 195 * Checks if any of the publicly defined strengths are set. 196 * 197 * @param promptInfo should be first processed by 198 * {@link #combineAuthenticatorBundles(PromptInfo)} 199 * @return true if biometric authentication is allowed. 200 */ isBiometricRequested(PromptInfo promptInfo)201 static boolean isBiometricRequested(PromptInfo promptInfo) { 202 return getPublicBiometricStrength(promptInfo) != 0; 203 } 204 205 /** 206 * @param sensorStrength the strength of the sensor 207 * @param requestedStrength the strength that it must meet 208 * @return true only if the sensor is at least as strong as the requested strength 209 */ isAtLeastStrength(@uthenticators.Types int sensorStrength, @Authenticators.Types int requestedStrength)210 public static boolean isAtLeastStrength(@Authenticators.Types int sensorStrength, 211 @Authenticators.Types int requestedStrength) { 212 // Clear out any bits that are not reserved for biometric 213 sensorStrength &= Authenticators.BIOMETRIC_MIN_STRENGTH; 214 215 // If the authenticator contains bits outside of the requested strength, it is too weak. 216 if ((sensorStrength & ~requestedStrength) != 0) { 217 return false; 218 } 219 220 for (int i = Authenticators.BIOMETRIC_MAX_STRENGTH; 221 i <= requestedStrength; i = (i << 1) | 1) { 222 if (i == sensorStrength) { 223 return true; 224 } 225 } 226 227 Slog.e(BiometricService.TAG, "Unknown sensorStrength: " + sensorStrength 228 + ", requestedStrength: " + requestedStrength); 229 return false; 230 } 231 232 /** 233 * Checks if the authenticator configuration is a valid combination of the public APIs 234 * @param promptInfo 235 * @return 236 */ isValidAuthenticatorConfig(Context context, PromptInfo promptInfo)237 static boolean isValidAuthenticatorConfig(Context context, PromptInfo promptInfo) { 238 final int authenticators = promptInfo.getAuthenticators(); 239 return isValidAuthenticatorConfig(context, authenticators); 240 } 241 242 /** 243 * Checks if the authenticator configuration is a valid combination of the public APIs. 244 * 245 * throws {@link SecurityException} if the caller requests for mandatory biometrics without 246 * {@link SET_BIOMETRIC_DIALOG_ADVANCED} permission 247 */ isValidAuthenticatorConfig(Context context, int authenticators)248 static boolean isValidAuthenticatorConfig(Context context, int authenticators) { 249 // The caller is not required to set the authenticators. But if they do, check the below. 250 if (authenticators == 0) { 251 return true; 252 } 253 254 // Check if any of the non-biometric and non-credential bits are set. If so, this is 255 // invalid. 256 final int testBits; 257 if (Flags.mandatoryBiometrics()) { 258 testBits = ~(Authenticators.DEVICE_CREDENTIAL 259 | Authenticators.BIOMETRIC_MIN_STRENGTH 260 | Authenticators.IDENTITY_CHECK); 261 } else { 262 testBits = ~(Authenticators.DEVICE_CREDENTIAL 263 | Authenticators.BIOMETRIC_MIN_STRENGTH); 264 } 265 if ((authenticators & testBits) != 0) { 266 Slog.e(BiometricService.TAG, "Non-biometric, non-credential bits found." 267 + " Authenticators: " + authenticators); 268 return false; 269 } 270 271 // Check that biometrics bits are either NONE, WEAK, or STRONG. If NONE, DEVICE_CREDENTIAL 272 // should be set. 273 final int biometricBits = authenticators & Authenticators.BIOMETRIC_MIN_STRENGTH; 274 if (biometricBits == Authenticators.EMPTY_SET 275 && isCredentialRequested(authenticators)) { 276 return true; 277 } else if (biometricBits == Authenticators.BIOMETRIC_STRONG) { 278 return true; 279 } else if (biometricBits == Authenticators.BIOMETRIC_WEAK) { 280 return true; 281 } else if (isMandatoryBiometricsRequested(authenticators)) { 282 //TODO(b/347123256): Update CTS test 283 context.enforceCallingOrSelfPermission(SET_BIOMETRIC_DIALOG_ADVANCED, 284 "Must have SET_BIOMETRIC_DIALOG_ADVANCED permission"); 285 return true; 286 } 287 288 Slog.e(BiometricService.TAG, "Unsupported biometric flags. Authenticators: " 289 + authenticators); 290 // Non-supported biometric flags are being used 291 return false; 292 } 293 294 /** 295 * Converts error codes from BiometricConstants, which are used in most of the internal plumbing 296 * and eventually returned to {@link BiometricPrompt.AuthenticationCallback} to public 297 * {@link BiometricManager} constants, which are used by APIs such as 298 * {@link BiometricManager#canAuthenticate(int)} 299 * 300 * @param biometricConstantsCode see {@link BiometricConstants} 301 * @return see {@link BiometricManager} 302 */ biometricConstantsToBiometricManager(int biometricConstantsCode)303 static int biometricConstantsToBiometricManager(int biometricConstantsCode) { 304 final int biometricManagerCode; 305 306 switch (biometricConstantsCode) { 307 case BiometricConstants.BIOMETRIC_SUCCESS: 308 biometricManagerCode = BiometricManager.BIOMETRIC_SUCCESS; 309 break; 310 case BiometricConstants.BIOMETRIC_ERROR_NO_BIOMETRICS: 311 case BiometricConstants.BIOMETRIC_ERROR_NO_DEVICE_CREDENTIAL: 312 biometricManagerCode = BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED; 313 break; 314 case BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE: 315 biometricManagerCode = BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE; 316 break; 317 case BiometricConstants.BIOMETRIC_ERROR_HW_NOT_PRESENT: 318 biometricManagerCode = BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE; 319 break; 320 case BiometricConstants.BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED: 321 biometricManagerCode = BiometricManager.BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED; 322 break; 323 case BiometricConstants.BIOMETRIC_ERROR_LOCKOUT: 324 case BiometricConstants.BIOMETRIC_ERROR_LOCKOUT_PERMANENT: 325 biometricManagerCode = Flags.mandatoryBiometrics() 326 ? BiometricManager.BIOMETRIC_ERROR_LOCKOUT 327 : BiometricManager.BIOMETRIC_SUCCESS; 328 break; 329 case BiometricConstants.BIOMETRIC_ERROR_SENSOR_PRIVACY_ENABLED: 330 biometricManagerCode = BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE; 331 break; 332 case BiometricConstants.BIOMETRIC_ERROR_IDENTITY_CHECK_NOT_ACTIVE: 333 biometricManagerCode = BiometricManager.BIOMETRIC_ERROR_IDENTITY_CHECK_NOT_ACTIVE; 334 break; 335 case BiometricConstants.BIOMETRIC_ERROR_NOT_ENABLED_FOR_APPS: 336 biometricManagerCode = BiometricManager.BIOMETRIC_ERROR_NOT_ENABLED_FOR_APPS; 337 break; 338 default: 339 Slog.e(BiometricService.TAG, "Unhandled result code: " + biometricConstantsCode); 340 biometricManagerCode = BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE; 341 break; 342 } 343 return biometricManagerCode; 344 } 345 346 /** 347 * Converts a {@link BiometricPrompt} dismissal reason to an authentication type at the level of 348 * granularity supported by {@link BiometricPrompt.AuthenticationResult}. 349 * 350 * @param reason The reason that the {@link BiometricPrompt} was dismissed. Must be one of: 351 * {@link BiometricPrompt#DISMISSED_REASON_CREDENTIAL_CONFIRMED}, 352 * {@link BiometricPrompt#DISMISSED_REASON_BIOMETRIC_CONFIRMED}, or 353 * {@link BiometricPrompt#DISMISSED_REASON_BIOMETRIC_CONFIRM_NOT_REQUIRED} 354 * @return An integer representing the authentication type for {@link 355 * BiometricPrompt.AuthenticationResult}. 356 * @throws IllegalArgumentException if given an invalid dismissal reason. 357 */ getAuthenticationTypeForResult(int reason)358 static @AuthenticationResultType int getAuthenticationTypeForResult(int reason) { 359 switch (reason) { 360 case BiometricPrompt.DISMISSED_REASON_CREDENTIAL_CONFIRMED: 361 return BiometricPrompt.AUTHENTICATION_RESULT_TYPE_DEVICE_CREDENTIAL; 362 363 case BiometricPrompt.DISMISSED_REASON_BIOMETRIC_CONFIRMED: 364 case BiometricPrompt.DISMISSED_REASON_BIOMETRIC_CONFIRM_NOT_REQUIRED: 365 return BiometricPrompt.AUTHENTICATION_RESULT_TYPE_BIOMETRIC; 366 367 default: 368 throw new IllegalArgumentException("Unsupported dismissal reason: " + reason); 369 } 370 } 371 372 authenticatorStatusToBiometricConstant( @reAuthInfo.AuthenticatorStatus int status)373 static int authenticatorStatusToBiometricConstant( 374 @PreAuthInfo.AuthenticatorStatus int status) { 375 switch (status) { 376 case BIOMETRIC_NO_HARDWARE: 377 case BIOMETRIC_INSUFFICIENT_STRENGTH: 378 return BiometricConstants.BIOMETRIC_ERROR_HW_NOT_PRESENT; 379 380 case AUTHENTICATOR_OK: 381 return BiometricConstants.BIOMETRIC_SUCCESS; 382 383 case BIOMETRIC_INSUFFICIENT_STRENGTH_AFTER_DOWNGRADE: 384 return BiometricConstants.BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED; 385 386 case BIOMETRIC_NOT_ENROLLED: 387 return BiometricConstants.BIOMETRIC_ERROR_NO_BIOMETRICS; 388 389 case CREDENTIAL_NOT_ENROLLED: 390 return BiometricConstants.BIOMETRIC_ERROR_NO_DEVICE_CREDENTIAL; 391 392 case BIOMETRIC_LOCKOUT_TIMED: 393 return BiometricConstants.BIOMETRIC_ERROR_LOCKOUT; 394 395 case BIOMETRIC_LOCKOUT_PERMANENT: 396 return BiometricConstants.BIOMETRIC_ERROR_LOCKOUT_PERMANENT; 397 case BIOMETRIC_SENSOR_PRIVACY_ENABLED: 398 return BiometricConstants.BIOMETRIC_ERROR_SENSOR_PRIVACY_ENABLED; 399 case MANDATORY_BIOMETRIC_UNAVAILABLE_ERROR: 400 return BiometricConstants.BIOMETRIC_ERROR_IDENTITY_CHECK_NOT_ACTIVE; 401 case BIOMETRIC_NOT_ENABLED_FOR_APPS: 402 if (Flags.mandatoryBiometrics()) { 403 return BiometricConstants.BIOMETRIC_ERROR_NOT_ENABLED_FOR_APPS; 404 } 405 case BIOMETRIC_DISABLED_BY_DEVICE_POLICY: 406 case BIOMETRIC_HARDWARE_NOT_DETECTED: 407 default: 408 return BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE; 409 } 410 } 411 isConfirmationSupported(@iometricAuthenticator.Modality int modality)412 static boolean isConfirmationSupported(@BiometricAuthenticator.Modality int modality) { 413 switch (modality) { 414 case BiometricAuthenticator.TYPE_FACE: 415 case BiometricAuthenticator.TYPE_IRIS: 416 return true; 417 default: 418 return false; 419 } 420 } 421 removeBiometricBits(@uthenticators.Types int authenticators)422 static int removeBiometricBits(@Authenticators.Types int authenticators) { 423 return authenticators & ~Authenticators.BIOMETRIC_MIN_STRENGTH; 424 } 425 listContains(int[] haystack, int needle)426 public static boolean listContains(int[] haystack, int needle) { 427 for (int i = 0; i < haystack.length; i++) { 428 if (haystack[i] == needle) { 429 return true; 430 } 431 } 432 return false; 433 } 434 435 /** Same as checkPermission but also allows shell. */ checkPermissionOrShell(Context context, String permission)436 public static void checkPermissionOrShell(Context context, String permission) { 437 if (Binder.getCallingUid() == Process.SHELL_UID) { 438 return; 439 } 440 checkPermission(context, permission); 441 } 442 443 checkPermission(Context context, String permission)444 public static void checkPermission(Context context, String permission) { 445 context.enforceCallingOrSelfPermission(permission, 446 "Must have " + permission + " permission."); 447 } 448 isCurrentUserOrProfile(Context context, int userId)449 public static boolean isCurrentUserOrProfile(Context context, int userId) { 450 UserManager um = UserManager.get(context); 451 if (um == null) { 452 Slog.e(TAG, "Unable to get UserManager"); 453 return false; 454 } 455 456 final long token = Binder.clearCallingIdentity(); 457 try { 458 // Allow current user or profiles of the current user... 459 for (int profileId : um.getEnabledProfileIds(ActivityManager.getCurrentUser())) { 460 if (profileId == userId) { 461 return true; 462 } 463 } 464 } finally { 465 Binder.restoreCallingIdentity(token); 466 } 467 468 return false; 469 } 470 isStrongBiometric(int sensorId)471 public static boolean isStrongBiometric(int sensorId) { 472 IBiometricService service = IBiometricService.Stub.asInterface( 473 ServiceManager.getService(Context.BIOMETRIC_SERVICE)); 474 try { 475 return Utils.isAtLeastStrength(service.getCurrentStrength(sensorId), 476 Authenticators.BIOMETRIC_STRONG); 477 } catch (RemoteException e) { 478 Slog.e(TAG, "RemoteException", e); 479 return false; 480 } 481 } 482 483 /** 484 * Returns the sensor's current strength, taking any updated strengths into effect. 485 * 486 * @param sensorId The sensor Id 487 * @return see {@link BiometricManager.Authenticators} 488 */ getCurrentStrength(int sensorId)489 public static @Authenticators.Types int getCurrentStrength(int sensorId) { 490 IBiometricService service = IBiometricService.Stub.asInterface( 491 ServiceManager.getService(Context.BIOMETRIC_SERVICE)); 492 try { 493 return service.getCurrentStrength(sensorId); 494 } catch (RemoteException e) { 495 Slog.e(TAG, "RemoteException", e); 496 return Authenticators.EMPTY_SET; 497 } 498 } 499 500 /** 501 * Checks if a client package matches Keyguard and can perform internal biometric operations. 502 * 503 * @param context The system context. 504 * @param clientPackage The name of the package to be checked against Keyguard. 505 * @return Whether the given package matches Keyguard. 506 */ isKeyguard(@onNull Context context, @Nullable String clientPackage)507 public static boolean isKeyguard(@NonNull Context context, @Nullable String clientPackage) { 508 final boolean hasPermission = hasInternalPermission(context); 509 final ComponentName keyguardComponent = ComponentName.unflattenFromString( 510 context.getResources().getString(R.string.config_keyguardComponent)); 511 final String keyguardPackage = keyguardComponent != null 512 ? keyguardComponent.getPackageName() : null; 513 return hasPermission && keyguardPackage != null && keyguardPackage.equals(clientPackage); 514 } 515 516 /** 517 * Checks if a client package matches the Android system and can perform internal biometric 518 * operations. 519 * 520 * @param context The system context. 521 * @param clientPackage The name of the package to be checked against the Android system. 522 * @return Whether the given package matches the Android system. 523 */ isSystem(@onNull Context context, @Nullable String clientPackage)524 public static boolean isSystem(@NonNull Context context, @Nullable String clientPackage) { 525 return hasInternalPermission(context) && "android".equals(clientPackage); 526 } 527 528 /** 529 * Checks if a client package matches Settings and can perform internal biometric operations. 530 * 531 * @param context The system context. 532 * @param clientPackage The name of the package to be checked against Settings. 533 * @return Whether the given package matches Settings. 534 */ isSettings(@onNull Context context, @Nullable String clientPackage)535 public static boolean isSettings(@NonNull Context context, @Nullable String clientPackage) { 536 return hasInternalPermission(context) && "com.android.settings".equals(clientPackage); 537 } 538 hasInternalPermission(@onNull Context context)539 private static boolean hasInternalPermission(@NonNull Context context) { 540 return context.checkCallingOrSelfPermission(USE_BIOMETRIC_INTERNAL) 541 == PackageManager.PERMISSION_GRANTED; 542 } 543 getClientName(@ullable BaseClientMonitor client)544 public static String getClientName(@Nullable BaseClientMonitor client) { 545 return client != null ? client.getClass().getSimpleName() : "null"; 546 } 547 containsFlag(int haystack, int needle)548 private static boolean containsFlag(int haystack, int needle) { 549 return (haystack & needle) != 0; 550 } 551 isUserEncryptedOrLockdown(@onNull LockPatternUtils lpu, int user)552 public static boolean isUserEncryptedOrLockdown(@NonNull LockPatternUtils lpu, int user) { 553 final int strongAuth = lpu.getStrongAuthForUser(user); 554 final boolean isEncrypted = containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_BOOT); 555 final boolean isLockDown = containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW) 556 || containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN); 557 Slog.d(TAG, "isEncrypted: " + isEncrypted + " isLockdown: " + isLockDown); 558 return isEncrypted || isLockDown; 559 } 560 isForeground(int callingUid, int callingPid)561 public static boolean isForeground(int callingUid, int callingPid) { 562 try { 563 final List<ActivityManager.RunningAppProcessInfo> procs = 564 ActivityManager.getService().getRunningAppProcesses(); 565 if (procs == null) { 566 Slog.e(TAG, "No running app processes found, defaulting to true"); 567 return true; 568 } 569 570 for (int i = 0; i < procs.size(); i++) { 571 ActivityManager.RunningAppProcessInfo proc = procs.get(i); 572 if (proc.pid == callingPid && proc.uid == callingUid 573 && proc.importance <= IMPORTANCE_FOREGROUND_SERVICE) { 574 return true; 575 } 576 } 577 } catch (RemoteException e) { 578 Slog.w(TAG, "am.getRunningAppProcesses() failed"); 579 } 580 return false; 581 } 582 583 /** 584 * Converts from {@link BiometricManager.Authenticators} biometric strength to the internal 585 * {@link SensorPropertiesInternal} strength. 586 */ authenticatorStrengthToPropertyStrength( @uthenticators.Types int strength)587 public static @SensorProperties.Strength int authenticatorStrengthToPropertyStrength( 588 @Authenticators.Types int strength) { 589 switch (strength) { 590 case BiometricManager.Authenticators.BIOMETRIC_CONVENIENCE: 591 return SensorProperties.STRENGTH_CONVENIENCE; 592 case BiometricManager.Authenticators.BIOMETRIC_WEAK: 593 return SensorProperties.STRENGTH_WEAK; 594 case BiometricManager.Authenticators.BIOMETRIC_STRONG: 595 return SensorProperties.STRENGTH_STRONG; 596 default: 597 throw new IllegalArgumentException("Unknown strength: " + strength); 598 } 599 } 600 propertyStrengthToAuthenticatorStrength( @ensorProperties.Strength int strength)601 public static @Authenticators.Types int propertyStrengthToAuthenticatorStrength( 602 @SensorProperties.Strength int strength) { 603 switch (strength) { 604 case SensorProperties.STRENGTH_CONVENIENCE: 605 return Authenticators.BIOMETRIC_CONVENIENCE; 606 case SensorProperties.STRENGTH_WEAK: 607 return Authenticators.BIOMETRIC_WEAK; 608 case SensorProperties.STRENGTH_STRONG: 609 return Authenticators.BIOMETRIC_STRONG; 610 default: 611 throw new IllegalArgumentException("Unknown strength: " + strength); 612 } 613 } 614 615 // LINT.IfChange 616 617 /** 618 * Checks if a client package is running in the background. 619 * 620 * @param clientPackage The name of the package to be checked. 621 * @return Whether the client package is running in background 622 */ isBackground(String clientPackage)623 public static boolean isBackground(String clientPackage) { 624 Slog.v(TAG, "Checking if the authenticating is in background," 625 + " clientPackage:" + clientPackage); 626 final List<ActivityManager.RunningTaskInfo> tasks = 627 ActivityTaskManager.getInstance().getTasks(Integer.MAX_VALUE); 628 629 if (tasks == null || tasks.isEmpty()) { 630 Slog.d(TAG, "No running tasks reported"); 631 return true; 632 } 633 634 for (ActivityManager.RunningTaskInfo taskInfo : tasks) { 635 final ComponentName topActivity = taskInfo.topActivity; 636 if (topActivity != null) { 637 final String topPackage = topActivity.getPackageName(); 638 if (topPackage.contentEquals(clientPackage) && taskInfo.isVisible()) { 639 return false; 640 } else { 641 Slog.i(TAG, "Running task, top: " + topPackage 642 + ", isVisible: " + taskInfo.isVisible()); 643 } 644 } 645 } 646 647 return true; 648 } 649 // LINT.ThenChange(frameworks/base/packages/SystemUI/shared/biometrics/src/com/android 650 // /systemui/biometrics/Utils.kt) 651 } 652