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