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.face;
18 
19 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
20 import static android.Manifest.permission.MANAGE_BIOMETRIC;
21 import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
22 import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE;
23 
24 import android.annotation.NonNull;
25 import android.annotation.Nullable;
26 import android.content.Context;
27 import android.hardware.biometrics.BiometricManager;
28 import android.hardware.biometrics.BiometricsProtoEnums;
29 import android.hardware.biometrics.IBiometricSensorReceiver;
30 import android.hardware.biometrics.IBiometricService;
31 import android.hardware.biometrics.IBiometricServiceLockoutResetCallback;
32 import android.hardware.biometrics.IInvalidationCallback;
33 import android.hardware.biometrics.ITestSession;
34 import android.hardware.biometrics.ITestSessionCallback;
35 import android.hardware.biometrics.face.IFace;
36 import android.hardware.biometrics.face.SensorProps;
37 import android.hardware.face.Face;
38 import android.hardware.face.FaceSensorPropertiesInternal;
39 import android.hardware.face.FaceServiceReceiver;
40 import android.hardware.face.IFaceService;
41 import android.hardware.face.IFaceServiceReceiver;
42 import android.os.Binder;
43 import android.os.Handler;
44 import android.os.IBinder;
45 import android.os.NativeHandle;
46 import android.os.Process;
47 import android.os.RemoteException;
48 import android.os.ServiceManager;
49 import android.os.UserHandle;
50 import android.util.Pair;
51 import android.util.Slog;
52 import android.util.proto.ProtoOutputStream;
53 import android.view.Surface;
54 
55 import com.android.internal.util.DumpUtils;
56 import com.android.internal.widget.LockPatternUtils;
57 import com.android.server.ServiceThread;
58 import com.android.server.SystemService;
59 import com.android.server.biometrics.Utils;
60 import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
61 import com.android.server.biometrics.sensors.LockoutResetDispatcher;
62 import com.android.server.biometrics.sensors.LockoutTracker;
63 import com.android.server.biometrics.sensors.face.aidl.FaceProvider;
64 import com.android.server.biometrics.sensors.face.hidl.Face10;
65 
66 import java.io.FileDescriptor;
67 import java.io.PrintWriter;
68 import java.util.ArrayList;
69 import java.util.Arrays;
70 import java.util.Collections;
71 import java.util.List;
72 
73 /**
74  * A service to manage multiple clients that want to access the face HAL API.
75  * The service is responsible for maintaining a list of clients and dispatching all
76  * face-related events.
77  */
78 public class FaceService extends SystemService {
79 
80     protected static final String TAG = "FaceService";
81 
82     private final FaceServiceWrapper mServiceWrapper;
83     private final LockoutResetDispatcher mLockoutResetDispatcher;
84     private final LockPatternUtils mLockPatternUtils;
85     @NonNull
86     private final List<ServiceProvider> mServiceProviders;
87 
88     @Nullable
getProviderForSensor(int sensorId)89     private ServiceProvider getProviderForSensor(int sensorId) {
90         for (ServiceProvider provider : mServiceProviders) {
91             if (provider.containsSensor(sensorId)) {
92                 return provider;
93             }
94         }
95         return null;
96     }
97 
98     /**
99      * For devices with only a single provider, returns that provider. If no providers, or multiple
100      * providers exist, returns null.
101      */
102     @Nullable
getSingleProvider()103     private Pair<Integer, ServiceProvider> getSingleProvider() {
104         final List<FaceSensorPropertiesInternal> properties = getSensorProperties();
105         if (properties.size() != 1) {
106             Slog.e(TAG, "Multiple sensors found: " + properties.size());
107             return null;
108         }
109 
110         // Theoretically we can just return the first provider, but maybe this is easier to
111         // understand.
112         final int sensorId = properties.get(0).sensorId;
113         for (ServiceProvider provider : mServiceProviders) {
114             if (provider.containsSensor(sensorId)) {
115                 return new Pair<>(sensorId, provider);
116             }
117         }
118 
119         Slog.e(TAG, "Single sensor, but provider not found");
120         return null;
121     }
122 
123     @NonNull
getSensorProperties()124     private List<FaceSensorPropertiesInternal> getSensorProperties() {
125         final List<FaceSensorPropertiesInternal> properties = new ArrayList<>();
126         for (ServiceProvider provider : mServiceProviders) {
127             properties.addAll(provider.getSensorProperties());
128         }
129         return properties;
130     }
131 
132     /**
133      * Receives the incoming binder calls from FaceManager.
134      */
135     private final class FaceServiceWrapper extends IFaceService.Stub {
136         @Override
createTestSession(int sensorId, @NonNull ITestSessionCallback callback, @NonNull String opPackageName)137         public ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback,
138                 @NonNull String opPackageName) {
139             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
140 
141             final ServiceProvider provider = getProviderForSensor(sensorId);
142 
143             if (provider == null) {
144                 Slog.w(TAG, "Null provider for createTestSession, sensorId: " + sensorId);
145                 return null;
146             }
147 
148             return provider.createTestSession(sensorId, callback, opPackageName);
149         }
150 
151         @Override
dumpSensorServiceStateProto(int sensorId, boolean clearSchedulerBuffer)152         public byte[] dumpSensorServiceStateProto(int sensorId, boolean clearSchedulerBuffer) {
153             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
154 
155             final ProtoOutputStream proto = new ProtoOutputStream();
156             final ServiceProvider provider = getProviderForSensor(sensorId);
157             if (provider != null) {
158                 provider.dumpProtoState(sensorId, proto, clearSchedulerBuffer);
159             }
160             proto.flush();
161             return proto.getBytes();
162         }
163 
164         @Override // Binder call
getSensorPropertiesInternal( String opPackageName)165         public List<FaceSensorPropertiesInternal> getSensorPropertiesInternal(
166                 String opPackageName) {
167             Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
168 
169             return FaceService.this.getSensorProperties();
170         }
171 
172         @Override // Binder call
getSensorProperties(int sensorId, @NonNull String opPackageName)173         public FaceSensorPropertiesInternal getSensorProperties(int sensorId,
174                 @NonNull String opPackageName) {
175             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
176 
177             final ServiceProvider provider = getProviderForSensor(sensorId);
178             if (provider == null) {
179                 Slog.w(TAG, "No matching sensor for getSensorProperties, sensorId: " + sensorId
180                         + ", caller: " + opPackageName);
181                 return null;
182             }
183 
184             return provider.getSensorProperties(sensorId);
185         }
186 
187         @Override // Binder call
generateChallenge(IBinder token, int sensorId, int userId, IFaceServiceReceiver receiver, String opPackageName)188         public void generateChallenge(IBinder token, int sensorId, int userId,
189                 IFaceServiceReceiver receiver, String opPackageName) {
190             Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
191 
192             final ServiceProvider provider = getProviderForSensor(sensorId);
193             if (provider == null) {
194                 Slog.w(TAG, "No matching sensor for generateChallenge, sensorId: " + sensorId);
195                 return;
196             }
197 
198             provider.scheduleGenerateChallenge(sensorId, userId, token, receiver, opPackageName);
199         }
200 
201         @Override // Binder call
revokeChallenge(IBinder token, int sensorId, int userId, String opPackageName, long challenge)202         public void revokeChallenge(IBinder token, int sensorId, int userId, String opPackageName,
203                 long challenge) {
204             Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
205 
206             final ServiceProvider provider = getProviderForSensor(sensorId);
207             if (provider == null) {
208                 Slog.w(TAG, "No matching sensor for revokeChallenge, sensorId: " + sensorId);
209                 return;
210             }
211 
212             provider.scheduleRevokeChallenge(sensorId, userId, token, opPackageName, challenge);
213         }
214 
215         @Override // Binder call
enroll(int userId, final IBinder token, final byte[] hardwareAuthToken, final IFaceServiceReceiver receiver, final String opPackageName, final int[] disabledFeatures, Surface previewSurface, boolean debugConsent)216         public long enroll(int userId, final IBinder token, final byte[] hardwareAuthToken,
217                 final IFaceServiceReceiver receiver, final String opPackageName,
218                 final int[] disabledFeatures, Surface previewSurface, boolean debugConsent) {
219             Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
220 
221             final Pair<Integer, ServiceProvider> provider = getSingleProvider();
222             if (provider == null) {
223                 Slog.w(TAG, "Null provider for enroll");
224                 return -1;
225             }
226 
227             return provider.second.scheduleEnroll(provider.first, token, hardwareAuthToken, userId,
228                     receiver, opPackageName, disabledFeatures, previewSurface, debugConsent);
229         }
230 
231         @Override // Binder call
enrollRemotely(int userId, final IBinder token, final byte[] hardwareAuthToken, final IFaceServiceReceiver receiver, final String opPackageName, final int[] disabledFeatures)232         public long enrollRemotely(int userId, final IBinder token, final byte[] hardwareAuthToken,
233                 final IFaceServiceReceiver receiver, final String opPackageName,
234                 final int[] disabledFeatures) {
235             Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
236             // TODO(b/145027036): Implement this.
237             return -1;
238         }
239 
240         @Override // Binder call
cancelEnrollment(final IBinder token, long requestId)241         public void cancelEnrollment(final IBinder token, long requestId) {
242             Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
243 
244             final Pair<Integer, ServiceProvider> provider = getSingleProvider();
245             if (provider == null) {
246                 Slog.w(TAG, "Null provider for cancelEnrollment");
247                 return;
248             }
249 
250             provider.second.cancelEnrollment(provider.first, token, requestId);
251         }
252 
253         @Override // Binder call
authenticate(final IBinder token, final long operationId, int userId, final IFaceServiceReceiver receiver, final String opPackageName, boolean isKeyguardBypassEnabled)254         public long authenticate(final IBinder token, final long operationId, int userId,
255                 final IFaceServiceReceiver receiver, final String opPackageName,
256                 boolean isKeyguardBypassEnabled) {
257             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
258 
259             // TODO(b/152413782): If the sensor supports face detect and the device is encrypted or
260             //  lockdown, something wrong happened. See similar path in FingerprintService.
261 
262             final boolean restricted = false; // Face APIs are private
263             final int statsClient = Utils.isKeyguard(getContext(), opPackageName)
264                     ? BiometricsProtoEnums.CLIENT_KEYGUARD
265                     : BiometricsProtoEnums.CLIENT_UNKNOWN;
266 
267             // Keyguard check must be done on the caller's binder identity, since it also checks
268             // permission.
269             final boolean isKeyguard = Utils.isKeyguard(getContext(), opPackageName);
270 
271             final Pair<Integer, ServiceProvider> provider = getSingleProvider();
272             if (provider == null) {
273                 Slog.w(TAG, "Null provider for authenticate");
274                 return -1;
275             }
276 
277             return provider.second.scheduleAuthenticate(provider.first, token, operationId, userId,
278                     0 /* cookie */,
279                     new ClientMonitorCallbackConverter(receiver), opPackageName, restricted,
280                     statsClient, isKeyguard, isKeyguardBypassEnabled);
281         }
282 
283         @Override // Binder call
detectFace(final IBinder token, final int userId, final IFaceServiceReceiver receiver, final String opPackageName)284         public long detectFace(final IBinder token, final int userId,
285                 final IFaceServiceReceiver receiver, final String opPackageName) {
286             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
287             if (!Utils.isKeyguard(getContext(), opPackageName)) {
288                 Slog.w(TAG, "detectFace called from non-sysui package: " + opPackageName);
289                 return -1;
290             }
291 
292             if (!Utils.isUserEncryptedOrLockdown(mLockPatternUtils, userId)) {
293                 // If this happens, something in KeyguardUpdateMonitor is wrong. This should only
294                 // ever be invoked when the user is encrypted or lockdown.
295                 Slog.e(TAG, "detectFace invoked when user is not encrypted or lockdown");
296                 return -1;
297             }
298 
299             final Pair<Integer, ServiceProvider> provider = getSingleProvider();
300             if (provider == null) {
301                 Slog.w(TAG, "Null provider for detectFace");
302                 return -1;
303             }
304 
305             return provider.second.scheduleFaceDetect(provider.first, token, userId,
306                     new ClientMonitorCallbackConverter(receiver), opPackageName,
307                     BiometricsProtoEnums.CLIENT_KEYGUARD);
308         }
309 
310         @Override // Binder call
prepareForAuthentication(int sensorId, boolean requireConfirmation, IBinder token, long operationId, int userId, IBiometricSensorReceiver sensorReceiver, String opPackageName, long requestId, int cookie, boolean allowBackgroundAuthentication)311         public void prepareForAuthentication(int sensorId, boolean requireConfirmation,
312                 IBinder token, long operationId, int userId,
313                 IBiometricSensorReceiver sensorReceiver, String opPackageName, long requestId,
314                 int cookie, boolean allowBackgroundAuthentication) {
315             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
316 
317             final ServiceProvider provider = getProviderForSensor(sensorId);
318             if (provider == null) {
319                 Slog.w(TAG, "Null provider for prepareForAuthentication");
320                 return;
321             }
322 
323             final boolean isKeyguardBypassEnabled = false; // only valid for keyguard clients
324             final boolean restricted = true; // BiometricPrompt is always restricted
325             provider.scheduleAuthenticate(sensorId, token, operationId, userId, cookie,
326                     new ClientMonitorCallbackConverter(sensorReceiver), opPackageName, requestId,
327                     restricted, BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT,
328                     allowBackgroundAuthentication, isKeyguardBypassEnabled);
329         }
330 
331         @Override // Binder call
startPreparedClient(int sensorId, int cookie)332         public void startPreparedClient(int sensorId, int cookie) {
333             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
334 
335             final ServiceProvider provider = getProviderForSensor(sensorId);
336             if (provider == null) {
337                 Slog.w(TAG, "Null provider for startPreparedClient");
338                 return;
339             }
340 
341             provider.startPreparedClient(sensorId, cookie);
342         }
343 
344         @Override // Binder call
cancelAuthentication(final IBinder token, final String opPackageName, final long requestId)345         public void cancelAuthentication(final IBinder token, final String opPackageName,
346                 final long requestId) {
347             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
348 
349             final Pair<Integer, ServiceProvider> provider = getSingleProvider();
350             if (provider == null) {
351                 Slog.w(TAG, "Null provider for cancelAuthentication");
352                 return;
353             }
354 
355             provider.second.cancelAuthentication(provider.first, token, requestId);
356         }
357 
358         @Override // Binder call
cancelFaceDetect(final IBinder token, final String opPackageName, final long requestId)359         public void cancelFaceDetect(final IBinder token, final String opPackageName,
360                 final long requestId) {
361             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
362             if (!Utils.isKeyguard(getContext(), opPackageName)) {
363                 Slog.w(TAG, "cancelFaceDetect called from non-sysui package: "
364                         + opPackageName);
365                 return;
366             }
367 
368             final Pair<Integer, ServiceProvider> provider = getSingleProvider();
369             if (provider == null) {
370                 Slog.w(TAG, "Null provider for cancelFaceDetect");
371                 return;
372             }
373 
374             provider.second.cancelFaceDetect(provider.first, token, requestId);
375         }
376 
377         @Override // Binder call
cancelAuthenticationFromService(int sensorId, final IBinder token, final String opPackageName, final long requestId)378         public void cancelAuthenticationFromService(int sensorId, final IBinder token,
379                 final String opPackageName, final long requestId) {
380             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
381 
382             final ServiceProvider provider = getProviderForSensor(sensorId);
383             if (provider == null) {
384                 Slog.w(TAG, "Null provider for cancelAuthenticationFromService");
385                 return;
386             }
387 
388             provider.cancelAuthentication(sensorId, token, requestId);
389         }
390 
391         @Override // Binder call
remove(final IBinder token, final int faceId, final int userId, final IFaceServiceReceiver receiver, final String opPackageName)392         public void remove(final IBinder token, final int faceId, final int userId,
393                 final IFaceServiceReceiver receiver, final String opPackageName) {
394             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
395 
396             final Pair<Integer, ServiceProvider> provider = getSingleProvider();
397             if (provider == null) {
398                 Slog.w(TAG, "Null provider for remove");
399                 return;
400             }
401 
402             provider.second.scheduleRemove(provider.first, token, faceId, userId, receiver,
403                     opPackageName);
404         }
405 
406         @Override // Binder call
removeAll(final IBinder token, final int userId, final IFaceServiceReceiver receiver, final String opPackageName)407         public void removeAll(final IBinder token, final int userId,
408                 final IFaceServiceReceiver receiver, final String opPackageName) {
409             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
410 
411             final FaceServiceReceiver internalReceiver = new FaceServiceReceiver() {
412                 int sensorsFinishedRemoving = 0;
413                 final int numSensors = getSensorPropertiesInternal(
414                         getContext().getOpPackageName()).size();
415                 @Override
416                 public void onRemoved(Face face, int remaining) throws RemoteException {
417                     if (remaining == 0) {
418                         sensorsFinishedRemoving++;
419                         Slog.d(TAG, "sensorsFinishedRemoving: " + sensorsFinishedRemoving
420                                 + ", numSensors: " + numSensors);
421                         if (sensorsFinishedRemoving == numSensors) {
422                             receiver.onRemoved(null, 0 /* remaining */);
423                         }
424                     }
425                 }
426             };
427 
428             // This effectively iterates through all sensors, but has to do so by finding all
429             // sensors under each provider.
430             for (ServiceProvider provider : mServiceProviders) {
431                 List<FaceSensorPropertiesInternal> props = provider.getSensorProperties();
432                 for (FaceSensorPropertiesInternal prop : props) {
433                     provider.scheduleRemoveAll(prop.sensorId, token, userId, internalReceiver,
434                             opPackageName);
435                 }
436             }
437         }
438 
439         @Override // Binder call
addLockoutResetCallback(final IBiometricServiceLockoutResetCallback callback, final String opPackageName)440         public void addLockoutResetCallback(final IBiometricServiceLockoutResetCallback callback,
441                 final String opPackageName) {
442             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
443             mLockoutResetDispatcher.addCallback(callback, opPackageName);
444         }
445 
446         @Override // Binder call
dump(@onNull FileDescriptor fd, @NonNull PrintWriter pw, String[] args)447         protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, String[] args) {
448             if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) {
449                 return;
450             }
451 
452             final long ident = Binder.clearCallingIdentity();
453             try {
454                 if (args.length > 1 && "--proto".equals(args[0]) && "--state".equals(args[1])) {
455                     final ProtoOutputStream proto = new ProtoOutputStream(fd);
456                     for (ServiceProvider provider : mServiceProviders) {
457                         for (FaceSensorPropertiesInternal props : provider.getSensorProperties()) {
458                             provider.dumpProtoState(props.sensorId, proto, false);
459                         }
460                     }
461                     proto.flush();
462                 } else if (args.length > 0 && "--proto".equals(args[0])) {
463                     for (ServiceProvider provider : mServiceProviders) {
464                         for (FaceSensorPropertiesInternal props : provider.getSensorProperties()) {
465                             provider.dumpProtoMetrics(props.sensorId, fd);
466                         }
467                     }
468                 } else if (args.length > 1 && "--hal".equals(args[0])) {
469                     for (ServiceProvider provider : mServiceProviders) {
470                         for (FaceSensorPropertiesInternal props : provider.getSensorProperties()) {
471                             provider.dumpHal(props.sensorId, fd,
472                                     Arrays.copyOfRange(args, 1, args.length, args.getClass()));
473                         }
474                     }
475                 } else {
476                     for (ServiceProvider provider : mServiceProviders) {
477                         for (FaceSensorPropertiesInternal props : provider.getSensorProperties()) {
478                             pw.println("Dumping for sensorId: " + props.sensorId
479                                     + ", provider: " + provider.getClass().getSimpleName());
480                             provider.dumpInternal(props.sensorId, pw);
481                             pw.println();
482                         }
483                     }
484                 }
485             } finally {
486                 Binder.restoreCallingIdentity(ident);
487             }
488         }
489 
490         @Override // Binder call
isHardwareDetected(int sensorId, String opPackageName)491         public boolean isHardwareDetected(int sensorId, String opPackageName) {
492             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
493 
494             final long token = Binder.clearCallingIdentity();
495             try {
496                 final ServiceProvider provider = getProviderForSensor(sensorId);
497                 if (provider == null) {
498                     Slog.w(TAG, "Null provider for isHardwareDetected, caller: " + opPackageName);
499                     return false;
500                 }
501                 return provider.isHardwareDetected(sensorId);
502             } finally {
503                 Binder.restoreCallingIdentity(token);
504             }
505         }
506 
507         @Override // Binder call
getEnrolledFaces(int sensorId, int userId, String opPackageName)508         public List<Face> getEnrolledFaces(int sensorId, int userId, String opPackageName) {
509             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
510 
511             if (userId != UserHandle.getCallingUserId()) {
512                 Utils.checkPermission(getContext(), INTERACT_ACROSS_USERS);
513             }
514 
515             final ServiceProvider provider = getProviderForSensor(sensorId);
516             if (provider == null) {
517                 Slog.w(TAG, "Null provider for getEnrolledFaces, caller: " + opPackageName);
518                 return Collections.emptyList();
519             }
520 
521             return provider.getEnrolledFaces(sensorId, userId);
522         }
523 
524         @Override // Binder call
hasEnrolledFaces(int sensorId, int userId, String opPackageName)525         public boolean hasEnrolledFaces(int sensorId, int userId, String opPackageName) {
526             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
527 
528             if (userId != UserHandle.getCallingUserId()) {
529                 Utils.checkPermission(getContext(), INTERACT_ACROSS_USERS);
530             }
531 
532             final ServiceProvider provider = getProviderForSensor(sensorId);
533             if (provider == null) {
534                 Slog.w(TAG, "Null provider for hasEnrolledFaces, caller: " + opPackageName);
535                 return false;
536             }
537 
538             return provider.getEnrolledFaces(sensorId, userId).size() > 0;
539         }
540 
541         @Override // Binder call
getLockoutModeForUser(int sensorId, int userId)542         public @LockoutTracker.LockoutMode int getLockoutModeForUser(int sensorId, int userId) {
543             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
544 
545             final ServiceProvider provider = getProviderForSensor(sensorId);
546             if (provider == null) {
547                 Slog.w(TAG, "Null provider for getLockoutModeForUser");
548                 return LockoutTracker.LOCKOUT_NONE;
549             }
550 
551             return provider.getLockoutModeForUser(sensorId, userId);
552         }
553 
554         @Override
invalidateAuthenticatorId(int sensorId, int userId, IInvalidationCallback callback)555         public void invalidateAuthenticatorId(int sensorId, int userId,
556                 IInvalidationCallback callback) {
557             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
558 
559             final ServiceProvider provider = getProviderForSensor(sensorId);
560             if (provider == null) {
561                 Slog.w(TAG, "Null provider for invalidateAuthenticatorId");
562                 return;
563             }
564             provider.scheduleInvalidateAuthenticatorId(sensorId, userId, callback);
565         }
566 
567         @Override // Binder call
getAuthenticatorId(int sensorId, int userId)568         public long getAuthenticatorId(int sensorId, int userId) {
569             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
570 
571             final ServiceProvider provider = getProviderForSensor(sensorId);
572             if (provider == null) {
573                 Slog.w(TAG, "Null provider for getAuthenticatorId");
574                 return 0;
575             }
576 
577             return provider.getAuthenticatorId(sensorId, userId);
578         }
579 
580         @Override // Binder call
resetLockout(IBinder token, int sensorId, int userId, byte[] hardwareAuthToken, String opPackageName)581         public void resetLockout(IBinder token, int sensorId, int userId, byte[] hardwareAuthToken,
582                 String opPackageName) {
583             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
584 
585             final ServiceProvider provider = getProviderForSensor(sensorId);
586             if (provider == null) {
587                 Slog.w(TAG, "Null provider for resetLockout, caller: " + opPackageName);
588                 return;
589             }
590 
591             provider.scheduleResetLockout(sensorId, userId, hardwareAuthToken);
592         }
593 
594         @Override
setFeature(final IBinder token, int userId, int feature, boolean enabled, final byte[] hardwareAuthToken, IFaceServiceReceiver receiver, final String opPackageName)595         public void setFeature(final IBinder token, int userId, int feature, boolean enabled,
596                 final byte[] hardwareAuthToken, IFaceServiceReceiver receiver,
597                 final String opPackageName) {
598             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
599 
600             final Pair<Integer, ServiceProvider> provider = getSingleProvider();
601             if (provider == null) {
602                 Slog.w(TAG, "Null provider for setFeature");
603                 return;
604             }
605 
606             provider.second.scheduleSetFeature(provider.first, token, userId, feature, enabled,
607                     hardwareAuthToken, receiver, opPackageName);
608         }
609 
610         @Override
getFeature(final IBinder token, int userId, int feature, IFaceServiceReceiver receiver, final String opPackageName)611         public void getFeature(final IBinder token, int userId, int feature,
612                 IFaceServiceReceiver receiver, final String opPackageName) {
613             Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
614 
615             final Pair<Integer, ServiceProvider> provider = getSingleProvider();
616             if (provider == null) {
617                 Slog.w(TAG, "Null provider for getFeature");
618                 return;
619             }
620 
621             provider.second.scheduleGetFeature(provider.first, token, userId, feature,
622                     new ClientMonitorCallbackConverter(receiver), opPackageName);
623         }
624 
addHidlProviders(@onNull List<FaceSensorPropertiesInternal> hidlSensors)625         private void addHidlProviders(@NonNull List<FaceSensorPropertiesInternal> hidlSensors) {
626             for (FaceSensorPropertiesInternal hidlSensor : hidlSensors) {
627                 mServiceProviders.add(
628                         Face10.newInstance(getContext(), hidlSensor, mLockoutResetDispatcher));
629             }
630         }
631 
addAidlProviders()632         private void addAidlProviders() {
633             final String[] instances = ServiceManager.getDeclaredInstances(IFace.DESCRIPTOR);
634             if (instances == null || instances.length == 0) {
635                 return;
636             }
637             for (String instance : instances) {
638                 final String fqName = IFace.DESCRIPTOR + "/" + instance;
639                 final IFace face = IFace.Stub.asInterface(
640                         Binder.allowBlocking(ServiceManager.waitForDeclaredService(fqName)));
641                 if (face == null) {
642                     Slog.e(TAG, "Unable to get declared service: " + fqName);
643                     continue;
644                 }
645                 try {
646                     final SensorProps[] props = face.getSensorProps();
647                     final FaceProvider provider = new FaceProvider(getContext(), props, instance,
648                             mLockoutResetDispatcher);
649                     mServiceProviders.add(provider);
650                 } catch (RemoteException e) {
651                     Slog.e(TAG, "Remote exception in getSensorProps: " + fqName);
652                 }
653             }
654         }
655 
656         @Override // Binder call
registerAuthenticators( @onNull List<FaceSensorPropertiesInternal> hidlSensors)657         public void registerAuthenticators(
658                 @NonNull List<FaceSensorPropertiesInternal> hidlSensors) {
659             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
660 
661             // Some HAL might not be started before the system service and will cause the code below
662             // to wait, and some of the operations below might take a significant amount of time to
663             // complete (calls to the HALs). To avoid blocking the rest of system server we put
664             // this on a background thread.
665             final ServiceThread thread = new ServiceThread(TAG, Process.THREAD_PRIORITY_BACKGROUND,
666                     true /* allowIo */);
667             thread.start();
668             final Handler handler = new Handler(thread.getLooper());
669 
670             handler.post(() -> {
671                 addHidlProviders(hidlSensors);
672                 addAidlProviders();
673 
674                 final IBiometricService biometricService = IBiometricService.Stub.asInterface(
675                         ServiceManager.getService(Context.BIOMETRIC_SERVICE));
676 
677                 // Register each sensor individually with BiometricService
678                 for (ServiceProvider provider : mServiceProviders) {
679                     final List<FaceSensorPropertiesInternal> props = provider.getSensorProperties();
680                     for (FaceSensorPropertiesInternal prop : props) {
681                         final int sensorId = prop.sensorId;
682                         final @BiometricManager.Authenticators.Types int strength =
683                                 Utils.propertyStrengthToAuthenticatorStrength(prop.sensorStrength);
684                         final FaceAuthenticator authenticator = new FaceAuthenticator(
685                                 mServiceWrapper, sensorId);
686                         try {
687                             biometricService.registerAuthenticator(sensorId, TYPE_FACE, strength,
688                                     authenticator);
689                         } catch (RemoteException e) {
690                             Slog.e(TAG, "Remote exception when registering sensorId: " + sensorId);
691                         }
692                     }
693                 }
694             });
695         }
696     }
697 
FaceService(Context context)698     public FaceService(Context context) {
699         super(context);
700         mServiceWrapper = new FaceServiceWrapper();
701         mLockoutResetDispatcher = new LockoutResetDispatcher(context);
702         mLockPatternUtils = new LockPatternUtils(context);
703         mServiceProviders = new ArrayList<>();
704     }
705 
706     @Override
onStart()707     public void onStart() {
708         publishBinderService(Context.FACE_SERVICE, mServiceWrapper);
709     }
710 
711     /**
712      * Acquires a NativeHandle that can be used to access the provided surface. The returned handle
713      * must be explicitly released with {@link #releaseSurfaceHandle(NativeHandle)} to avoid memory
714      * leaks.
715      *
716      * The caller is responsible for ensuring that the surface is valid while using the handle.
717      * This method provides no lifecycle synchronization between the surface and the handle.
718      *
719      * @param surface a valid Surface.
720      * @return {@link android.os.NativeHandle} a NativeHandle for the provided surface.
721      */
acquireSurfaceHandle(@onNull Surface surface)722     public static native NativeHandle acquireSurfaceHandle(@NonNull Surface surface);
723 
724     /**
725      * Releases resources associated with a NativeHandle that was acquired with
726      * {@link #acquireSurfaceHandle(Surface)}.
727      *
728      * This method has no affect on the surface for which the handle was acquired. It only frees up
729      * the resources that are associated with the handle.
730      *
731      * @param handle a handle that was obtained from {@link #acquireSurfaceHandle(Surface)}.
732      */
releaseSurfaceHandle(@onNull NativeHandle handle)733     public static native void releaseSurfaceHandle(@NonNull NativeHandle handle);
734 }
735