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