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