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 com.android.server.biometrics;
18 
19 import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
20 import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE;
21 import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
22 import static android.hardware.biometrics.BiometricManager.Authenticators;
23 import static android.hardware.biometrics.BiometricManager.BIOMETRIC_NO_AUTHENTICATION;
24 
25 import static com.android.server.biometrics.BiometricServiceStateProto.STATE_AUTH_IDLE;
26 
27 import android.annotation.NonNull;
28 import android.annotation.Nullable;
29 import android.app.ActivityManager;
30 import android.app.IActivityManager;
31 import android.app.UserSwitchObserver;
32 import android.app.admin.DevicePolicyManager;
33 import android.app.trust.ITrustManager;
34 import android.content.ContentResolver;
35 import android.content.ComponentName;
36 import android.content.Context;
37 import android.content.pm.PackageManager;
38 import android.content.pm.UserInfo;
39 import android.database.ContentObserver;
40 import android.hardware.SensorPrivacyManager;
41 import android.hardware.biometrics.BiometricAuthenticator;
42 import android.hardware.biometrics.BiometricConstants;
43 import android.hardware.biometrics.BiometricPrompt;
44 import android.hardware.biometrics.Flags;
45 import android.hardware.biometrics.IBiometricAuthenticator;
46 import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback;
47 import android.hardware.biometrics.IBiometricSensorReceiver;
48 import android.hardware.biometrics.IBiometricService;
49 import android.hardware.biometrics.IBiometricServiceReceiver;
50 import android.hardware.biometrics.IBiometricSysuiReceiver;
51 import android.hardware.biometrics.IInvalidationCallback;
52 import android.hardware.biometrics.ITestSession;
53 import android.hardware.biometrics.ITestSessionCallback;
54 import android.hardware.biometrics.PromptInfo;
55 import android.hardware.biometrics.SensorPropertiesInternal;
56 import android.hardware.camera2.CameraManager;
57 import android.hardware.fingerprint.FingerprintManager;
58 import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
59 import android.hardware.security.keymint.HardwareAuthenticatorType;
60 import android.net.Uri;
61 import android.os.Binder;
62 import android.os.Build;
63 import android.os.DeadObjectException;
64 import android.os.Handler;
65 import android.os.IBinder;
66 import android.os.RemoteException;
67 import android.os.ServiceManager;
68 import android.os.UserHandle;
69 import android.os.UserManager;
70 import android.provider.Settings;
71 import android.security.GateKeeper;
72 import android.security.KeyStoreAuthorization;
73 import android.service.gatekeeper.IGateKeeperService;
74 import android.text.TextUtils;
75 import android.util.ArraySet;
76 import android.util.Pair;
77 import android.util.Slog;
78 import android.util.proto.ProtoOutputStream;
79 
80 import com.android.internal.R;
81 import com.android.internal.annotations.VisibleForTesting;
82 import com.android.internal.os.SomeArgs;
83 import com.android.internal.statusbar.IStatusBarService;
84 import com.android.internal.util.DumpUtils;
85 import com.android.server.SystemService;
86 import com.android.server.biometrics.log.BiometricContext;
87 import com.android.server.utils.Slogf;
88 
89 import java.io.FileDescriptor;
90 import java.io.PrintWriter;
91 import java.util.ArrayList;
92 import java.util.HashMap;
93 import java.util.List;
94 import java.util.Map;
95 import java.util.Random;
96 import java.util.Set;
97 import java.util.concurrent.atomic.AtomicLong;
98 import java.util.function.Supplier;
99 
100 /**
101  * System service that arbitrates the modality for BiometricPrompt to use.
102  */
103 public class BiometricService extends SystemService {
104 
105     static final String TAG = "BiometricService";
106 
107     private final Injector mInjector;
108     private final DevicePolicyManager mDevicePolicyManager;
109     @VisibleForTesting
110     final IBiometricService.Stub mImpl;
111     @VisibleForTesting
112     final SettingObserver mSettingObserver;
113     private final List<EnabledOnKeyguardCallback> mEnabledOnKeyguardCallbacks;
114     private final Random mRandom = new Random();
115     @NonNull private final Supplier<Long> mRequestCounter;
116     @NonNull private final BiometricContext mBiometricContext;
117     private final UserManager mUserManager;
118 
119     @VisibleForTesting
120     IStatusBarService mStatusBarService;
121     @VisibleForTesting
122     ITrustManager mTrustManager;
123     @VisibleForTesting
124     KeyStoreAuthorization mKeyStoreAuthorization;
125     @VisibleForTesting
126     IGateKeeperService mGateKeeper;
127 
128     // Get and cache the available biometric authenticators and their associated info.
129     final ArrayList<BiometricSensor> mSensors = new ArrayList<>();
130 
131     @VisibleForTesting
132     BiometricStrengthController mBiometricStrengthController;
133 
134     // The current authentication session, null if idle/done.
135     @VisibleForTesting
136     AuthSession mAuthSession;
137     private final Handler mHandler;
138 
139     private final BiometricCameraManager mBiometricCameraManager;
140 
141     private final BiometricNotificationLogger mBiometricNotificationLogger;
142 
143     /**
144      * Tracks authenticatorId invalidation. For more details, see
145      * {@link com.android.server.biometrics.sensors.InvalidationRequesterClient}.
146      */
147     @VisibleForTesting
148     static class InvalidationTracker {
149         @NonNull private final IInvalidationCallback mClientCallback;
150         @NonNull private final Set<Integer> mSensorsPendingInvalidation;
151 
start(@onNull Context context, @NonNull ArrayList<BiometricSensor> sensors, int userId, int fromSensorId, @NonNull IInvalidationCallback clientCallback)152         public static InvalidationTracker start(@NonNull Context context,
153                 @NonNull ArrayList<BiometricSensor> sensors,
154                 int userId, int fromSensorId, @NonNull IInvalidationCallback clientCallback) {
155             return new InvalidationTracker(context, sensors, userId, fromSensorId, clientCallback);
156         }
157 
InvalidationTracker(@onNull Context context, @NonNull ArrayList<BiometricSensor> sensors, int userId, int fromSensorId, @NonNull IInvalidationCallback clientCallback)158         private InvalidationTracker(@NonNull Context context,
159                 @NonNull ArrayList<BiometricSensor> sensors, int userId,
160                 int fromSensorId, @NonNull IInvalidationCallback clientCallback) {
161             mClientCallback = clientCallback;
162             mSensorsPendingInvalidation = new ArraySet<>();
163 
164             for (BiometricSensor sensor : sensors) {
165                 if (sensor.id == fromSensorId) {
166                     continue;
167                 }
168 
169                 if (!Utils.isAtLeastStrength(sensor.oemStrength, Authenticators.BIOMETRIC_STRONG)) {
170                     continue;
171                 }
172 
173                 try {
174                     if (!sensor.impl.hasEnrolledTemplates(userId, context.getOpPackageName())) {
175                         continue;
176                     }
177                 } catch (RemoteException e) {
178                     Slog.e(TAG, "Remote Exception", e);
179                 }
180 
181                 Slog.d(TAG, "Requesting authenticatorId invalidation for sensor: " + sensor.id);
182 
183                 synchronized (this) {
184                     mSensorsPendingInvalidation.add(sensor.id);
185                 }
186 
187                 try {
188                     sensor.impl.invalidateAuthenticatorId(userId, new IInvalidationCallback.Stub() {
189                         @Override
190                         public void onCompleted() {
191                             onInvalidated(sensor.id);
192                         }
193                     });
194                 } catch (RemoteException e) {
195                     Slog.d(TAG, "RemoteException", e);
196                 }
197             }
198 
199             synchronized (this) {
200                 if (mSensorsPendingInvalidation.isEmpty()) {
201                     try {
202                         Slog.d(TAG, "No sensors require invalidation");
203                         mClientCallback.onCompleted();
204                     } catch (RemoteException e) {
205                         Slog.e(TAG, "Remote Exception", e);
206                     }
207                 }
208             }
209         }
210 
211         @VisibleForTesting
onInvalidated(int sensorId)212         void onInvalidated(int sensorId) {
213             synchronized (this) {
214                 mSensorsPendingInvalidation.remove(sensorId);
215 
216                 Slog.d(TAG, "Sensor " + sensorId + " invalidated, remaining size: "
217                         + mSensorsPendingInvalidation.size());
218 
219                 if (mSensorsPendingInvalidation.isEmpty()) {
220                     try {
221                         mClientCallback.onCompleted();
222                     } catch (RemoteException e) {
223                         Slog.e(TAG, "Remote Exception", e);
224                     }
225                 }
226             }
227         }
228     }
229 
230     @VisibleForTesting
231     public static class SettingObserver extends ContentObserver {
232 
233         private static final boolean DEFAULT_KEYGUARD_ENABLED = true;
234         private static final boolean DEFAULT_APP_ENABLED = true;
235         private static final boolean DEFAULT_ALWAYS_REQUIRE_CONFIRMATION = false;
236 
237         // Some devices that shipped before S already have face-specific settings. Instead of
238         // migrating, which is complicated, let's just keep using the existing settings.
239         private final boolean mUseLegacyFaceOnlySettings;
240 
241         // Only used for legacy face-only devices
242         private final Uri FACE_UNLOCK_KEYGUARD_ENABLED =
243                 Settings.Secure.getUriFor(Settings.Secure.FACE_UNLOCK_KEYGUARD_ENABLED);
244         private final Uri FACE_UNLOCK_APP_ENABLED =
245                 Settings.Secure.getUriFor(Settings.Secure.FACE_UNLOCK_APP_ENABLED);
246 
247         // Continues to be used, even though it's face-specific.
248         private final Uri FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION =
249                 Settings.Secure.getUriFor(Settings.Secure.FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION);
250 
251         // Used for all devices other than legacy face-only devices
252         private final Uri BIOMETRIC_KEYGUARD_ENABLED =
253                 Settings.Secure.getUriFor(Settings.Secure.BIOMETRIC_KEYGUARD_ENABLED);
254         private final Uri BIOMETRIC_APP_ENABLED =
255                 Settings.Secure.getUriFor(Settings.Secure.BIOMETRIC_APP_ENABLED);
256 
257         private final ContentResolver mContentResolver;
258         private final List<BiometricService.EnabledOnKeyguardCallback> mCallbacks;
259 
260         private final Map<Integer, Boolean> mBiometricEnabledOnKeyguard = new HashMap<>();
261         private final Map<Integer, Boolean> mBiometricEnabledForApps = new HashMap<>();
262         private final Map<Integer, Boolean> mFaceAlwaysRequireConfirmation = new HashMap<>();
263 
264         /**
265          * Creates a content observer.
266          *
267          * @param handler The handler to run {@link #onChange} on, or null if none.
268          */
SettingObserver(Context context, Handler handler, List<BiometricService.EnabledOnKeyguardCallback> callbacks)269         public SettingObserver(Context context, Handler handler,
270                 List<BiometricService.EnabledOnKeyguardCallback> callbacks) {
271             super(handler);
272             mContentResolver = context.getContentResolver();
273             mCallbacks = callbacks;
274 
275             final boolean hasFingerprint = context.getPackageManager()
276                     .hasSystemFeature(PackageManager.FEATURE_FINGERPRINT);
277             final boolean hasFace = context.getPackageManager()
278                     .hasSystemFeature(PackageManager.FEATURE_FACE);
279 
280             // Use the legacy setting on face-only devices that shipped on or before Q
281             mUseLegacyFaceOnlySettings =
282                     Build.VERSION.DEVICE_INITIAL_SDK_INT <= Build.VERSION_CODES.Q
283                     && hasFace && !hasFingerprint;
284 
285             updateContentObserver();
286         }
287 
updateContentObserver()288         public void updateContentObserver() {
289             mContentResolver.unregisterContentObserver(this);
290 
291             if (mUseLegacyFaceOnlySettings) {
292                 mContentResolver.registerContentObserver(FACE_UNLOCK_KEYGUARD_ENABLED,
293                         false /* notifyForDescendants */,
294                         this /* observer */,
295                         UserHandle.USER_ALL);
296                 mContentResolver.registerContentObserver(FACE_UNLOCK_APP_ENABLED,
297                         false /* notifyForDescendants */,
298                         this /* observer */,
299                         UserHandle.USER_ALL);
300             } else {
301                 mContentResolver.registerContentObserver(BIOMETRIC_KEYGUARD_ENABLED,
302                         false /* notifyForDescendants */,
303                         this /* observer */,
304                         UserHandle.USER_ALL);
305                 mContentResolver.registerContentObserver(BIOMETRIC_APP_ENABLED,
306                         false /* notifyForDescendants */,
307                         this /* observer */,
308                         UserHandle.USER_ALL);
309             }
310             mContentResolver.registerContentObserver(FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION,
311                     false /* notifyForDescendants */,
312                     this /* observer */,
313                     UserHandle.USER_ALL);
314         }
315 
316         @Override
onChange(boolean selfChange, Uri uri, int userId)317         public void onChange(boolean selfChange, Uri uri, int userId) {
318             if (FACE_UNLOCK_KEYGUARD_ENABLED.equals(uri)) {
319                 mBiometricEnabledOnKeyguard.put(userId, Settings.Secure.getIntForUser(
320                                 mContentResolver,
321                                 Settings.Secure.FACE_UNLOCK_KEYGUARD_ENABLED,
322                                 DEFAULT_KEYGUARD_ENABLED ? 1 : 0 /* default */,
323                                 userId) != 0);
324 
325                 if (userId == ActivityManager.getCurrentUser() && !selfChange) {
326                     notifyEnabledOnKeyguardCallbacks(userId);
327                 }
328             } else if (FACE_UNLOCK_APP_ENABLED.equals(uri)) {
329                 mBiometricEnabledForApps.put(userId, Settings.Secure.getIntForUser(
330                                 mContentResolver,
331                                 Settings.Secure.FACE_UNLOCK_APP_ENABLED,
332                                 DEFAULT_APP_ENABLED ? 1 : 0 /* default */,
333                                 userId) != 0);
334             } else if (FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION.equals(uri)) {
335                 mFaceAlwaysRequireConfirmation.put(userId, Settings.Secure.getIntForUser(
336                                 mContentResolver,
337                                 Settings.Secure.FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION,
338                                 DEFAULT_ALWAYS_REQUIRE_CONFIRMATION ? 1 : 0 /* default */,
339                                 userId) != 0);
340             } else if (BIOMETRIC_KEYGUARD_ENABLED.equals(uri)) {
341                 mBiometricEnabledOnKeyguard.put(userId, Settings.Secure.getIntForUser(
342                         mContentResolver,
343                         Settings.Secure.BIOMETRIC_KEYGUARD_ENABLED,
344                         DEFAULT_KEYGUARD_ENABLED ? 1 : 0 /* default */,
345                         userId) != 0);
346 
347                 if (userId == ActivityManager.getCurrentUser() && !selfChange) {
348                     notifyEnabledOnKeyguardCallbacks(userId);
349                 }
350             } else if (BIOMETRIC_APP_ENABLED.equals(uri)) {
351                 mBiometricEnabledForApps.put(userId, Settings.Secure.getIntForUser(
352                         mContentResolver,
353                         Settings.Secure.BIOMETRIC_APP_ENABLED,
354                         DEFAULT_APP_ENABLED ? 1 : 0 /* default */,
355                         userId) != 0);
356             }
357         }
358 
getEnabledOnKeyguard(int userId)359         public boolean getEnabledOnKeyguard(int userId) {
360             if (!mBiometricEnabledOnKeyguard.containsKey(userId)) {
361                 if (mUseLegacyFaceOnlySettings) {
362                     onChange(true /* selfChange */, FACE_UNLOCK_KEYGUARD_ENABLED, userId);
363                 } else {
364                     onChange(true /* selfChange */, BIOMETRIC_KEYGUARD_ENABLED, userId);
365                 }
366             }
367             return mBiometricEnabledOnKeyguard.get(userId);
368         }
369 
getEnabledForApps(int userId)370         public boolean getEnabledForApps(int userId) {
371             if (!mBiometricEnabledForApps.containsKey(userId)) {
372                 if (mUseLegacyFaceOnlySettings) {
373                     onChange(true /* selfChange */, FACE_UNLOCK_APP_ENABLED, userId);
374                 } else {
375                     onChange(true /* selfChange */, BIOMETRIC_APP_ENABLED, userId);
376                 }
377             }
378             return mBiometricEnabledForApps.getOrDefault(userId, DEFAULT_APP_ENABLED);
379         }
380 
getConfirmationAlwaysRequired(@iometricAuthenticator.Modality int modality, int userId)381         public boolean getConfirmationAlwaysRequired(@BiometricAuthenticator.Modality int modality,
382                 int userId) {
383             switch (modality) {
384                 case TYPE_FACE:
385                     if (!mFaceAlwaysRequireConfirmation.containsKey(userId)) {
386                         onChange(true /* selfChange */,
387                                 FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION,
388                                 userId);
389                     }
390                     return mFaceAlwaysRequireConfirmation.get(userId);
391 
392                 default:
393                     return false;
394             }
395         }
396 
notifyEnabledOnKeyguardCallbacks(int userId)397         void notifyEnabledOnKeyguardCallbacks(int userId) {
398             List<EnabledOnKeyguardCallback> callbacks = mCallbacks;
399             for (int i = 0; i < callbacks.size(); i++) {
400                 callbacks.get(i).notify(
401                         mBiometricEnabledOnKeyguard.getOrDefault(userId, DEFAULT_KEYGUARD_ENABLED),
402                         userId);
403             }
404         }
405     }
406 
407     final class EnabledOnKeyguardCallback implements IBinder.DeathRecipient {
408 
409         private final IBiometricEnabledOnKeyguardCallback mCallback;
410 
EnabledOnKeyguardCallback(IBiometricEnabledOnKeyguardCallback callback)411         EnabledOnKeyguardCallback(IBiometricEnabledOnKeyguardCallback callback) {
412             mCallback = callback;
413             try {
414                 mCallback.asBinder().linkToDeath(EnabledOnKeyguardCallback.this, 0);
415             } catch (RemoteException e) {
416                 Slog.w(TAG, "Unable to linkToDeath", e);
417             }
418         }
419 
notify(boolean enabled, int userId)420         void notify(boolean enabled, int userId) {
421             try {
422                 mCallback.onChanged(enabled, userId);
423             } catch (DeadObjectException e) {
424                 Slog.w(TAG, "Death while invoking notify", e);
425                 mEnabledOnKeyguardCallbacks.remove(this);
426             } catch (RemoteException e) {
427                 Slog.w(TAG, "Failed to invoke onChanged", e);
428             }
429         }
430 
431         @Override
binderDied()432         public void binderDied() {
433             Slog.e(TAG, "Enabled callback binder died");
434             mEnabledOnKeyguardCallbacks.remove(this);
435         }
436     }
437 
438     // Receives events from individual biometric sensors.
createBiometricSensorReceiver(final long requestId)439     private IBiometricSensorReceiver createBiometricSensorReceiver(final long requestId) {
440         return new IBiometricSensorReceiver.Stub() {
441             @Override
442             public void onAuthenticationSucceeded(int sensorId, byte[] token) {
443                 mHandler.post(() -> handleAuthenticationSucceeded(requestId, sensorId, token));
444             }
445 
446             @Override
447             public void onAuthenticationFailed(int sensorId) {
448                 Slog.v(TAG, "onAuthenticationFailed");
449                 mHandler.post(() -> handleAuthenticationRejected(requestId, sensorId));
450             }
451 
452             @Override
453             public void onError(int sensorId, int cookie, @BiometricConstants.Errors int error,
454                     int vendorCode) {
455                 // Determine if error is hard or soft error. Certain errors (such as TIMEOUT) are
456                 // soft errors and we should allow the user to try authenticating again instead of
457                 // dismissing BiometricPrompt.
458                 if (error == BiometricConstants.BIOMETRIC_ERROR_TIMEOUT) {
459                     mHandler.post(() -> handleAuthenticationTimedOut(
460                             requestId, sensorId, cookie, error, vendorCode));
461                 } else {
462                     mHandler.post(() -> handleOnError(
463                             requestId, sensorId, cookie, error, vendorCode));
464                 }
465             }
466 
467             @Override
468             public void onAcquired(int sensorId, int acquiredInfo, int vendorCode) {
469                 mHandler.post(() -> handleOnAcquired(
470                         requestId, sensorId, acquiredInfo, vendorCode));
471             }
472         };
473     }
474 
475     private IBiometricSysuiReceiver createSysuiReceiver(final long requestId) {
476         return new IBiometricSysuiReceiver.Stub() {
477             @Override
478             public void onDialogDismissed(@BiometricPrompt.DismissedReason int reason,
479                     @Nullable byte[] credentialAttestation) {
480                 mHandler.post(() -> handleOnDismissed(requestId, reason, credentialAttestation));
481             }
482 
483             @Override
484             public void onTryAgainPressed() {
485                 mHandler.post(() -> handleOnTryAgainPressed(requestId));
486             }
487 
488             @Override
489             public void onDeviceCredentialPressed() {
490                 mHandler.post(() -> handleOnDeviceCredentialPressed(requestId));
491             }
492 
493             @Override
494             public void onSystemEvent(int event) {
495                 mHandler.post(() -> handleOnSystemEvent(requestId, event));
496             }
497 
498             @Override
499             public void onDialogAnimatedIn(boolean startFingerprintNow) {
500                 mHandler.post(() -> handleOnDialogAnimatedIn(requestId, startFingerprintNow));
501             }
502 
503             @Override
504             public void onStartFingerprintNow() {
505                 mHandler.post(() -> handleOnStartFingerprintNow(requestId));
506             }
507         };
508     }
509 
510     private AuthSession.ClientDeathReceiver createClientDeathReceiver(final long requestId) {
511         return () -> mHandler.post(() -> handleClientDied(requestId));
512     };
513 
514     /**
515      * Implementation of the BiometricPrompt/BiometricManager APIs. Handles client requests,
516      * sensor arbitration, threading, etc.
517      */
518     private final class BiometricServiceWrapper extends IBiometricService.Stub {
519         @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
520         @Override // Binder call
521         public ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback,
522                 @NonNull String opPackageName) throws RemoteException {
523 
524             super.createTestSession_enforcePermission();
525 
526             for (BiometricSensor sensor : mSensors) {
527                 if (sensor.id == sensorId) {
528                     return sensor.impl.createTestSession(callback, opPackageName);
529                 }
530             }
531 
532             Slog.e(TAG, "Unknown sensor for createTestSession: " + sensorId);
533             return null;
534         }
535 
536         @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
537         @Override // Binder call
538         public List<SensorPropertiesInternal> getSensorProperties(String opPackageName)
539                 throws RemoteException {
540 
541             super.getSensorProperties_enforcePermission();
542 
543             final List<SensorPropertiesInternal> sensors = new ArrayList<>();
544             for (BiometricSensor sensor : mSensors) {
545                 // Explicitly re-create as the super class, since AIDL doesn't play nicely with
546                 // "List<? extends SensorPropertiesInternal> ...
547                 final SensorPropertiesInternal prop = SensorPropertiesInternal
548                         .from(sensor.impl.getSensorProperties(opPackageName));
549                 sensors.add(prop);
550             }
551 
552             return sensors;
553         }
554 
555         @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
556         @Override // Binder call
557         public void onReadyForAuthentication(long requestId, int cookie) {
558 
559             super.onReadyForAuthentication_enforcePermission();
560 
561             mHandler.post(() -> handleOnReadyForAuthentication(requestId, cookie));
562         }
563 
564         @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
565         @Override // Binder call
566         public long authenticate(IBinder token, long operationId, int userId,
567                 IBiometricServiceReceiver receiver, String opPackageName, PromptInfo promptInfo) {
568 
569             super.authenticate_enforcePermission();
570 
571             if (token == null || receiver == null || opPackageName == null || promptInfo == null) {
572                 Slog.e(TAG, "Unable to authenticate, one or more null arguments");
573                 return -1;
574             }
575 
576             if (!Utils.isValidAuthenticatorConfig(promptInfo)) {
577                 throw new SecurityException("Invalid authenticator configuration");
578             }
579 
580             Utils.combineAuthenticatorBundles(promptInfo);
581 
582             final long requestId = mRequestCounter.get();
583             mHandler.post(() -> handleAuthenticate(
584                     token, requestId, operationId, userId, receiver, opPackageName, promptInfo));
585 
586             return requestId;
587         }
588 
589         @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
590         @Override // Binder call
591         public void cancelAuthentication(IBinder token, String opPackageName, long requestId) {
592 
593             super.cancelAuthentication_enforcePermission();
594 
595             SomeArgs args = SomeArgs.obtain();
596             args.arg1 = token;
597             args.arg2 = opPackageName;
598             args.arg3 = requestId;
599 
600             mHandler.post(() -> handleCancelAuthentication(requestId));
601         }
602 
603         @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
604         @Override // Binder call
605         public int canAuthenticate(String opPackageName, int userId, int callingUserId,
606                 @Authenticators.Types int authenticators) {
607 
608             super.canAuthenticate_enforcePermission();
609 
610             Slog.d(TAG, "canAuthenticate: User=" + userId
611                     + ", Caller=" + callingUserId
612                     + ", Authenticators=" + authenticators);
613 
614             if (!Utils.isValidAuthenticatorConfig(authenticators)) {
615                 throw new SecurityException("Invalid authenticator configuration");
616             }
617 
618             try {
619                 final PreAuthInfo preAuthInfo =
620                         createPreAuthInfo(opPackageName, userId, authenticators);
621                 return preAuthInfo.getCanAuthenticateResult();
622             } catch (RemoteException e) {
623                 Slog.e(TAG, "Remote exception", e);
624                 return BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE;
625             }
626         }
627 
628         @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
629         @Override // Binder call
630         public long getLastAuthenticationTime(
631                 int userId, @Authenticators.Types int authenticators) {
632             super.getLastAuthenticationTime_enforcePermission();
633 
634             if (!Flags.lastAuthenticationTime()) {
635                 throw new UnsupportedOperationException();
636             }
637 
638             Slogf.d(TAG, "getLastAuthenticationTime(userId=%d, authenticators=0x%x)",
639                     userId, authenticators);
640 
641             final long secureUserId;
642             try {
643                 secureUserId = mGateKeeper.getSecureUserId(userId);
644             } catch (RemoteException e) {
645                 Slogf.w(TAG, "Failed to get secure user id for " + userId, e);
646                 return BIOMETRIC_NO_AUTHENTICATION;
647             }
648 
649             if (secureUserId == GateKeeper.INVALID_SECURE_USER_ID) {
650                 Slogf.w(TAG, "No secure user id for " + userId);
651                 return BIOMETRIC_NO_AUTHENTICATION;
652             }
653 
654             ArrayList<Integer> hardwareAuthenticators = new ArrayList<>(2);
655 
656             if ((authenticators & Authenticators.DEVICE_CREDENTIAL) != 0) {
657                 hardwareAuthenticators.add(HardwareAuthenticatorType.PASSWORD);
658             }
659 
660             if ((authenticators & Authenticators.BIOMETRIC_STRONG) != 0) {
661                 hardwareAuthenticators.add(HardwareAuthenticatorType.FINGERPRINT);
662             }
663 
664             if (hardwareAuthenticators.isEmpty()) {
665                 throw new IllegalArgumentException("authenticators must not be empty");
666             }
667 
668             int[] authTypesArray = hardwareAuthenticators.stream()
669                     .mapToInt(Integer::intValue)
670                     .toArray();
671             return mKeyStoreAuthorization.getLastAuthTime(secureUserId, authTypesArray);
672         }
673 
674         @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
675         @Override
676         public boolean hasEnrolledBiometrics(int userId, String opPackageName) {
677 
678             super.hasEnrolledBiometrics_enforcePermission();
679 
680             try {
681                 for (BiometricSensor sensor : mSensors) {
682                     if (sensor.impl.hasEnrolledTemplates(userId, opPackageName)) {
683                         return true;
684                     }
685                 }
686             } catch (RemoteException e) {
687                 Slog.e(TAG, "Remote exception", e);
688             }
689 
690             return false;
691         }
692 
693         @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
694         @Override
695         public synchronized void registerAuthenticator(int id, int modality,
696                 @Authenticators.Types int strength,
697                 @NonNull IBiometricAuthenticator authenticator) {
698 
699             super.registerAuthenticator_enforcePermission();
700 
701             Slog.d(TAG, "Registering ID: " + id
702                     + " Modality: " + modality
703                     + " Strength: " + strength);
704 
705             if (authenticator == null) {
706                 throw new IllegalArgumentException("Authenticator must not be null."
707                         + " Did you forget to modify the core/res/res/values/xml overlay for"
708                         + " config_biometric_sensors?");
709             }
710 
711             // Note that we allow BIOMETRIC_CONVENIENCE to register because BiometricService
712             // also does / will do other things such as keep track of lock screen timeout, etc.
713             // Just because a biometric is registered does not mean it can participate in
714             // the android.hardware.biometrics APIs.
715             if (strength != Authenticators.BIOMETRIC_STRONG
716                     && strength != Authenticators.BIOMETRIC_WEAK
717                     && strength != Authenticators.BIOMETRIC_CONVENIENCE) {
718                 throw new IllegalStateException("Unsupported strength");
719             }
720 
721             for (BiometricSensor sensor : mSensors) {
722                 if (sensor.id == id) {
723                     throw new IllegalStateException("Cannot register duplicate authenticator");
724                 }
725             }
726 
727             mSensors.add(new BiometricSensor(getContext(), id, modality, strength, authenticator) {
728                 @Override
729                 boolean confirmationAlwaysRequired(int userId) {
730                     return mSettingObserver.getConfirmationAlwaysRequired(modality, userId);
731                 }
732 
733                 @Override
734                 boolean confirmationSupported() {
735                     return Utils.isConfirmationSupported(modality);
736                 }
737             });
738 
739             mBiometricStrengthController.updateStrengths();
740         }
741 
742         @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
743         @Override // Binder call
744         public void registerEnabledOnKeyguardCallback(
745                 IBiometricEnabledOnKeyguardCallback callback) {
746 
747             super.registerEnabledOnKeyguardCallback_enforcePermission();
748 
749             mEnabledOnKeyguardCallbacks.add(new EnabledOnKeyguardCallback(callback));
750             final List<UserInfo> aliveUsers = mUserManager.getAliveUsers();
751             try {
752                 for (UserInfo userInfo: aliveUsers) {
753                     final int userId = userInfo.id;
754                     callback.onChanged(mSettingObserver.getEnabledOnKeyguard(userId),
755                             userId);
756                 }
757             } catch (RemoteException e) {
758                 Slog.w(TAG, "Remote exception", e);
759             }
760         }
761 
762         @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
763         @Override // Binder call
764         public void invalidateAuthenticatorIds(int userId, int fromSensorId,
765                 IInvalidationCallback callback) {
766 
767             super.invalidateAuthenticatorIds_enforcePermission();
768 
769             InvalidationTracker.start(getContext(), mSensors, userId, fromSensorId, callback);
770         }
771 
772         @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
773         @Override // Binder call
774         public long[] getAuthenticatorIds(int callingUserId) {
775 
776             super.getAuthenticatorIds_enforcePermission();
777 
778             final List<Long> authenticatorIds = new ArrayList<>();
779             for (BiometricSensor sensor : mSensors) {
780                 try {
781                     final boolean hasEnrollments = sensor.impl.hasEnrolledTemplates(callingUserId,
782                             getContext().getOpPackageName());
783                     final long authenticatorId = sensor.impl.getAuthenticatorId(callingUserId);
784                     if (hasEnrollments && Utils.isAtLeastStrength(sensor.getCurrentStrength(),
785                             Authenticators.BIOMETRIC_STRONG)) {
786                         authenticatorIds.add(authenticatorId);
787                     } else {
788                         Slog.d(TAG, "Sensor " + sensor + ", sensorId " + sensor.id
789                                 + ", hasEnrollments: " + hasEnrollments
790                                 + " cannot participate in Keystore operations");
791                     }
792                 } catch (RemoteException e) {
793                     Slog.e(TAG, "RemoteException", e);
794                 }
795             }
796 
797             long[] result = new long[authenticatorIds.size()];
798             for (int i = 0; i < authenticatorIds.size(); i++) {
799                 result[i] = authenticatorIds.get(i);
800             }
801             return result;
802         }
803 
804         @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
805         @Override // Binder call
806         public void resetLockoutTimeBound(IBinder token, String opPackageName, int fromSensorId,
807                 int userId, byte[] hardwareAuthToken) {
808 
809             // Check originating strength
810             super.resetLockoutTimeBound_enforcePermission();
811 
812             if (!Utils.isAtLeastStrength(getSensorForId(fromSensorId).getCurrentStrength(),
813                     Authenticators.BIOMETRIC_STRONG)) {
814                 Slog.w(TAG, "Sensor: " + fromSensorId + " is does not meet the required strength to"
815                         + " request resetLockout");
816                 return;
817             }
818 
819             // Request resetLockout for applicable sensors
820             for (BiometricSensor sensor : mSensors) {
821                 if (sensor.id == fromSensorId) {
822                     continue;
823                 }
824                 try {
825                     final SensorPropertiesInternal props = sensor.impl
826                             .getSensorProperties(getContext().getOpPackageName());
827                     final boolean supportsChallengelessHat =
828                             props.resetLockoutRequiresHardwareAuthToken
829                             && !props.resetLockoutRequiresChallenge;
830                     final boolean doesNotRequireHat = !props.resetLockoutRequiresHardwareAuthToken;
831 
832                     if (supportsChallengelessHat || doesNotRequireHat) {
833                         Slog.d(TAG, "resetLockout from: " + fromSensorId
834                                 + ", for: " + sensor.id
835                                 + ", userId: " + userId);
836                         sensor.impl.resetLockout(token, opPackageName, userId,
837                                 hardwareAuthToken);
838                     }
839                 } catch (RemoteException e) {
840                     Slog.e(TAG, "Remote exception", e);
841                 }
842             }
843         }
844 
845         @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
846         @Override // Binder call
847         public void resetLockout(
848                 int userId, byte[] hardwareAuthToken) {
849             super.resetLockout_enforcePermission();
850 
851             Slog.d(TAG, "resetLockout(userId=" + userId
852                     + ", hat=" + (hardwareAuthToken == null ? "null " : "present") + ")");
853             mHandler.post(() -> {
854                 mBiometricContext.getAuthSessionCoordinator()
855                     .resetLockoutFor(userId, Authenticators.BIOMETRIC_STRONG, -1);
856             });
857         }
858 
859         @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
860         @Override // Binder call
861         public int getCurrentStrength(int sensorId) {
862 
863             super.getCurrentStrength_enforcePermission();
864 
865             for (BiometricSensor sensor : mSensors) {
866                 if (sensor.id == sensorId) {
867                     return sensor.getCurrentStrength();
868                 }
869             }
870             Slog.e(TAG, "Unknown sensorId: " + sensorId);
871             return Authenticators.EMPTY_SET;
872         }
873 
874         @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
875         @Override // Binder call
876         public int getCurrentModality(
877                 String opPackageName,
878                 int userId,
879                 int callingUserId,
880                 @Authenticators.Types int authenticators) {
881 
882 
883             super.getCurrentModality_enforcePermission();
884 
885             Slog.d(TAG, "getCurrentModality: User=" + userId
886                     + ", Caller=" + callingUserId
887                     + ", Authenticators=" + authenticators);
888 
889             if (!Utils.isValidAuthenticatorConfig(authenticators)) {
890                 throw new SecurityException("Invalid authenticator configuration");
891             }
892 
893             try {
894                 final PreAuthInfo preAuthInfo =
895                         createPreAuthInfo(opPackageName, userId, authenticators);
896                 return preAuthInfo.getPreAuthenticateStatus().first;
897             } catch (RemoteException e) {
898                 Slog.e(TAG, "Remote exception", e);
899                 return BiometricAuthenticator.TYPE_NONE;
900             }
901         }
902 
903         @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
904         @Override // Binder call
905         public int getSupportedModalities(@Authenticators.Types int authenticators) {
906 
907             super.getSupportedModalities_enforcePermission();
908 
909             Slog.d(TAG, "getSupportedModalities: Authenticators=" + authenticators);
910 
911             if (!Utils.isValidAuthenticatorConfig(authenticators)) {
912                 throw new SecurityException("Invalid authenticator configuration");
913             }
914 
915             @BiometricAuthenticator.Modality int modality =
916                     Utils.isCredentialRequested(authenticators)
917                             ? BiometricAuthenticator.TYPE_CREDENTIAL
918                             : BiometricAuthenticator.TYPE_NONE;
919 
920             if (Utils.isBiometricRequested(authenticators)) {
921                 @Authenticators.Types final int requestedStrength =
922                         Utils.getPublicBiometricStrength(authenticators);
923 
924                 // Add modalities of all biometric sensors that meet the authenticator requirements.
925                 for (final BiometricSensor sensor : mSensors) {
926                     @Authenticators.Types final int sensorStrength = sensor.getCurrentStrength();
927                     if (Utils.isAtLeastStrength(sensorStrength, requestedStrength)) {
928                         modality |= sensor.modality;
929                     }
930                 }
931             }
932 
933             return modality;
934         }
935 
936         @Override
937         protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, String[] args) {
938             if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) {
939                 return;
940             }
941 
942             final long ident = Binder.clearCallingIdentity();
943             try {
944                 if (args.length > 0 && "--proto".equals(args[0])) {
945                     final boolean clearSchedulerBuffer = args.length > 1
946                             && "--clear-scheduler-buffer".equals(args[1]);
947                     Slog.d(TAG, "ClearSchedulerBuffer: " + clearSchedulerBuffer);
948                     final ProtoOutputStream proto = new ProtoOutputStream(fd);
949                     proto.write(BiometricServiceStateProto.AUTH_SESSION_STATE,
950                             mAuthSession != null ? mAuthSession.getState() : STATE_AUTH_IDLE);
951                     for (BiometricSensor sensor : mSensors) {
952                         byte[] serviceState = sensor.impl
953                                 .dumpSensorServiceStateProto(clearSchedulerBuffer);
954                         proto.write(BiometricServiceStateProto.SENSOR_SERVICE_STATES, serviceState);
955                     }
956                     proto.flush();
957                 } else {
958                     dumpInternal(pw);
959                 }
960             } catch (RemoteException e) {
961                 Slog.e(TAG, "Remote exception", e);
962             } finally {
963                 Binder.restoreCallingIdentity(ident);
964             }
965         }
966     }
967 
968     private void checkInternalPermission() {
969         getContext().enforceCallingOrSelfPermission(USE_BIOMETRIC_INTERNAL,
970                 "Must have USE_BIOMETRIC_INTERNAL permission");
971     }
972 
973     @NonNull
974     private PreAuthInfo createPreAuthInfo(
975             @NonNull String opPackageName,
976             int userId,
977             @Authenticators.Types int authenticators) throws RemoteException {
978 
979         final PromptInfo promptInfo = new PromptInfo();
980         promptInfo.setAuthenticators(authenticators);
981 
982         return PreAuthInfo.create(mTrustManager, mDevicePolicyManager, mSettingObserver, mSensors,
983                 userId, promptInfo, opPackageName, false /* checkDevicePolicyManager */,
984                 getContext(), mBiometricCameraManager);
985     }
986 
987     /**
988      * Class for injecting dependencies into BiometricService.
989      * TODO(b/141025588): Replace with a dependency injection framework (e.g. Guice, Dagger).
990      */
991     @VisibleForTesting
992     public static class Injector {
993 
994         public IActivityManager getActivityManagerService() {
995             return ActivityManager.getService();
996         }
997 
998         public KeyStoreAuthorization getKeyStoreAuthorization() {
999             return KeyStoreAuthorization.getInstance();
1000         }
1001 
1002         public IGateKeeperService getGateKeeperService() {
1003             return GateKeeper.getService();
1004         }
1005 
1006         public ITrustManager getTrustManager() {
1007             return ITrustManager.Stub.asInterface(ServiceManager.getService(Context.TRUST_SERVICE));
1008         }
1009 
1010         public IStatusBarService getStatusBarService() {
1011             return IStatusBarService.Stub.asInterface(
1012                     ServiceManager.getService(Context.STATUS_BAR_SERVICE));
1013         }
1014 
1015         /**
1016          * Allows to mock SettingObserver for testing.
1017          */
1018         public SettingObserver getSettingObserver(Context context, Handler handler,
1019                 List<EnabledOnKeyguardCallback> callbacks) {
1020             return new SettingObserver(context, handler, callbacks);
1021         }
1022 
1023         /**
1024          * Allows to enable/disable debug logs.
1025          */
1026         public boolean isDebugEnabled(Context context, int userId) {
1027             return Utils.isDebugEnabled(context, userId);
1028         }
1029 
1030         /**
1031          * Allows to stub publishBinderService(...) for testing.
1032          */
1033         public void publishBinderService(BiometricService service, IBiometricService.Stub impl) {
1034             service.publishBinderService(Context.BIOMETRIC_SERVICE, impl);
1035         }
1036 
1037         /**
1038          * Allows to mock BiometricStrengthController for testing.
1039          */
1040         public BiometricStrengthController getBiometricStrengthController(
1041                 BiometricService service) {
1042             return new BiometricStrengthController(service);
1043         }
1044 
1045         /**
1046          * Allows to test with various device sensor configurations.
1047          * @param context System Server context
1048          * @return the sensor configuration from core/res/res/values/config.xml
1049          */
1050         public String[] getConfiguration(Context context) {
1051             return context.getResources().getStringArray(R.array.config_biometric_sensors);
1052         }
1053 
1054         public DevicePolicyManager getDevicePolicyManager(Context context) {
1055             return context.getSystemService(DevicePolicyManager.class);
1056         }
1057 
1058         public List<FingerprintSensorPropertiesInternal> getFingerprintSensorProperties(
1059                 Context context) {
1060             if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
1061                 final FingerprintManager fpm = context.getSystemService(FingerprintManager.class);
1062                 if (fpm != null) {
1063                     return fpm.getSensorPropertiesInternal();
1064                 }
1065             }
1066             return new ArrayList<>();
1067         }
1068 
1069         public Supplier<Long> getRequestGenerator() {
1070             final AtomicLong generator = new AtomicLong(0);
1071             return () -> generator.incrementAndGet();
1072         }
1073 
1074         public BiometricContext getBiometricContext(Context context) {
1075             return BiometricContext.getInstance(context);
1076         }
1077 
1078         public UserManager getUserManager(Context context) {
1079             return context.getSystemService(UserManager.class);
1080         }
1081 
1082         public BiometricCameraManager getBiometricCameraManager(Context context) {
1083             return new BiometricCameraManagerImpl(context.getSystemService(CameraManager.class),
1084                     context.getSystemService(SensorPrivacyManager.class));
1085         }
1086 
1087         public BiometricNotificationLogger getNotificationLogger() {
1088             return new BiometricNotificationLogger();
1089         }
1090     }
1091 
1092     /**
1093      * Initializes the system service.
1094      * <p>
1095      * Subclasses must define a single argument constructor that accepts the context
1096      * and passes it to super.
1097      * </p>
1098      *
1099      * @param context The system server context.
1100      */
1101     public BiometricService(Context context) {
1102         this(context, new Injector(), BiometricHandlerProvider.getInstance());
1103     }
1104 
1105     @VisibleForTesting
1106     BiometricService(Context context, Injector injector,
1107             BiometricHandlerProvider biometricHandlerProvider) {
1108         super(context);
1109 
1110         mInjector = injector;
1111         mHandler = biometricHandlerProvider.getBiometricCallbackHandler();
1112         mDevicePolicyManager = mInjector.getDevicePolicyManager(context);
1113         mImpl = new BiometricServiceWrapper();
1114         mEnabledOnKeyguardCallbacks = new ArrayList<>();
1115         mSettingObserver = mInjector.getSettingObserver(context, mHandler,
1116                 mEnabledOnKeyguardCallbacks);
1117         mRequestCounter = mInjector.getRequestGenerator();
1118         mBiometricContext = injector.getBiometricContext(context);
1119         mUserManager = injector.getUserManager(context);
1120         mBiometricCameraManager = injector.getBiometricCameraManager(context);
1121         mKeyStoreAuthorization = injector.getKeyStoreAuthorization();
1122         mGateKeeper = injector.getGateKeeperService();
1123         mBiometricNotificationLogger = injector.getNotificationLogger();
1124 
1125         try {
1126             injector.getActivityManagerService().registerUserSwitchObserver(
1127                     new UserSwitchObserver() {
1128                         @Override
1129                         public void onUserSwitchComplete(int newUserId) {
1130                             mSettingObserver.updateContentObserver();
1131                             mSettingObserver.notifyEnabledOnKeyguardCallbacks(newUserId);
1132                         }
1133                     }, BiometricService.class.getName()
1134             );
1135         } catch (RemoteException e) {
1136             Slog.e(TAG, "Failed to register user switch observer", e);
1137         }
1138     }
1139 
1140     @Override
1141     public void onStart() {
1142         mStatusBarService = mInjector.getStatusBarService();
1143         mTrustManager = mInjector.getTrustManager();
1144         mInjector.publishBinderService(this, mImpl);
1145         mBiometricStrengthController = mInjector.getBiometricStrengthController(this);
1146         mBiometricStrengthController.startListening();
1147 
1148         mHandler.post(new Runnable(){
1149             @Override
1150             public void run() {
1151                 try {
1152                     mBiometricNotificationLogger.registerAsSystemService(getContext(),
1153                             new ComponentName(getContext(), BiometricNotificationLogger.class),
1154                             UserHandle.USER_ALL);
1155                 } catch (RemoteException e) {
1156                     // Intra-process call, should never happen.
1157                 }
1158             }
1159 
1160         });
1161     }
1162 
1163     private boolean isStrongBiometric(int id) {
1164         for (BiometricSensor sensor : mSensors) {
1165             if (sensor.id == id) {
1166                 return Utils.isAtLeastStrength(sensor.getCurrentStrength(),
1167                         Authenticators.BIOMETRIC_STRONG);
1168             }
1169         }
1170         Slog.e(TAG, "Unknown sensorId: " + id);
1171         return false;
1172     }
1173 
1174     @Nullable
1175     private AuthSession getAuthSessionIfCurrent(long requestId) {
1176         final AuthSession session = mAuthSession;
1177         if (session != null && session.getRequestId() == requestId) {
1178             return session;
1179         }
1180         return null;
1181     }
1182 
1183     private void handleAuthenticationSucceeded(long requestId, int sensorId, byte[] token) {
1184         Slog.v(TAG, "handleAuthenticationSucceeded(), sensorId: " + sensorId);
1185         // Should never happen, log this to catch bad HAL behavior (e.g. auth succeeded
1186         // after user dismissed/canceled dialog).
1187         final AuthSession session = getAuthSessionIfCurrent(requestId);
1188         if (session == null) {
1189             Slog.e(TAG, "handleAuthenticationSucceeded: AuthSession is null");
1190             return;
1191         }
1192 
1193         session.onAuthenticationSucceeded(sensorId, isStrongBiometric(sensorId), token);
1194     }
1195 
1196     private void handleAuthenticationRejected(long requestId, int sensorId) {
1197         Slog.v(TAG, "handleAuthenticationRejected()");
1198 
1199         // Should never happen, log this to catch bad HAL behavior (e.g. auth rejected
1200         // after user dismissed/canceled dialog).
1201         final AuthSession session = getAuthSessionIfCurrent(requestId);
1202         if (session == null) {
1203             Slog.w(TAG, "handleAuthenticationRejected: AuthSession is not current");
1204             return;
1205         }
1206 
1207         session.onAuthenticationRejected(sensorId);
1208     }
1209 
1210     private void handleAuthenticationTimedOut(long requestId, int sensorId, int cookie, int error,
1211             int vendorCode) {
1212         Slog.v(TAG, "handleAuthenticationTimedOut(), sensorId: " + sensorId
1213                 + ", cookie: " + cookie
1214                 + ", error: " + error
1215                 + ", vendorCode: " + vendorCode);
1216         // Should never happen, log this to catch bad HAL behavior (e.g. auth succeeded
1217         // after user dismissed/canceled dialog).
1218         final AuthSession session = getAuthSessionIfCurrent(requestId);
1219         if (session == null) {
1220             Slog.w(TAG, "handleAuthenticationTimedOut: AuthSession is not current");
1221             return;
1222         }
1223 
1224         session.onAuthenticationTimedOut(sensorId, cookie, error, vendorCode);
1225     }
1226 
1227     private void handleOnError(long requestId, int sensorId, int cookie,
1228             @BiometricConstants.Errors int error, int vendorCode) {
1229         Slog.d(TAG, "handleOnError() sensorId: " + sensorId
1230                 + ", cookie: " + cookie
1231                 + ", error: " + error
1232                 + ", vendorCode: " + vendorCode);
1233 
1234         final AuthSession session = getAuthSessionIfCurrent(requestId);
1235         if (session == null) {
1236             Slog.w(TAG, "handleOnError: AuthSession is not current");
1237             return;
1238         }
1239 
1240         try {
1241             final boolean finished = session.onErrorReceived(sensorId, cookie, error, vendorCode);
1242             if (finished) {
1243                 Slog.d(TAG, "handleOnError: AuthSession finished");
1244                 mAuthSession = null;
1245             }
1246         } catch (RemoteException e) {
1247             Slog.e(TAG, "RemoteException", e);
1248         }
1249     }
1250 
1251     private void handleOnAcquired(long requestId, int sensorId, int acquiredInfo, int vendorCode) {
1252         // Should never happen, log this to catch bad HAL behavior (e.g. auth succeeded
1253         // after user dismissed/canceled dialog).
1254         final AuthSession session = getAuthSessionIfCurrent(requestId);
1255         if (session == null) {
1256             Slog.w(TAG, "onAcquired: AuthSession is not current");
1257             return;
1258         }
1259 
1260         session.onAcquired(sensorId, acquiredInfo, vendorCode);
1261     }
1262 
1263     private void handleOnDismissed(long requestId, @BiometricPrompt.DismissedReason int reason,
1264             @Nullable byte[] credentialAttestation) {
1265         final AuthSession session = getAuthSessionIfCurrent(requestId);
1266         if (session == null) {
1267             Slog.e(TAG, "onDismissed: " + reason + ", AuthSession is not current");
1268             return;
1269         }
1270 
1271         session.onDialogDismissed(reason, credentialAttestation);
1272         mAuthSession = null;
1273     }
1274 
1275     private void handleOnTryAgainPressed(long requestId) {
1276         Slog.d(TAG, "onTryAgainPressed");
1277         // No need to check permission, since it can only be invoked by SystemUI
1278         // (or system server itself).
1279         final AuthSession session = getAuthSessionIfCurrent(requestId);
1280         if (session == null) {
1281             Slog.w(TAG, "handleOnTryAgainPressed: AuthSession is not current");
1282             return;
1283         }
1284 
1285         session.onTryAgainPressed();
1286     }
1287 
1288     private void handleOnDeviceCredentialPressed(long requestId) {
1289         Slog.d(TAG, "onDeviceCredentialPressed");
1290         final AuthSession session = getAuthSessionIfCurrent(requestId);
1291         if (session == null) {
1292             Slog.w(TAG, "handleOnDeviceCredentialPressed: AuthSession is not current");
1293             return;
1294         }
1295 
1296         session.onDeviceCredentialPressed();
1297     }
1298 
1299     private void handleOnSystemEvent(long requestId, int event) {
1300         Slog.d(TAG, "onSystemEvent: " + event);
1301 
1302         final AuthSession session = getAuthSessionIfCurrent(requestId);
1303         if (session == null) {
1304             Slog.w(TAG, "handleOnSystemEvent: AuthSession is not current");
1305             return;
1306         }
1307 
1308         session.onSystemEvent(event);
1309     }
1310 
1311     private void handleClientDied(long requestId) {
1312         final AuthSession session = getAuthSessionIfCurrent(requestId);
1313         if (session == null) {
1314             Slog.w(TAG, "handleClientDied: AuthSession is not current");
1315             return;
1316         }
1317 
1318         Slog.e(TAG, "Session: " + session);
1319         final boolean finished = session.onClientDied();
1320         if (finished) {
1321             mAuthSession = null;
1322         }
1323     }
1324 
1325     private void handleOnDialogAnimatedIn(long requestId, boolean startFingerprintNow) {
1326         Slog.d(TAG, "handleOnDialogAnimatedIn");
1327 
1328         final AuthSession session = getAuthSessionIfCurrent(requestId);
1329         if (session == null) {
1330             Slog.w(TAG, "handleOnDialogAnimatedIn: AuthSession is not current");
1331             return;
1332         }
1333 
1334         session.onDialogAnimatedIn(startFingerprintNow);
1335     }
1336 
1337     private void handleOnStartFingerprintNow(long requestId) {
1338         Slog.d(TAG, "handleOnStartFingerprintNow");
1339 
1340         final AuthSession session = getAuthSessionIfCurrent(requestId);
1341         if (session == null) {
1342             Slog.w(TAG, "handleOnStartFingerprintNow: AuthSession is not current");
1343             return;
1344         }
1345 
1346         session.onStartFingerprint();
1347     }
1348 
1349     /**
1350      * Invoked when each service has notified that its client is ready to be started. When
1351      * all biometrics are ready, this invokes the SystemUI dialog through StatusBar.
1352      */
1353     private void handleOnReadyForAuthentication(long requestId, int cookie) {
1354         final AuthSession session = getAuthSessionIfCurrent(requestId);
1355         if (session == null) {
1356             // Only should happen if a biometric was locked out when authenticate() was invoked.
1357             // In that case, if device credentials are allowed, the UI is already showing. If not
1358             // allowed, the error has already been returned to the caller.
1359             Slog.w(TAG, "handleOnReadyForAuthentication: AuthSession is not current");
1360             return;
1361         }
1362 
1363         session.onCookieReceived(cookie);
1364     }
1365 
1366     private void handleAuthenticate(IBinder token, long requestId, long operationId, int userId,
1367             IBiometricServiceReceiver receiver, String opPackageName, PromptInfo promptInfo) {
1368         mHandler.post(() -> {
1369             try {
1370                 final PreAuthInfo preAuthInfo = PreAuthInfo.create(mTrustManager,
1371                         mDevicePolicyManager, mSettingObserver, mSensors, userId, promptInfo,
1372                         opPackageName, promptInfo.isDisallowBiometricsIfPolicyExists(),
1373                         getContext(), mBiometricCameraManager);
1374 
1375                 // Set the default title if necessary.
1376                 if (promptInfo.isUseDefaultTitle()) {
1377                     if (TextUtils.isEmpty(promptInfo.getTitle())) {
1378                         promptInfo.setTitle(getContext()
1379                                 .getString(R.string.biometric_dialog_default_title));
1380                     }
1381                 }
1382 
1383                 final int eligible = preAuthInfo.getEligibleModalities();
1384                 final boolean hasEligibleFingerprintSensor =
1385                         (eligible & TYPE_FINGERPRINT) == TYPE_FINGERPRINT;
1386                 final boolean hasEligibleFaceSensor = (eligible & TYPE_FACE) == TYPE_FACE;
1387 
1388                 // Set the subtitle according to the modality.
1389                 if (promptInfo.isUseDefaultSubtitle()) {
1390                     if (hasEligibleFingerprintSensor && hasEligibleFaceSensor) {
1391                         promptInfo.setSubtitle(getContext()
1392                                 .getString(R.string.biometric_dialog_default_subtitle));
1393                     } else if (hasEligibleFingerprintSensor) {
1394                         promptInfo.setSubtitle(getContext()
1395                                 .getString(R.string.fingerprint_dialog_default_subtitle));
1396                     } else if (hasEligibleFaceSensor) {
1397                         promptInfo.setSubtitle(getContext()
1398                                 .getString(R.string.face_dialog_default_subtitle));
1399                     } else {
1400                         promptInfo.setSubtitle(getContext()
1401                                 .getString(R.string.screen_lock_dialog_default_subtitle));
1402                     }
1403                 }
1404 
1405                 final Pair<Integer, Integer> preAuthStatus = preAuthInfo.getPreAuthenticateStatus();
1406 
1407                 Slog.d(TAG, "handleAuthenticate: modality(" + preAuthStatus.first
1408                         + "), status(" + preAuthStatus.second + "), preAuthInfo: " + preAuthInfo
1409                         + " requestId: " + requestId + " promptInfo.isIgnoreEnrollmentState: "
1410                         + promptInfo.isIgnoreEnrollmentState());
1411                 // BIOMETRIC_ERROR_SENSOR_PRIVACY_ENABLED is added so that BiometricPrompt can
1412                 // be shown for this case.
1413                 if (preAuthStatus.second == BiometricConstants.BIOMETRIC_SUCCESS) {
1414                     // If BIOMETRIC_WEAK or BIOMETRIC_STRONG are allowed, but not enrolled, but
1415                     // CREDENTIAL is requested and available, set the bundle to only request
1416                     // CREDENTIAL.
1417                     // TODO: We should clean this up, as well as the interface with SystemUI
1418                     if (preAuthInfo.credentialRequested && preAuthInfo.credentialAvailable
1419                             && preAuthInfo.eligibleSensors.isEmpty()) {
1420                         promptInfo.setAuthenticators(Authenticators.DEVICE_CREDENTIAL);
1421                     }
1422 
1423                     authenticateInternal(token, requestId, operationId, userId, receiver,
1424                             opPackageName, promptInfo, preAuthInfo);
1425                 } else {
1426                     receiver.onError(preAuthStatus.first /* modality */,
1427                             preAuthStatus.second /* errorCode */,
1428                             0 /* vendorCode */);
1429                 }
1430             } catch (RemoteException e) {
1431                 Slog.e(TAG, "Remote exception", e);
1432             }
1433         });
1434     }
1435 
1436     /**
1437      * handleAuthenticate() (above) which is called from BiometricPrompt determines which
1438      * modality/modalities to start authenticating with. authenticateInternal() should only be
1439      * used for preparing <Biometric>Services for authentication when BiometricPrompt#authenticate
1440      * is invoked, shortly after which BiometricPrompt is shown and authentication starts.
1441      *
1442      * Note that this path is NOT invoked when the BiometricPrompt "Try again" button is pressed.
1443      * In that case, see {@link #handleOnTryAgainPressed()}.
1444      */
1445     private void authenticateInternal(IBinder token, long requestId, long operationId, int userId,
1446             IBiometricServiceReceiver receiver, String opPackageName, PromptInfo promptInfo,
1447             PreAuthInfo preAuthInfo) {
1448         Slog.d(TAG, "Creating authSession with authRequest: " + preAuthInfo);
1449 
1450         // No need to dismiss dialog / send error yet if we're continuing authentication, e.g.
1451         // "Try again" is showing due to something like ERROR_TIMEOUT.
1452         if (mAuthSession != null) {
1453             // Forcefully cancel authentication. Dismiss the UI, and immediately send
1454             // ERROR_CANCELED to the client. Note that we should/will ignore HAL ERROR_CANCELED.
1455             // Expect to see some harmless "unknown cookie" errors.
1456             Slog.w(TAG, "Existing AuthSession: " + mAuthSession);
1457             mAuthSession.onCancelAuthSession(true /* force */);
1458             mAuthSession = null;
1459         }
1460 
1461         final boolean debugEnabled = mInjector.isDebugEnabled(getContext(), userId);
1462         mAuthSession = new AuthSession(getContext(), mBiometricContext, mStatusBarService,
1463                 createSysuiReceiver(requestId), mKeyStoreAuthorization, mRandom,
1464                 createClientDeathReceiver(requestId), preAuthInfo, token, requestId,
1465                 operationId, userId, createBiometricSensorReceiver(requestId), receiver,
1466                 opPackageName, promptInfo, debugEnabled,
1467                 mInjector.getFingerprintSensorProperties(getContext()));
1468         try {
1469             mAuthSession.goToInitialState();
1470         } catch (RemoteException e) {
1471             Slog.e(TAG, "RemoteException", e);
1472         }
1473     }
1474 
1475     private void handleCancelAuthentication(long requestId) {
1476         final AuthSession session = getAuthSessionIfCurrent(requestId);
1477         if (session == null) {
1478             Slog.w(TAG, "handleCancelAuthentication: AuthSession is not current");
1479             // TODO: actually cancel the operation?
1480             return;
1481         }
1482 
1483         final boolean finished = session.onCancelAuthSession(false /* force */);
1484         if (finished) {
1485             Slog.d(TAG, "handleCancelAuthentication: AuthSession finished");
1486             mAuthSession = null;
1487         }
1488     }
1489 
1490     @Nullable
1491     private BiometricSensor getSensorForId(int sensorId) {
1492         for (BiometricSensor sensor : mSensors) {
1493             if (sensor.id == sensorId) {
1494                 return sensor;
1495             }
1496         }
1497         return null;
1498     }
1499 
1500     private void dumpInternal(PrintWriter pw) {
1501         pw.println("Legacy Settings: " + mSettingObserver.mUseLegacyFaceOnlySettings);
1502         pw.println();
1503 
1504         pw.println("Sensors:");
1505         for (BiometricSensor sensor : mSensors) {
1506             pw.println(" " + sensor);
1507         }
1508         pw.println();
1509         pw.println("CurrentSession: " + mAuthSession);
1510         pw.println();
1511     }
1512 
1513 }
1514