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