• 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.CREDENTIAL_NOT_ENROLLED;
37 
38 import android.annotation.NonNull;
39 import android.annotation.Nullable;
40 import android.app.ActivityManager;
41 import android.content.ComponentName;
42 import android.content.Context;
43 import android.content.pm.PackageManager;
44 import android.hardware.biometrics.BiometricAuthenticator;
45 import android.hardware.biometrics.BiometricConstants;
46 import android.hardware.biometrics.BiometricManager;
47 import android.hardware.biometrics.BiometricPrompt;
48 import android.hardware.biometrics.BiometricPrompt.AuthenticationResultType;
49 import android.hardware.biometrics.IBiometricService;
50 import android.hardware.biometrics.PromptInfo;
51 import android.hardware.biometrics.SensorProperties;
52 import android.hardware.biometrics.SensorPropertiesInternal;
53 import android.hardware.fingerprint.IUdfpsOverlayController;
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.AuthenticationClient;
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             default:
284                 Slog.e(BiometricService.TAG, "Unhandled result code: " + biometricConstantsCode);
285                 biometricManagerCode = BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE;
286                 break;
287         }
288         return biometricManagerCode;
289     }
290 
291     /**
292      * Converts a {@link BiometricPrompt} dismissal reason to an authentication type at the level of
293      * granularity supported by {@link BiometricPrompt.AuthenticationResult}.
294      *
295      * @param reason The reason that the {@link BiometricPrompt} was dismissed. Must be one of:
296      *               {@link BiometricPrompt#DISMISSED_REASON_CREDENTIAL_CONFIRMED},
297      *               {@link BiometricPrompt#DISMISSED_REASON_BIOMETRIC_CONFIRMED}, or
298      *               {@link BiometricPrompt#DISMISSED_REASON_BIOMETRIC_CONFIRM_NOT_REQUIRED}
299      * @return An integer representing the authentication type for {@link
300      *         BiometricPrompt.AuthenticationResult}.
301      * @throws IllegalArgumentException if given an invalid dismissal reason.
302      */
getAuthenticationTypeForResult(int reason)303     static @AuthenticationResultType int getAuthenticationTypeForResult(int reason) {
304         switch (reason) {
305             case BiometricPrompt.DISMISSED_REASON_CREDENTIAL_CONFIRMED:
306                 return BiometricPrompt.AUTHENTICATION_RESULT_TYPE_DEVICE_CREDENTIAL;
307 
308             case BiometricPrompt.DISMISSED_REASON_BIOMETRIC_CONFIRMED:
309             case BiometricPrompt.DISMISSED_REASON_BIOMETRIC_CONFIRM_NOT_REQUIRED:
310                 return BiometricPrompt.AUTHENTICATION_RESULT_TYPE_BIOMETRIC;
311 
312             default:
313                 throw new IllegalArgumentException("Unsupported dismissal reason: " + reason);
314         }
315     }
316 
317 
authenticatorStatusToBiometricConstant( @reAuthInfo.AuthenticatorStatus int status)318     static int authenticatorStatusToBiometricConstant(
319             @PreAuthInfo.AuthenticatorStatus int status) {
320         switch (status) {
321             case BIOMETRIC_NO_HARDWARE:
322             case BIOMETRIC_INSUFFICIENT_STRENGTH:
323                 return BiometricConstants.BIOMETRIC_ERROR_HW_NOT_PRESENT;
324 
325             case AUTHENTICATOR_OK:
326                 return BiometricConstants.BIOMETRIC_SUCCESS;
327 
328             case BIOMETRIC_INSUFFICIENT_STRENGTH_AFTER_DOWNGRADE:
329                 return BiometricConstants.BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED;
330 
331             case BIOMETRIC_NOT_ENROLLED:
332                 return BiometricConstants.BIOMETRIC_ERROR_NO_BIOMETRICS;
333 
334             case CREDENTIAL_NOT_ENROLLED:
335                 return BiometricConstants.BIOMETRIC_ERROR_NO_DEVICE_CREDENTIAL;
336 
337             case BIOMETRIC_LOCKOUT_TIMED:
338                 return BiometricConstants.BIOMETRIC_ERROR_LOCKOUT;
339 
340             case BIOMETRIC_LOCKOUT_PERMANENT:
341                 return BiometricConstants.BIOMETRIC_ERROR_LOCKOUT_PERMANENT;
342 
343             case BIOMETRIC_DISABLED_BY_DEVICE_POLICY:
344             case BIOMETRIC_HARDWARE_NOT_DETECTED:
345             case BIOMETRIC_NOT_ENABLED_FOR_APPS:
346             default:
347                 return BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE;
348         }
349     }
350 
isConfirmationSupported(@iometricAuthenticator.Modality int modality)351     static boolean isConfirmationSupported(@BiometricAuthenticator.Modality int modality) {
352         switch (modality) {
353             case BiometricAuthenticator.TYPE_FACE:
354             case BiometricAuthenticator.TYPE_IRIS:
355                 return true;
356             default:
357                 return false;
358         }
359     }
360 
removeBiometricBits(@uthenticators.Types int authenticators)361     static int removeBiometricBits(@Authenticators.Types int authenticators) {
362         return authenticators & ~Authenticators.BIOMETRIC_MIN_STRENGTH;
363     }
364 
listContains(int[] haystack, int needle)365     public static boolean listContains(int[] haystack, int needle) {
366         for (int i = 0; i < haystack.length; i++) {
367             if (haystack[i] == needle) {
368                 return true;
369             }
370         }
371         return false;
372     }
373 
checkPermission(Context context, String permission)374     public static void checkPermission(Context context, String permission) {
375         context.enforceCallingOrSelfPermission(permission,
376                 "Must have " + permission + " permission.");
377     }
378 
isCurrentUserOrProfile(Context context, int userId)379     public static boolean isCurrentUserOrProfile(Context context, int userId) {
380         UserManager um = UserManager.get(context);
381         if (um == null) {
382             Slog.e(TAG, "Unable to get UserManager");
383             return false;
384         }
385 
386         final long token = Binder.clearCallingIdentity();
387         try {
388             // Allow current user or profiles of the current user...
389             for (int profileId : um.getEnabledProfileIds(ActivityManager.getCurrentUser())) {
390                 if (profileId == userId) {
391                     return true;
392                 }
393             }
394         } finally {
395             Binder.restoreCallingIdentity(token);
396         }
397 
398         return false;
399     }
400 
isStrongBiometric(int sensorId)401     public static boolean isStrongBiometric(int sensorId) {
402         IBiometricService service = IBiometricService.Stub.asInterface(
403                 ServiceManager.getService(Context.BIOMETRIC_SERVICE));
404         try {
405             return Utils.isAtLeastStrength(service.getCurrentStrength(sensorId),
406                     Authenticators.BIOMETRIC_STRONG);
407         } catch (RemoteException e) {
408             Slog.e(TAG, "RemoteException", e);
409             return false;
410         }
411     }
412 
413     /**
414      * Returns the sensor's current strength, taking any updated strengths into effect.
415      *
416      * @param sensorId The sensor Id
417      * @return see {@link BiometricManager.Authenticators}
418      */
getCurrentStrength(int sensorId)419     public static @Authenticators.Types int getCurrentStrength(int sensorId) {
420         IBiometricService service = IBiometricService.Stub.asInterface(
421                 ServiceManager.getService(Context.BIOMETRIC_SERVICE));
422         try {
423             return service.getCurrentStrength(sensorId);
424         } catch (RemoteException e) {
425             Slog.e(TAG, "RemoteException", e);
426             return Authenticators.EMPTY_SET;
427         }
428     }
429 
430     /**
431      * Checks if a client package matches Keyguard and can perform internal biometric operations.
432      *
433      * @param context The system context.
434      * @param clientPackage The name of the package to be checked against Keyguard.
435      * @return Whether the given package matches Keyguard.
436      */
isKeyguard(@onNull Context context, @Nullable String clientPackage)437     public static boolean isKeyguard(@NonNull Context context, @Nullable String clientPackage) {
438         final boolean hasPermission = hasInternalPermission(context);
439         final ComponentName keyguardComponent = ComponentName.unflattenFromString(
440                 context.getResources().getString(R.string.config_keyguardComponent));
441         final String keyguardPackage = keyguardComponent != null
442                 ? keyguardComponent.getPackageName() : null;
443         return hasPermission && keyguardPackage != null && keyguardPackage.equals(clientPackage);
444     }
445 
446     /**
447      * Checks if a client package matches the Android system and can perform internal biometric
448      * operations.
449      *
450      * @param context The system context.
451      * @param clientPackage The name of the package to be checked against the Android system.
452      * @return Whether the given package matches the Android system.
453      */
isSystem(@onNull Context context, @Nullable String clientPackage)454     public static boolean isSystem(@NonNull Context context, @Nullable String clientPackage) {
455         return hasInternalPermission(context) && "android".equals(clientPackage);
456     }
457 
458     /**
459      * Checks if a client package matches Settings and can perform internal biometric operations.
460      *
461      * @param context The system context.
462      * @param clientPackage The name of the package to be checked against Settings.
463      * @return Whether the given package matches Settings.
464      */
isSettings(@onNull Context context, @Nullable String clientPackage)465     public static boolean isSettings(@NonNull Context context, @Nullable String clientPackage) {
466         return hasInternalPermission(context) && "com.android.settings".equals(clientPackage);
467     }
468 
hasInternalPermission(@onNull Context context)469     private static boolean hasInternalPermission(@NonNull Context context) {
470         return context.checkCallingOrSelfPermission(USE_BIOMETRIC_INTERNAL)
471                 == PackageManager.PERMISSION_GRANTED;
472     }
473 
getClientName(@ullable BaseClientMonitor client)474     public static String getClientName(@Nullable BaseClientMonitor client) {
475         return client != null ? client.getClass().getSimpleName() : "null";
476     }
477 
containsFlag(int haystack, int needle)478     private static boolean containsFlag(int haystack, int needle) {
479         return (haystack & needle) != 0;
480     }
481 
isUserEncryptedOrLockdown(@onNull LockPatternUtils lpu, int user)482     public static boolean isUserEncryptedOrLockdown(@NonNull LockPatternUtils lpu, int user) {
483         final int strongAuth = lpu.getStrongAuthForUser(user);
484         final boolean isEncrypted = containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_BOOT);
485         final boolean isLockDown = containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW)
486                 || containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
487         Slog.d(TAG, "isEncrypted: " + isEncrypted + " isLockdown: " + isLockDown);
488         return isEncrypted || isLockDown;
489     }
490 
isForeground(int callingUid, int callingPid)491     public static boolean isForeground(int callingUid, int callingPid) {
492         try {
493             final List<ActivityManager.RunningAppProcessInfo> procs =
494                     ActivityManager.getService().getRunningAppProcesses();
495             if (procs == null) {
496                 Slog.e(TAG, "No running app processes found, defaulting to true");
497                 return true;
498             }
499 
500             for (int i = 0; i < procs.size(); i++) {
501                 ActivityManager.RunningAppProcessInfo proc = procs.get(i);
502                 if (proc.pid == callingPid && proc.uid == callingUid
503                         && proc.importance <= IMPORTANCE_FOREGROUND_SERVICE) {
504                     return true;
505                 }
506             }
507         } catch (RemoteException e) {
508             Slog.w(TAG, "am.getRunningAppProcesses() failed");
509         }
510         return false;
511     }
512 
513     /**
514      * Converts from {@link BiometricManager.Authenticators} biometric strength to the internal
515      * {@link SensorPropertiesInternal} strength.
516      */
authenticatorStrengthToPropertyStrength( @uthenticators.Types int strength)517     public static @SensorProperties.Strength int authenticatorStrengthToPropertyStrength(
518             @Authenticators.Types int strength) {
519         switch (strength) {
520             case BiometricManager.Authenticators.BIOMETRIC_CONVENIENCE:
521                 return SensorProperties.STRENGTH_CONVENIENCE;
522             case BiometricManager.Authenticators.BIOMETRIC_WEAK:
523                 return SensorProperties.STRENGTH_WEAK;
524             case BiometricManager.Authenticators.BIOMETRIC_STRONG:
525                 return SensorProperties.STRENGTH_STRONG;
526             default:
527                 throw new IllegalArgumentException("Unknown strength: " + strength);
528         }
529     }
530 
propertyStrengthToAuthenticatorStrength( @ensorProperties.Strength int strength)531     public static @Authenticators.Types int propertyStrengthToAuthenticatorStrength(
532             @SensorProperties.Strength int strength) {
533         switch (strength) {
534             case SensorProperties.STRENGTH_CONVENIENCE:
535                 return Authenticators.BIOMETRIC_CONVENIENCE;
536             case SensorProperties.STRENGTH_WEAK:
537                 return Authenticators.BIOMETRIC_WEAK;
538             case SensorProperties.STRENGTH_STRONG:
539                 return Authenticators.BIOMETRIC_STRONG;
540             default:
541                 throw new IllegalArgumentException("Unknown strength: " + strength);
542         }
543     }
544 
getUdfpsAuthReason(@onNull AuthenticationClient<?> client)545     public static int getUdfpsAuthReason(@NonNull AuthenticationClient<?> client) {
546         if (client.isKeyguard()) {
547             return IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD;
548         } else if (client.isBiometricPrompt()) {
549             return IUdfpsOverlayController.REASON_AUTH_BP;
550         } else {
551             return IUdfpsOverlayController.REASON_AUTH_FPM_OTHER;
552         }
553     }
554 }
555