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