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