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