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.USE_BIOMETRIC;
20 import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
21 import static android.Manifest.permission.WRITE_DEVICE_CONFIG;
22 
23 import android.annotation.IntDef;
24 import android.annotation.RequiresPermission;
25 import android.annotation.SystemApi;
26 import android.annotation.SystemService;
27 import android.content.Context;
28 import android.os.RemoteException;
29 import android.security.keystore.KeyGenParameterSpec;
30 import android.security.keystore.KeyProperties;
31 import android.util.Slog;
32 
33 /**
34  * A class that contains biometric utilities. For authentication, see {@link BiometricPrompt}.
35  */
36 @SystemService(Context.BIOMETRIC_SERVICE)
37 public class BiometricManager {
38 
39     private static final String TAG = "BiometricManager";
40 
41     /**
42      * No error detected.
43      */
44     public static final int BIOMETRIC_SUCCESS =
45             BiometricConstants.BIOMETRIC_SUCCESS;
46 
47     /**
48      * The hardware is unavailable. Try again later.
49      */
50     public static final int BIOMETRIC_ERROR_HW_UNAVAILABLE =
51             BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE;
52 
53     /**
54      * The user does not have any biometrics enrolled.
55      */
56     public static final int BIOMETRIC_ERROR_NONE_ENROLLED =
57             BiometricConstants.BIOMETRIC_ERROR_NO_BIOMETRICS;
58 
59     /**
60      * There is no biometric hardware.
61      */
62     public static final int BIOMETRIC_ERROR_NO_HARDWARE =
63             BiometricConstants.BIOMETRIC_ERROR_HW_NOT_PRESENT;
64 
65     /**
66      * A security vulnerability has been discovered and the sensor is unavailable until a
67      * security update has addressed this issue. This error can be received if for example,
68      * authentication was requested with {@link Authenticators#BIOMETRIC_STRONG}, but the
69      * sensor's strength can currently only meet {@link Authenticators#BIOMETRIC_WEAK}.
70      */
71     public static final int BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED =
72             BiometricConstants.BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED;
73 
74     @IntDef({BIOMETRIC_SUCCESS,
75             BIOMETRIC_ERROR_HW_UNAVAILABLE,
76             BIOMETRIC_ERROR_NONE_ENROLLED,
77             BIOMETRIC_ERROR_NO_HARDWARE,
78             BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED})
79     @interface BiometricError {}
80 
81     /**
82      * Types of authenticators, defined at a level of granularity supported by
83      * {@link BiometricManager} and {@link BiometricPrompt}.
84      *
85      * <p>Types may combined via bitwise OR into a single integer representing multiple
86      * authenticators (e.g. <code>DEVICE_CREDENTIAL | BIOMETRIC_WEAK</code>).
87      *
88      * @see #canAuthenticate(int)
89      * @see BiometricPrompt.Builder#setAllowedAuthenticators(int)
90      */
91     public interface Authenticators {
92         /**
93          * An {@link IntDef} representing valid combinations of authenticator types.
94          * @hide
95          */
96         @IntDef(flag = true, value = {
97                 BIOMETRIC_STRONG,
98                 BIOMETRIC_WEAK,
99                 DEVICE_CREDENTIAL,
100         })
101         @interface Types {}
102 
103         /**
104          * Empty set with no authenticators specified.
105          *
106          * <p>This constant is intended for use by {@link android.provider.DeviceConfig} to adjust
107          * the reported strength of a biometric sensor. It is not a valid parameter for any of the
108          * public {@link android.hardware.biometrics} APIs.
109          *
110          * @hide
111          */
112         @SystemApi
113         @RequiresPermission(WRITE_DEVICE_CONFIG)
114         int EMPTY_SET = 0x0000;
115 
116         /**
117          * Placeholder for the theoretical strongest biometric security tier.
118          * @hide
119          */
120         int BIOMETRIC_MAX_STRENGTH = 0x0001;
121 
122         /**
123          * Any biometric (e.g. fingerprint, iris, or face) on the device that meets or exceeds the
124          * requirements for <strong>Class 3</strong> (formerly <strong>Strong</strong>), as defined
125          * by the Android CDD.
126          *
127          * <p>This corresponds to {@link KeyProperties#AUTH_BIOMETRIC_STRONG} during key generation.
128          *
129          * @see KeyGenParameterSpec.Builder#setUserAuthenticationParameters(int, int)
130          */
131         int BIOMETRIC_STRONG = 0x000F;
132 
133         /**
134          * Any biometric (e.g. fingerprint, iris, or face) on the device that meets or exceeds the
135          * requirements for <strong>Class 2</strong> (formerly <strong>Weak</strong>), as defined by
136          * the Android CDD.
137          *
138          * <p>Note that this is a superset of {@link #BIOMETRIC_STRONG} and is defined such that
139          * {@code BIOMETRIC_STRONG | BIOMETRIC_WEAK == BIOMETRIC_WEAK}.
140          */
141         int BIOMETRIC_WEAK = 0x00FF;
142 
143         /**
144          * Any biometric (e.g. fingerprint, iris, or face) on the device that meets or exceeds the
145          * requirements for <strong>Class 1</strong> (formerly <strong>Convenience</strong>), as
146          * defined by the Android CDD.
147          *
148          * <p>This constant is intended for use by {@link android.provider.DeviceConfig} to adjust
149          * the reported strength of a biometric sensor. It is not a valid parameter for any of the
150          * public {@link android.hardware.biometrics} APIs.
151          *
152          * @hide
153          */
154         @SystemApi
155         @RequiresPermission(WRITE_DEVICE_CONFIG)
156         int BIOMETRIC_CONVENIENCE = 0x0FFF;
157 
158         /**
159          * Placeholder for the theoretical weakest biometric security tier.
160          * @hide
161          */
162         int BIOMETRIC_MIN_STRENGTH = 0x7FFF;
163 
164         /**
165          * The non-biometric credential used to secure the device (i.e., PIN, pattern, or password).
166          * This should typically only be used in combination with a biometric auth type, such as
167          * {@link #BIOMETRIC_WEAK}.
168          *
169          * <p>This corresponds to {@link KeyProperties#AUTH_DEVICE_CREDENTIAL} during key
170          * generation.
171          *
172          * @see KeyGenParameterSpec.Builder#setUserAuthenticationParameters(int, int)
173          */
174         int DEVICE_CREDENTIAL = 1 << 15;
175     }
176 
177     private final Context mContext;
178     private final IAuthService mService;
179 
180     /**
181      * @hide
182      * @param context
183      * @param service
184      */
BiometricManager(Context context, IAuthService service)185     public BiometricManager(Context context, IAuthService service) {
186         mContext = context;
187         mService = service;
188     }
189 
190     /**
191      * Determine if biometrics can be used. In other words, determine if
192      * {@link BiometricPrompt} can be expected to be shown (hardware available, templates enrolled,
193      * user-enabled). This is the equivalent of {@link #canAuthenticate(int)} with
194      * {@link Authenticators#BIOMETRIC_WEAK}
195      *
196      * @return {@link #BIOMETRIC_ERROR_NONE_ENROLLED} if the user does not have any strong
197      *     biometrics enrolled, or {@link #BIOMETRIC_ERROR_HW_UNAVAILABLE} if none are currently
198      *     supported/enabled. Returns {@link #BIOMETRIC_SUCCESS} if a strong biometric can currently
199      *     be used (enrolled and available).
200      *
201      * @deprecated See {@link #canAuthenticate(int)}.
202      */
203     @Deprecated
204     @RequiresPermission(USE_BIOMETRIC)
canAuthenticate()205     public @BiometricError int canAuthenticate() {
206         return canAuthenticate(Authenticators.BIOMETRIC_WEAK);
207     }
208 
209     /**
210      * Determine if any of the provided authenticators can be used. In other words, determine if
211      * {@link BiometricPrompt} can be expected to be shown (hardware available, templates enrolled,
212      * user-enabled).
213      *
214      * For biometric authenticators, determine if the device can currently authenticate with at
215      * least the requested strength. For example, invoking this API with
216      * {@link Authenticators#BIOMETRIC_WEAK} on a device that currently only has
217      * {@link Authenticators#BIOMETRIC_STRONG} enrolled will return {@link #BIOMETRIC_SUCCESS}.
218      *
219      * Invoking this API with {@link Authenticators#DEVICE_CREDENTIAL} can be used to determine
220      * if the user has a PIN/Pattern/Password set up.
221      *
222      * @param authenticators bit field consisting of constants defined in {@link Authenticators}.
223      *                       If multiple authenticators are queried, a logical OR will be applied.
224      *                       For example, if {@link Authenticators#DEVICE_CREDENTIAL} |
225      *                       {@link Authenticators#BIOMETRIC_STRONG} is queried and only
226      *                       {@link Authenticators#DEVICE_CREDENTIAL} is set up, this API will
227      *                       return {@link #BIOMETRIC_SUCCESS}
228      *
229      * @return {@link #BIOMETRIC_ERROR_NONE_ENROLLED} if the user does not have any of the
230      *     requested authenticators enrolled, or {@link #BIOMETRIC_ERROR_HW_UNAVAILABLE} if none are
231      *     currently supported/enabled. Returns {@link #BIOMETRIC_SUCCESS} if one of the requested
232      *     authenticators can currently be used (enrolled and available).
233      */
234     @RequiresPermission(USE_BIOMETRIC)
canAuthenticate(@uthenticators.Types int authenticators)235     public @BiometricError int canAuthenticate(@Authenticators.Types int authenticators) {
236         return canAuthenticate(mContext.getUserId(), authenticators);
237     }
238 
239     /**
240      * @hide
241      */
242     @RequiresPermission(USE_BIOMETRIC_INTERNAL)
canAuthenticate(int userId, @Authenticators.Types int authenticators)243     public @BiometricError int canAuthenticate(int userId,
244             @Authenticators.Types int authenticators) {
245         if (mService != null) {
246             try {
247                 final String opPackageName = mContext.getOpPackageName();
248                 return mService.canAuthenticate(opPackageName, userId, authenticators);
249             } catch (RemoteException e) {
250                 throw e.rethrowFromSystemServer();
251             }
252         } else {
253             Slog.w(TAG, "hasEnrolledBiometrics(): Service not connected");
254             return BIOMETRIC_ERROR_HW_UNAVAILABLE;
255         }
256     }
257 
258     /**
259      * @hide
260      * @param userId
261      * @return
262      */
263     @RequiresPermission(USE_BIOMETRIC_INTERNAL)
hasEnrolledBiometrics(int userId)264     public boolean hasEnrolledBiometrics(int userId) {
265         if (mService != null) {
266             try {
267                 return mService.hasEnrolledBiometrics(userId, mContext.getOpPackageName());
268             } catch (RemoteException e) {
269                 Slog.w(TAG, "Remote exception in hasEnrolledBiometrics(): " + e);
270                 return false;
271             }
272         } else {
273             return false;
274         }
275     }
276 
277     /**
278      * Listens for changes to biometric eligibility on keyguard from user settings.
279      * @param callback
280      * @hide
281      */
282     @RequiresPermission(USE_BIOMETRIC_INTERNAL)
registerEnabledOnKeyguardCallback(IBiometricEnabledOnKeyguardCallback callback)283     public void registerEnabledOnKeyguardCallback(IBiometricEnabledOnKeyguardCallback callback) {
284         if (mService != null) {
285             try {
286                 mService.registerEnabledOnKeyguardCallback(callback);
287             } catch (RemoteException e) {
288                 throw e.rethrowFromSystemServer();
289             }
290         } else {
291             Slog.w(TAG, "registerEnabledOnKeyguardCallback(): Service not connected");
292         }
293     }
294 
295     /**
296      * Sets the active user.
297      * @hide
298      */
299     @RequiresPermission(USE_BIOMETRIC_INTERNAL)
setActiveUser(int userId)300     public void setActiveUser(int userId) {
301         if (mService != null) {
302             try {
303                 mService.setActiveUser(userId);
304             } catch (RemoteException e) {
305                 throw e.rethrowFromSystemServer();
306             }
307         } else {
308             Slog.w(TAG, "setActiveUser(): Service not connected");
309         }
310     }
311 
312     /**
313      * Reset the lockout when user authenticates with strong auth (e.g. PIN, pattern or password)
314      *
315      * @param token an opaque token returned by password confirmation.
316      * @hide
317      */
318     @RequiresPermission(USE_BIOMETRIC_INTERNAL)
resetLockout(byte[] token)319     public void resetLockout(byte[] token) {
320         if (mService != null) {
321             try {
322                 mService.resetLockout(token);
323             } catch (RemoteException e) {
324                 throw e.rethrowFromSystemServer();
325             }
326         } else {
327             Slog.w(TAG, "resetLockout(): Service not connected");
328         }
329     }
330 
331     /**
332      * Get a list of AuthenticatorIDs for biometric authenticators which have 1) enrolled templates,
333      * and 2) meet the requirements for integrating with Keystore. The AuthenticatorIDs are known
334      * in Keystore land as SIDs, and are used during key generation.
335      * @hide
336      */
337     @RequiresPermission(USE_BIOMETRIC_INTERNAL)
getAuthenticatorIds()338     public long[] getAuthenticatorIds() {
339         if (mService != null) {
340             try {
341                 return mService.getAuthenticatorIds();
342             } catch (RemoteException e) {
343                 throw e.rethrowFromSystemServer();
344             }
345         } else {
346             Slog.w(TAG, "getAuthenticatorIds(): Service not connected");
347             return new long[0];
348         }
349     }
350 
351 }
352 
353