Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d6848140 authored by Kevin Chyn's avatar Kevin Chyn Committed by Android (Google) Code Review
Browse files

Merge changes from topic "biometric-id"

* changes:
  7/n: BiometricService is the source of truth for sensor strength
  Add biometric tests to presubmit
  6/n: Key by Biometric ID instead of Modality
  5/n: Rename sessionId to operationId
  4/n: AuthContainerView should filter out non-biometric modalities
  3/n: Add IntDefs for several biometric-related constants
  2/n: Move AuthenticatorWrapper its own file
  1/n: Move BiometricService.AuthSession to its own class
parents f96672e5 68b19ae9
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -17,11 +17,14 @@
package android.hardware.biometrics;

import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.hardware.biometrics.BiometricPrompt.AuthenticationResultType;
import android.os.CancellationSignal;
import android.os.Parcelable;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.concurrent.Executor;

/**
@@ -61,6 +64,12 @@ public interface BiometricAuthenticator {
     * @hide
     */
    int TYPE_FACE = 1 << 3;
    @IntDef({TYPE_NONE,
            TYPE_CREDENTIAL,
            TYPE_FINGERPRINT,
            TYPE_IRIS})
    @Retention(RetentionPolicy.SOURCE)
    @interface Modality {}

    /**
     * Container for biometric data
+25 −0
Original line number Diff line number Diff line
@@ -18,8 +18,12 @@ package android.hardware.biometrics;

import static android.hardware.biometrics.BiometricManager.Authenticators;

import android.annotation.IntDef;
import android.compat.annotation.UnsupportedAppUsage;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * Interface containing all of the biometric modality agnostic constants.
 *
@@ -152,6 +156,27 @@ public interface BiometricConstants {
    @UnsupportedAppUsage
    int BIOMETRIC_ERROR_VENDOR_BASE = 1000;

    @IntDef({BIOMETRIC_SUCCESS,
            BIOMETRIC_ERROR_HW_UNAVAILABLE,
            BIOMETRIC_ERROR_UNABLE_TO_PROCESS,
            BIOMETRIC_ERROR_TIMEOUT,
            BIOMETRIC_ERROR_NO_SPACE,
            BIOMETRIC_ERROR_CANCELED,
            BIOMETRIC_ERROR_UNABLE_TO_REMOVE,
            BIOMETRIC_ERROR_LOCKOUT,
            BIOMETRIC_ERROR_VENDOR,
            BIOMETRIC_ERROR_LOCKOUT_PERMANENT,
            BIOMETRIC_ERROR_USER_CANCELED,
            BIOMETRIC_ERROR_NO_BIOMETRICS,
            BIOMETRIC_ERROR_HW_NOT_PRESENT,
            BIOMETRIC_ERROR_NEGATIVE_BUTTON,
            BIOMETRIC_ERROR_NO_DEVICE_CREDENTIAL,
            BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED,
            BIOMETRIC_PAUSED_REJECTED,
            BIOMETRIC_ERROR_VENDOR_BASE})
    @Retention(RetentionPolicy.SOURCE)
    @interface Errors {}

    //
    // Image acquisition messages.
    //
+8 −1
Original line number Diff line number Diff line
@@ -28,6 +28,9 @@ import android.content.Context;
import android.os.RemoteException;
import android.util.Slog;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * A class that contains biometric utilities. For authentication, see {@link BiometricPrompt}.
 */
