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