1 /* 2 * Copyright (C) 2014 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 android.hardware.fingerprint; 18 19 import static android.Manifest.permission.INTERACT_ACROSS_USERS; 20 import static android.Manifest.permission.MANAGE_FINGERPRINT; 21 import static android.Manifest.permission.RESET_FINGERPRINT_LOCKOUT; 22 import static android.Manifest.permission.TEST_BIOMETRIC; 23 import static android.Manifest.permission.USE_BIOMETRIC; 24 import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL; 25 import static android.Manifest.permission.USE_FINGERPRINT; 26 import static android.hardware.biometrics.BiometricConstants.BIOMETRIC_LOCKOUT_NONE; 27 import static android.hardware.biometrics.Flags.FLAG_ADD_KEY_AGREEMENT_CRYPTO_OBJECT; 28 import static android.hardware.fingerprint.FingerprintCallback.REMOVE_ALL; 29 import static android.hardware.fingerprint.FingerprintCallback.REMOVE_SINGLE; 30 import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_POWER_BUTTON; 31 32 import static com.android.internal.util.FrameworkStatsLog.AUTH_DEPRECATED_APIUSED__DEPRECATED_API__API_FINGERPRINT_MANAGER_AUTHENTICATE; 33 import static com.android.internal.util.FrameworkStatsLog.AUTH_DEPRECATED_APIUSED__DEPRECATED_API__API_FINGERPRINT_MANAGER_HAS_ENROLLED_FINGERPRINTS; 34 import static com.android.internal.util.FrameworkStatsLog.AUTH_DEPRECATED_APIUSED__DEPRECATED_API__API_FINGERPRINT_MANAGER_IS_HARDWARE_DETECTED; 35 36 import android.annotation.FlaggedApi; 37 import android.annotation.IntDef; 38 import android.annotation.NonNull; 39 import android.annotation.Nullable; 40 import android.annotation.RequiresFeature; 41 import android.annotation.RequiresPermission; 42 import android.annotation.SystemService; 43 import android.annotation.TestApi; 44 import android.app.ActivityManager; 45 import android.compat.annotation.UnsupportedAppUsage; 46 import android.content.Context; 47 import android.content.pm.PackageManager; 48 import android.hardware.biometrics.BiometricAuthenticator; 49 import android.hardware.biometrics.BiometricConstants; 50 import android.hardware.biometrics.BiometricFingerprintConstants; 51 import android.hardware.biometrics.BiometricPrompt; 52 import android.hardware.biometrics.BiometricStateListener; 53 import android.hardware.biometrics.BiometricTestSession; 54 import android.hardware.biometrics.IBiometricServiceLockoutResetCallback; 55 import android.hardware.biometrics.SensorProperties; 56 import android.hardware.biometrics.fingerprint.PointerContext; 57 import android.os.Binder; 58 import android.os.Build; 59 import android.os.CancellationSignal; 60 import android.os.CancellationSignal.OnCancelListener; 61 import android.os.Handler; 62 import android.os.HandlerExecutor; 63 import android.os.IBinder; 64 import android.os.IRemoteCallback; 65 import android.os.PowerManager; 66 import android.os.RemoteException; 67 import android.os.UserHandle; 68 import android.security.identity.IdentityCredential; 69 import android.security.identity.PresentationSession; 70 import android.util.Slog; 71 import android.view.Surface; 72 73 import com.android.internal.util.FrameworkStatsLog; 74 75 import java.lang.annotation.Retention; 76 import java.lang.annotation.RetentionPolicy; 77 import java.security.Signature; 78 import java.util.ArrayList; 79 import java.util.List; 80 import java.util.concurrent.Executor; 81 82 import javax.crypto.Cipher; 83 import javax.crypto.KeyAgreement; 84 import javax.crypto.Mac; 85 86 /** 87 * A class that coordinates access to the fingerprint hardware. 88 * @deprecated See {@link BiometricPrompt} which shows a system-provided dialog upon starting 89 * authentication. In a world where devices may have different types of biometric authentication, 90 * it's much more realistic to have a system-provided authentication dialog since the method may 91 * vary by vendor/device. 92 */ 93 @SuppressWarnings("deprecation") 94 @Deprecated 95 @SystemService(Context.FINGERPRINT_SERVICE) 96 @RequiresFeature(PackageManager.FEATURE_FINGERPRINT) 97 public class FingerprintManager implements BiometricAuthenticator, BiometricFingerprintConstants { 98 private static final String TAG = "FingerprintManager"; 99 100 /** 101 * @hide 102 */ 103 public static final int ENROLL_FIND_SENSOR = 1; 104 /** 105 * @hide 106 */ 107 public static final int ENROLL_ENROLL = 2; 108 109 /** 110 * @hide 111 */ 112 @IntDef({ENROLL_FIND_SENSOR, ENROLL_ENROLL}) 113 @Retention(RetentionPolicy.SOURCE) 114 public @interface EnrollReason {} 115 116 /** 117 * Udfps ui event of overlay is shown on the screen. 118 * @hide 119 */ 120 public static final int UDFPS_UI_OVERLAY_SHOWN = 1; 121 /** 122 * Udfps ui event of the udfps UI being ready (e.g. HBM illumination is enabled). 123 * @hide 124 */ 125 public static final int UDFPS_UI_READY = 2; 126 127 /** 128 * @hide 129 */ 130 @IntDef({UDFPS_UI_OVERLAY_SHOWN, UDFPS_UI_READY}) 131 @Retention(RetentionPolicy.SOURCE) 132 public @interface UdfpsUiEvent{} 133 134 /** 135 * Request authentication with any single sensor. 136 * @hide 137 */ 138 public static final int SENSOR_ID_ANY = -1; 139 140 private final IFingerprintService mService; 141 private final Context mContext; 142 private final IBinder mToken = new Binder(); 143 144 private Handler mHandler; 145 @Nullable private float[] mEnrollStageThresholds; 146 private List<FingerprintSensorPropertiesInternal> mProps = new ArrayList<>(); 147 private HandlerExecutor mExecutor; 148 149 /** 150 * Retrieves a list of properties for all fingerprint sensors on the device. 151 * @hide 152 */ 153 @TestApi 154 @NonNull 155 @RequiresPermission(TEST_BIOMETRIC) getSensorProperties()156 public List<SensorProperties> getSensorProperties() { 157 final List<SensorProperties> properties = new ArrayList<>(); 158 final List<FingerprintSensorPropertiesInternal> internalProperties 159 = getSensorPropertiesInternal(); 160 for (FingerprintSensorPropertiesInternal internalProp : internalProperties) { 161 properties.add(FingerprintSensorProperties.from(internalProp)); 162 } 163 return properties; 164 } 165 166 /** 167 * Retrieves a test session for FingerprintManager. 168 * @hide 169 */ 170 @TestApi 171 @NonNull 172 @RequiresPermission(TEST_BIOMETRIC) createTestSession(int sensorId)173 public BiometricTestSession createTestSession(int sensorId) { 174 try { 175 return new BiometricTestSession(mContext, sensorId, 176 (context, sensorId1, callback) -> mService 177 .createTestSession(sensorId1, callback, context.getOpPackageName())); 178 } catch (RemoteException e) { 179 throw e.rethrowFromSystemServer(); 180 } 181 } 182 183 private class OnEnrollCancelListener implements OnCancelListener { 184 private final long mAuthRequestId; 185 OnEnrollCancelListener(long id)186 private OnEnrollCancelListener(long id) { 187 mAuthRequestId = id; 188 } 189 190 @Override onCancel()191 public void onCancel() { 192 Slog.d(TAG, "Cancel fingerprint enrollment requested for: " + mAuthRequestId); 193 cancelEnrollment(mAuthRequestId); 194 } 195 } 196 197 private class OnAuthenticationCancelListener implements OnCancelListener { 198 private final long mAuthRequestId; 199 OnAuthenticationCancelListener(long id)200 OnAuthenticationCancelListener(long id) { 201 mAuthRequestId = id; 202 } 203 204 @Override onCancel()205 public void onCancel() { 206 Slog.d(TAG, "Cancel fingerprint authentication requested for: " + mAuthRequestId); 207 cancelAuthentication(mAuthRequestId); 208 } 209 } 210 211 private class OnFingerprintDetectionCancelListener implements OnCancelListener { 212 private final long mAuthRequestId; 213 OnFingerprintDetectionCancelListener(long id)214 OnFingerprintDetectionCancelListener(long id) { 215 mAuthRequestId = id; 216 } 217 218 @Override onCancel()219 public void onCancel() { 220 Slog.d(TAG, "Cancel fingerprint detect requested for: " + mAuthRequestId); 221 cancelFingerprintDetect(mAuthRequestId); 222 } 223 } 224 225 /** 226 * A wrapper class for the crypto objects supported by FingerprintManager. Currently the 227 * framework supports {@link Signature}, {@link Cipher} and {@link Mac} objects. 228 * @deprecated See {@link android.hardware.biometrics.BiometricPrompt.CryptoObject} 229 */ 230 @Deprecated 231 public static final class CryptoObject extends android.hardware.biometrics.CryptoObject { CryptoObject(@onNull Signature signature)232 public CryptoObject(@NonNull Signature signature) { 233 super(signature); 234 } 235 CryptoObject(@onNull Cipher cipher)236 public CryptoObject(@NonNull Cipher cipher) { 237 super(cipher); 238 } 239 CryptoObject(@onNull Mac mac)240 public CryptoObject(@NonNull Mac mac) { 241 super(mac); 242 } 243 244 /** 245 * Get {@link Signature} object. 246 * @return {@link Signature} object or null if this doesn't contain one. 247 */ getSignature()248 public Signature getSignature() { 249 return super.getSignature(); 250 } 251 252 /** 253 * Get {@link Cipher} object. 254 * @return {@link Cipher} object or null if this doesn't contain one. 255 */ getCipher()256 public Cipher getCipher() { 257 return super.getCipher(); 258 } 259 260 /** 261 * Get {@link Mac} object. 262 * @return {@link Mac} object or null if this doesn't contain one. 263 */ getMac()264 public Mac getMac() { 265 return super.getMac(); 266 } 267 268 /** 269 * Get {@link IdentityCredential} object. 270 * @return {@link IdentityCredential} object or null if this doesn't contain one. 271 * @hide 272 * @deprecated Use {@link PresentationSession} instead of {@link IdentityCredential}. 273 */ 274 @Deprecated getIdentityCredential()275 public IdentityCredential getIdentityCredential() { 276 return super.getIdentityCredential(); 277 } 278 279 /** 280 * Get {@link PresentationSession} object. 281 * @return {@link PresentationSession} object or null if this doesn't contain one. 282 * @hide 283 */ getPresentationSession()284 public PresentationSession getPresentationSession() { 285 return super.getPresentationSession(); 286 } 287 288 /** 289 * Get {@link KeyAgreement} object. 290 * @return {@link KeyAgreement} object or null if this doesn't contain one. 291 * @hide 292 */ 293 @FlaggedApi(FLAG_ADD_KEY_AGREEMENT_CRYPTO_OBJECT) getKeyAgreement()294 public KeyAgreement getKeyAgreement() { 295 return super.getKeyAgreement(); 296 } 297 } 298 299 /** 300 * Container for callback data from {@link FingerprintManager#authenticate(CryptoObject, 301 * CancellationSignal, int, AuthenticationCallback, Handler)}. 302 * @deprecated See {@link android.hardware.biometrics.BiometricPrompt.AuthenticationResult} 303 */ 304 @Deprecated 305 public static class AuthenticationResult { 306 private Fingerprint mFingerprint; 307 private CryptoObject mCryptoObject; 308 private int mUserId; 309 private boolean mIsStrongBiometric; 310 311 /** 312 * Authentication result 313 * 314 * @param crypto the crypto object 315 * @param fingerprint the recognized fingerprint data, if allowed. 316 * @hide 317 */ AuthenticationResult(CryptoObject crypto, Fingerprint fingerprint, int userId, boolean isStrongBiometric)318 public AuthenticationResult(CryptoObject crypto, Fingerprint fingerprint, int userId, 319 boolean isStrongBiometric) { 320 mCryptoObject = crypto; 321 mFingerprint = fingerprint; 322 mUserId = userId; 323 mIsStrongBiometric = isStrongBiometric; 324 } 325 326 /** 327 * Obtain the crypto object associated with this transaction 328 * @return crypto object provided to {@link FingerprintManager#authenticate(CryptoObject, 329 * CancellationSignal, int, AuthenticationCallback, Handler)}. 330 */ getCryptoObject()331 public CryptoObject getCryptoObject() { return mCryptoObject; } 332 333 /** 334 * Obtain the Fingerprint associated with this operation. Applications are strongly 335 * discouraged from associating specific fingers with specific applications or operations. 336 * 337 * @hide 338 */ 339 @UnsupportedAppUsage getFingerprint()340 public Fingerprint getFingerprint() { return mFingerprint; } 341 342 /** 343 * Obtain the userId for which this fingerprint was authenticated. 344 * @hide 345 */ getUserId()346 public int getUserId() { return mUserId; } 347 348 /** 349 * Check whether the strength of the fingerprint modality associated with this operation is 350 * strong (i.e. not weak or convenience). 351 * @hide 352 */ isStrongBiometric()353 public boolean isStrongBiometric() { 354 return mIsStrongBiometric; 355 } 356 } 357 358 /** 359 * Callback structure provided to {@link FingerprintManager#authenticate(CryptoObject, 360 * CancellationSignal, int, AuthenticationCallback, Handler)}. Users of {@link 361 * FingerprintManager#authenticate(CryptoObject, CancellationSignal, 362 * int, AuthenticationCallback, Handler) } must provide an implementation of this for listening to 363 * fingerprint events. 364 * @deprecated See {@link android.hardware.biometrics.BiometricPrompt.AuthenticationCallback} 365 */ 366 @Deprecated 367 public abstract static class AuthenticationCallback 368 extends BiometricAuthenticator.AuthenticationCallback { 369 /** 370 * Called when an unrecoverable error has been encountered and the operation is complete. 371 * No further callbacks will be made on this object. 372 * @param errorCode An integer identifying the error message 373 * @param errString A human-readable error string that can be shown in UI 374 */ 375 @Override onAuthenticationError(int errorCode, CharSequence errString)376 public void onAuthenticationError(int errorCode, CharSequence errString) { } 377 378 /** 379 * Called when a recoverable error has been encountered during authentication. The help 380 * string is provided to give the user guidance for what went wrong, such as 381 * "Sensor dirty, please clean it." 382 * @param helpCode An integer identifying the error message 383 * @param helpString A human-readable string that can be shown in UI 384 */ 385 @Override onAuthenticationHelp(int helpCode, CharSequence helpString)386 public void onAuthenticationHelp(int helpCode, CharSequence helpString) { } 387 388 /** 389 * Called when a fingerprint is recognized. 390 * @param result An object containing authentication-related data 391 */ onAuthenticationSucceeded(AuthenticationResult result)392 public void onAuthenticationSucceeded(AuthenticationResult result) { } 393 394 /** 395 * Called when a fingerprint is valid but not recognized. 396 */ 397 @Override onAuthenticationFailed()398 public void onAuthenticationFailed() { } 399 400 /** 401 * Called when a fingerprint image has been acquired, but wasn't processed yet. 402 * 403 * @param acquireInfo one of FINGERPRINT_ACQUIRED_* constants 404 * @hide 405 */ 406 @Override onAuthenticationAcquired(int acquireInfo)407 public void onAuthenticationAcquired(int acquireInfo) {} 408 409 /** 410 * Invoked for under-display fingerprint sensors when a touch has been detected on the 411 * sensor area. 412 * @hide 413 */ onUdfpsPointerDown(int sensorId)414 public void onUdfpsPointerDown(int sensorId) {} 415 416 /** 417 * Invoked for under-display fingerprint sensors when a touch has been removed from the 418 * sensor area. 419 * @hide 420 */ onUdfpsPointerUp(int sensorId)421 public void onUdfpsPointerUp(int sensorId) {} 422 } 423 424 /** 425 * Callback structure provided for {@link #detectFingerprint(CancellationSignal, 426 * FingerprintDetectionCallback, int, Surface)}. 427 * @hide 428 */ 429 public interface FingerprintDetectionCallback { 430 /** 431 * Invoked when a fingerprint has been detected. 432 */ onFingerprintDetected(int sensorId, int userId, boolean isStrongBiometric)433 void onFingerprintDetected(int sensorId, int userId, boolean isStrongBiometric); 434 435 /** 436 * An error has occurred with fingerprint detection. 437 * 438 * This callback signifies that this operation has been completed, and 439 * no more callbacks should be expected. 440 */ onDetectionError(int errorMsgId)441 default void onDetectionError(int errorMsgId) {} 442 } 443 444 /** 445 * Callback structure provided to {@link FingerprintManager#enroll(byte[], CancellationSignal, 446 * int, EnrollmentCallback)} must provide an implementation of this for listening to 447 * fingerprint events. 448 * 449 * @hide 450 */ 451 public abstract static class EnrollmentCallback { 452 /** 453 * Called when an unrecoverable error has been encountered and the operation is complete. 454 * No further callbacks will be made on this object. 455 * @param errMsgId An integer identifying the error message 456 * @param errString A human-readable error string that can be shown in UI 457 */ onEnrollmentError(int errMsgId, CharSequence errString)458 public void onEnrollmentError(int errMsgId, CharSequence errString) { } 459 460 /** 461 * Called when a recoverable error has been encountered during enrollment. The help 462 * string is provided to give the user guidance for what went wrong, such as 463 * "Sensor dirty, please clean it" or what they need to do next, such as 464 * "Touch sensor again." 465 * @param helpMsgId An integer identifying the error message 466 * @param helpString A human-readable string that can be shown in UI 467 */ onEnrollmentHelp(int helpMsgId, CharSequence helpString)468 public void onEnrollmentHelp(int helpMsgId, CharSequence helpString) { } 469 470 /** 471 * Called as each enrollment step progresses. Enrollment is considered complete when 472 * remaining reaches 0. This function will not be called if enrollment fails. See 473 * {@link EnrollmentCallback#onEnrollmentError(int, CharSequence)} 474 * @param remaining The number of remaining steps 475 */ onEnrollmentProgress(int remaining)476 public void onEnrollmentProgress(int remaining) { } 477 478 /** 479 * Called when a fingerprint image has been acquired. 480 * @param isAcquiredGood whether the fingerprint image was good. 481 */ onAcquired(boolean isAcquiredGood)482 public void onAcquired(boolean isAcquiredGood){ } 483 484 /** 485 * Called when a pointer down event has occurred. 486 */ onUdfpsPointerDown(int sensorId)487 public void onUdfpsPointerDown(int sensorId){ } 488 489 /** 490 * Called when a pointer up event has occurred. 491 */ onUdfpsPointerUp(int sensorId)492 public void onUdfpsPointerUp(int sensorId){ } 493 494 /** 495 * Called when udfps overlay is shown. 496 */ onUdfpsOverlayShown()497 public void onUdfpsOverlayShown() { } 498 } 499 500 /** 501 * Callback structure provided to {@link #remove}. Users of {@link FingerprintManager} may 502 * optionally provide an implementation of this to 503 * {@link #remove(Fingerprint, int, RemovalCallback)} for listening to fingerprint template 504 * removal events. 505 * 506 * @hide 507 */ 508 public abstract static class RemovalCallback { 509 /** 510 * Called when the given fingerprint can't be removed. 511 * @param fp The fingerprint that the call attempted to remove 512 * @param errMsgId An associated error message id 513 * @param errString An error message indicating why the fingerprint id can't be removed 514 */ onRemovalError(Fingerprint fp, int errMsgId, CharSequence errString)515 public void onRemovalError(Fingerprint fp, int errMsgId, CharSequence errString) { } 516 517 /** 518 * Called when a given fingerprint is successfully removed. 519 * @param fp The fingerprint template that was removed. 520 * @param remaining The number of fingerprints yet to be removed in this operation. If 521 * {@link #remove} is called on one fingerprint, this should be 0. If 522 * {@link #remove} is called on a group, this should be the number of remaining 523 * fingerprints in the group, and 0 after the last fingerprint is removed. 524 */ onRemovalSucceeded(@ullable Fingerprint fp, int remaining)525 public void onRemovalSucceeded(@Nullable Fingerprint fp, int remaining) { } 526 } 527 528 /** 529 * @hide 530 */ 531 public abstract static class LockoutResetCallback { 532 533 /** 534 * Called when lockout period expired and clients are allowed to listen for fingerprint 535 * again. 536 */ onLockoutReset(int sensorId)537 public void onLockoutReset(int sensorId) { } 538 } 539 540 /** 541 * Callbacks for generate challenge operations. 542 * 543 * @hide 544 */ 545 public interface GenerateChallengeCallback { 546 /** Called when a challenged has been generated. */ onChallengeGenerated(int sensorId, int userId, long challenge)547 void onChallengeGenerated(int sensorId, int userId, long challenge); 548 } 549 550 /** 551 * Use the provided handler thread for events. 552 * @param handler 553 */ useHandler(Handler handler)554 private void useHandler(Handler handler) { 555 if (handler != null) { 556 mHandler = handler; 557 mExecutor = new HandlerExecutor(mHandler); 558 } else if (mHandler != mContext.getMainThreadHandler()) { 559 mHandler = mContext.getMainThreadHandler(); 560 mExecutor = new HandlerExecutor(mHandler); 561 } 562 } 563 564 /** 565 * Request authentication of a crypto object. This call warms up the fingerprint hardware 566 * and starts scanning for a fingerprint. It terminates when 567 * {@link AuthenticationCallback#onAuthenticationError(int, CharSequence)} or 568 * {@link AuthenticationCallback#onAuthenticationSucceeded(AuthenticationResult)} is called, at 569 * which point the object is no longer valid. The operation can be canceled by using the 570 * provided cancel object. 571 * 572 * @param crypto object associated with the call or null if none required. 573 * @param cancel an object that can be used to cancel authentication 574 * @param flags optional flags; should be 0 575 * @param callback an object to receive authentication events 576 * @param handler an optional handler to handle callback events 577 * 578 * @throws IllegalArgumentException if the crypto operation is not supported or is not backed 579 * by <a href="{@docRoot}training/articles/keystore.html">Android Keystore 580 * facility</a>. 581 * @throws IllegalStateException if the crypto primitive is not initialized. 582 * @deprecated See {@link BiometricPrompt#authenticate(CancellationSignal, Executor, 583 * BiometricPrompt.AuthenticationCallback)} and {@link BiometricPrompt#authenticate( 584 * BiometricPrompt.CryptoObject, CancellationSignal, Executor, 585 * BiometricPrompt.AuthenticationCallback)} 586 */ 587 @Deprecated 588 @RequiresPermission(anyOf = {USE_BIOMETRIC, USE_FINGERPRINT}) authenticate(@ullable CryptoObject crypto, @Nullable CancellationSignal cancel, int flags, @NonNull AuthenticationCallback callback, @Nullable Handler handler)589 public void authenticate(@Nullable CryptoObject crypto, @Nullable CancellationSignal cancel, 590 int flags, @NonNull AuthenticationCallback callback, @Nullable Handler handler) { 591 authenticate(crypto, cancel, callback, handler, SENSOR_ID_ANY, mContext.getUserId(), flags); 592 } 593 594 /** 595 * Per-user version of authenticate. 596 * @deprecated use {@link #authenticate(CryptoObject, CancellationSignal, AuthenticationCallback, Handler, FingerprintAuthenticateOptions)}. 597 * @hide 598 */ 599 @Deprecated 600 @RequiresPermission(anyOf = {USE_BIOMETRIC, USE_FINGERPRINT}) authenticate(@ullable CryptoObject crypto, @Nullable CancellationSignal cancel, @NonNull AuthenticationCallback callback, Handler handler, int userId)601 public void authenticate(@Nullable CryptoObject crypto, @Nullable CancellationSignal cancel, 602 @NonNull AuthenticationCallback callback, Handler handler, int userId) { 603 authenticate(crypto, cancel, callback, handler, SENSOR_ID_ANY, userId, 0 /* flags */); 604 } 605 606 /** 607 * Per-user and per-sensor version of authenticate. 608 * @deprecated use {@link #authenticate(CryptoObject, CancellationSignal, AuthenticationCallback, Handler, FingerprintAuthenticateOptions)}. 609 * @hide 610 */ 611 @Deprecated 612 @RequiresPermission(anyOf = {USE_BIOMETRIC, USE_FINGERPRINT}) authenticate(@ullable CryptoObject crypto, @Nullable CancellationSignal cancel, @NonNull AuthenticationCallback callback, Handler handler, int sensorId, int userId, int flags)613 public void authenticate(@Nullable CryptoObject crypto, @Nullable CancellationSignal cancel, 614 @NonNull AuthenticationCallback callback, Handler handler, int sensorId, int userId, 615 int flags) { 616 authenticate(crypto, cancel, callback, handler, new FingerprintAuthenticateOptions.Builder() 617 .setSensorId(sensorId) 618 .setUserId(userId) 619 .setIgnoreEnrollmentState(flags != 0) 620 .build()); 621 } 622 623 /** 624 * Version of authenticate with additional options. 625 * @hide 626 */ 627 @RequiresPermission(anyOf = {USE_BIOMETRIC, USE_FINGERPRINT}) authenticate(@ullable CryptoObject crypto, @Nullable CancellationSignal cancel, @NonNull AuthenticationCallback callback, @NonNull Handler handler, @NonNull FingerprintAuthenticateOptions options)628 public void authenticate(@Nullable CryptoObject crypto, @Nullable CancellationSignal cancel, 629 @NonNull AuthenticationCallback callback, @NonNull Handler handler, 630 @NonNull FingerprintAuthenticateOptions options) { 631 FrameworkStatsLog.write(FrameworkStatsLog.AUTH_DEPRECATED_API_USED, 632 AUTH_DEPRECATED_APIUSED__DEPRECATED_API__API_FINGERPRINT_MANAGER_AUTHENTICATE, 633 mContext.getApplicationInfo().uid, 634 mContext.getApplicationInfo().targetSdkVersion); 635 636 if (callback == null) { 637 throw new IllegalArgumentException("Must supply an authentication callback"); 638 } 639 640 if (cancel != null && cancel.isCanceled()) { 641 Slog.w(TAG, "authentication already canceled"); 642 return; 643 } 644 645 options.setOpPackageName(mContext.getOpPackageName()); 646 options.setAttributionTag(mContext.getAttributionTag()); 647 648 if (mService != null) { 649 try { 650 final FingerprintCallback fingerprintCallback = new FingerprintCallback(callback, 651 crypto); 652 useHandler(handler); 653 final long operationId = crypto != null ? crypto.getOpId() : 0; 654 final long authId = mService.authenticate(mToken, operationId, 655 new FingerprintServiceReceiver(fingerprintCallback), options); 656 if (cancel != null) { 657 cancel.setOnCancelListener(new OnAuthenticationCancelListener(authId)); 658 } 659 } catch (RemoteException e) { 660 Slog.w(TAG, "Remote exception while authenticating: ", e); 661 // Though this may not be a hardware issue, it will cause apps to give up or try 662 // again later. 663 callback.onAuthenticationError(FINGERPRINT_ERROR_HW_UNAVAILABLE, 664 getErrorString(mContext, FINGERPRINT_ERROR_HW_UNAVAILABLE, 665 0 /* vendorCode */)); 666 } 667 } 668 } 669 670 /** 671 * Uses the fingerprint hardware to detect for the presence of a finger, without giving details 672 * about accept/reject/lockout. 673 * @hide 674 */ 675 @RequiresPermission(USE_BIOMETRIC_INTERNAL) detectFingerprint(@onNull CancellationSignal cancel, @NonNull FingerprintDetectionCallback callback, @NonNull FingerprintAuthenticateOptions options)676 public void detectFingerprint(@NonNull CancellationSignal cancel, 677 @NonNull FingerprintDetectionCallback callback, @NonNull FingerprintAuthenticateOptions options) { 678 if (mService == null) { 679 return; 680 } 681 682 if (cancel.isCanceled()) { 683 Slog.w(TAG, "Detection already cancelled"); 684 return; 685 } 686 687 options.setOpPackageName(mContext.getOpPackageName()); 688 options.setAttributionTag(mContext.getAttributionTag()); 689 690 final FingerprintCallback fingerprintCallback = new FingerprintCallback(callback); 691 692 try { 693 final long authId = mService.detectFingerprint(mToken, 694 new FingerprintServiceReceiver(fingerprintCallback), options); 695 cancel.setOnCancelListener(new OnFingerprintDetectionCancelListener(authId)); 696 } catch (RemoteException e) { 697 Slog.w(TAG, "Remote exception when requesting finger detect", e); 698 } 699 } 700 701 /** 702 * Set whether the HAL should ignore display touches. 703 * Only applies to sensors where the HAL is reponsible for handling touches. 704 * @hide 705 */ 706 @RequiresPermission(USE_BIOMETRIC_INTERNAL) setIgnoreDisplayTouches(long requestId, int sensorId, boolean ignoreTouch)707 public void setIgnoreDisplayTouches(long requestId, int sensorId, boolean ignoreTouch) { 708 if (mService == null) { 709 Slog.w(TAG, "setIgnoreDisplayTouches: no fingerprint service"); 710 return; 711 } 712 713 try { 714 mService.setIgnoreDisplayTouches(requestId, sensorId, ignoreTouch); 715 } catch (RemoteException e) { 716 throw e.rethrowFromSystemServer(); 717 } 718 } 719 720 /** 721 * Request fingerprint enrollment. This call warms up the fingerprint hardware 722 * and starts scanning for fingerprints. Progress will be indicated by callbacks to the 723 * {@link EnrollmentCallback} object. It terminates when 724 * {@link EnrollmentCallback#onEnrollmentError(int, CharSequence)} or 725 * {@link EnrollmentCallback#onEnrollmentProgress(int) is called with remaining == 0, at 726 * which point the object is no longer valid. The operation can be canceled by using the 727 * provided cancel object. 728 * @param token a unique token provided by a recent creation or verification of device 729 * credentials (e.g. pin, pattern or password). 730 * @param cancel an object that can be used to cancel enrollment 731 * @param userId the user to whom this fingerprint will belong to 732 * @param callback an object to receive enrollment events 733 * @param shouldLogMetrics a flag that indicates if enrollment failure/success metrics 734 * should be logged. 735 * @hide 736 */ 737 @RequiresPermission(MANAGE_FINGERPRINT) enroll(byte [] hardwareAuthToken, CancellationSignal cancel, int userId, EnrollmentCallback callback, @EnrollReason int enrollReason, FingerprintEnrollOptions options)738 public void enroll(byte [] hardwareAuthToken, CancellationSignal cancel, int userId, 739 EnrollmentCallback callback, @EnrollReason int enrollReason, 740 FingerprintEnrollOptions options) { 741 if (userId == UserHandle.USER_CURRENT) { 742 userId = getCurrentUserId(); 743 } 744 if (callback == null) { 745 throw new IllegalArgumentException("Must supply an enrollment callback"); 746 } 747 748 if (cancel != null && cancel.isCanceled()) { 749 Slog.w(TAG, "enrollment already canceled"); 750 return; 751 } 752 753 if (hardwareAuthToken == null) { 754 callback.onEnrollmentError(FINGERPRINT_ERROR_UNABLE_TO_PROCESS, 755 getErrorString(mContext, FINGERPRINT_ERROR_UNABLE_TO_PROCESS, 756 0 /* vendorCode */)); 757 return; 758 } 759 760 if (mService != null) { 761 try { 762 final FingerprintCallback fingerprintCallback = new FingerprintCallback(callback); 763 final long enrollId = mService.enroll(mToken, hardwareAuthToken, userId, 764 new FingerprintServiceReceiver(fingerprintCallback), 765 mContext.getOpPackageName(), enrollReason, options); 766 if (cancel != null) { 767 cancel.setOnCancelListener(new OnEnrollCancelListener(enrollId)); 768 } 769 } catch (RemoteException e) { 770 Slog.w(TAG, "Remote exception in enroll: ", e); 771 // Though this may not be a hardware issue, it will cause apps to give up or try 772 // again later. 773 callback.onEnrollmentError(FINGERPRINT_ERROR_HW_UNAVAILABLE, 774 getErrorString(mContext, FINGERPRINT_ERROR_HW_UNAVAILABLE, 775 0 /* vendorCode */)); 776 } 777 } 778 } 779 780 /** 781 * Generates a unique random challenge in the TEE. A typical use case is to have it wrapped in a 782 * HardwareAuthenticationToken, minted by Gatekeeper upon PIN/Pattern/Password verification. 783 * The HardwareAuthenticationToken can then be sent to the biometric HAL together with a 784 * request to perform sensitive operation(s) (for example enroll), represented by the challenge. 785 * Doing this ensures that a the sensitive operation cannot be performed unless the user has 786 * entered confirmed PIN/Pattern/Password. 787 * 788 * @see com.android.server.locksettings.LockSettingsService 789 * 790 * @hide 791 */ 792 @RequiresPermission(MANAGE_FINGERPRINT) generateChallenge(int sensorId, int userId, GenerateChallengeCallback callback)793 public void generateChallenge(int sensorId, int userId, GenerateChallengeCallback callback) { 794 if (mService != null) try { 795 final FingerprintCallback fingerprintCallback = new FingerprintCallback(callback); 796 mService.generateChallenge(mToken, sensorId, userId, 797 new FingerprintServiceReceiver(fingerprintCallback), 798 mContext.getOpPackageName()); 799 } catch (RemoteException e) { 800 throw e.rethrowFromSystemServer(); 801 } 802 } 803 804 /** 805 * Same as {@link #generateChallenge(int, GenerateChallengeCallback)}, but assumes the first 806 * enumerated sensor. 807 * @hide 808 */ 809 @RequiresPermission(MANAGE_FINGERPRINT) generateChallenge(int userId, GenerateChallengeCallback callback)810 public void generateChallenge(int userId, GenerateChallengeCallback callback) { 811 final FingerprintSensorPropertiesInternal sensorProps = getFirstFingerprintSensor(); 812 if (sensorProps == null) { 813 Slog.e(TAG, "No sensors"); 814 return; 815 } 816 generateChallenge(sensorProps.sensorId, userId, callback); 817 } 818 819 /** 820 * Revokes the specified challenge. 821 * @hide 822 */ 823 @RequiresPermission(MANAGE_FINGERPRINT) revokeChallenge(int userId, long challenge)824 public void revokeChallenge(int userId, long challenge) { 825 if (mService != null) { 826 try { 827 final FingerprintSensorPropertiesInternal sensorProps = getFirstFingerprintSensor(); 828 if (sensorProps == null) { 829 Slog.e(TAG, "No sensors"); 830 return; 831 } 832 mService.revokeChallenge(mToken, sensorProps.sensorId, userId, 833 mContext.getOpPackageName(), challenge); 834 } catch (RemoteException e) { 835 throw e.rethrowFromSystemServer(); 836 } 837 } 838 } 839 840 /** 841 * Reset the lockout when user authenticates with strong auth (e.g. PIN, pattern or password) 842 * 843 * @param sensorId Sensor ID that this operation takes effect for 844 * @param userId User ID that this operation takes effect for. 845 * @param hardwareAuthToken An opaque token returned by password confirmation. 846 * @hide 847 */ 848 @RequiresPermission(RESET_FINGERPRINT_LOCKOUT) resetLockout(int sensorId, int userId, @Nullable byte[] hardwareAuthToken)849 public void resetLockout(int sensorId, int userId, @Nullable byte[] hardwareAuthToken) { 850 if (mService != null) { 851 try { 852 mService.resetLockout(mToken, sensorId, userId, hardwareAuthToken, 853 mContext.getOpPackageName()); 854 } catch (RemoteException e) { 855 throw e.rethrowFromSystemServer(); 856 } 857 } 858 } 859 860 /** 861 * Remove given fingerprint template from fingerprint hardware and/or protected storage. 862 * @param fp the fingerprint item to remove 863 * @param userId the user who this fingerprint belongs to 864 * @param callback an optional callback to verify that fingerprint templates have been 865 * successfully removed. May be null of no callback is required. 866 * 867 * @hide 868 */ 869 @RequiresPermission(MANAGE_FINGERPRINT) remove(Fingerprint fp, int userId, RemovalCallback callback)870 public void remove(Fingerprint fp, int userId, RemovalCallback callback) { 871 if (mService != null) try { 872 final FingerprintCallback fingerprintCallback = new FingerprintCallback(callback, 873 REMOVE_SINGLE, fp); 874 mService.remove(mToken, fp.getBiometricId(), userId, 875 new FingerprintServiceReceiver(fingerprintCallback), 876 mContext.getOpPackageName()); 877 } catch (RemoteException e) { 878 throw e.rethrowFromSystemServer(); 879 } 880 } 881 882 /** 883 * Removes all fingerprint templates for the given user. 884 * @hide 885 */ 886 @RequiresPermission(MANAGE_FINGERPRINT) removeAll(int userId, @NonNull RemovalCallback callback)887 public void removeAll(int userId, @NonNull RemovalCallback callback) { 888 if (mService != null) { 889 try { 890 final FingerprintCallback fingerprintCallback = new FingerprintCallback(callback, 891 REMOVE_ALL, null); 892 mService.removeAll(mToken, userId, 893 new FingerprintServiceReceiver(fingerprintCallback), 894 mContext.getOpPackageName()); 895 } catch (RemoteException e) { 896 throw e.rethrowFromSystemServer(); 897 } 898 } 899 } 900 901 /** 902 * Renames the given fingerprint template 903 * @param fpId the fingerprint id 904 * @param userId the user who this fingerprint belongs to 905 * @param newName the new name 906 * 907 * @hide 908 */ 909 @RequiresPermission(MANAGE_FINGERPRINT) rename(int fpId, int userId, String newName)910 public void rename(int fpId, int userId, String newName) { 911 // Renames the given fpId 912 if (mService != null) { 913 try { 914 mService.rename(fpId, userId, newName); 915 } catch (RemoteException e) { 916 throw e.rethrowFromSystemServer(); 917 } 918 } else { 919 Slog.w(TAG, "rename(): Service not connected!"); 920 } 921 } 922 923 /** 924 * Obtain the list of enrolled fingerprints templates. 925 * @return list of current fingerprint items 926 * 927 * @hide 928 */ 929 @RequiresPermission(USE_FINGERPRINT) 930 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) getEnrolledFingerprints(int userId)931 public List<Fingerprint> getEnrolledFingerprints(int userId) { 932 if (mService != null) try { 933 return mService.getEnrolledFingerprints( 934 userId, mContext.getOpPackageName(), mContext.getAttributionTag()); 935 } catch (RemoteException e) { 936 throw e.rethrowFromSystemServer(); 937 } 938 return null; 939 } 940 941 /** 942 * Obtain the list of enrolled fingerprints templates. 943 * @return list of current fingerprint items 944 * 945 * @hide 946 */ 947 @RequiresPermission(USE_FINGERPRINT) 948 @UnsupportedAppUsage getEnrolledFingerprints()949 public List<Fingerprint> getEnrolledFingerprints() { 950 return getEnrolledFingerprints(mContext.getUserId()); 951 } 952 953 /** 954 * @hide 955 */ hasEnrolledTemplates()956 public boolean hasEnrolledTemplates() { 957 return hasEnrolledFingerprints(); 958 } 959 960 /** 961 * @hide 962 */ hasEnrolledTemplates(int userId)963 public boolean hasEnrolledTemplates(int userId) { 964 return hasEnrolledFingerprints(userId); 965 } 966 967 /** 968 * @hide 969 */ 970 @RequiresPermission(USE_BIOMETRIC_INTERNAL) setUdfpsOverlayController(@onNull IUdfpsOverlayController controller)971 public void setUdfpsOverlayController(@NonNull IUdfpsOverlayController controller) { 972 if (mService == null) { 973 Slog.w(TAG, "setUdfpsOverlayController: no fingerprint service"); 974 return; 975 } 976 977 try { 978 mService.setUdfpsOverlayController(controller); 979 } catch (RemoteException e) { 980 throw e.rethrowFromSystemServer(); 981 } 982 } 983 984 /** 985 * Forwards BiometricStateListener to FingerprintService 986 * @param listener new BiometricStateListener being added 987 * @hide 988 */ registerBiometricStateListener(@onNull BiometricStateListener listener)989 public void registerBiometricStateListener(@NonNull BiometricStateListener listener) { 990 try { 991 mService.registerBiometricStateListener(listener); 992 } catch (RemoteException e) { 993 throw e.rethrowFromSystemServer(); 994 } 995 } 996 997 /** 998 * @hide 999 */ 1000 @RequiresPermission(USE_BIOMETRIC_INTERNAL) onPointerDown(long requestId, int sensorId, int x, int y, float minor, float major)1001 public void onPointerDown(long requestId, int sensorId, int x, int y, 1002 float minor, float major) { 1003 if (mService == null) { 1004 Slog.w(TAG, "onPointerDown: no fingerprint service"); 1005 return; 1006 } 1007 1008 final PointerContext pc = new PointerContext(); 1009 pc.x = (int) x; 1010 pc.y = (int) y; 1011 pc.minor = minor; 1012 pc.major = major; 1013 1014 try { 1015 mService.onPointerDown(requestId, sensorId, pc); 1016 } catch (RemoteException e) { 1017 throw e.rethrowFromSystemServer(); 1018 } 1019 } 1020 1021 /** 1022 * @hide 1023 */ 1024 @RequiresPermission(USE_BIOMETRIC_INTERNAL) onPointerUp(long requestId, int sensorId)1025 public void onPointerUp(long requestId, int sensorId) { 1026 if (mService == null) { 1027 Slog.w(TAG, "onPointerUp: no fingerprint service"); 1028 return; 1029 } 1030 1031 final PointerContext pc = new PointerContext(); 1032 1033 try { 1034 mService.onPointerUp(requestId, sensorId, pc); 1035 } catch (RemoteException e) { 1036 throw e.rethrowFromSystemServer(); 1037 } 1038 } 1039 1040 /** 1041 * TODO(b/218388821): The parameter list should be replaced with PointerContext. 1042 * @hide 1043 */ 1044 @RequiresPermission(USE_BIOMETRIC_INTERNAL) onPointerDown( long requestId, int sensorId, int pointerId, float x, float y, float minor, float major, float orientation, long time, long gestureStart, boolean isAod)1045 public void onPointerDown( 1046 long requestId, 1047 int sensorId, 1048 int pointerId, 1049 float x, 1050 float y, 1051 float minor, 1052 float major, 1053 float orientation, 1054 long time, 1055 long gestureStart, 1056 boolean isAod) { 1057 if (mService == null) { 1058 Slog.w(TAG, "onPointerDown: no fingerprint service"); 1059 return; 1060 } 1061 1062 final PointerContext pc = new PointerContext(); 1063 pc.pointerId = pointerId; 1064 pc.x = x; 1065 pc.y = y; 1066 pc.minor = minor; 1067 pc.major = major; 1068 pc.orientation = orientation; 1069 pc.time = time; 1070 pc.gestureStart = gestureStart; 1071 pc.isAod = isAod; 1072 1073 try { 1074 mService.onPointerDown(requestId, sensorId, pc); 1075 } catch (RemoteException e) { 1076 throw e.rethrowFromSystemServer(); 1077 } 1078 } 1079 1080 /** 1081 * TODO(b/218388821): The parameter list should be replaced with PointerContext. 1082 * @hide 1083 */ 1084 @RequiresPermission(USE_BIOMETRIC_INTERNAL) onPointerUp( long requestId, int sensorId, int pointerId, float x, float y, float minor, float major, float orientation, long time, long gestureStart, boolean isAod)1085 public void onPointerUp( 1086 long requestId, 1087 int sensorId, 1088 int pointerId, 1089 float x, 1090 float y, 1091 float minor, 1092 float major, 1093 float orientation, 1094 long time, 1095 long gestureStart, 1096 boolean isAod) { 1097 if (mService == null) { 1098 Slog.w(TAG, "onPointerUp: no fingerprint service"); 1099 return; 1100 } 1101 1102 final PointerContext pc = new PointerContext(); 1103 pc.pointerId = pointerId; 1104 pc.x = x; 1105 pc.y = y; 1106 pc.minor = minor; 1107 pc.major = major; 1108 pc.orientation = orientation; 1109 pc.time = time; 1110 pc.gestureStart = gestureStart; 1111 pc.isAod = isAod; 1112 1113 try { 1114 mService.onPointerUp(requestId, sensorId, pc); 1115 } catch (RemoteException e) { 1116 throw e.rethrowFromSystemServer(); 1117 } 1118 } 1119 1120 /** 1121 * @hide 1122 */ 1123 @RequiresPermission(USE_BIOMETRIC_INTERNAL) onUdfpsUiEvent(@dfpsUiEvent int event, long requestId, int sensorId)1124 public void onUdfpsUiEvent(@UdfpsUiEvent int event, long requestId, int sensorId) { 1125 if (mService == null) { 1126 Slog.w(TAG, "onUdfpsUiEvent: no fingerprint service"); 1127 return; 1128 } 1129 1130 try { 1131 mService.onUdfpsUiEvent(event, requestId, sensorId); 1132 } catch (RemoteException e) { 1133 throw e.rethrowFromSystemServer(); 1134 } 1135 } 1136 1137 /** 1138 * This is triggered by SideFpsEventHandler 1139 * @hide 1140 */ 1141 @RequiresPermission(USE_BIOMETRIC_INTERNAL) onPowerPressed()1142 public void onPowerPressed() { 1143 Slog.i(TAG, "onPowerPressed"); 1144 mExecutor.execute(() -> sendPowerPressed()); 1145 } 1146 1147 /** 1148 * Determine if there is at least one fingerprint enrolled. 1149 * 1150 * @return true if at least one fingerprint is enrolled, false otherwise 1151 * @deprecated See {@link BiometricPrompt} and 1152 * {@link FingerprintManager#FINGERPRINT_ERROR_NO_FINGERPRINTS} 1153 */ 1154 @Deprecated 1155 @RequiresPermission(USE_FINGERPRINT) hasEnrolledFingerprints()1156 public boolean hasEnrolledFingerprints() { 1157 FrameworkStatsLog.write(FrameworkStatsLog.AUTH_DEPRECATED_API_USED, 1158 AUTH_DEPRECATED_APIUSED__DEPRECATED_API__API_FINGERPRINT_MANAGER_HAS_ENROLLED_FINGERPRINTS, 1159 mContext.getApplicationInfo().uid, 1160 mContext.getApplicationInfo().targetSdkVersion); 1161 1162 return hasEnrolledFingerprints(UserHandle.myUserId()); 1163 } 1164 1165 /** 1166 * @hide 1167 */ 1168 @RequiresPermission(allOf = { 1169 USE_FINGERPRINT, 1170 INTERACT_ACROSS_USERS}) hasEnrolledFingerprints(int userId)1171 public boolean hasEnrolledFingerprints(int userId) { 1172 if (mService != null) try { 1173 return mService.hasEnrolledFingerprintsDeprecated( 1174 userId, mContext.getOpPackageName(), mContext.getAttributionTag()); 1175 } catch (RemoteException e) { 1176 throw e.rethrowFromSystemServer(); 1177 } 1178 return false; 1179 } 1180 1181 /** 1182 * Determine if fingerprint hardware is present and functional. 1183 * 1184 * @return true if hardware is present and functional, false otherwise. 1185 * @deprecated See {@link BiometricPrompt} and 1186 * {@link FingerprintManager#FINGERPRINT_ERROR_HW_UNAVAILABLE} 1187 */ 1188 @Deprecated 1189 @RequiresPermission(USE_FINGERPRINT) isHardwareDetected()1190 public boolean isHardwareDetected() { 1191 FrameworkStatsLog.write(FrameworkStatsLog.AUTH_DEPRECATED_API_USED, 1192 AUTH_DEPRECATED_APIUSED__DEPRECATED_API__API_FINGERPRINT_MANAGER_IS_HARDWARE_DETECTED, 1193 mContext.getApplicationInfo().uid, 1194 mContext.getApplicationInfo().targetSdkVersion); 1195 1196 if (mService != null) { 1197 try { 1198 return mService.isHardwareDetectedDeprecated( 1199 mContext.getOpPackageName(), mContext.getAttributionTag()); 1200 } catch (RemoteException e) { 1201 throw e.rethrowFromSystemServer(); 1202 } 1203 } else { 1204 Slog.w(TAG, "isFingerprintHardwareDetected(): Service not connected!"); 1205 } 1206 return false; 1207 } 1208 1209 /** 1210 * Get statically configured sensor properties. 1211 * @deprecated Generally unsafe to use, use 1212 * {@link FingerprintManager#addAuthenticatorsRegisteredCallback} API instead. 1213 * In most cases this method will work as expected, but during early boot up, it will be 1214 * null/empty and there is no way for the caller to know when it's actual value is ready. 1215 * @hide 1216 */ 1217 @RequiresPermission(USE_BIOMETRIC_INTERNAL) 1218 @NonNull getSensorPropertiesInternal()1219 public List<FingerprintSensorPropertiesInternal> getSensorPropertiesInternal() { 1220 try { 1221 if (!mProps.isEmpty() || mService == null) { 1222 return mProps; 1223 } 1224 return mService.getSensorPropertiesInternal(mContext.getOpPackageName()); 1225 } catch (RemoteException e) { 1226 throw e.rethrowFromSystemServer(); 1227 } 1228 } 1229 1230 /** 1231 * Returns whether the device has a power button fingerprint sensor. 1232 * @return boolean indicating whether power button is fingerprint sensor 1233 * @hide 1234 */ isPowerbuttonFps()1235 public boolean isPowerbuttonFps() { 1236 final FingerprintSensorPropertiesInternal sensorProps = getFirstFingerprintSensor(); 1237 return sensorProps == null ? false : sensorProps.sensorType == TYPE_POWER_BUTTON; 1238 } 1239 1240 /** 1241 * Adds a callback that gets called when the service registers all of the fingerprint 1242 * authenticators (HALs). 1243 * 1244 * If the fingerprint authenticators are already registered when the callback is added, the 1245 * callback is invoked immediately. 1246 * 1247 * The callback is automatically removed after it's invoked. 1248 * 1249 * @hide 1250 */ 1251 @RequiresPermission(USE_BIOMETRIC_INTERNAL) addAuthenticatorsRegisteredCallback( IFingerprintAuthenticatorsRegisteredCallback callback)1252 public void addAuthenticatorsRegisteredCallback( 1253 IFingerprintAuthenticatorsRegisteredCallback callback) { 1254 if (mService != null) { 1255 try { 1256 mService.addAuthenticatorsRegisteredCallback(callback); 1257 } catch (RemoteException e) { 1258 throw e.rethrowFromSystemServer(); 1259 } 1260 } else { 1261 Slog.w(TAG, "addProvidersAvailableCallback(): Service not connected!"); 1262 } 1263 } 1264 1265 /** 1266 * @hide 1267 */ 1268 @RequiresPermission(USE_BIOMETRIC_INTERNAL) 1269 @BiometricConstants.LockoutMode getLockoutModeForUser(int sensorId, int userId)1270 public int getLockoutModeForUser(int sensorId, int userId) { 1271 if (mService != null) { 1272 try { 1273 return mService.getLockoutModeForUser(sensorId, userId); 1274 } catch (RemoteException e) { 1275 e.rethrowFromSystemServer(); 1276 } 1277 } 1278 return BIOMETRIC_LOCKOUT_NONE; 1279 } 1280 1281 /** 1282 * Schedules a watchdog. 1283 * 1284 * @hide 1285 */ 1286 @RequiresPermission(USE_BIOMETRIC_INTERNAL) scheduleWatchdog()1287 public void scheduleWatchdog() { 1288 try { 1289 mService.scheduleWatchdog(); 1290 } catch (RemoteException e) { 1291 throw e.rethrowFromSystemServer(); 1292 } 1293 } 1294 1295 /** 1296 * @hide 1297 */ addLockoutResetCallback(final LockoutResetCallback callback)1298 public void addLockoutResetCallback(final LockoutResetCallback callback) { 1299 if (mService != null) { 1300 try { 1301 final PowerManager powerManager = mContext.getSystemService(PowerManager.class); 1302 mService.addLockoutResetCallback( 1303 new IBiometricServiceLockoutResetCallback.Stub() { 1304 1305 @Override 1306 public void onLockoutReset(int sensorId, IRemoteCallback serverCallback) 1307 throws RemoteException { 1308 try { 1309 final PowerManager.WakeLock wakeLock = powerManager.newWakeLock( 1310 PowerManager.PARTIAL_WAKE_LOCK, "lockoutResetCallback"); 1311 wakeLock.acquire(); 1312 mHandler.post(() -> { 1313 try { 1314 callback.onLockoutReset(sensorId); 1315 } finally { 1316 wakeLock.release(); 1317 } 1318 }); 1319 } finally { 1320 serverCallback.sendResult(null /* data */); 1321 } 1322 } 1323 }, mContext.getOpPackageName()); 1324 } catch (RemoteException e) { 1325 throw e.rethrowFromSystemServer(); 1326 } 1327 } else { 1328 Slog.w(TAG, "addLockoutResetCallback(): Service not connected!"); 1329 } 1330 } 1331 sendPowerPressed()1332 private void sendPowerPressed() { 1333 try { 1334 mService.onPowerPressed(); 1335 } catch (RemoteException e) { 1336 Slog.e(TAG, "Error sending power press", e); 1337 } 1338 } 1339 1340 /** 1341 * @hide 1342 */ FingerprintManager(Context context, IFingerprintService service)1343 public FingerprintManager(Context context, IFingerprintService service) { 1344 mContext = context; 1345 mService = service; 1346 if (mService == null) { 1347 Slog.v(TAG, "FingerprintService was null"); 1348 } 1349 if (context.checkCallingOrSelfPermission(USE_BIOMETRIC_INTERNAL) 1350 == PackageManager.PERMISSION_GRANTED) { 1351 addAuthenticatorsRegisteredCallback( 1352 new IFingerprintAuthenticatorsRegisteredCallback.Stub() { 1353 @Override 1354 public void onAllAuthenticatorsRegistered( 1355 @NonNull List<FingerprintSensorPropertiesInternal> sensors) { 1356 mProps = sensors; 1357 } 1358 }); 1359 } 1360 mHandler = context.getMainThreadHandler(); 1361 mExecutor = new HandlerExecutor(mHandler); 1362 } 1363 getCurrentUserId()1364 private int getCurrentUserId() { 1365 try { 1366 return ActivityManager.getService().getCurrentUser().id; 1367 } catch (RemoteException e) { 1368 throw e.rethrowFromSystemServer(); 1369 } 1370 } 1371 1372 @Nullable getFirstFingerprintSensor()1373 private FingerprintSensorPropertiesInternal getFirstFingerprintSensor() { 1374 final List<FingerprintSensorPropertiesInternal> allSensors = getSensorPropertiesInternal(); 1375 return allSensors.isEmpty() ? null : allSensors.get(0); 1376 } 1377 cancelEnrollment(long requestId)1378 private void cancelEnrollment(long requestId) { 1379 if (mService != null) try { 1380 mService.cancelEnrollment(mToken, requestId); 1381 } catch (RemoteException e) { 1382 throw e.rethrowFromSystemServer(); 1383 } 1384 } 1385 cancelAuthentication(long requestId)1386 private void cancelAuthentication(long requestId) { 1387 if (mService != null) try { 1388 mService.cancelAuthentication( 1389 mToken, 1390 mContext.getOpPackageName(), 1391 mContext.getAttributionTag(), 1392 requestId); 1393 } catch (RemoteException e) { 1394 throw e.rethrowFromSystemServer(); 1395 } 1396 } 1397 cancelFingerprintDetect(long requestId)1398 private void cancelFingerprintDetect(long requestId) { 1399 if (mService == null) { 1400 return; 1401 } 1402 1403 try { 1404 mService.cancelFingerprintDetect(mToken, mContext.getOpPackageName(), requestId); 1405 } catch (RemoteException e) { 1406 throw e.rethrowFromSystemServer(); 1407 } 1408 } 1409 1410 /** 1411 * @hide 1412 */ getEnrollStageCount()1413 public int getEnrollStageCount() { 1414 if (mEnrollStageThresholds == null) { 1415 mEnrollStageThresholds = createEnrollStageThresholds(mContext); 1416 } 1417 return mEnrollStageThresholds.length + 1; 1418 } 1419 1420 /** 1421 * @hide 1422 */ getEnrollStageThreshold(int index)1423 public float getEnrollStageThreshold(int index) { 1424 if (mEnrollStageThresholds == null) { 1425 mEnrollStageThresholds = createEnrollStageThresholds(mContext); 1426 } 1427 1428 if (index < 0 || index > mEnrollStageThresholds.length) { 1429 Slog.w(TAG, "Unsupported enroll stage index: " + index); 1430 return index < 0 ? 0f : 1f; 1431 } 1432 1433 // The implicit threshold for the final stage is always 1. 1434 return index == mEnrollStageThresholds.length ? 1f : mEnrollStageThresholds[index]; 1435 } 1436 1437 @NonNull 1438 @RequiresPermission(USE_BIOMETRIC_INTERNAL) createEnrollStageThresholds(@onNull Context context)1439 private float[] createEnrollStageThresholds(@NonNull Context context) { 1440 // TODO(b/200604947): Fetch this value from FingerprintService, rather than internal config 1441 final String[] enrollStageThresholdStrings; 1442 if (isPowerbuttonFps()) { 1443 enrollStageThresholdStrings = context.getResources().getStringArray( 1444 com.android.internal.R.array.config_sfps_enroll_stage_thresholds); 1445 } else { 1446 enrollStageThresholdStrings = context.getResources().getStringArray( 1447 com.android.internal.R.array.config_udfps_enroll_stage_thresholds); 1448 } 1449 1450 final float[] enrollStageThresholds = new float[enrollStageThresholdStrings.length]; 1451 for (int i = 0; i < enrollStageThresholds.length; i++) { 1452 enrollStageThresholds[i] = Float.parseFloat(enrollStageThresholdStrings[i]); 1453 } 1454 return enrollStageThresholds; 1455 } 1456 1457 /** 1458 * @hide 1459 */ getErrorString(Context context, int errMsg, int vendorCode)1460 public static String getErrorString(Context context, int errMsg, int vendorCode) { 1461 switch (errMsg) { 1462 case FINGERPRINT_ERROR_HW_UNAVAILABLE: 1463 return context.getString( 1464 com.android.internal.R.string.fingerprint_error_hw_not_available); 1465 case FINGERPRINT_ERROR_UNABLE_TO_PROCESS: 1466 return context.getString( 1467 com.android.internal.R.string.fingerprint_error_unable_to_process); 1468 case FINGERPRINT_ERROR_TIMEOUT: 1469 return context.getString(com.android.internal.R.string.fingerprint_error_timeout); 1470 case FINGERPRINT_ERROR_NO_SPACE: 1471 return context.getString( 1472 com.android.internal.R.string.fingerprint_error_no_space); 1473 case FINGERPRINT_ERROR_CANCELED: 1474 return context.getString(com.android.internal.R.string.fingerprint_error_canceled); 1475 case FINGERPRINT_ERROR_LOCKOUT: 1476 return context.getString(com.android.internal.R.string.fingerprint_error_lockout); 1477 case FINGERPRINT_ERROR_LOCKOUT_PERMANENT: 1478 return context.getString( 1479 com.android.internal.R.string.fingerprint_error_lockout_permanent); 1480 case FINGERPRINT_ERROR_USER_CANCELED: 1481 return context.getString( 1482 com.android.internal.R.string.fingerprint_error_user_canceled); 1483 case FINGERPRINT_ERROR_NO_FINGERPRINTS: 1484 return context.getString( 1485 com.android.internal.R.string.fingerprint_error_no_fingerprints); 1486 case FINGERPRINT_ERROR_HW_NOT_PRESENT: 1487 return context.getString( 1488 com.android.internal.R.string.fingerprint_error_hw_not_present); 1489 case BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED: 1490 return context.getString( 1491 com.android.internal.R.string.fingerprint_error_security_update_required); 1492 case FINGERPRINT_ERROR_BAD_CALIBRATION: 1493 return context.getString( 1494 com.android.internal.R.string.fingerprint_error_bad_calibration); 1495 case BIOMETRIC_ERROR_POWER_PRESSED: 1496 return context.getString( 1497 com.android.internal.R.string.fingerprint_error_power_pressed); 1498 case FINGERPRINT_ERROR_VENDOR: { 1499 String[] msgArray = context.getResources().getStringArray( 1500 com.android.internal.R.array.fingerprint_error_vendor); 1501 if (vendorCode < msgArray.length) { 1502 return msgArray[vendorCode]; 1503 } 1504 } 1505 } 1506 1507 // This is used as a last resort in case a vendor string is missing 1508 // It should not happen for anything other than FINGERPRINT_ERROR_VENDOR, but 1509 // warn and use the default if all else fails. 1510 Slog.w(TAG, "Invalid error message: " + errMsg + ", " + vendorCode); 1511 return context.getString( 1512 com.android.internal.R.string.fingerprint_error_vendor_unknown); 1513 } 1514 1515 /** 1516 * @hide 1517 */ getAcquiredString(Context context, int acquireInfo, int vendorCode)1518 public static String getAcquiredString(Context context, int acquireInfo, int vendorCode) { 1519 switch (acquireInfo) { 1520 case FINGERPRINT_ACQUIRED_GOOD: 1521 return null; 1522 case FINGERPRINT_ACQUIRED_PARTIAL: 1523 return context.getString( 1524 com.android.internal.R.string.fingerprint_acquired_partial); 1525 case FINGERPRINT_ACQUIRED_INSUFFICIENT: 1526 return context.getString( 1527 com.android.internal.R.string.fingerprint_acquired_insufficient); 1528 case FINGERPRINT_ACQUIRED_IMAGER_DIRTY: 1529 return context.getString( 1530 com.android.internal.R.string.fingerprint_acquired_imager_dirty); 1531 case FINGERPRINT_ACQUIRED_TOO_SLOW: 1532 return context.getString( 1533 com.android.internal.R.string.fingerprint_acquired_too_slow); 1534 case FINGERPRINT_ACQUIRED_TOO_FAST: 1535 return context.getString( 1536 com.android.internal.R.string.fingerprint_acquired_too_fast); 1537 case FINGERPRINT_ACQUIRED_IMMOBILE: 1538 return context.getString( 1539 com.android.internal.R.string.fingerprint_acquired_immobile); 1540 case FINGERPRINT_ACQUIRED_TOO_BRIGHT: 1541 return context.getString( 1542 com.android.internal.R.string.fingerprint_acquired_too_bright); 1543 case FINGERPRINT_ACQUIRED_POWER_PRESSED: 1544 return context.getString( 1545 com.android.internal.R.string.fingerprint_acquired_power_press); 1546 case FINGERPRINT_ACQUIRED_VENDOR: { 1547 String[] msgArray = context.getResources().getStringArray( 1548 com.android.internal.R.array.fingerprint_acquired_vendor); 1549 if (vendorCode < msgArray.length) { 1550 return msgArray[vendorCode]; 1551 } 1552 } 1553 break; 1554 case FINGERPRINT_ACQUIRED_START: 1555 return null; 1556 } 1557 Slog.w(TAG, "Invalid acquired message: " + acquireInfo + ", " + vendorCode); 1558 return null; 1559 } 1560 1561 class FingerprintServiceReceiver extends IFingerprintServiceReceiver.Stub { 1562 private final FingerprintCallback mFingerprintCallback; 1563 FingerprintServiceReceiver(FingerprintCallback fingerprintCallback)1564 FingerprintServiceReceiver(FingerprintCallback fingerprintCallback) { 1565 mFingerprintCallback = fingerprintCallback; 1566 } 1567 1568 @Override // binder call onEnrollResult(Fingerprint fp, int remaining)1569 public void onEnrollResult(Fingerprint fp, int remaining) { 1570 mExecutor.execute(() -> mFingerprintCallback.sendEnrollResult(remaining)); 1571 } 1572 1573 @Override // binder call onAcquired(int acquireInfo, int vendorCode)1574 public void onAcquired(int acquireInfo, int vendorCode) { 1575 mExecutor.execute(() -> mFingerprintCallback.sendAcquiredResult(mContext, acquireInfo, 1576 vendorCode)); 1577 } 1578 1579 @Override // binder call onAuthenticationSucceeded(Fingerprint fp, int userId, boolean isStrongBiometric)1580 public void onAuthenticationSucceeded(Fingerprint fp, int userId, 1581 boolean isStrongBiometric) { 1582 mExecutor.execute(() -> mFingerprintCallback.sendAuthenticatedSucceeded(fp, userId, 1583 isStrongBiometric)); 1584 } 1585 1586 @Override onFingerprintDetected(int sensorId, int userId, boolean isStrongBiometric)1587 public void onFingerprintDetected(int sensorId, int userId, boolean isStrongBiometric) { 1588 mExecutor.execute(() -> mFingerprintCallback.sendFingerprintDetected(sensorId, userId, 1589 isStrongBiometric)); 1590 } 1591 1592 @Override // binder call onAuthenticationFailed()1593 public void onAuthenticationFailed() { 1594 mExecutor.execute(mFingerprintCallback::sendAuthenticatedFailed); 1595 } 1596 1597 @Override // binder call onError(int error, int vendorCode)1598 public void onError(int error, int vendorCode) { 1599 mExecutor.execute(() -> mFingerprintCallback.sendErrorResult(mContext, error, 1600 vendorCode)); 1601 } 1602 1603 @Override // binder call onRemoved(Fingerprint fp, int remaining)1604 public void onRemoved(Fingerprint fp, int remaining) { 1605 mExecutor.execute(() -> mFingerprintCallback.sendRemovedResult(fp, remaining)); 1606 } 1607 1608 @Override // binder call onChallengeGenerated(int sensorId, int userId, long challenge)1609 public void onChallengeGenerated(int sensorId, int userId, long challenge) { 1610 mExecutor.execute(() -> mFingerprintCallback.sendChallengeGenerated(challenge, sensorId, 1611 userId)); 1612 } 1613 1614 @Override // binder call onUdfpsPointerDown(int sensorId)1615 public void onUdfpsPointerDown(int sensorId) { 1616 mExecutor.execute(() -> mFingerprintCallback.sendUdfpsPointerDown(sensorId)); 1617 } 1618 1619 @Override // binder call onUdfpsPointerUp(int sensorId)1620 public void onUdfpsPointerUp(int sensorId) { 1621 mExecutor.execute(() -> mFingerprintCallback.sendUdfpsPointerUp(sensorId)); 1622 } 1623 1624 @Override onUdfpsOverlayShown()1625 public void onUdfpsOverlayShown() { 1626 mExecutor.execute(mFingerprintCallback::sendUdfpsOverlayShown); 1627 } 1628 } 1629 } 1630