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