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