1 /*
2  * Copyright (C) 2018 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 android.hardware.biometrics;
18 
19 import static android.Manifest.permission.TEST_BIOMETRIC;
20 import static android.Manifest.permission.USE_BIOMETRIC;
21 import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
22 import static android.Manifest.permission.WRITE_DEVICE_CONFIG;
23 
24 import static com.android.internal.util.FrameworkStatsLog.AUTH_DEPRECATED_APIUSED__DEPRECATED_API__API_BIOMETRIC_MANAGER_CAN_AUTHENTICATE;
25 
26 import android.annotation.IntDef;
27 import android.annotation.NonNull;
28 import android.annotation.Nullable;
29 import android.annotation.RequiresPermission;
30 import android.annotation.SystemApi;
31 import android.annotation.SystemService;
32 import android.annotation.TestApi;
33 import android.content.Context;
34 import android.os.IBinder;
35 import android.os.RemoteException;
36 import android.os.UserHandle;
37 import android.security.keystore.KeyProperties;
38 import android.util.Slog;
39 
40 import com.android.internal.util.FrameworkStatsLog;
41 
42 import java.lang.annotation.Retention;
43 import java.lang.annotation.RetentionPolicy;
44 import java.util.ArrayList;
45 import java.util.List;
46 
47 /**
48  * A class that contains biometric utilities. For authentication, see {@link BiometricPrompt}.
49  */
50 @SystemService(Context.BIOMETRIC_SERVICE)
51 public class BiometricManager {
52 
53     private static final String TAG = "BiometricManager";
54 
55     /**
56      * No error detected.
57      */
58     public static final int BIOMETRIC_SUCCESS =
59             BiometricConstants.BIOMETRIC_SUCCESS;
60 
61     /**
62      * The hardware is unavailable. Try again later.
63      */
64     public static final int BIOMETRIC_ERROR_HW_UNAVAILABLE =
65             BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE;
66 
67     /**
68      * The user does not have any biometrics enrolled.
69      */
70     public static final int BIOMETRIC_ERROR_NONE_ENROLLED =
71             BiometricConstants.BIOMETRIC_ERROR_NO_BIOMETRICS;
72 
73     /**
74      * There is no biometric hardware.
75      */
76     public static final int BIOMETRIC_ERROR_NO_HARDWARE =
77             BiometricConstants.BIOMETRIC_ERROR_HW_NOT_PRESENT;
78 
79     /**
80      * A security vulnerability has been discovered and the sensor is unavailable until a
81      * security update has addressed this issue. This error can be received if for example,
82      * authentication was requested with {@link Authenticators#BIOMETRIC_STRONG}, but the
83      * sensor's strength can currently only meet {@link Authenticators#BIOMETRIC_WEAK}.
84      */
85     public static final int BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED =
86             BiometricConstants.BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED;
87 
88     /**
89      * @hide
90      */
91     @IntDef({BIOMETRIC_SUCCESS,
92             BIOMETRIC_ERROR_HW_UNAVAILABLE,
93             BIOMETRIC_ERROR_NONE_ENROLLED,
94             BIOMETRIC_ERROR_NO_HARDWARE,
95             BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED})
96     @Retention(RetentionPolicy.SOURCE)
97     public @interface BiometricError {}
98 
99     /**
100      * Types of authenticators, defined at a level of granularity supported by
101      * {@link BiometricManager} and {@link BiometricPrompt}.
102      *
103      * <p>Types may combined via bitwise OR into a single integer representing multiple
104      * authenticators (e.g. <code>DEVICE_CREDENTIAL | BIOMETRIC_WEAK</code>).
105      *
106      * @see #canAuthenticate(int)
107      * @see BiometricPrompt.Builder#setAllowedAuthenticators(int)
108      */
109     public interface Authenticators {
110         /**
111          * An {@link IntDef} representing valid combinations of authenticator types.
112          * @hide
113          */
114         @IntDef(flag = true, value = {
115                 BIOMETRIC_STRONG,
116                 BIOMETRIC_WEAK,
117                 BIOMETRIC_CONVENIENCE,
118                 DEVICE_CREDENTIAL,
119         })
120         @interface Types {}
121 
122         /**
123          * Empty set with no authenticators specified.
124          *
125          * <p>This constant is intended for use by {@link android.provider.DeviceConfig} to adjust
126          * the reported strength of a biometric sensor. It is not a valid parameter for any of the
127          * public {@link android.hardware.biometrics} APIs.
128          *
129          * @hide
130          */
131         @SystemApi
132         @RequiresPermission(WRITE_DEVICE_CONFIG)
133         int EMPTY_SET = 0x0000;
134 
135         /**
136          * Placeholder for the theoretical strongest biometric security tier.
137          * @hide
138          */
139         int BIOMETRIC_MAX_STRENGTH = 0x0001;
140 
141         /**
142          * Any biometric (e.g. fingerprint, iris, or face) on the device that meets or exceeds the
143          * requirements for <strong>Class 3</strong> (formerly <strong>Strong</strong>), as defined
144          * by the Android CDD.
145          *
146          * <p>This corresponds to {@link KeyProperties#AUTH_BIOMETRIC_STRONG} during key generation.
147          *
148          * @see android.security.keystore.KeyGenParameterSpec.Builder
149          */
150         int BIOMETRIC_STRONG = 0x000F;
151 
152         /**
153          * Any biometric (e.g. fingerprint, iris, or face) on the device that meets or exceeds the
154          * requirements for <strong>Class 2</strong> (formerly <strong>Weak</strong>), as defined by
155          * the Android CDD.
156          *
157          * <p>Note that this is a superset of {@link #BIOMETRIC_STRONG} and is defined such that
158          * {@code BIOMETRIC_STRONG | BIOMETRIC_WEAK == BIOMETRIC_WEAK}.
159          */
160         int BIOMETRIC_WEAK = 0x00FF;
161 
162         /**
163          * Any biometric (e.g. fingerprint, iris, or face) on the device that meets or exceeds the
164          * requirements for <strong>Class 1</strong> (formerly <strong>Convenience</strong>), as
165          * defined by the Android CDD.
166          *
167          * <p>This constant is intended for use by {@link android.provider.DeviceConfig} to adjust
168          * the reported strength of a biometric sensor. It is not a valid parameter for any of the
169          * public {@link android.hardware.biometrics} APIs.
170          *
171          * @hide
172          */
173         @SystemApi
174         @RequiresPermission(WRITE_DEVICE_CONFIG)
175         int BIOMETRIC_CONVENIENCE = 0x0FFF;
176 
177         /**
178          * Placeholder for the theoretical weakest biometric security tier.
179          * @hide
180          */
181         int BIOMETRIC_MIN_STRENGTH = 0x7FFF;
182 
183         /**
184          * The non-biometric credential used to secure the device (i.e., PIN, pattern, or password).
185          * This should typically only be used in combination with a biometric auth type, such as
186          * {@link #BIOMETRIC_WEAK}.
187          *
188          * <p>This corresponds to {@link KeyProperties#AUTH_DEVICE_CREDENTIAL} during key
189          * generation.
190          *
191          * @see android.security.keystore.KeyGenParameterSpec.Builder
192          */
193         int DEVICE_CREDENTIAL = 1 << 15;
194 
195     }
196 
197     /**
198      * @hide
199      * returns a string representation of an authenticator type.
200      */
authenticatorToStr(@uthenticators.Types int authenticatorType)201     @NonNull public static String authenticatorToStr(@Authenticators.Types int authenticatorType) {
202         switch(authenticatorType) {
203             case Authenticators.BIOMETRIC_STRONG:
204                 return "BIOMETRIC_STRONG";
205             case Authenticators.BIOMETRIC_WEAK:
206                 return "BIOMETRIC_WEAK";
207             case Authenticators.BIOMETRIC_CONVENIENCE:
208                 return "BIOMETRIC_CONVENIENCE";
209             case Authenticators.DEVICE_CREDENTIAL:
210                 return "DEVICE_CREDENTIAL";
211             default:
212                 return "Unknown authenticator type: " + authenticatorType;
213         }
214     }
215 
216     /**
217      * Provides localized strings for an application that uses {@link BiometricPrompt} to
218      * authenticate the user.
219      */
220     public static class Strings {
221         @NonNull private final Context mContext;
222         @NonNull private final IAuthService mService;
223         @Authenticators.Types int mAuthenticators;
224 
Strings(@onNull Context context, @NonNull IAuthService service, @Authenticators.Types int authenticators)225         private Strings(@NonNull Context context, @NonNull IAuthService service,
226                 @Authenticators.Types int authenticators) {
227             mContext = context;
228             mService = service;
229             mAuthenticators = authenticators;
230         }
231 
232         /**
233          * Provides a localized string that can be used as the label for a button that invokes
234          * {@link BiometricPrompt}.
235          *
236          * <p>When possible, this method should use the given authenticator requirements to more
237          * precisely specify the authentication type that will be used. For example, if
238          * <strong>Class 3</strong> biometric authentication is requested on a device with a
239          * <strong>Class 3</strong> fingerprint sensor and a <strong>Class 2</strong> face sensor,
240          * the returned string should indicate that fingerprint authentication will be used.
241          *
242          * <p>This method should also try to specify which authentication method(s) will be used in
243          * practice when multiple authenticators meet the given requirements. For example, if
244          * biometric authentication is requested on a device with both face and fingerprint sensors
245          * but the user has selected face as their preferred method, the returned string should
246          * indicate that face authentication will be used.
247          *
248          * <p>This method may return {@code null} if none of the requested authenticator types are
249          * available, but this should <em>not</em> be relied upon for checking the status of
250          * authenticators. Instead, use {@link #canAuthenticate(int)}.
251          *
252          * @return The label for a button that invokes {@link BiometricPrompt} for authentication.
253          */
254         @RequiresPermission(USE_BIOMETRIC)
255         @Nullable
getButtonLabel()256         public CharSequence getButtonLabel() {
257             final int userId = mContext.getUserId();
258             final String opPackageName = mContext.getOpPackageName();
259             try {
260                 return mService.getButtonLabel(userId, opPackageName, mAuthenticators);
261             } catch (RemoteException e) {
262                 throw e.rethrowFromSystemServer();
263             }
264         }
265 
266         /**
267          * Provides a localized string that can be shown while the user is authenticating with
268          * {@link BiometricPrompt}.
269          *
270          * <p>When possible, this method should use the given authenticator requirements to more
271          * precisely specify the authentication type that will be used. For example, if
272          * <strong>Class 3</strong> biometric authentication is requested on a device with a
273          * <strong>Class 3</strong> fingerprint sensor and a <strong>Class 2</strong> face sensor,
274          * the returned string should indicate that fingerprint authentication will be used.
275          *
276          * <p>This method should also try to specify which authentication method(s) will be used in
277          * practice when multiple authenticators meet the given requirements. For example, if
278          * biometric authentication is requested on a device with both face and fingerprint sensors
279          * but the user has selected face as their preferred method, the returned string should
280          * indicate that face authentication will be used.
281          *
282          * <p>This method may return {@code null} if none of the requested authenticator types are
283          * available, but this should <em>not</em> be relied upon for checking the status of
284          * authenticators. Instead, use {@link #canAuthenticate(int)}.
285          *
286          * @return The label for a button that invokes {@link BiometricPrompt} for authentication.
287          */
288         @RequiresPermission(USE_BIOMETRIC)
289         @Nullable
getPromptMessage()290         public CharSequence getPromptMessage() {
291             final int userId = mContext.getUserId();
292             final String opPackageName = mContext.getOpPackageName();
293             try {
294                 return mService.getPromptMessage(userId, opPackageName, mAuthenticators);
295             } catch (RemoteException e) {
296                 throw e.rethrowFromSystemServer();
297             }
298         }
299 
300         /**
301          * Provides a localized string that can be shown as the title for an app setting that
302          * enables authentication with {@link BiometricPrompt}.
303          *
304          * <p>When possible, this method should use the given authenticator requirements to more
305          * precisely specify the authentication type that will be used. For example, if
306          * <strong>Class 3</strong> biometric authentication is requested on a device with a
307          * <strong>Class 3</strong> fingerprint sensor and a <strong>Class 2</strong> face sensor,
308          * the returned string should indicate that fingerprint authentication will be used.
309          *
310          * <p>This method should <em>not</em> try to specify which authentication method(s) will be
311          * used in practice when multiple authenticators meet the given requirements. For example,
312          * if biometric authentication is requested on a device with both face and fingerprint
313          * sensors, the returned string should indicate that either face or fingerprint
314          * authentication may be used, regardless of whether the user has enrolled or selected
315          * either as their preferred method.
316          *
317          * <p>This method may return {@code null} if none of the requested authenticator types are
318          * supported by the system, but this should <em>not</em> be relied upon for checking the
319          * status of authenticators. Instead, use {@link #canAuthenticate(int)} or
320          * {@link android.content.pm.PackageManager#hasSystemFeature(String)}.
321          *
322          * @return The label for a button that invokes {@link BiometricPrompt} for authentication.
323          */
324         @RequiresPermission(USE_BIOMETRIC)
325         @Nullable
getSettingName()326         public CharSequence getSettingName() {
327             final int userId = mContext.getUserId();
328             final String opPackageName = mContext.getOpPackageName();
329             try {
330                 return mService.getSettingName(userId, opPackageName, mAuthenticators);
331             } catch (RemoteException e) {
332                 throw e.rethrowFromSystemServer();
333             }
334         }
335     }
336 
337     @NonNull private final Context mContext;
338     @NonNull private final IAuthService mService;
339 
340     /**
341      * @hide
342      * @param context
343      * @param service
344      */
BiometricManager(@onNull Context context, @NonNull IAuthService service)345     public BiometricManager(@NonNull Context context, @NonNull IAuthService service) {
346         mContext = context;
347         mService = service;
348     }
349 
350     /**
351      * @return A list of {@link SensorProperties}
352      * @hide
353      */
354     @TestApi
355     @NonNull
356     @RequiresPermission(TEST_BIOMETRIC)
getSensorProperties()357     public List<SensorProperties> getSensorProperties() {
358         try {
359             final List<SensorPropertiesInternal> internalProperties =
360                     mService.getSensorProperties(mContext.getOpPackageName());
361             final List<SensorProperties> properties = new ArrayList<>();
362             for (SensorPropertiesInternal internalProp : internalProperties) {
363                 properties.add(SensorProperties.from(internalProp));
364             }
365             return properties;
366         } catch (RemoteException e) {
367             throw e.rethrowFromSystemServer();
368         }
369     }
370 
371     /**
372      * Retrieves a test session for BiometricManager/BiometricPrompt.
373      * @hide
374      */
375     @TestApi
376     @NonNull
377     @RequiresPermission(TEST_BIOMETRIC)
createTestSession(int sensorId)378     public BiometricTestSession createTestSession(int sensorId) {
379         try {
380             return new BiometricTestSession(mContext, sensorId,
381                     (context, sensorId1, callback) -> mService
382                             .createTestSession(sensorId1, callback, context.getOpPackageName()));
383         } catch (RemoteException e) {
384             throw e.rethrowFromSystemServer();
385         }
386     }
387 
388     /**
389      * Retrieves the package where BiometricPrompt's UI is implemented.
390      * @hide
391      */
392     @TestApi
393     @NonNull
394     @RequiresPermission(TEST_BIOMETRIC)
getUiPackage()395     public String getUiPackage() {
396         try {
397             return mService.getUiPackage();
398         } catch (RemoteException e) {
399             throw e.rethrowFromSystemServer();
400         }
401     }
402 
403     /**
404      * Determine if biometrics can be used. In other words, determine if
405      * {@link BiometricPrompt} can be expected to be shown (hardware available, templates enrolled,
406      * user-enabled). This is the equivalent of {@link #canAuthenticate(int)} with
407      * {@link Authenticators#BIOMETRIC_WEAK}
408      *
409      * @return {@link #BIOMETRIC_ERROR_NONE_ENROLLED} if the user does not have any strong
410      *     biometrics enrolled, or {@link #BIOMETRIC_ERROR_HW_UNAVAILABLE} if none are currently
411      *     supported/enabled. Returns {@link #BIOMETRIC_SUCCESS} if a strong biometric can currently
412      *     be used (enrolled and available).
413      *
414      * @deprecated See {@link #canAuthenticate(int)}.
415      */
416     @Deprecated
417     @RequiresPermission(USE_BIOMETRIC)
418     @BiometricError
canAuthenticate()419     public int canAuthenticate() {
420         @BiometricError final int result = canAuthenticate(mContext.getUserId(),
421                 Authenticators.BIOMETRIC_WEAK);
422 
423         FrameworkStatsLog.write(FrameworkStatsLog.AUTH_MANAGER_CAN_AUTHENTICATE_INVOKED,
424                 false /* isAllowedAuthenticatorsSet */, Authenticators.EMPTY_SET, result);
425         FrameworkStatsLog.write(FrameworkStatsLog.AUTH_DEPRECATED_API_USED,
426                 AUTH_DEPRECATED_APIUSED__DEPRECATED_API__API_BIOMETRIC_MANAGER_CAN_AUTHENTICATE,
427                 mContext.getApplicationInfo().uid,
428                 mContext.getApplicationInfo().targetSdkVersion);
429 
430         return result;
431     }
432 
433     /**
434      * Determine if any of the provided authenticators can be used. In other words, determine if
435      * {@link BiometricPrompt} can be expected to be shown (hardware available, templates enrolled,
436      * user-enabled).
437      *
438      * For biometric authenticators, determine if the device can currently authenticate with at
439      * least the requested strength. For example, invoking this API with
440      * {@link Authenticators#BIOMETRIC_WEAK} on a device that currently only has
441      * {@link Authenticators#BIOMETRIC_STRONG} enrolled will return {@link #BIOMETRIC_SUCCESS}.
442      *
443      * Invoking this API with {@link Authenticators#DEVICE_CREDENTIAL} can be used to determine
444      * if the user has a PIN/Pattern/Password set up.
445      *
446      * @param authenticators bit field consisting of constants defined in {@link Authenticators}.
447      *                       If multiple authenticators are queried, a logical OR will be applied.
448      *                       For example, if {@link Authenticators#DEVICE_CREDENTIAL} |
449      *                       {@link Authenticators#BIOMETRIC_STRONG} is queried and only
450      *                       {@link Authenticators#DEVICE_CREDENTIAL} is set up, this API will
451      *                       return {@link #BIOMETRIC_SUCCESS}
452      *
453      * @return {@link #BIOMETRIC_ERROR_NONE_ENROLLED} if the user does not have any of the
454      *     requested authenticators enrolled, or {@link #BIOMETRIC_ERROR_HW_UNAVAILABLE} if none are
455      *     currently supported/enabled. Returns {@link #BIOMETRIC_SUCCESS} if one of the requested
456      *     authenticators can currently be used (enrolled and available).
457      */
458     @RequiresPermission(USE_BIOMETRIC)
459     @BiometricError
canAuthenticate(@uthenticators.Types int authenticators)460     public int canAuthenticate(@Authenticators.Types int authenticators) {
461         @BiometricError final int result = canAuthenticate(mContext.getUserId(), authenticators);
462 
463         FrameworkStatsLog.write(FrameworkStatsLog.AUTH_MANAGER_CAN_AUTHENTICATE_INVOKED,
464                 true /* isAllowedAuthenticatorsSet */, authenticators, result);
465 
466         return result;
467     }
468 
469     /**
470      * @hide
471      */
472     @RequiresPermission(USE_BIOMETRIC_INTERNAL)
473     @BiometricError
canAuthenticate(int userId, @Authenticators.Types int authenticators)474     public int canAuthenticate(int userId, @Authenticators.Types int authenticators) {
475         if (mService != null) {
476             try {
477                 final String opPackageName = mContext.getOpPackageName();
478                 return mService.canAuthenticate(opPackageName, userId, authenticators);
479             } catch (RemoteException e) {
480                 throw e.rethrowFromSystemServer();
481             }
482         } else {
483             Slog.w(TAG, "canAuthenticate(): Service not connected");
484             return BIOMETRIC_ERROR_HW_UNAVAILABLE;
485         }
486     }
487 
488     /**
489      * Produces an instance of the {@link Strings} class, which provides localized strings for an
490      * application, given a set of allowed authenticator types.
491      *
492      * @param authenticators A bit field representing the types of {@link Authenticators} that may
493      *                       be used for authentication.
494      * @return A {@link Strings} collection for the given allowed authenticator types.
495      */
496     @RequiresPermission(USE_BIOMETRIC)
497     @NonNull
getStrings(@uthenticators.Types int authenticators)498     public Strings getStrings(@Authenticators.Types int authenticators) {
499         return new Strings(mContext, mService, authenticators);
500     }
501 
502     /**
503      * @hide
504      * @param userId
505      * @return
506      */
507     @RequiresPermission(USE_BIOMETRIC_INTERNAL)
hasEnrolledBiometrics(int userId)508     public boolean hasEnrolledBiometrics(int userId) {
509         if (mService != null) {
510             try {
511                 return mService.hasEnrolledBiometrics(userId, mContext.getOpPackageName());
512             } catch (RemoteException e) {
513                 Slog.w(TAG, "Remote exception in hasEnrolledBiometrics(): " + e);
514                 return false;
515             }
516         } else {
517             return false;
518         }
519     }
520 
521     /**
522      * Listens for changes to biometric eligibility on keyguard from user settings.
523      * @param callback
524      * @hide
525      */
526     @RequiresPermission(USE_BIOMETRIC_INTERNAL)
registerEnabledOnKeyguardCallback(IBiometricEnabledOnKeyguardCallback callback)527     public void registerEnabledOnKeyguardCallback(IBiometricEnabledOnKeyguardCallback callback) {
528         if (mService != null) {
529             try {
530                 mService.registerEnabledOnKeyguardCallback(callback);
531             } catch (RemoteException e) {
532                 throw e.rethrowFromSystemServer();
533             }
534         } else {
535             Slog.w(TAG, "registerEnabledOnKeyguardCallback(): Service not connected");
536         }
537     }
538 
539     /**
540      * Requests all {@link Authenticators.Types#BIOMETRIC_STRONG} sensors to have their
541      * authenticatorId invalidated for the specified user. This happens when enrollments have been
542      * added on devices with multiple biometric sensors.
543      *
544      * @param userId userId that the authenticatorId should be invalidated for
545      * @param fromSensorId sensor that triggered the invalidation request
546      * @hide
547      */
548     @RequiresPermission(USE_BIOMETRIC_INTERNAL)
invalidateAuthenticatorIds(int userId, int fromSensorId, @NonNull IInvalidationCallback callback)549     public void invalidateAuthenticatorIds(int userId, int fromSensorId,
550             @NonNull IInvalidationCallback callback) {
551         if (mService != null) {
552             try {
553                 mService.invalidateAuthenticatorIds(userId, fromSensorId, callback);
554             } catch (RemoteException e) {
555                 throw e.rethrowFromSystemServer();
556             }
557         }
558     }
559 
560     /**
561      * Get a list of AuthenticatorIDs for biometric authenticators which have 1) enrolled templates,
562      * and 2) meet the requirements for integrating with Keystore. The AuthenticatorIDs are known
563      * in Keystore land as SIDs, and are used during key generation.
564      * @hide
565      */
getAuthenticatorIds()566     public long[] getAuthenticatorIds() {
567         return getAuthenticatorIds(UserHandle.myUserId());
568     }
569 
570     /**
571      * Get a list of AuthenticatorIDs for biometric authenticators which have 1) enrolled templates,
572      * and 2) meet the requirements for integrating with Keystore. The AuthenticatorIDs are known
573      * in Keystore land as SIDs, and are used during key generation.
574      *
575      * @param userId Android user ID for user to look up.
576      *
577      * @hide
578      */
getAuthenticatorIds(int userId)579     public long[] getAuthenticatorIds(int userId) {
580         if (mService != null) {
581             try {
582                 return mService.getAuthenticatorIds(userId);
583             } catch (RemoteException e) {
584                 throw e.rethrowFromSystemServer();
585             }
586         } else {
587             Slog.w(TAG, "getAuthenticatorIds(): Service not connected");
588             return new long[0];
589         }
590     }
591 
592     /**
593      * Requests all other biometric sensors to resetLockout. Note that this is a "time bound"
594      * See the {@link android.hardware.biometrics.fingerprint.ISession#resetLockout(int,
595      * HardwareAuthToken)} and {@link android.hardware.biometrics.face.ISession#resetLockout(int,
596      * HardwareAuthToken)} documentation for complete details.
597      *
598      * @param token A binder from the caller, for the service to linkToDeath
599      * @param opPackageName Caller's package name
600      * @param fromSensorId The originating sensor that just authenticated. Note that this MUST
601      *                     be a sensor that meets {@link Authenticators#BIOMETRIC_STRONG} strength.
602      *                     The strength will also be enforced on the BiometricService side.
603      * @param userId The user that authentication succeeded for, and also the user that resetLockout
604      *               should be applied to.
605      * @param hardwareAuthToken A valid HAT generated upon successful biometric authentication. Note
606      *                          that it is not necessary for the HAT to contain a challenge.
607      * @hide
608      */
609     @RequiresPermission(USE_BIOMETRIC_INTERNAL)
resetLockoutTimeBound(IBinder token, String opPackageName, int fromSensorId, int userId, byte[] hardwareAuthToken)610     public void resetLockoutTimeBound(IBinder token, String opPackageName, int fromSensorId,
611             int userId, byte[] hardwareAuthToken) {
612         if (mService != null) {
613             try {
614                 mService.resetLockoutTimeBound(token, opPackageName, fromSensorId, userId,
615                         hardwareAuthToken);
616             } catch (RemoteException e) {
617                 throw e.rethrowFromSystemServer();
618             }
619         }
620     }
621 
622     /**
623      * Notifies AuthService that keyguard has been dismissed for the given userId.
624      *
625      * @param userId
626      * @param hardwareAuthToken
627      * @hide
628      */
629     @RequiresPermission(USE_BIOMETRIC_INTERNAL)
resetLockout(int userId, byte[] hardwareAuthToken)630     public void resetLockout(int userId, byte[] hardwareAuthToken) {
631         if (mService != null) {
632             try {
633                 mService.resetLockout(userId, hardwareAuthToken);
634             } catch (RemoteException e) {
635                 throw e.rethrowFromSystemServer();
636             }
637         }
638 
639     }
640 }
641 
642