• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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.sensors.fingerprint;
18 
19 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
20 import static android.Manifest.permission.MANAGE_BIOMETRIC;
21 import static android.Manifest.permission.MANAGE_FINGERPRINT;
22 import static android.Manifest.permission.RESET_FINGERPRINT_LOCKOUT;
23 import static android.Manifest.permission.TEST_BIOMETRIC;
24 import static android.Manifest.permission.USE_BIOMETRIC;
25 import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
26 import static android.Manifest.permission.USE_FINGERPRINT;
27 import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
28 import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_VENDOR;
29 import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ERROR_USER_CANCELED;
30 import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ERROR_VENDOR;
31 import static android.hardware.biometrics.SensorProperties.STRENGTH_STRONG;
32 
33 import android.annotation.NonNull;
34 import android.annotation.Nullable;
35 import android.app.AppOpsManager;
36 import android.content.Context;
37 import android.content.pm.PackageManager;
38 import android.content.pm.UserInfo;
39 import android.hardware.biometrics.BiometricManager;
40 import android.hardware.biometrics.BiometricPrompt;
41 import android.hardware.biometrics.BiometricsProtoEnums;
42 import android.hardware.biometrics.IBiometricSensorReceiver;
43 import android.hardware.biometrics.IBiometricService;
44 import android.hardware.biometrics.IBiometricServiceLockoutResetCallback;
45 import android.hardware.biometrics.IBiometricStateListener;
46 import android.hardware.biometrics.IInvalidationCallback;
47 import android.hardware.biometrics.ITestSession;
48 import android.hardware.biometrics.ITestSessionCallback;
49 import android.hardware.biometrics.fingerprint.IFingerprint;
50 import android.hardware.biometrics.fingerprint.SensorProps;
51 import android.hardware.fingerprint.Fingerprint;
52 import android.hardware.fingerprint.FingerprintManager;
53 import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
54 import android.hardware.fingerprint.FingerprintServiceReceiver;
55 import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback;
56 import android.hardware.fingerprint.IFingerprintClientActiveCallback;
57 import android.hardware.fingerprint.IFingerprintService;
58 import android.hardware.fingerprint.IFingerprintServiceReceiver;
59 import android.hardware.fingerprint.ISidefpsController;
60 import android.hardware.fingerprint.IUdfpsOverlayController;
61 import android.os.Binder;
62 import android.os.Build;
63 import android.os.CancellationSignal;
64 import android.os.Handler;
65 import android.os.IBinder;
66 import android.os.Looper;
67 import android.os.Process;
68 import android.os.RemoteCallbackList;
69 import android.os.RemoteException;
70 import android.os.ServiceManager;
71 import android.os.UserHandle;
72 import android.os.UserManager;
73 import android.provider.Settings;
74 import android.util.EventLog;
75 import android.util.Pair;
76 import android.util.Slog;
77 import android.util.proto.ProtoOutputStream;
78 
79 import com.android.internal.R;
80 import com.android.internal.annotations.GuardedBy;
81 import com.android.internal.util.DumpUtils;
82 import com.android.internal.widget.LockPatternUtils;
83 import com.android.server.ServiceThread;
84 import com.android.server.SystemService;
85 import com.android.server.biometrics.Utils;
86 import com.android.server.biometrics.log.BiometricContext;
87 import com.android.server.biometrics.sensors.BiometricStateCallback;
88 import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
89 import com.android.server.biometrics.sensors.LockoutResetDispatcher;
90 import com.android.server.biometrics.sensors.LockoutTracker;
91 import com.android.server.biometrics.sensors.fingerprint.aidl.FingerprintProvider;
92 import com.android.server.biometrics.sensors.fingerprint.hidl.Fingerprint21;
93 import com.android.server.biometrics.sensors.fingerprint.hidl.Fingerprint21UdfpsMock;
94 
95 import java.io.FileDescriptor;
96 import java.io.PrintWriter;
97 import java.util.ArrayList;
98 import java.util.Collections;
99 import java.util.List;
100 import java.util.concurrent.Executor;
101 
102 /**
103  * A service to manage multiple clients that want to access the fingerprint HAL API.
104  * The service is responsible for maintaining a list of clients and dispatching all
105  * fingerprint-related events.
106  */
107 public class FingerprintService extends SystemService {
108 
109     protected static final String TAG = "FingerprintService";
110 
111     private final Object mLock = new Object();
112     private final AppOpsManager mAppOps;
113     private final LockoutResetDispatcher mLockoutResetDispatcher;
114     private final GestureAvailabilityDispatcher mGestureAvailabilityDispatcher;
115     private final LockPatternUtils mLockPatternUtils;
116     private final FingerprintServiceWrapper mServiceWrapper;
117     @NonNull private final List<ServiceProvider> mServiceProviders;
118     @NonNull private final BiometricStateCallback mBiometricStateCallback;
119     @NonNull private final Handler mHandler;
120 
121     @GuardedBy("mLock")
122     @NonNull private final RemoteCallbackList<IFingerprintAuthenticatorsRegisteredCallback>
123             mAuthenticatorsRegisteredCallbacks;
124 
125     @GuardedBy("mLock")
126     @NonNull private final List<FingerprintSensorPropertiesInternal> mSensorProps;
127 
128     /**
129      * Registers BiometricStateListener in list stored by FingerprintService
130      * @param listener new BiometricStateListener being added
131      */
registerBiometricStateListener(@onNull IBiometricStateListener listener)132     public void registerBiometricStateListener(@NonNull IBiometricStateListener listener) {
133         mBiometricStateCallback.registerBiometricStateListener(listener);
134         broadcastCurrentEnrollmentState(listener);
135     }
136 
137     /**
138      * @param listener if non-null, notifies only this listener. if null, notifies all listeners
139      *                 in {@link BiometricStateCallback}. This is slightly ugly, but reduces
140      *                 redundant code.
141      */
broadcastCurrentEnrollmentState(@ullable IBiometricStateListener listener)142     private void broadcastCurrentEnrollmentState(@Nullable IBiometricStateListener listener) {
143         final UserManager um = UserManager.get(getContext());
144         synchronized (mLock) {
145             // Update the new listener with current state of all sensors
146             for (FingerprintSensorPropertiesInternal prop : mSensorProps) {
147                 final ServiceProvider provider = getProviderForSensor(prop.sensorId);
148                 for (UserInfo userInfo : um.getAliveUsers()) {
149                     final boolean enrolled = !provider
150                             .getEnrolledFingerprints(prop.sensorId, userInfo.id).isEmpty();
151 
152                     // Defer this work and allow the loop to release the lock sooner
153                     mHandler.post(() -> {
154                         if (listener != null) {
155                             mBiometricStateCallback.notifyEnrollmentStateChanged(
156                                     listener, userInfo.id, prop.sensorId, enrolled);
157                         } else {
158                             mBiometricStateCallback.notifyAllEnrollmentStateChanged(
159                                     userInfo.id, prop.sensorId, enrolled);
160                         }
161                     });
162                 }
163             }
164         }
165     }
166 
167     /**
168      * Receives the incoming binder calls from FingerprintManager.
169      */
170     private final class FingerprintServiceWrapper extends IFingerprintService.Stub {
171         @Override
createTestSession(int sensorId, @NonNull ITestSessionCallback callback, @NonNull String opPackageName)172         public ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback,
173                 @NonNull String opPackageName) {
174             Utils.checkPermission(getContext(), TEST_BIOMETRIC);
175 
176             final ServiceProvider provider = getProviderForSensor(sensorId);
177 
178             if (provider == null) {
179                 Slog.w(TAG, "Null provider for createTestSession, sensorId: " + sensorId);
180                 return null;
181             }
182 
183             return provider.createTestSession(sensorId, callback, opPackageName);
184         }
185 
186         @Override
dumpSensorServiceStateProto(int sensorId, boolean clearSchedulerBuffer)187         public byte[] dumpSensorServiceStateProto(int sensorId, boolean clearSchedulerBuffer) {
188             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
189 
190             final ProtoOutputStream proto = new ProtoOutputStream();
191             final ServiceProvider provider = getProviderForSensor(sensorId);
192             if (provider != null) {
193                 provider.dumpProtoState(sensorId, proto, clearSchedulerBuffer);
194             }
195             proto.flush();
196             return proto.getBytes();
197         }
198 
199         @Override // Binder call
getSensorPropertiesInternal( @onNull String opPackageName)200         public List<FingerprintSensorPropertiesInternal> getSensorPropertiesInternal(
201                 @NonNull String opPackageName) {
202             if (getContext().checkCallingOrSelfPermission(USE_BIOMETRIC_INTERNAL)
203                     != PackageManager.PERMISSION_GRANTED) {
204                 Utils.checkPermission(getContext(), TEST_BIOMETRIC);
205             }
206 
207             return FingerprintService.this.getSensorProperties();
208         }
209 
210         @Override
getSensorProperties(int sensorId, @NonNull String opPackageName)211         public FingerprintSensorPropertiesInternal getSensorProperties(int sensorId,
212                 @NonNull String opPackageName) {
213             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
214 
215             final ServiceProvider provider = getProviderForSensor(sensorId);
216             if (provider == null) {
217                 Slog.w(TAG, "No matching sensor for getSensorProperties, sensorId: " + sensorId
218                         + ", caller: " + opPackageName);
219                 return null;
220             }
221             return provider.getSensorProperties(sensorId);
222         }
223 
224         @Override // Binder call
generateChallenge(IBinder token, int sensorId, int userId, IFingerprintServiceReceiver receiver, String opPackageName)225         public void generateChallenge(IBinder token, int sensorId, int userId,
226                 IFingerprintServiceReceiver receiver, String opPackageName) {
227             Utils.checkPermission(getContext(), MANAGE_FINGERPRINT);
228 
229             final ServiceProvider provider = getProviderForSensor(sensorId);
230             if (provider == null) {
231                 Slog.w(TAG, "No matching sensor for generateChallenge, sensorId: " + sensorId);
232                 return;
233             }
234 
235             provider.scheduleGenerateChallenge(sensorId, userId, token, receiver, opPackageName);
236         }
237 
238         @Override // Binder call
revokeChallenge(IBinder token, int sensorId, int userId, String opPackageName, long challenge)239         public void revokeChallenge(IBinder token, int sensorId, int userId, String opPackageName,
240                 long challenge) {
241             Utils.checkPermission(getContext(), MANAGE_FINGERPRINT);
242 
243             final ServiceProvider provider = getProviderForSensor(sensorId);
244             if (provider == null) {
245                 Slog.w(TAG, "No matching sensor for revokeChallenge, sensorId: " + sensorId);
246                 return;
247             }
248 
249             provider.scheduleRevokeChallenge(sensorId, userId, token, opPackageName,
250                     challenge);
251         }
252 
253         @Override // Binder call
enroll(final IBinder token, @NonNull final byte[] hardwareAuthToken, final int userId, final IFingerprintServiceReceiver receiver, final String opPackageName, @FingerprintManager.EnrollReason int enrollReason)254         public long enroll(final IBinder token, @NonNull final byte[] hardwareAuthToken,
255                 final int userId, final IFingerprintServiceReceiver receiver,
256                 final String opPackageName, @FingerprintManager.EnrollReason int enrollReason) {
257             Utils.checkPermission(getContext(), MANAGE_FINGERPRINT);
258 
259             final Pair<Integer, ServiceProvider> provider = getSingleProvider();
260             if (provider == null) {
261                 Slog.w(TAG, "Null provider for enroll");
262                 return -1;
263             }
264 
265             return provider.second.scheduleEnroll(provider.first, token, hardwareAuthToken, userId,
266                     receiver, opPackageName, enrollReason);
267         }
268 
269         @Override // Binder call
cancelEnrollment(final IBinder token, long requestId)270         public void cancelEnrollment(final IBinder token, long requestId) {
271             Utils.checkPermission(getContext(), MANAGE_FINGERPRINT);
272 
273             final Pair<Integer, ServiceProvider> provider = getSingleProvider();
274             if (provider == null) {
275                 Slog.w(TAG, "Null provider for cancelEnrollment");
276                 return;
277             }
278 
279             provider.second.cancelEnrollment(provider.first, token, requestId);
280         }
281 
282         @SuppressWarnings("deprecation")
283         @Override // Binder call
authenticate( final IBinder token, final long operationId, final int sensorId, final int userId, final IFingerprintServiceReceiver receiver, final String opPackageName, final String attributionTag, boolean ignoreEnrollmentState)284         public long authenticate(
285                 final IBinder token,
286                 final long operationId,
287                 final int sensorId,
288                 final int userId,
289                 final IFingerprintServiceReceiver receiver,
290                 final String opPackageName,
291                 final String attributionTag,
292                 boolean ignoreEnrollmentState) {
293             final int callingUid = Binder.getCallingUid();
294             final int callingPid = Binder.getCallingPid();
295             final int callingUserId = UserHandle.getCallingUserId();
296 
297             if (!canUseFingerprint(
298                     opPackageName,
299                     attributionTag,
300                     true /* requireForeground */,
301                     callingUid,
302                     callingPid,
303                     callingUserId)) {
304                 Slog.w(TAG, "Authenticate rejecting package: " + opPackageName);
305                 return -1;
306             }
307 
308             // Keyguard check must be done on the caller's binder identity, since it also checks
309             // permission.
310             final boolean isKeyguard = Utils.isKeyguard(getContext(), opPackageName);
311 
312             // Clear calling identity when checking LockPatternUtils for StrongAuth flags.
313             final long identity1 = Binder.clearCallingIdentity();
314             try {
315                 if (isKeyguard && Utils.isUserEncryptedOrLockdown(mLockPatternUtils, userId)) {
316                     // If this happens, something in KeyguardUpdateMonitor is wrong.
317                     // SafetyNet for b/79776455
318                     EventLog.writeEvent(0x534e4554, "79776455");
319                     Slog.e(TAG, "Authenticate invoked when user is encrypted or lockdown");
320                     return -1;
321                 }
322             } finally {
323                 Binder.restoreCallingIdentity(identity1);
324             }
325 
326             final boolean restricted = getContext().checkCallingPermission(MANAGE_FINGERPRINT)
327                     != PackageManager.PERMISSION_GRANTED;
328             final int statsClient = isKeyguard ? BiometricsProtoEnums.CLIENT_KEYGUARD
329                     : BiometricsProtoEnums.CLIENT_FINGERPRINT_MANAGER;
330 
331             final Pair<Integer, ServiceProvider> provider;
332             if (sensorId == FingerprintManager.SENSOR_ID_ANY) {
333                 provider = getSingleProvider();
334             } else {
335                 Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
336                 provider = new Pair<>(sensorId, getProviderForSensor(sensorId));
337             }
338             if (provider == null) {
339                 Slog.w(TAG, "Null provider for authenticate");
340                 return -1;
341             }
342 
343             final FingerprintSensorPropertiesInternal sensorProps =
344                     provider.second.getSensorProperties(sensorId);
345             if (!isKeyguard && !Utils.isSettings(getContext(), opPackageName)
346                     && sensorProps != null && (sensorProps.isAnyUdfpsType()
347                     || sensorProps.isAnySidefpsType())) {
348                 try {
349                     return authenticateWithPrompt(operationId, sensorProps, callingUid,
350                             callingUserId, receiver, opPackageName, ignoreEnrollmentState);
351                 } catch (PackageManager.NameNotFoundException e) {
352                     Slog.e(TAG, "Invalid package", e);
353                     return -1;
354                 }
355             }
356             return provider.second.scheduleAuthenticate(provider.first, token, operationId, userId,
357                     0 /* cookie */, new ClientMonitorCallbackConverter(receiver), opPackageName,
358                     restricted, statsClient, isKeyguard);
359         }
360 
authenticateWithPrompt( final long operationId, @NonNull final FingerprintSensorPropertiesInternal props, final int uId, final int userId, final IFingerprintServiceReceiver receiver, final String opPackageName, boolean ignoreEnrollmentState)361         private long authenticateWithPrompt(
362                 final long operationId,
363                 @NonNull final FingerprintSensorPropertiesInternal props,
364                 final int uId,
365                 final int userId,
366                 final IFingerprintServiceReceiver receiver,
367                 final String opPackageName,
368                 boolean ignoreEnrollmentState) throws PackageManager.NameNotFoundException {
369 
370             final Context context = getUiContext();
371             final Context promptContext = context.createPackageContextAsUser(
372                     opPackageName, 0 /* flags */, UserHandle.getUserHandleForUid(uId));
373             final Executor executor = context.getMainExecutor();
374 
375             final BiometricPrompt biometricPrompt = new BiometricPrompt.Builder(promptContext)
376                     .setTitle(context.getString(R.string.biometric_dialog_default_title))
377                     .setSubtitle(context.getString(R.string.fingerprint_dialog_default_subtitle))
378                     .setNegativeButton(
379                             context.getString(R.string.cancel),
380                             executor,
381                             (dialog, which) -> {
382                                 try {
383                                     receiver.onError(
384                                             FINGERPRINT_ERROR_USER_CANCELED, 0 /* vendorCode */);
385                                 } catch (RemoteException e) {
386                                     Slog.e(TAG, "Remote exception in negative button onClick()", e);
387                                 }
388                             })
389                     .setIsForLegacyFingerprintManager(props.sensorId)
390                     .setIgnoreEnrollmentState(ignoreEnrollmentState)
391                     .build();
392 
393             final BiometricPrompt.AuthenticationCallback promptCallback =
394                     new BiometricPrompt.AuthenticationCallback() {
395                         @Override
396                         public void onAuthenticationError(int errorCode, CharSequence errString) {
397                             try {
398                                 if (FingerprintUtils.isKnownErrorCode(errorCode)) {
399                                     receiver.onError(errorCode, 0 /* vendorCode */);
400                                 } else {
401                                     receiver.onError(FINGERPRINT_ERROR_VENDOR, errorCode);
402                                 }
403                             } catch (RemoteException e) {
404                                 Slog.e(TAG, "Remote exception in onAuthenticationError()", e);
405                             }
406                         }
407 
408                         @Override
409                         public void onAuthenticationSucceeded(
410                                 BiometricPrompt.AuthenticationResult result) {
411                             final Fingerprint fingerprint = new Fingerprint("", 0, 0L);
412                             final boolean isStrong = props.sensorStrength == STRENGTH_STRONG;
413                             try {
414                                 receiver.onAuthenticationSucceeded(fingerprint, userId, isStrong);
415                             } catch (RemoteException e) {
416                                 Slog.e(TAG, "Remote exception in onAuthenticationSucceeded()", e);
417                             }
418                         }
419 
420                         @Override
421                         public void onAuthenticationFailed() {
422                             try {
423                                 receiver.onAuthenticationFailed();
424                             } catch (RemoteException e) {
425                                 Slog.e(TAG, "Remote exception in onAuthenticationFailed()", e);
426                             }
427                         }
428 
429                         @Override
430                         public void onAuthenticationAcquired(int acquireInfo) {
431                             try {
432                                 if (FingerprintUtils.isKnownAcquiredCode(acquireInfo)) {
433                                     receiver.onAcquired(acquireInfo, 0 /* vendorCode */);
434                                 } else {
435                                     receiver.onAcquired(FINGERPRINT_ACQUIRED_VENDOR, acquireInfo);
436                                 }
437                             } catch (RemoteException e) {
438                                 Slog.e(TAG, "Remote exception in onAuthenticationAcquired()", e);
439                             }
440                         }
441                     };
442 
443             return biometricPrompt.authenticateForOperation(
444                     new CancellationSignal(), executor, promptCallback, operationId);
445         }
446 
447         @Override
detectFingerprint(final IBinder token, final int userId, final IFingerprintServiceReceiver receiver, final String opPackageName)448         public long detectFingerprint(final IBinder token, final int userId,
449                 final IFingerprintServiceReceiver receiver, final String opPackageName) {
450             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
451             if (!Utils.isKeyguard(getContext(), opPackageName)) {
452                 Slog.w(TAG, "detectFingerprint called from non-sysui package: " + opPackageName);
453                 return -1;
454             }
455 
456             final Pair<Integer, ServiceProvider> provider = getSingleProvider();
457             if (provider == null) {
458                 Slog.w(TAG, "Null provider for detectFingerprint");
459                 return -1;
460             }
461 
462             return provider.second.scheduleFingerDetect(provider.first, token, userId,
463                     new ClientMonitorCallbackConverter(receiver), opPackageName,
464                     BiometricsProtoEnums.CLIENT_KEYGUARD);
465         }
466 
467         @Override // Binder call
prepareForAuthentication(int sensorId, IBinder token, long operationId, int userId, IBiometricSensorReceiver sensorReceiver, String opPackageName, long requestId, int cookie, boolean allowBackgroundAuthentication)468         public void prepareForAuthentication(int sensorId, IBinder token, long operationId,
469                 int userId, IBiometricSensorReceiver sensorReceiver, String opPackageName,
470                 long requestId, int cookie, boolean allowBackgroundAuthentication) {
471             Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
472 
473             final ServiceProvider provider = getProviderForSensor(sensorId);
474             if (provider == null) {
475                 Slog.w(TAG, "Null provider for prepareForAuthentication");
476                 return;
477             }
478 
479             final boolean restricted = true; // BiometricPrompt is always restricted
480             provider.scheduleAuthenticate(sensorId, token, operationId, userId, cookie,
481                     new ClientMonitorCallbackConverter(sensorReceiver), opPackageName, requestId,
482                     restricted, BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT,
483                     allowBackgroundAuthentication);
484         }
485 
486         @Override // Binder call
startPreparedClient(int sensorId, int cookie)487         public void startPreparedClient(int sensorId, int cookie) {
488             Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
489 
490             final ServiceProvider provider = getProviderForSensor(sensorId);
491             if (provider == null) {
492                 Slog.w(TAG, "Null provider for startPreparedClient");
493                 return;
494             }
495 
496             provider.startPreparedClient(sensorId, cookie);
497         }
498 
499         @Override // Binder call
cancelAuthentication( final IBinder token, final String opPackageName, final String attributionTag, long requestId)500         public void cancelAuthentication(
501                 final IBinder token,
502                 final String opPackageName,
503                 final String attributionTag,
504                 long requestId) {
505             final int callingUid = Binder.getCallingUid();
506             final int callingPid = Binder.getCallingPid();
507             final int callingUserId = UserHandle.getCallingUserId();
508 
509             if (!canUseFingerprint(
510                     opPackageName,
511                     attributionTag,
512                     true /* requireForeground */,
513                     callingUid,
514                     callingPid,
515                     callingUserId)) {
516                 Slog.w(TAG, "cancelAuthentication rejecting package: " + opPackageName);
517                 return;
518             }
519 
520             final Pair<Integer, ServiceProvider> provider = getSingleProvider();
521             if (provider == null) {
522                 Slog.w(TAG, "Null provider for cancelAuthentication");
523                 return;
524             }
525 
526             provider.second.cancelAuthentication(provider.first, token, requestId);
527         }
528 
529         @Override // Binder call
cancelFingerprintDetect(final IBinder token, final String opPackageName, final long requestId)530         public void cancelFingerprintDetect(final IBinder token, final String opPackageName,
531                 final long requestId) {
532             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
533             if (!Utils.isKeyguard(getContext(), opPackageName)) {
534                 Slog.w(TAG, "cancelFingerprintDetect called from non-sysui package: "
535                         + opPackageName);
536                 return;
537             }
538 
539             // For IBiometricsFingerprint2.1, cancelling fingerprint detect is the same as
540             // cancelling authentication.
541             final Pair<Integer, ServiceProvider> provider = getSingleProvider();
542             if (provider == null) {
543                 Slog.w(TAG, "Null provider for cancelFingerprintDetect");
544                 return;
545             }
546 
547             provider.second.cancelAuthentication(provider.first, token, requestId);
548         }
549 
550         @Override // Binder call
cancelAuthenticationFromService(final int sensorId, final IBinder token, final String opPackageName, final long requestId)551         public void cancelAuthenticationFromService(final int sensorId, final IBinder token,
552                 final String opPackageName, final long requestId) {
553 
554             Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
555 
556             Slog.d(TAG, "cancelAuthenticationFromService, sensorId: " + sensorId);
557 
558             final ServiceProvider provider = getProviderForSensor(sensorId);
559             if (provider == null) {
560                 Slog.w(TAG, "Null provider for cancelAuthenticationFromService");
561                 return;
562             }
563 
564             provider.cancelAuthentication(sensorId, token, requestId);
565         }
566 
567         @Override // Binder call
remove(final IBinder token, final int fingerId, final int userId, final IFingerprintServiceReceiver receiver, final String opPackageName)568         public void remove(final IBinder token, final int fingerId, final int userId,
569                 final IFingerprintServiceReceiver receiver, final String opPackageName) {
570             Utils.checkPermission(getContext(), MANAGE_FINGERPRINT);
571 
572             final Pair<Integer, ServiceProvider> provider = getSingleProvider();
573             if (provider == null) {
574                 Slog.w(TAG, "Null provider for remove");
575                 return;
576             }
577             provider.second.scheduleRemove(provider.first, token, receiver, fingerId, userId,
578                     opPackageName);
579         }
580 
581         @Override // Binder call
removeAll(final IBinder token, final int userId, final IFingerprintServiceReceiver receiver, final String opPackageName)582         public void removeAll(final IBinder token, final int userId,
583                 final IFingerprintServiceReceiver receiver, final String opPackageName) {
584             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
585 
586             final FingerprintServiceReceiver internalReceiver = new FingerprintServiceReceiver() {
587                 int sensorsFinishedRemoving = 0;
588                 final int numSensors = getSensorPropertiesInternal(
589                         getContext().getOpPackageName()).size();
590                 @Override
591                 public void onRemoved(Fingerprint fp, int remaining) throws RemoteException {
592                     if (remaining == 0) {
593                         sensorsFinishedRemoving++;
594                         Slog.d(TAG, "sensorsFinishedRemoving: " + sensorsFinishedRemoving
595                                 + ", numSensors: " + numSensors);
596                         if (sensorsFinishedRemoving == numSensors) {
597                             receiver.onRemoved(null, 0 /* remaining */);
598                         }
599                     }
600                 }
601             };
602 
603             // This effectively iterates through all sensors, but has to do so by finding all
604             // sensors under each provider.
605             for (ServiceProvider provider : mServiceProviders) {
606                 List<FingerprintSensorPropertiesInternal> props = provider.getSensorProperties();
607                 for (FingerprintSensorPropertiesInternal prop : props) {
608                     provider.scheduleRemoveAll(prop.sensorId, token, internalReceiver, userId,
609                             opPackageName);
610                 }
611             }
612         }
613 
614         @Override // Binder call
addLockoutResetCallback(final IBiometricServiceLockoutResetCallback callback, final String opPackageName)615         public void addLockoutResetCallback(final IBiometricServiceLockoutResetCallback callback,
616                 final String opPackageName) {
617             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
618             mLockoutResetDispatcher.addCallback(callback, opPackageName);
619         }
620 
621         @Override // Binder call
dump(@onNull FileDescriptor fd, @NonNull PrintWriter pw, String[] args)622         protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, String[] args) {
623             if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) {
624                 return;
625             }
626 
627             final long ident = Binder.clearCallingIdentity();
628             try {
629                 if (args.length > 1 && "--proto".equals(args[0]) && "--state".equals(args[1])) {
630                     final ProtoOutputStream proto = new ProtoOutputStream(fd);
631                     for (ServiceProvider provider : mServiceProviders) {
632                         for (FingerprintSensorPropertiesInternal props
633                                 : provider.getSensorProperties()) {
634                             provider.dumpProtoState(props.sensorId, proto, false);
635                         }
636                     }
637                     proto.flush();
638                 } else if (args.length > 0 && "--proto".equals(args[0])) {
639                     for (ServiceProvider provider : mServiceProviders) {
640                         for (FingerprintSensorPropertiesInternal props
641                                 : provider.getSensorProperties()) {
642                             provider.dumpProtoMetrics(props.sensorId, fd);
643                         }
644                     }
645                 } else {
646                     for (ServiceProvider provider : mServiceProviders) {
647                         for (FingerprintSensorPropertiesInternal props
648                                 : provider.getSensorProperties()) {
649                             pw.println("Dumping for sensorId: " + props.sensorId
650                                     + ", provider: " + provider.getClass().getSimpleName());
651                             pw.println("Fps state: "
652                                     + mBiometricStateCallback.getBiometricState());
653                             provider.dumpInternal(props.sensorId, pw);
654                             pw.println();
655                         }
656                     }
657                 }
658             } finally {
659                 Binder.restoreCallingIdentity(ident);
660             }
661         }
662 
663         @Override // Binder call
isHardwareDetectedDeprecated(String opPackageName, String attributionTag)664         public boolean isHardwareDetectedDeprecated(String opPackageName, String attributionTag) {
665             if (!canUseFingerprint(
666                     opPackageName,
667                     attributionTag,
668                     false /* foregroundOnly */,
669                     Binder.getCallingUid(),
670                     Binder.getCallingPid(),
671                     UserHandle.getCallingUserId())) {
672                 return false;
673             }
674 
675             final long token = Binder.clearCallingIdentity();
676             try {
677                 final Pair<Integer, ServiceProvider> provider = getSingleProvider();
678                 if (provider == null) {
679                     Slog.w(TAG, "Null provider for isHardwareDetectedDeprecated, caller: "
680                             + opPackageName);
681                     return false;
682                 }
683                 return provider.second.isHardwareDetected(provider.first);
684             } finally {
685                 Binder.restoreCallingIdentity(token);
686             }
687         }
688 
689         @Override // Binder call
isHardwareDetected(int sensorId, String opPackageName)690         public boolean isHardwareDetected(int sensorId, String opPackageName) {
691             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
692 
693             final ServiceProvider provider = getProviderForSensor(sensorId);
694             if (provider == null) {
695                 Slog.w(TAG, "Null provider for isHardwareDetected, caller: " + opPackageName);
696                 return false;
697             }
698 
699             return provider.isHardwareDetected(sensorId);
700         }
701 
702         @Override // Binder call
rename(final int fingerId, final int userId, final String name)703         public void rename(final int fingerId, final int userId, final String name) {
704             Utils.checkPermission(getContext(), MANAGE_FINGERPRINT);
705             if (!Utils.isCurrentUserOrProfile(getContext(), userId)) {
706                 return;
707             }
708 
709             final Pair<Integer, ServiceProvider> provider = getSingleProvider();
710             if (provider == null) {
711                 Slog.w(TAG, "Null provider for rename");
712                 return;
713             }
714 
715             provider.second.rename(provider.first, fingerId, userId, name);
716         }
717 
718         @Override // Binder call
getEnrolledFingerprints( int userId, String opPackageName, String attributionTag)719         public List<Fingerprint> getEnrolledFingerprints(
720                 int userId, String opPackageName, String attributionTag) {
721             if (!canUseFingerprint(
722                     opPackageName,
723                     attributionTag,
724                     false /* foregroundOnly */,
725                     Binder.getCallingUid(),
726                     Binder.getCallingPid(),
727                     UserHandle.getCallingUserId())) {
728                 return Collections.emptyList();
729             }
730 
731             if (userId != UserHandle.getCallingUserId()) {
732                 Utils.checkPermission(getContext(), INTERACT_ACROSS_USERS);
733             }
734 
735             return FingerprintService.this.getEnrolledFingerprintsDeprecated(userId, opPackageName);
736         }
737 
738         @Override // Binder call
hasEnrolledFingerprintsDeprecated( int userId, String opPackageName, String attributionTag)739         public boolean hasEnrolledFingerprintsDeprecated(
740                 int userId, String opPackageName, String attributionTag) {
741             if (!canUseFingerprint(
742                     opPackageName,
743                     attributionTag,
744                     false /* foregroundOnly */,
745                     Binder.getCallingUid(),
746                     Binder.getCallingPid(),
747                     UserHandle.getCallingUserId())) {
748                 return false;
749             }
750 
751             if (userId != UserHandle.getCallingUserId()) {
752                 Utils.checkPermission(getContext(), INTERACT_ACROSS_USERS);
753             }
754             return !FingerprintService.this.getEnrolledFingerprintsDeprecated(userId, opPackageName)
755                     .isEmpty();
756         }
757 
hasEnrolledFingerprints(int sensorId, int userId, String opPackageName)758         public boolean hasEnrolledFingerprints(int sensorId, int userId, String opPackageName) {
759             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
760 
761             final ServiceProvider provider = getProviderForSensor(sensorId);
762             if (provider == null) {
763                 Slog.w(TAG, "Null provider for hasEnrolledFingerprints, caller: " + opPackageName);
764                 return false;
765             }
766 
767             return provider.getEnrolledFingerprints(sensorId, userId).size() > 0;
768         }
769 
770         @Override // Binder call
getLockoutModeForUser(int sensorId, int userId)771         public @LockoutTracker.LockoutMode int getLockoutModeForUser(int sensorId, int userId) {
772             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
773 
774             final ServiceProvider provider = getProviderForSensor(sensorId);
775             if (provider == null) {
776                 Slog.w(TAG, "Null provider for getLockoutModeForUser");
777                 return LockoutTracker.LOCKOUT_NONE;
778             }
779             return provider.getLockoutModeForUser(sensorId, userId);
780         }
781 
782         @Override
invalidateAuthenticatorId(int sensorId, int userId, IInvalidationCallback callback)783         public void invalidateAuthenticatorId(int sensorId, int userId,
784                 IInvalidationCallback callback) {
785             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
786 
787             final ServiceProvider provider = getProviderForSensor(sensorId);
788             if (provider == null) {
789                 Slog.w(TAG, "Null provider for invalidateAuthenticatorId");
790                 return;
791             }
792             provider.scheduleInvalidateAuthenticatorId(sensorId, userId, callback);
793         }
794 
795         @Override // Binder call
getAuthenticatorId(int sensorId, int userId)796         public long getAuthenticatorId(int sensorId, int userId) {
797             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
798 
799             final ServiceProvider provider = getProviderForSensor(sensorId);
800             if (provider == null) {
801                 Slog.w(TAG, "Null provider for getAuthenticatorId");
802                 return 0;
803             }
804             return provider.getAuthenticatorId(sensorId, userId);
805         }
806 
807         @Override // Binder call
resetLockout(IBinder token, int sensorId, int userId, @Nullable byte[] hardwareAuthToken, String opPackageName)808         public void resetLockout(IBinder token, int sensorId, int userId,
809                 @Nullable byte[] hardwareAuthToken, String opPackageName) {
810             Utils.checkPermission(getContext(), RESET_FINGERPRINT_LOCKOUT);
811 
812             final ServiceProvider provider = getProviderForSensor(sensorId);
813             if (provider == null) {
814                 Slog.w(TAG, "Null provider for resetLockout, caller: " + opPackageName);
815                 return;
816             }
817 
818             provider.scheduleResetLockout(sensorId, userId, hardwareAuthToken);
819         }
820 
821         @Override
isClientActive()822         public boolean isClientActive() {
823             Utils.checkPermission(getContext(), MANAGE_FINGERPRINT);
824             return mGestureAvailabilityDispatcher.isAnySensorActive();
825         }
826 
827         @Override
addClientActiveCallback(IFingerprintClientActiveCallback callback)828         public void addClientActiveCallback(IFingerprintClientActiveCallback callback) {
829             Utils.checkPermission(getContext(), MANAGE_FINGERPRINT);
830             mGestureAvailabilityDispatcher.registerCallback(callback);
831         }
832 
833         @Override
removeClientActiveCallback(IFingerprintClientActiveCallback callback)834         public void removeClientActiveCallback(IFingerprintClientActiveCallback callback) {
835             Utils.checkPermission(getContext(), MANAGE_FINGERPRINT);
836             mGestureAvailabilityDispatcher.removeCallback(callback);
837         }
838 
addHidlProviders(List<FingerprintSensorPropertiesInternal> hidlSensors)839         private void addHidlProviders(List<FingerprintSensorPropertiesInternal> hidlSensors) {
840             for (FingerprintSensorPropertiesInternal hidlSensor : hidlSensors) {
841                 final Fingerprint21 fingerprint21;
842                 if ((Build.IS_USERDEBUG || Build.IS_ENG)
843                         && getContext().getResources().getBoolean(R.bool.allow_test_udfps)
844                         && Settings.Secure.getIntForUser(getContext().getContentResolver(),
845                         Fingerprint21UdfpsMock.CONFIG_ENABLE_TEST_UDFPS, 0 /* default */,
846                         UserHandle.USER_CURRENT) != 0) {
847                     fingerprint21 = Fingerprint21UdfpsMock.newInstance(getContext(),
848                             mBiometricStateCallback, hidlSensor,
849                             mLockoutResetDispatcher, mGestureAvailabilityDispatcher,
850                             BiometricContext.getInstance(getContext()));
851                 } else {
852                     fingerprint21 = Fingerprint21.newInstance(getContext(),
853                             mBiometricStateCallback, hidlSensor, mHandler,
854                             mLockoutResetDispatcher, mGestureAvailabilityDispatcher);
855                 }
856                 mServiceProviders.add(fingerprint21);
857             }
858         }
859 
addAidlProviders()860         private void addAidlProviders() {
861             final String[] instances = ServiceManager.getDeclaredInstances(IFingerprint.DESCRIPTOR);
862             if (instances == null || instances.length == 0) {
863                 return;
864             }
865             for (String instance : instances) {
866                 final String fqName = IFingerprint.DESCRIPTOR + "/" + instance;
867                 final IFingerprint fp = IFingerprint.Stub.asInterface(
868                         Binder.allowBlocking(ServiceManager.waitForDeclaredService(fqName)));
869                 if (fp == null) {
870                     Slog.e(TAG, "Unable to get declared service: " + fqName);
871                     continue;
872                 }
873                 try {
874                     final SensorProps[] props = fp.getSensorProps();
875                     final FingerprintProvider provider =
876                             new FingerprintProvider(getContext(), mBiometricStateCallback, props,
877                                     instance, mLockoutResetDispatcher,
878                                     mGestureAvailabilityDispatcher,
879                                     BiometricContext.getInstance(getContext()));
880                     mServiceProviders.add(provider);
881                 } catch (RemoteException e) {
882                     Slog.e(TAG, "Remote exception in getSensorProps: " + fqName);
883                 }
884             }
885         }
886 
887         @Override // Binder call
registerAuthenticators( @onNull List<FingerprintSensorPropertiesInternal> hidlSensors)888         public void registerAuthenticators(
889                 @NonNull List<FingerprintSensorPropertiesInternal> hidlSensors) {
890             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
891 
892             // Some HAL might not be started before the system service and will cause the code below
893             // to wait, and some of the operations below might take a significant amount of time to
894             // complete (calls to the HALs). To avoid blocking the rest of system server we put
895             // this on a background thread.
896             final ServiceThread thread = new ServiceThread(TAG, Process.THREAD_PRIORITY_BACKGROUND,
897                     true /* allowIo */);
898             thread.start();
899             final Handler handler = new Handler(thread.getLooper());
900 
901             handler.post(() -> {
902                 addHidlProviders(hidlSensors);
903                 addAidlProviders();
904 
905                 final IBiometricService biometricService = IBiometricService.Stub.asInterface(
906                         ServiceManager.getService(Context.BIOMETRIC_SERVICE));
907 
908                 // Register each sensor individually with BiometricService
909                 for (ServiceProvider provider : mServiceProviders) {
910                     final List<FingerprintSensorPropertiesInternal> props =
911                             provider.getSensorProperties();
912                     for (FingerprintSensorPropertiesInternal prop : props) {
913                         final int sensorId = prop.sensorId;
914                         final @BiometricManager.Authenticators.Types int strength =
915                                 Utils.propertyStrengthToAuthenticatorStrength(prop.sensorStrength);
916                         final FingerprintAuthenticator authenticator = new FingerprintAuthenticator(
917                                 mServiceWrapper, sensorId);
918                         try {
919                             biometricService.registerAuthenticator(sensorId, TYPE_FINGERPRINT,
920                                     strength, authenticator);
921                         } catch (RemoteException e) {
922                             Slog.e(TAG, "Remote exception when registering sensorId: " + sensorId);
923                         }
924                     }
925                 }
926 
927                 synchronized (mLock) {
928                     for (ServiceProvider provider : mServiceProviders) {
929                         mSensorProps.addAll(provider.getSensorProperties());
930                     }
931                 }
932 
933                 broadcastCurrentEnrollmentState(null); // broadcasts to all listeners
934                 broadcastAllAuthenticatorsRegistered();
935             });
936         }
937 
938         @Override
addAuthenticatorsRegisteredCallback( IFingerprintAuthenticatorsRegisteredCallback callback)939         public void addAuthenticatorsRegisteredCallback(
940                 IFingerprintAuthenticatorsRegisteredCallback callback) {
941             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
942             if (callback == null) {
943                 Slog.e(TAG, "addAuthenticatorsRegisteredCallback, callback is null");
944                 return;
945             }
946 
947             final boolean registered;
948             final boolean hasSensorProps;
949             synchronized (mLock) {
950                 registered = mAuthenticatorsRegisteredCallbacks.register(callback);
951                 hasSensorProps = !mSensorProps.isEmpty();
952             }
953             if (registered && hasSensorProps) {
954                 broadcastAllAuthenticatorsRegistered();
955             } else if (!registered) {
956                 Slog.e(TAG, "addAuthenticatorsRegisteredCallback failed to register callback");
957             }
958         }
959 
960         @Override
onPointerDown(long requestId, int sensorId, int x, int y, float minor, float major)961         public void onPointerDown(long requestId, int sensorId, int x, int y,
962                 float minor, float major) {
963             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
964 
965             final ServiceProvider provider = getProviderForSensor(sensorId);
966             if (provider == null) {
967                 Slog.w(TAG, "No matching provider for onFingerDown, sensorId: " + sensorId);
968                 return;
969             }
970             provider.onPointerDown(requestId, sensorId, x, y, minor, major);
971         }
972 
973         @Override
onPointerUp(long requestId, int sensorId)974         public void onPointerUp(long requestId, int sensorId) {
975             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
976 
977             final ServiceProvider provider = getProviderForSensor(sensorId);
978             if (provider == null) {
979                 Slog.w(TAG, "No matching provider for onFingerUp, sensorId: " + sensorId);
980                 return;
981             }
982             provider.onPointerUp(requestId, sensorId);
983         }
984 
985         @Override
onUiReady(long requestId, int sensorId)986         public void onUiReady(long requestId, int sensorId) {
987             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
988 
989             final ServiceProvider provider = getProviderForSensor(sensorId);
990             if (provider == null) {
991                 Slog.w(TAG, "No matching provider for onUiReady, sensorId: " + sensorId);
992                 return;
993             }
994             provider.onUiReady(requestId, sensorId);
995         }
996 
997         @Override
setUdfpsOverlayController(@onNull IUdfpsOverlayController controller)998         public void setUdfpsOverlayController(@NonNull IUdfpsOverlayController controller) {
999             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
1000 
1001             for (ServiceProvider provider : mServiceProviders) {
1002                 provider.setUdfpsOverlayController(controller);
1003             }
1004         }
1005 
1006         @Override
setSidefpsController(@onNull ISidefpsController controller)1007         public void setSidefpsController(@NonNull ISidefpsController controller) {
1008             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
1009 
1010             for (ServiceProvider provider : mServiceProviders) {
1011                 provider.setSidefpsController(controller);
1012             }
1013         }
1014 
1015         @Override
registerBiometricStateListener(@onNull IBiometricStateListener listener)1016         public void registerBiometricStateListener(@NonNull IBiometricStateListener listener) {
1017             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
1018             FingerprintService.this.registerBiometricStateListener(listener);
1019         }
1020 
1021         @Override
onPowerPressed()1022         public void onPowerPressed() {
1023             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
1024             for (ServiceProvider provider : mServiceProviders) {
1025                 provider.onPowerPressed();
1026             }
1027         }
1028     };
1029 
FingerprintService(Context context)1030     public FingerprintService(Context context) {
1031         super(context);
1032         mServiceWrapper = new FingerprintServiceWrapper();
1033         mAppOps = context.getSystemService(AppOpsManager.class);
1034         mGestureAvailabilityDispatcher = new GestureAvailabilityDispatcher();
1035         mLockoutResetDispatcher = new LockoutResetDispatcher(context);
1036         mLockPatternUtils = new LockPatternUtils(context);
1037         mServiceProviders = new ArrayList<>();
1038         mBiometricStateCallback = new BiometricStateCallback();
1039         mAuthenticatorsRegisteredCallbacks = new RemoteCallbackList<>();
1040         mSensorProps = new ArrayList<>();
1041         mHandler = new Handler(Looper.getMainLooper());
1042     }
1043 
1044     // Notifies the callbacks that all of the authenticators have been registered and removes the
1045     // invoked callbacks from the callback list.
broadcastAllAuthenticatorsRegistered()1046     private void broadcastAllAuthenticatorsRegistered() {
1047         // Make a local copy of the data so it can be used outside of the synchronized block when
1048         // making Binder calls.
1049         final List<IFingerprintAuthenticatorsRegisteredCallback> callbacks = new ArrayList<>();
1050         final List<FingerprintSensorPropertiesInternal> props;
1051         synchronized (mLock) {
1052             if (!mSensorProps.isEmpty()) {
1053                 props = new ArrayList<>(mSensorProps);
1054             } else {
1055                 Slog.e(TAG, "mSensorProps is empty");
1056                 return;
1057             }
1058             final int n = mAuthenticatorsRegisteredCallbacks.beginBroadcast();
1059             for (int i = 0; i < n; ++i) {
1060                 final IFingerprintAuthenticatorsRegisteredCallback cb =
1061                         mAuthenticatorsRegisteredCallbacks.getBroadcastItem(i);
1062                 callbacks.add(cb);
1063                 mAuthenticatorsRegisteredCallbacks.unregister(cb);
1064             }
1065             mAuthenticatorsRegisteredCallbacks.finishBroadcast();
1066         }
1067         for (IFingerprintAuthenticatorsRegisteredCallback cb : callbacks) {
1068             try {
1069                 cb.onAllAuthenticatorsRegistered(props);
1070             } catch (RemoteException e) {
1071                 Slog.e(TAG, "Remote exception in onAllAuthenticatorsRegistered", e);
1072             }
1073         }
1074     }
1075 
1076     @Override
onStart()1077     public void onStart() {
1078         publishBinderService(Context.FINGERPRINT_SERVICE, mServiceWrapper);
1079     }
1080 
1081     @Nullable
getProviderForSensor(int sensorId)1082     private ServiceProvider getProviderForSensor(int sensorId) {
1083         for (ServiceProvider provider : mServiceProviders) {
1084             if (provider.containsSensor(sensorId)) {
1085                 return provider;
1086             }
1087         }
1088         return null;
1089     }
1090 
1091     /**
1092      * For devices with only a single provider, returns that provider. If multiple providers,
1093      * returns the first one. If no providers, returns null.
1094      */
1095     @Nullable
getSingleProvider()1096     private Pair<Integer, ServiceProvider> getSingleProvider() {
1097         final List<FingerprintSensorPropertiesInternal> properties = getSensorProperties();
1098         if (properties.isEmpty()) {
1099             Slog.e(TAG, "No providers found");
1100             return null;
1101         }
1102 
1103         // Theoretically we can just return the first provider, but maybe this is easier to
1104         // understand.
1105         final int sensorId = properties.get(0).sensorId;
1106         for (ServiceProvider provider : mServiceProviders) {
1107             if (provider.containsSensor(sensorId)) {
1108                 return new Pair<>(sensorId, provider);
1109             }
1110         }
1111 
1112         Slog.e(TAG, "Provider not found");
1113         return null;
1114     }
1115 
1116     @NonNull
getSensorProperties()1117     private List<FingerprintSensorPropertiesInternal> getSensorProperties() {
1118         synchronized (mLock) {
1119             return mSensorProps;
1120         }
1121     }
1122 
1123     @NonNull
getEnrolledFingerprintsDeprecated(int userId, String opPackageName)1124     private List<Fingerprint> getEnrolledFingerprintsDeprecated(int userId, String opPackageName) {
1125         final Pair<Integer, ServiceProvider> provider = getSingleProvider();
1126         if (provider == null) {
1127             Slog.w(TAG, "Null provider for getEnrolledFingerprintsDeprecated, caller: "
1128                     + opPackageName);
1129             return Collections.emptyList();
1130         }
1131 
1132         return provider.second.getEnrolledFingerprints(provider.first, userId);
1133     }
1134 
1135     /** Checks for public API invocations to ensure that permissions, etc are granted/correct. */
1136     @SuppressWarnings("BooleanMethodIsAlwaysInverted")
canUseFingerprint( String opPackageName, String attributionTag, boolean requireForeground, int uid, int pid, int userId)1137     private boolean canUseFingerprint(
1138             String opPackageName,
1139             String attributionTag,
1140             boolean requireForeground,
1141             int uid,
1142             int pid,
1143             int userId) {
1144         if (getContext().checkCallingPermission(USE_FINGERPRINT)
1145                 != PackageManager.PERMISSION_GRANTED) {
1146             Utils.checkPermission(getContext(), USE_BIOMETRIC);
1147         }
1148 
1149         if (Binder.getCallingUid() == Process.SYSTEM_UID) {
1150             return true; // System process (BiometricService, etc) is always allowed
1151         }
1152         if (Utils.isKeyguard(getContext(), opPackageName)) {
1153             return true;
1154         }
1155         if (!Utils.isCurrentUserOrProfile(getContext(), userId)) {
1156             Slog.w(TAG, "Rejecting " + opPackageName + "; not a current user or profile");
1157             return false;
1158         }
1159         if (!checkAppOps(uid, opPackageName, attributionTag)) {
1160             Slog.w(TAG, "Rejecting " + opPackageName + "; permission denied");
1161             return false;
1162         }
1163         if (requireForeground && !Utils.isForeground(uid, pid)) {
1164             Slog.w(TAG, "Rejecting " + opPackageName + "; not in foreground");
1165             return false;
1166         }
1167         return true;
1168     }
1169 
checkAppOps(int uid, String opPackageName, String attributionTag)1170     private boolean checkAppOps(int uid, String opPackageName, String attributionTag) {
1171         boolean appOpsOk = false;
1172         if (mAppOps.noteOp(AppOpsManager.OP_USE_BIOMETRIC, uid, opPackageName, attributionTag, null)
1173                 == AppOpsManager.MODE_ALLOWED) {
1174             appOpsOk = true;
1175         } else if (mAppOps.noteOp(
1176                         AppOpsManager.OP_USE_FINGERPRINT, uid, opPackageName, attributionTag, null)
1177                 == AppOpsManager.MODE_ALLOWED) {
1178             appOpsOk = true;
1179         }
1180         return appOpsOk;
1181     }
1182 }
1183