• 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_FINGERPRINT;
21 import static android.Manifest.permission.TEST_BIOMETRIC;
22 import static android.Manifest.permission.USE_BIOMETRIC;
23 import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
24 import static android.Manifest.permission.USE_FINGERPRINT;
25 import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_VENDOR;
26 import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ERROR_USER_CANCELED;
27 import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ERROR_VENDOR;
28 import static android.hardware.biometrics.SensorProperties.STRENGTH_STRONG;
29 
30 import android.annotation.NonNull;
31 import android.annotation.Nullable;
32 import android.app.ActivityManager;
33 import android.app.AppOpsManager;
34 import android.content.Context;
35 import android.content.pm.PackageManager;
36 import android.hardware.biometrics.AuthenticationStateListener;
37 import android.hardware.biometrics.BiometricPrompt;
38 import android.hardware.biometrics.BiometricsProtoEnums;
39 import android.hardware.biometrics.IBiometricSensorReceiver;
40 import android.hardware.biometrics.IBiometricService;
41 import android.hardware.biometrics.IBiometricServiceLockoutResetCallback;
42 import android.hardware.biometrics.IBiometricStateListener;
43 import android.hardware.biometrics.IInvalidationCallback;
44 import android.hardware.biometrics.ITestSession;
45 import android.hardware.biometrics.ITestSessionCallback;
46 import android.hardware.biometrics.fingerprint.IFingerprint;
47 import android.hardware.biometrics.fingerprint.PointerContext;
48 import android.hardware.biometrics.fingerprint.SensorProps;
49 import android.hardware.fingerprint.Fingerprint;
50 import android.hardware.fingerprint.FingerprintAuthenticateOptions;
51 import android.hardware.fingerprint.FingerprintEnrollOptions;
52 import android.hardware.fingerprint.FingerprintManager;
53 import android.hardware.fingerprint.FingerprintSensorConfigurations;
54 import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
55 import android.hardware.fingerprint.FingerprintServiceReceiver;
56 import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback;
57 import android.hardware.fingerprint.IFingerprintClientActiveCallback;
58 import android.hardware.fingerprint.IFingerprintService;
59 import android.hardware.fingerprint.IFingerprintServiceReceiver;
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.RemoteException;
69 import android.os.ResultReceiver;
70 import android.os.ServiceManager;
71 import android.os.ShellCallback;
72 import android.os.UserHandle;
73 import android.os.UserManager;
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.VisibleForTesting;
81 import com.android.internal.util.DumpUtils;
82 import com.android.internal.widget.LockPatternUtils;
83 import com.android.server.SystemService;
84 import com.android.server.biometrics.Utils;
85 import com.android.server.biometrics.log.BiometricContext;
86 import com.android.server.biometrics.sensors.AuthenticationStateListeners;
87 import com.android.server.biometrics.sensors.BaseClientMonitor;
88 import com.android.server.biometrics.sensors.BiometricStateCallback;
89 import com.android.server.biometrics.sensors.ClientMonitorCallback;
90 import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
91 import com.android.server.biometrics.sensors.LockoutResetDispatcher;
92 import com.android.server.biometrics.sensors.LockoutTracker;
93 import com.android.server.biometrics.sensors.fingerprint.aidl.FingerprintProvider;
94 import com.android.server.companion.virtual.VirtualDeviceManagerInternal;
95 
96 import java.io.FileDescriptor;
97 import java.io.PrintWriter;
98 import java.util.ArrayList;
99 import java.util.Collections;
100 import java.util.List;
101 import java.util.concurrent.CountDownLatch;
102 import java.util.concurrent.Executor;
103 import java.util.concurrent.TimeUnit;
104 import java.util.function.Function;
105 import java.util.function.Supplier;
106 
107 /**
108  * A service to manage multiple clients that want to access the fingerprint HAL API.
109  * The service is responsible for maintaining a list of clients and dispatching all
110  * fingerprint-related events.
111  */
112 public class FingerprintService extends SystemService {
113 
114     protected static final String TAG = "FingerprintService";
115 
116     private final AppOpsManager mAppOps;
117     private final LockoutResetDispatcher mLockoutResetDispatcher;
118     private final GestureAvailabilityDispatcher mGestureAvailabilityDispatcher;
119     private final LockPatternUtils mLockPatternUtils;
120     @NonNull
121     private final BiometricContext mBiometricContext;
122     @NonNull
123     private final Supplier<String[]> mAidlInstanceNameSupplier;
124     @NonNull
125     private final Function<String, FingerprintProvider> mFingerprintProvider;
126     @NonNull
127     private final FingerprintProviderFunction mFingerprintProviderFunction;
128     @NonNull
129     private final BiometricStateCallback<ServiceProvider, FingerprintSensorPropertiesInternal>
130             mBiometricStateCallback;
131     @NonNull
132     private final AuthenticationStateListeners mAuthenticationStateListeners;
133     @NonNull
134     private final Handler mHandler;
135     @NonNull
136     private final FingerprintServiceRegistry mRegistry;
137 
138     interface FingerprintProviderFunction {
getFingerprintProvider(Pair<String, SensorProps[]> filteredSensorProp, boolean resetLockoutRequiresHardwareAuthToken)139         FingerprintProvider getFingerprintProvider(Pair<String, SensorProps[]> filteredSensorProp,
140                 boolean resetLockoutRequiresHardwareAuthToken);
141     }
142 
143     /** Receives the incoming binder calls from FingerprintManager. */
144     @VisibleForTesting
145     final IFingerprintService.Stub mServiceWrapper = new IFingerprintService.Stub() {
146         @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
147         @Override
148         public ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback,
149                 @NonNull String opPackageName) {
150             super.createTestSession_enforcePermission();
151 
152             final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
153 
154             if (provider == null) {
155                 Slog.w(TAG, "Null provider for createTestSession, sensorId: " + sensorId);
156                 return null;
157             }
158 
159             return provider.createTestSession(sensorId, callback, opPackageName);
160         }
161 
162         @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
163         @Override
164         public byte[] dumpSensorServiceStateProto(int sensorId, boolean clearSchedulerBuffer) {
165             super.dumpSensorServiceStateProto_enforcePermission();
166 
167             final ProtoOutputStream proto = new ProtoOutputStream();
168             final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
169             if (provider != null) {
170                 provider.dumpProtoState(sensorId, proto, clearSchedulerBuffer);
171             }
172             proto.flush();
173             return proto.getBytes();
174         }
175 
176         @Override // Binder call
177         public List<FingerprintSensorPropertiesInternal> getSensorPropertiesInternal(
178                 @NonNull String opPackageName) {
179             if (getContext().checkCallingOrSelfPermission(USE_BIOMETRIC_INTERNAL)
180                     != PackageManager.PERMISSION_GRANTED) {
181                 Utils.checkPermission(getContext(), TEST_BIOMETRIC);
182             }
183             return mRegistry.getAllProperties();
184         }
185 
186         @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
187         @Override
188         public FingerprintSensorPropertiesInternal getSensorProperties(int sensorId,
189                 @NonNull String opPackageName) {
190             super.getSensorProperties_enforcePermission();
191 
192             final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
193             if (provider == null) {
194                 Slog.w(TAG, "No matching sensor for getSensorProperties, sensorId: " + sensorId
195                         + ", caller: " + opPackageName);
196                 return null;
197             }
198             return provider.getSensorProperties(sensorId);
199         }
200 
201         @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_FINGERPRINT)
202         @Override // Binder call
203         public void generateChallenge(IBinder token, int sensorId, int userId,
204                 IFingerprintServiceReceiver receiver, String opPackageName) {
205             super.generateChallenge_enforcePermission();
206 
207             final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
208             if (provider == null) {
209                 Slog.w(TAG, "No matching sensor for generateChallenge, sensorId: " + sensorId);
210                 return;
211             }
212 
213             provider.scheduleGenerateChallenge(sensorId, userId, token, receiver, opPackageName);
214         }
215 
216         @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_FINGERPRINT)
217         @Override // Binder call
218         public void revokeChallenge(IBinder token, int sensorId, int userId, String opPackageName,
219                 long challenge) {
220             super.revokeChallenge_enforcePermission();
221 
222             final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
223             if (provider == null) {
224                 Slog.w(TAG, "No matching sensor for revokeChallenge, sensorId: " + sensorId);
225                 return;
226             }
227 
228             provider.scheduleRevokeChallenge(sensorId, userId, token, opPackageName,
229                     challenge);
230         }
231 
232         @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_FINGERPRINT)
233         @Override // Binder call
234         public long enroll(final IBinder token, @NonNull final byte[] hardwareAuthToken,
235                 final int userId, final IFingerprintServiceReceiver receiver,
236                 final String opPackageName, @FingerprintManager.EnrollReason int enrollReason,
237                 FingerprintEnrollOptions options) {
238             super.enroll_enforcePermission();
239 
240             final Pair<Integer, ServiceProvider> provider = mRegistry.getSingleProvider();
241             if (provider == null) {
242                 Slog.w(TAG, "Null provider for enroll");
243                 return -1;
244             }
245 
246             return provider.second.scheduleEnroll(provider.first, token, hardwareAuthToken, userId,
247                     receiver, opPackageName, enrollReason, options);
248         }
249 
250         @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_FINGERPRINT)
251         @Override // Binder call
252         public void cancelEnrollment(final IBinder token, long requestId) {
253             super.cancelEnrollment_enforcePermission();
254 
255             final Pair<Integer, ServiceProvider> provider = mRegistry.getSingleProvider();
256             if (provider == null) {
257                 Slog.w(TAG, "Null provider for cancelEnrollment");
258                 return;
259             }
260 
261             provider.second.cancelEnrollment(provider.first, token, requestId);
262         }
263 
264         @SuppressWarnings("deprecation")
265         @Override // Binder call
266         public long authenticate(
267                 final IBinder token,
268                 final long operationId,
269                 final IFingerprintServiceReceiver receiver,
270                 final FingerprintAuthenticateOptions options) {
271             final int callingUid = Binder.getCallingUid();
272             final int callingPid = Binder.getCallingPid();
273             final int callingUserId = UserHandle.getCallingUserId();
274             final String opPackageName = options.getOpPackageName();
275             final String attributionTag = options.getAttributionTag();
276             final int userId = options.getUserId();
277 
278             if (!canUseFingerprint(
279                     opPackageName,
280                     attributionTag,
281                     true /* requireForeground */,
282                     callingUid,
283                     callingPid,
284                     callingUserId)) {
285                 Slog.w(TAG, "Authenticate rejecting package: " + opPackageName);
286                 return -1;
287             }
288 
289             // Keyguard check must be done on the caller's binder identity, since it also checks
290             // permission.
291             final boolean isKeyguard = Utils.isKeyguard(getContext(), opPackageName);
292 
293             // Clear calling identity when checking LockPatternUtils for StrongAuth flags.
294             final long identity1 = Binder.clearCallingIdentity();
295             try {
296                 if (isKeyguard && Utils.isUserEncryptedOrLockdown(mLockPatternUtils, userId)) {
297                     // If this happens, something in KeyguardUpdateMonitor is wrong.
298                     // SafetyNet for b/79776455
299                     EventLog.writeEvent(0x534e4554, "79776455");
300                     Slog.e(TAG, "Authenticate invoked when user is encrypted or lockdown");
301                     return -1;
302                 }
303             } finally {
304                 Binder.restoreCallingIdentity(identity1);
305             }
306 
307             final boolean restricted = getContext().checkCallingPermission(MANAGE_FINGERPRINT)
308                     != PackageManager.PERMISSION_GRANTED;
309             final int statsClient = isKeyguard ? BiometricsProtoEnums.CLIENT_KEYGUARD
310                     : BiometricsProtoEnums.CLIENT_FINGERPRINT_MANAGER;
311 
312             final Pair<Integer, ServiceProvider> provider;
313             if (options.getSensorId() == FingerprintManager.SENSOR_ID_ANY) {
314                 provider = mRegistry.getSingleProvider();
315             } else {
316                 Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
317                 provider = new Pair<>(options.getSensorId(),
318                         mRegistry.getProviderForSensor(options.getSensorId()));
319             }
320 
321             if (provider == null) {
322                 Slog.w(TAG, "Null provider for authenticate");
323                 return -1;
324             }
325             options.setSensorId(provider.first);
326 
327             final FingerprintSensorPropertiesInternal sensorProps =
328                     provider.second.getSensorProperties(options.getSensorId());
329             if (!isKeyguard && !Utils.isSettings(getContext(), opPackageName)
330                     && sensorProps != null && (sensorProps.isAnyUdfpsType()
331                     || sensorProps.isAnySidefpsType())) {
332                 try {
333                     return authenticateWithPrompt(operationId, sensorProps, callingUid,
334                             callingUserId, receiver, opPackageName,
335                             options.isIgnoreEnrollmentState());
336                 } catch (PackageManager.NameNotFoundException e) {
337                     Slog.e(TAG, "Invalid package", e);
338                     return -1;
339                 }
340             }
341             final long identity2 = Binder.clearCallingIdentity();
342             try {
343                 VirtualDeviceManagerInternal vdm = getLocalService(
344                         VirtualDeviceManagerInternal.class);
345                 if (vdm != null) {
346                     vdm.onAuthenticationPrompt(callingUid);
347                 }
348             } finally {
349                 Binder.restoreCallingIdentity(identity2);
350             }
351             return provider.second.scheduleAuthenticate(token, operationId,
352                     0 /* cookie */, new ClientMonitorCallbackConverter(receiver), options,
353                     restricted, statsClient, isKeyguard);
354         }
355 
356         private long authenticateWithPrompt(
357                 final long operationId,
358                 @NonNull final FingerprintSensorPropertiesInternal props,
359                 final int uId,
360                 final int userId,
361                 final IFingerprintServiceReceiver receiver,
362                 final String opPackageName,
363                 boolean ignoreEnrollmentState) throws PackageManager.NameNotFoundException {
364             final Context context = getUiContext();
365             final Context promptContext = context.createPackageContextAsUser(
366                     opPackageName, 0 /* flags */, UserHandle.getUserHandleForUid(uId));
367             final Executor executor = context.getMainExecutor();
368 
369             final BiometricPrompt biometricPrompt = new BiometricPrompt.Builder(promptContext)
370                     .setTitle(context.getString(R.string.biometric_dialog_default_title))
371                     .setSubtitle(context.getString(R.string.fingerprint_dialog_default_subtitle))
372                     .setNegativeButton(
373                             context.getString(R.string.cancel),
374                             executor,
375                             (dialog, which) -> {
376                                 try {
377                                     receiver.onError(
378                                             FINGERPRINT_ERROR_USER_CANCELED, 0 /* vendorCode */);
379                                 } catch (RemoteException e) {
380                                     Slog.e(TAG, "Remote exception in negative button onClick()", e);
381                                 }
382                             })
383                     .setIsForLegacyFingerprintManager(props.sensorId)
384                     .setIgnoreEnrollmentState(ignoreEnrollmentState)
385                     .build();
386 
387             final BiometricPrompt.AuthenticationCallback promptCallback =
388                     new BiometricPrompt.AuthenticationCallback() {
389                         @Override
390                         public void onAuthenticationError(int errorCode, CharSequence errString) {
391                             try {
392                                 if (FingerprintUtils.isKnownErrorCode(errorCode)) {
393                                     receiver.onError(errorCode, 0 /* vendorCode */);
394                                 } else {
395                                     receiver.onError(FINGERPRINT_ERROR_VENDOR, errorCode);
396                                 }
397                             } catch (RemoteException e) {
398                                 Slog.e(TAG, "Remote exception in onAuthenticationError()", e);
399                             }
400                         }
401 
402                         @Override
403                         public void onAuthenticationSucceeded(
404                                 BiometricPrompt.AuthenticationResult result) {
405                             final Fingerprint fingerprint = new Fingerprint("", 0, 0L);
406                             final boolean isStrong = props.sensorStrength == STRENGTH_STRONG;
407                             try {
408                                 receiver.onAuthenticationSucceeded(fingerprint, userId, isStrong);
409                             } catch (RemoteException e) {
410                                 Slog.e(TAG, "Remote exception in onAuthenticationSucceeded()", e);
411                             }
412                         }
413 
414                         @Override
415                         public void onAuthenticationFailed() {
416                             try {
417                                 receiver.onAuthenticationFailed();
418                             } catch (RemoteException e) {
419                                 Slog.e(TAG, "Remote exception in onAuthenticationFailed()", e);
420                             }
421                         }
422 
423                         @Override
424                         public void onAuthenticationAcquired(int acquireInfo) {
425                             try {
426                                 if (FingerprintUtils.isKnownAcquiredCode(acquireInfo)) {
427                                     receiver.onAcquired(acquireInfo, 0 /* vendorCode */);
428                                 } else {
429                                     receiver.onAcquired(FINGERPRINT_ACQUIRED_VENDOR, acquireInfo);
430                                 }
431                             } catch (RemoteException e) {
432                                 Slog.e(TAG, "Remote exception in onAuthenticationAcquired()", e);
433                             }
434                         }
435 
436                         @Override
437                         public void onAuthenticationHelp(int acquireInfo, CharSequence helpString) {
438                             onAuthenticationAcquired(acquireInfo);
439                         }
440                     };
441 
442             return biometricPrompt.authenticateForOperation(
443                     new CancellationSignal(), executor, promptCallback, operationId);
444         }
445 
446         @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
447         @Override
448         public long detectFingerprint(final IBinder token,
449                 final IFingerprintServiceReceiver receiver,
450                 final FingerprintAuthenticateOptions options) {
451             super.detectFingerprint_enforcePermission();
452 
453             final String opPackageName = options.getOpPackageName();
454             if (!Utils.isKeyguard(getContext(), opPackageName)) {
455                 Slog.w(TAG, "detectFingerprint called from non-sysui package: " + opPackageName);
456                 return -1;
457             }
458 
459             final Pair<Integer, ServiceProvider> provider = mRegistry.getSingleProvider();
460             if (provider == null) {
461                 Slog.w(TAG, "Null provider for detectFingerprint");
462                 return -1;
463             }
464             options.setSensorId(provider.first);
465 
466             return provider.second.scheduleFingerDetect(token,
467                     new ClientMonitorCallbackConverter(receiver), options,
468                     BiometricsProtoEnums.CLIENT_KEYGUARD);
469         }
470 
471         @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_BIOMETRIC)
472         @Override // Binder call
473         public void prepareForAuthentication(IBinder token, long operationId,
474                 IBiometricSensorReceiver sensorReceiver,
475                 @NonNull FingerprintAuthenticateOptions options,
476                 long requestId, int cookie, boolean allowBackgroundAuthentication,
477                 boolean isForLegacyFingerprintManager) {
478             super.prepareForAuthentication_enforcePermission();
479 
480             final ServiceProvider provider = mRegistry.getProviderForSensor(options.getSensorId());
481             if (provider == null) {
482                 Slog.w(TAG, "Null provider for prepareForAuthentication");
483                 return;
484             }
485 
486             final int statsClient =
487                     isForLegacyFingerprintManager ? BiometricsProtoEnums.CLIENT_FINGERPRINT_MANAGER
488                             : BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT;
489             final boolean restricted = true; // BiometricPrompt is always restricted
490             provider.scheduleAuthenticate(token, operationId, cookie,
491                     new ClientMonitorCallbackConverter(sensorReceiver), options, requestId,
492                     restricted, statsClient,
493                     allowBackgroundAuthentication);
494         }
495 
496         @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_BIOMETRIC)
497         @Override // Binder call
498         public void startPreparedClient(int sensorId, int cookie) {
499             super.startPreparedClient_enforcePermission();
500 
501             final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
502             if (provider == null) {
503                 Slog.w(TAG, "Null provider for startPreparedClient");
504                 return;
505             }
506 
507             provider.startPreparedClient(sensorId, cookie);
508         }
509 
510         @Override // Binder call
511         public void cancelAuthentication(
512                 final IBinder token,
513                 final String opPackageName,
514                 final String attributionTag,
515                 long requestId) {
516             final int callingUid = Binder.getCallingUid();
517             final int callingPid = Binder.getCallingPid();
518             final int callingUserId = UserHandle.getCallingUserId();
519 
520             if (!canUseFingerprint(
521                     opPackageName,
522                     attributionTag,
523                     true /* requireForeground */,
524                     callingUid,
525                     callingPid,
526                     callingUserId)) {
527                 Slog.w(TAG, "cancelAuthentication rejecting package: " + opPackageName);
528                 return;
529             }
530 
531             final Pair<Integer, ServiceProvider> provider = mRegistry.getSingleProvider();
532             if (provider == null) {
533                 Slog.w(TAG, "Null provider for cancelAuthentication");
534                 return;
535             }
536 
537             provider.second.cancelAuthentication(provider.first, token, requestId);
538         }
539 
540         @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
541         @Override // Binder call
542         public void cancelFingerprintDetect(final IBinder token, final String opPackageName,
543                 final long requestId) {
544             super.cancelFingerprintDetect_enforcePermission();
545 
546             if (!Utils.isKeyguard(getContext(), opPackageName)) {
547                 Slog.w(TAG, "cancelFingerprintDetect called from non-sysui package: "
548                         + opPackageName);
549                 return;
550             }
551 
552             // For IBiometricsFingerprint2.1, cancelling fingerprint detect is the same as
553             // cancelling authentication.
554             final Pair<Integer, ServiceProvider> provider = mRegistry.getSingleProvider();
555             if (provider == null) {
556                 Slog.w(TAG, "Null provider for cancelFingerprintDetect");
557                 return;
558             }
559 
560             provider.second.cancelAuthentication(provider.first, token, requestId);
561         }
562 
563         @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_BIOMETRIC)
564         @Override // Binder call
565         public void cancelAuthenticationFromService(final int sensorId, final IBinder token,
566                 final String opPackageName, final long requestId) {
567             super.cancelAuthenticationFromService_enforcePermission();
568 
569             Slog.d(TAG, "cancelAuthenticationFromService, sensorId: " + sensorId);
570 
571             final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
572             if (provider == null) {
573                 Slog.w(TAG, "Null provider for cancelAuthenticationFromService");
574                 return;
575             }
576 
577             provider.cancelAuthentication(sensorId, token, requestId);
578         }
579 
580         @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_FINGERPRINT)
581         @Override // Binder call
582         public void remove(final IBinder token, final int fingerId, final int userId,
583                 final IFingerprintServiceReceiver receiver, final String opPackageName) {
584             super.remove_enforcePermission();
585 
586             final Pair<Integer, ServiceProvider> provider = mRegistry.getSingleProvider();
587             if (provider == null) {
588                 Slog.w(TAG, "Null provider for remove");
589                 return;
590             }
591             provider.second.scheduleRemove(provider.first, token, receiver, fingerId, userId,
592                     opPackageName);
593         }
594 
595         @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
596         @Override // Binder call
597         public void removeAll(final IBinder token, final int userId,
598                 final IFingerprintServiceReceiver receiver, final String opPackageName) {
599 
600             super.removeAll_enforcePermission();
601 
602             final FingerprintServiceReceiver internalReceiver = new FingerprintServiceReceiver() {
603                 int sensorsFinishedRemoving = 0;
604                 final int numSensors = getSensorPropertiesInternal(
605                         getContext().getOpPackageName()).size();
606                 @Override
607                 public void onRemoved(Fingerprint fp, int remaining) throws RemoteException {
608                     if (remaining == 0) {
609                         sensorsFinishedRemoving++;
610                         Slog.d(TAG, "sensorsFinishedRemoving: " + sensorsFinishedRemoving
611                                 + ", numSensors: " + numSensors);
612                         if (sensorsFinishedRemoving == numSensors) {
613                             receiver.onRemoved(null, 0 /* remaining */);
614                         }
615                     }
616                 }
617             };
618 
619             // This effectively iterates through all sensors, but has to do so by finding all
620             // sensors under each provider.
621             for (ServiceProvider provider : mRegistry.getProviders()) {
622                 List<FingerprintSensorPropertiesInternal> props = provider.getSensorProperties();
623                 for (FingerprintSensorPropertiesInternal prop : props) {
624                     provider.scheduleRemoveAll(prop.sensorId, token, internalReceiver, userId,
625                             opPackageName);
626                 }
627             }
628         }
629 
630         @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
631         @Override // Binder call
632         public void addLockoutResetCallback(final IBiometricServiceLockoutResetCallback callback,
633                 final String opPackageName) {
634             super.addLockoutResetCallback_enforcePermission();
635 
636             mLockoutResetDispatcher.addCallback(callback, opPackageName);
637         }
638 
639         @Override // Binder call
640         public void onShellCommand(@Nullable FileDescriptor in, @Nullable FileDescriptor out,
641                 @Nullable FileDescriptor err, @NonNull String[] args,
642                 @Nullable ShellCallback callback, @NonNull ResultReceiver resultReceiver)
643                 throws RemoteException {
644             (new FingerprintShellCommand(getContext(), FingerprintService.this))
645                     .exec(this, in, out, err, args, callback, resultReceiver);
646         }
647 
648         @Override // Binder call
649         protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, String[] args) {
650             if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) {
651                 return;
652             }
653 
654             final long ident = Binder.clearCallingIdentity();
655             try {
656                 if (args.length > 1 && "--proto".equals(args[0]) && "--state".equals(args[1])) {
657                     final ProtoOutputStream proto = new ProtoOutputStream(fd);
658                     for (ServiceProvider provider : mRegistry.getProviders()) {
659                         for (FingerprintSensorPropertiesInternal props
660                                 : provider.getSensorProperties()) {
661                             provider.dumpProtoState(props.sensorId, proto, false);
662                         }
663                     }
664                     proto.flush();
665                 } else if (args.length > 0 && "--proto".equals(args[0])) {
666                     for (ServiceProvider provider : mRegistry.getProviders()) {
667                         for (FingerprintSensorPropertiesInternal props
668                                 : provider.getSensorProperties()) {
669                             provider.dumpProtoMetrics(props.sensorId, fd);
670                         }
671                     }
672                 } else {
673                     for (ServiceProvider provider : mRegistry.getProviders()) {
674                         for (FingerprintSensorPropertiesInternal props
675                                 : provider.getSensorProperties()) {
676                             pw.println("Dumping for sensorId: " + props.sensorId
677                                     + ", provider: " + provider.getClass().getSimpleName());
678                             pw.println("Fps state: "
679                                     + mBiometricStateCallback.getBiometricState());
680                             provider.dumpInternal(props.sensorId, pw);
681                             pw.println();
682                         }
683                     }
684                 }
685             } finally {
686                 Binder.restoreCallingIdentity(ident);
687             }
688         }
689 
690         @Override // Binder call
691         public boolean isHardwareDetectedDeprecated(String opPackageName, String attributionTag) {
692             if (!canUseFingerprint(
693                     opPackageName,
694                     attributionTag,
695                     false /* foregroundOnly */,
696                     Binder.getCallingUid(),
697                     Binder.getCallingPid(),
698                     UserHandle.getCallingUserId())) {
699                 return false;
700             }
701 
702             final long token = Binder.clearCallingIdentity();
703             try {
704                 final Pair<Integer, ServiceProvider> provider = mRegistry.getSingleProvider();
705                 if (provider == null) {
706                     Slog.w(TAG, "Null provider for isHardwareDetectedDeprecated, caller: "
707                             + opPackageName);
708                     return false;
709                 }
710                 return provider.second.isHardwareDetected(provider.first);
711             } finally {
712                 Binder.restoreCallingIdentity(token);
713             }
714         }
715 
716         @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
717         @Override // Binder call
718         public boolean isHardwareDetected(int sensorId, String opPackageName) {
719             super.isHardwareDetected_enforcePermission();
720 
721             final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
722             if (provider == null) {
723                 Slog.w(TAG, "Null provider for isHardwareDetected, caller: " + opPackageName);
724                 return false;
725             }
726 
727             return provider.isHardwareDetected(sensorId);
728         }
729 
730         @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_FINGERPRINT)
731         @Override // Binder call
732         public void rename(final int fingerId, final int userId, final String name) {
733             super.rename_enforcePermission();
734 
735             if (!Utils.isCurrentUserOrProfile(getContext(), userId)) {
736                 return;
737             }
738 
739             final Pair<Integer, ServiceProvider> provider = mRegistry.getSingleProvider();
740             if (provider == null) {
741                 Slog.w(TAG, "Null provider for rename");
742                 return;
743             }
744 
745             provider.second.rename(provider.first, fingerId, userId, name);
746         }
747 
748         @Override // Binder call
749         public List<Fingerprint> getEnrolledFingerprints(
750                 int userId, String opPackageName, String attributionTag) {
751             if (!canUseFingerprint(
752                     opPackageName,
753                     attributionTag,
754                     false /* foregroundOnly */,
755                     Binder.getCallingUid(),
756                     Binder.getCallingPid(),
757                     UserHandle.getCallingUserId())) {
758                 return Collections.emptyList();
759             }
760 
761             if (userId != UserHandle.getCallingUserId()) {
762                 Utils.checkPermission(getContext(), INTERACT_ACROSS_USERS);
763             }
764 
765             return FingerprintService.this.getEnrolledFingerprintsDeprecated(userId, opPackageName);
766         }
767 
768         @Override // Binder call
769         public boolean hasEnrolledFingerprintsDeprecated(
770                 int userId, String opPackageName, String attributionTag) {
771             if (!canUseFingerprint(
772                     opPackageName,
773                     attributionTag,
774                     false /* foregroundOnly */,
775                     Binder.getCallingUid(),
776                     Binder.getCallingPid(),
777                     UserHandle.getCallingUserId())) {
778                 return false;
779             }
780 
781             if (userId != UserHandle.getCallingUserId()) {
782                 Utils.checkPermission(getContext(), INTERACT_ACROSS_USERS);
783             }
784             return !FingerprintService.this.getEnrolledFingerprintsDeprecated(userId, opPackageName)
785                     .isEmpty();
786         }
787 
788         @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
789         public boolean hasEnrolledFingerprints(int sensorId, int userId, String opPackageName) {
790             super.hasEnrolledFingerprints_enforcePermission();
791 
792             final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
793             if (provider == null) {
794                 Slog.w(TAG, "Null provider for hasEnrolledFingerprints, caller: " + opPackageName);
795                 return false;
796             }
797 
798             return provider.getEnrolledFingerprints(sensorId, userId).size() > 0;
799         }
800 
801         @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
802         @Override // Binder call
803         public @LockoutTracker.LockoutMode int getLockoutModeForUser(int sensorId, int userId) {
804             super.getLockoutModeForUser_enforcePermission();
805 
806             final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
807             if (provider == null) {
808                 Slog.w(TAG, "Null provider for getLockoutModeForUser");
809                 return LockoutTracker.LOCKOUT_NONE;
810             }
811             return provider.getLockoutModeForUser(sensorId, userId);
812         }
813 
814         @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
815         @Override
816         public void invalidateAuthenticatorId(int sensorId, int userId,
817                 IInvalidationCallback callback) {
818             super.invalidateAuthenticatorId_enforcePermission();
819 
820             final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
821             if (provider == null) {
822                 Slog.w(TAG, "Null provider for invalidateAuthenticatorId");
823                 return;
824             }
825             provider.scheduleInvalidateAuthenticatorId(sensorId, userId, callback);
826         }
827 
828         @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
829         @Override // Binder call
830         public long getAuthenticatorId(int sensorId, int userId) {
831             super.getAuthenticatorId_enforcePermission();
832 
833             final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
834             if (provider == null) {
835                 Slog.w(TAG, "Null provider for getAuthenticatorId");
836                 return 0;
837             }
838             return provider.getAuthenticatorId(sensorId, userId);
839         }
840 
841         @android.annotation.EnforcePermission(android.Manifest.permission.RESET_FINGERPRINT_LOCKOUT)
842         @Override // Binder call
843         public void resetLockout(IBinder token, int sensorId, int userId,
844                 @Nullable byte[] hardwareAuthToken, String opPackageName) {
845             super.resetLockout_enforcePermission();
846 
847             final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
848             if (provider == null) {
849                 Slog.w(TAG, "Null provider for resetLockout, caller: " + opPackageName);
850                 return;
851             }
852 
853             provider.scheduleResetLockout(sensorId, userId, hardwareAuthToken);
854         }
855 
856         @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_FINGERPRINT)
857         @Override
858         public boolean isClientActive() {
859             super.isClientActive_enforcePermission();
860 
861             return mGestureAvailabilityDispatcher.isAnySensorActive();
862         }
863 
864         @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_FINGERPRINT)
865         @Override
866         public void addClientActiveCallback(IFingerprintClientActiveCallback callback) {
867             super.addClientActiveCallback_enforcePermission();
868 
869             mGestureAvailabilityDispatcher.registerCallback(callback);
870         }
871 
872         @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_FINGERPRINT)
873         @Override
874         public void removeClientActiveCallback(IFingerprintClientActiveCallback callback) {
875             super.removeClientActiveCallback_enforcePermission();
876 
877             mGestureAvailabilityDispatcher.removeCallback(callback);
878         }
879 
880         @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
881         @Override // Binder call
882         public void registerAuthenticators(
883                 @NonNull FingerprintSensorConfigurations fingerprintSensorConfigurations) {
884             super.registerAuthenticators_enforcePermission();
885             if (!fingerprintSensorConfigurations.hasSensorConfigurations()) {
886                 Slog.d(TAG, "No fingerprint sensors available.");
887                 return;
888             }
889             mRegistry.registerAll(() -> getProviders(fingerprintSensorConfigurations));
890         }
891 
892         @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
893         @Override
894         public void addAuthenticatorsRegisteredCallback(
895                 IFingerprintAuthenticatorsRegisteredCallback callback) {
896             super.addAuthenticatorsRegisteredCallback_enforcePermission();
897 
898             mRegistry.addAllRegisteredCallback(callback);
899         }
900 
901         @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
902         @Override
903         public void registerAuthenticationStateListener(
904                 @NonNull AuthenticationStateListener listener) {
905             super.registerAuthenticationStateListener_enforcePermission();
906 
907             mAuthenticationStateListeners.registerAuthenticationStateListener(listener);
908         }
909 
910         @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
911         @Override
912         public void unregisterAuthenticationStateListener(
913                 @NonNull AuthenticationStateListener listener) {
914             super.unregisterAuthenticationStateListener_enforcePermission();
915 
916             mAuthenticationStateListeners.unregisterAuthenticationStateListener(listener);
917         }
918 
919         @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
920         @Override
921         public void registerBiometricStateListener(@NonNull IBiometricStateListener listener) {
922             super.registerBiometricStateListener_enforcePermission();
923 
924             mBiometricStateCallback.registerBiometricStateListener(listener);
925         }
926 
927         @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
928         @Override
929         public void onPointerDown(long requestId, int sensorId, PointerContext pc) {
930             super.onPointerDown_enforcePermission();
931             final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
932             if (provider == null) {
933                 Slog.w(TAG, "No matching provider for onFingerDown, sensorId: " + sensorId);
934                 return;
935             }
936             provider.onPointerDown(requestId, sensorId, pc);
937         }
938         @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
939         @Override
940 
941         public void onPointerUp(long requestId, int sensorId, PointerContext pc) {
942             super.onPointerUp_enforcePermission();
943             final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
944             if (provider == null) {
945                 Slog.w(TAG, "No matching provider for onFingerUp, sensorId: " + sensorId);
946                 return;
947             }
948             provider.onPointerUp(requestId, sensorId, pc);
949         }
950 
951         @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
952         @Override
953         public void onUdfpsUiEvent(@FingerprintManager.UdfpsUiEvent int event, long requestId,
954                 int sensorId) {
955             super.onUdfpsUiEvent_enforcePermission();
956 
957             final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
958             if (provider == null) {
959                 Slog.w(TAG, "No matching provider for onUdfpsUiEvent, sensorId: " + sensorId);
960                 return;
961             }
962             provider.onUdfpsUiEvent(event, requestId, sensorId);
963         }
964 
965         @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
966         @Override
967         public void setIgnoreDisplayTouches(long requestId, int sensorId, boolean ignoreTouches) {
968             super.setIgnoreDisplayTouches_enforcePermission();
969 
970             final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
971             if (provider == null) {
972                 Slog.w(TAG,
973                         "No matching provider for setIgnoreDisplayTouches, sensorId: " + sensorId);
974                 return;
975             }
976             provider.setIgnoreDisplayTouches(requestId, sensorId, ignoreTouches);
977         }
978 
979         @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
980         @Override
981         public void setUdfpsOverlayController(@NonNull IUdfpsOverlayController controller) {
982             super.setUdfpsOverlayController_enforcePermission();
983 
984             for (ServiceProvider provider : mRegistry.getProviders()) {
985                 provider.setUdfpsOverlayController(controller);
986             }
987         }
988 
989         @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
990         @Override
991         public void onPowerPressed() {
992             super.onPowerPressed_enforcePermission();
993 
994             for (ServiceProvider provider : mRegistry.getProviders()) {
995                 provider.onPowerPressed();
996             }
997         }
998 
999         @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
1000         @Override
1001         public void scheduleWatchdog() {
1002             super.scheduleWatchdog_enforcePermission();
1003 
1004             final Pair<Integer, ServiceProvider> provider = mRegistry.getSingleProvider();
1005             if (provider == null) {
1006                 Slog.w(TAG, "Null provider for scheduling watchdog");
1007                 return;
1008             }
1009 
1010             provider.second.scheduleWatchdog(provider.first);
1011         }
1012     };
1013 
FingerprintService(Context context)1014     public FingerprintService(Context context) {
1015         this(context, BiometricContext.getInstance(context),
1016                 () -> IBiometricService.Stub.asInterface(
1017                         ServiceManager.getService(Context.BIOMETRIC_SERVICE)),
1018                 () -> ServiceManager.getDeclaredInstances(IFingerprint.DESCRIPTOR),
1019                 null /* fingerprintProvider */,
1020                 null /* fingerprintProviderFunction */);
1021     }
1022 
1023     @VisibleForTesting
FingerprintService(Context context, BiometricContext biometricContext, Supplier<IBiometricService> biometricServiceSupplier, Supplier<String[]> aidlInstanceNameSupplier, Function<String, FingerprintProvider> fingerprintProvider, FingerprintProviderFunction fingerprintProviderFunction)1024     FingerprintService(Context context,
1025             BiometricContext biometricContext,
1026             Supplier<IBiometricService> biometricServiceSupplier,
1027             Supplier<String[]> aidlInstanceNameSupplier,
1028             Function<String, FingerprintProvider> fingerprintProvider,
1029             FingerprintProviderFunction fingerprintProviderFunction) {
1030         super(context);
1031         mBiometricContext = biometricContext;
1032         mAidlInstanceNameSupplier = aidlInstanceNameSupplier;
1033         mAppOps = context.getSystemService(AppOpsManager.class);
1034         mGestureAvailabilityDispatcher = new GestureAvailabilityDispatcher();
1035         mLockoutResetDispatcher = new LockoutResetDispatcher(context);
1036         mLockPatternUtils = new LockPatternUtils(context);
1037         mBiometricStateCallback = new BiometricStateCallback<>(UserManager.get(context));
1038         mAuthenticationStateListeners = new AuthenticationStateListeners();
1039         mFingerprintProvider = fingerprintProvider != null ? fingerprintProvider :
1040                 (name) -> {
1041                     final String fqName = IFingerprint.DESCRIPTOR + "/" + name;
1042                     final IFingerprint fp = IFingerprint.Stub.asInterface(
1043                             Binder.allowBlocking(ServiceManager.waitForDeclaredService(fqName)));
1044                     if (fp != null) {
1045                         try {
1046                             return new FingerprintProvider(getContext(),
1047                                     mBiometricStateCallback, mAuthenticationStateListeners,
1048                                     fp.getSensorProps(), name, mLockoutResetDispatcher,
1049                                     mGestureAvailabilityDispatcher, mBiometricContext,
1050                                     true /* resetLockoutRequiresHardwareAuthToken */);
1051                         } catch (RemoteException e) {
1052                             Slog.e(TAG, "Remote exception in getSensorProps: " + fqName);
1053                         }
1054                     } else {
1055                         Slog.e(TAG, "Unable to get declared service: " + fqName);
1056                     }
1057 
1058                     return null;
1059                 };
1060         mFingerprintProviderFunction = fingerprintProviderFunction != null
1061                 ? fingerprintProviderFunction :
1062                         (filteredSensorProps, resetLockoutRequiresHardwareAuthToken) ->
1063                                 new FingerprintProvider(getContext(), mBiometricStateCallback,
1064                                         mAuthenticationStateListeners, filteredSensorProps.second,
1065                                         filteredSensorProps.first, mLockoutResetDispatcher,
1066                                         mGestureAvailabilityDispatcher, mBiometricContext,
1067                                         resetLockoutRequiresHardwareAuthToken);
1068 
1069         mHandler = new Handler(Looper.getMainLooper());
1070         mRegistry = new FingerprintServiceRegistry(mServiceWrapper, biometricServiceSupplier);
1071         mRegistry.addAllRegisteredCallback(new IFingerprintAuthenticatorsRegisteredCallback.Stub() {
1072             @Override
1073             public void onAllAuthenticatorsRegistered(
1074                     List<FingerprintSensorPropertiesInternal> sensors) {
1075                 mBiometricStateCallback.start(mRegistry.getProviders());
1076             }
1077         });
1078     }
1079 
1080     @NonNull
getProviders(@onNull FingerprintSensorConfigurations fingerprintSensorConfigurations)1081     private List<ServiceProvider> getProviders(@NonNull FingerprintSensorConfigurations
1082             fingerprintSensorConfigurations) {
1083         final List<ServiceProvider> providers = new ArrayList<>();
1084         final Pair<String, SensorProps[]> filteredSensorProps = filterAvailableHalInstances(
1085                 fingerprintSensorConfigurations);
1086         providers.add(mFingerprintProviderFunction.getFingerprintProvider(filteredSensorProps,
1087                 fingerprintSensorConfigurations.getResetLockoutRequiresHardwareAuthToken()));
1088 
1089         return providers;
1090     }
1091 
1092     @NonNull
filterAvailableHalInstances( FingerprintSensorConfigurations fingerprintSensorConfigurations)1093     private Pair<String, SensorProps[]> filterAvailableHalInstances(
1094             FingerprintSensorConfigurations fingerprintSensorConfigurations) {
1095         final String finalSensorInstance = fingerprintSensorConfigurations.getSensorInstance();
1096         if (fingerprintSensorConfigurations.isSingleSensorConfigurationPresent()) {
1097             return new Pair<>(finalSensorInstance,
1098                     fingerprintSensorConfigurations.getSensorPropForInstance(finalSensorInstance));
1099         }
1100         final String virtualInstance = "virtual";
1101         final boolean isVirtualHalPresent =
1102                 fingerprintSensorConfigurations.doesInstanceExist(virtualInstance);
1103         if (Utils.isFingerprintVirtualEnabled(getContext())) {
1104             if (isVirtualHalPresent) {
1105                 return new Pair<>(virtualInstance,
1106                         fingerprintSensorConfigurations.getSensorPropForInstance(virtualInstance));
1107             } else {
1108                 Slog.e(TAG, "Could not find virtual interface while it is enabled");
1109                 return new Pair<>(finalSensorInstance,
1110                         fingerprintSensorConfigurations.getSensorPropForInstance(
1111                                 finalSensorInstance));
1112             }
1113         } else {
1114             if (isVirtualHalPresent) {
1115                 final String notAVirtualInstance = fingerprintSensorConfigurations
1116                         .getSensorNameNotForInstance(virtualInstance);
1117                 if (notAVirtualInstance != null) {
1118                     return new Pair<>(notAVirtualInstance, fingerprintSensorConfigurations
1119                             .getSensorPropForInstance(notAVirtualInstance));
1120                 }
1121             }
1122         }
1123         return new Pair<>(finalSensorInstance, fingerprintSensorConfigurations
1124                 .getSensorPropForInstance(finalSensorInstance));
1125     }
1126 
1127     @Override
onStart()1128     public void onStart() {
1129         publishBinderService(Context.FINGERPRINT_SERVICE, mServiceWrapper);
1130     }
1131 
1132     @NonNull
getEnrolledFingerprintsDeprecated(int userId, String opPackageName)1133     private List<Fingerprint> getEnrolledFingerprintsDeprecated(int userId, String opPackageName) {
1134         final Pair<Integer, ServiceProvider> provider = mRegistry.getSingleProvider();
1135         if (provider == null) {
1136             Slog.w(TAG, "Null provider for getEnrolledFingerprintsDeprecated, caller: "
1137                     + opPackageName);
1138             return Collections.emptyList();
1139         }
1140 
1141         return provider.second.getEnrolledFingerprints(provider.first, userId);
1142     }
1143 
1144     /** Checks for public API invocations to ensure that permissions, etc are granted/correct. */
1145     @SuppressWarnings("BooleanMethodIsAlwaysInverted")
canUseFingerprint( String opPackageName, String attributionTag, boolean requireForeground, int uid, int pid, int userId)1146     private boolean canUseFingerprint(
1147             String opPackageName,
1148             String attributionTag,
1149             boolean requireForeground,
1150             int uid,
1151             int pid,
1152             int userId) {
1153         if (getContext().checkCallingPermission(USE_FINGERPRINT)
1154                 != PackageManager.PERMISSION_GRANTED) {
1155             Utils.checkPermission(getContext(), USE_BIOMETRIC);
1156         }
1157 
1158         if (Binder.getCallingUid() == Process.SYSTEM_UID) {
1159             return true; // System process (BiometricService, etc) is always allowed
1160         }
1161         if (Utils.isKeyguard(getContext(), opPackageName)) {
1162             return true;
1163         }
1164         if (!Utils.isCurrentUserOrProfile(getContext(), userId)) {
1165             Slog.w(TAG, "Rejecting " + opPackageName + "; not a current user or profile");
1166             return false;
1167         }
1168         if (!checkAppOps(uid, opPackageName, attributionTag)) {
1169             Slog.w(TAG, "Rejecting " + opPackageName + "; permission denied");
1170             return false;
1171         }
1172         if (requireForeground && !Utils.isForeground(uid, pid)) {
1173             Slog.w(TAG, "Rejecting " + opPackageName + "; not in foreground");
1174             return false;
1175         }
1176         return true;
1177     }
1178 
checkAppOps(int uid, String opPackageName, String attributionTag)1179     private boolean checkAppOps(int uid, String opPackageName, String attributionTag) {
1180         boolean appOpsOk = false;
1181         if (mAppOps.noteOp(AppOpsManager.OP_USE_BIOMETRIC, uid, opPackageName, attributionTag, null)
1182                 == AppOpsManager.MODE_ALLOWED) {
1183             appOpsOk = true;
1184         } else if (mAppOps.noteOp(
1185                         AppOpsManager.OP_USE_FINGERPRINT, uid, opPackageName, attributionTag, null)
1186                 == AppOpsManager.MODE_ALLOWED) {
1187             appOpsOk = true;
1188         }
1189         return appOpsOk;
1190     }
1191 
syncEnrollmentsNow()1192     void syncEnrollmentsNow() {
1193         Utils.checkPermissionOrShell(getContext(), MANAGE_FINGERPRINT);
1194         if (Utils.isFingerprintVirtualEnabled(getContext())) {
1195             Slog.i(TAG, "Sync virtual enrollments");
1196             final int userId = ActivityManager.getCurrentUser();
1197             final CountDownLatch latch = new CountDownLatch(mRegistry.getProviders().size());
1198             for (ServiceProvider provider : mRegistry.getProviders()) {
1199                 for (FingerprintSensorPropertiesInternal props : provider.getSensorProperties()) {
1200                     provider.scheduleInternalCleanup(props.sensorId, userId,
1201                             new ClientMonitorCallback() {
1202                                 @Override
1203                                 public void onClientFinished(
1204                                         @NonNull BaseClientMonitor clientMonitor,
1205                                         boolean success) {
1206                                     latch.countDown();
1207                                     if (!success) {
1208                                         Slog.e(TAG, "Sync virtual enrollments failed");
1209                                     }
1210                                 }
1211                             }, true /* favorHalEnrollments */);
1212                 }
1213             }
1214             try {
1215                 latch.await(3, TimeUnit.SECONDS);
1216             } catch (Exception e) {
1217                 Slog.e(TAG, "Failed to wait for sync finishing", e);
1218             }
1219         }
1220     }
1221 
simulateVhalFingerDown()1222     void simulateVhalFingerDown() {
1223         if (Utils.isFingerprintVirtualEnabled(getContext())) {
1224             Slog.i(TAG, "Simulate virtual HAL finger down event");
1225             final Pair<Integer, ServiceProvider> provider = mRegistry.getSingleProvider();
1226             if (provider != null) {
1227                 provider.second.simulateVhalFingerDown(UserHandle.getCallingUserId(),
1228                         provider.first);
1229             }
1230         }
1231     }
1232 
1233     /**
1234      * This should only be called from FingerprintShellCommand
1235      */
sendFingerprintReEnrollNotification()1236     void sendFingerprintReEnrollNotification() {
1237         Utils.checkPermissionOrShell(getContext(), MANAGE_FINGERPRINT);
1238         if (Build.IS_DEBUGGABLE) {
1239             final long identity = Binder.clearCallingIdentity();
1240             try {
1241                 final Pair<Integer, ServiceProvider> provider = mRegistry.getSingleProvider();
1242                 if (provider != null) {
1243                     FingerprintProvider fingerprintProvider = (FingerprintProvider) provider.second;
1244                     fingerprintProvider.sendFingerprintReEnrollNotification();
1245                 } else {
1246                     Slog.w(TAG, "Null provider for notification");
1247                 }
1248             } finally {
1249                 Binder.restoreCallingIdentity(identity);
1250             }
1251         }
1252     }
1253 }
1254