@@ -69,12 +72,16 @@ public class BiometricManager {
    public static final int BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED =
            BiometricConstants.BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED;

    /**
     * @hide
     */
    @IntDef({BIOMETRIC_SUCCESS,
            BIOMETRIC_ERROR_HW_UNAVAILABLE,
            BIOMETRIC_ERROR_NONE_ENROLLED,
            BIOMETRIC_ERROR_NO_HARDWARE,
            BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED})
    @interface BiometricError {}
    @Retention(RetentionPolicy.SOURCE)
    public @interface BiometricError {}

    /**
     * Types of authenticators, defined at a level of granularity supported by
+46 −21
Original line number Diff line number Diff line
@@ -460,8 +460,7 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
            new IBiometricServiceReceiver.Stub() {

        @Override
        public void onAuthenticationSucceeded(@AuthenticationResultType int authenticationType)
                throws RemoteException {
        public void onAuthenticationSucceeded(@AuthenticationResultType int authenticationType) {
            mExecutor.execute(() -> {
                final AuthenticationResult result =
                        new AuthenticationResult(mCryptoObject, authenticationType);
@@ -470,42 +469,68 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
        }

        @Override
        public void onAuthenticationFailed() throws RemoteException {
        public void onAuthenticationFailed() {
            mExecutor.execute(() -> {
                mAuthenticationCallback.onAuthenticationFailed();
            });
        }

        @Override
        public void onError(int modality, int error, int vendorCode) throws RemoteException {
            mExecutor.execute(() -> {
                String errorMessage;
        public void onError(@BiometricAuthenticator.Modality int modality, int error,
                int vendorCode) {

            String errorMessage = null;
            switch (modality) {
                case TYPE_FACE:
                    errorMessage = FaceManager.getErrorString(mContext, error, vendorCode);
                    break;

                case TYPE_FINGERPRINT:
                        errorMessage = FingerprintManager.getErrorString(mContext, error,
                                vendorCode);
                    errorMessage = FingerprintManager.getErrorString(mContext, error, vendorCode);
                    break;
            }

            // Look for generic errors, as it may be a combination of modalities, or no modality
            // (e.g. attempted biometric authentication without biometric sensors).
            if (errorMessage == null) {
                switch (error) {
                    case BIOMETRIC_ERROR_CANCELED:
                        errorMessage = mContext.getString(R.string.biometric_error_canceled);
                        break;
                    case BIOMETRIC_ERROR_USER_CANCELED:
                        errorMessage = mContext.getString(R.string.biometric_error_user_canceled);
                        break;
                    case BIOMETRIC_ERROR_HW_NOT_PRESENT:
                        errorMessage = mContext.getString(R.string.biometric_error_hw_unavailable);
                        break;
                    case BIOMETRIC_ERROR_NO_DEVICE_CREDENTIAL:
                        errorMessage = mContext.getString(
                                R.string.biometric_error_device_not_secured);
                        break;
                    default:
                        errorMessage = "";
                        Log.e(TAG, "Unknown error, modality: " + modality
                                + " error: " + error
                                + " vendorCode: " + vendorCode);
                        errorMessage = mContext.getString(R.string.biometric_error_generic);
                        break;
                }
            }
                mAuthenticationCallback.onAuthenticationError(error, errorMessage);

            final String stringToSend = errorMessage;
            mExecutor.execute(() -> {
                mAuthenticationCallback.onAuthenticationError(error, stringToSend);
            });
        }

        @Override
        public void onAcquired(int acquireInfo, String message) throws RemoteException {
        public void onAcquired(int acquireInfo, String message) {
            mExecutor.execute(() -> {
                mAuthenticationCallback.onAuthenticationHelp(acquireInfo, message);
            });
        }

        @Override
        public void onDialogDismissed(int reason) throws RemoteException {
        public void onDialogDismissed(int reason) {
            // Check the reason and invoke OnClickListener(s) if necessary
            if (reason == DISMISSED_REASON_BIOMETRIC_CONFIRMED) {
                mPositiveButtonInfo.executor.execute(() -> {
@@ -519,7 +544,7 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
        }

        @Override
        public void onSystemEvent(int event) throws RemoteException {
        public void onSystemEvent(int event) {
            mExecutor.execute(() -> {
                mAuthenticationCallback.onSystemEvent(event);
            });
@@ -934,7 +959,7 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
            mCryptoObject = crypto;
            mExecutor = executor;
            mAuthenticationCallback = callback;
            final long sessionId = crypto != null ? crypto.getOpId() : 0;
            final long operationId = crypto != null ? crypto.getOpId() : 0;

            final Bundle bundle;
            if (crypto != null) {
@@ -950,7 +975,7 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
                bundle = mBundle;
            }

            mService.authenticate(mToken, sessionId, userId, mBiometricServiceReceiver,
            mService.authenticate(mToken, operationId, userId, mBiometricServiceReceiver,
                    mContext.getOpPackageName(), bundle);

        } catch (RemoteException e) {
+1 −1
Original line number Diff line number Diff line
@@ -33,7 +33,7 @@ interface IBiometricAuthenticator {
    // called from BiometricService. The additional uid, pid, userId arguments should be determined
    // by BiometricService. To start authentication after the clients are ready, use
    // startPreparedClient().
    void prepareForAuthentication(boolean requireConfirmation, IBinder token, long sessionId,
    void prepareForAuthentication(boolean requireConfirmation, IBinder token, long operationId,
            int userId, IBiometricServiceReceiverInternal wrapperReceiver, String opPackageName,
            int cookie, int callingUid, int callingPid, int callingUserId);

Loading