• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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