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