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

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

Merge changes from topic "biometric-strength"

* changes:
  Enforce that registered authenticators are not null
  Ensure that cancelling authentication ends up in the correct state
  Enforce authenticator registration
  Enforce that only public authenticator combinations are accepted
  Add phenotype namespace and flag for biometrics
  Use @Authenticators.Types for authenticator selection
  Add setAllowedAuthenticators(int) to BiometricPrompt
parents 18408b13 9cef3631
Loading
Loading
Loading
Loading
+16 −2
Original line number Diff line number Diff line
@@ -16780,16 +16780,29 @@ package android.hardware {
package android.hardware.biometrics {
  public class BiometricManager {
    method @RequiresPermission(android.Manifest.permission.USE_BIOMETRIC) public int canAuthenticate();
    method @Deprecated @RequiresPermission(android.Manifest.permission.USE_BIOMETRIC) public int canAuthenticate();
    method @RequiresPermission(android.Manifest.permission.USE_BIOMETRIC) public int canAuthenticate(int);
    field public static final int BIOMETRIC_ERROR_HW_UNAVAILABLE = 1; // 0x1
    field public static final int BIOMETRIC_ERROR_NONE_ENROLLED = 11; // 0xb
    field public static final int BIOMETRIC_ERROR_NO_HARDWARE = 12; // 0xc
    field public static final int BIOMETRIC_SUCCESS = 0; // 0x0
  }
  public static interface BiometricManager.Authenticators {
    field public static final int BIOMETRIC_STRONG = 15; // 0xf
    field public static final int BIOMETRIC_WEAK = 255; // 0xff
    field public static final int DEVICE_CREDENTIAL = 32768; // 0x8000
  }
  public class BiometricPrompt {
    method @RequiresPermission(android.Manifest.permission.USE_BIOMETRIC) public void authenticate(@NonNull android.hardware.biometrics.BiometricPrompt.CryptoObject, @NonNull android.os.CancellationSignal, @NonNull java.util.concurrent.Executor, @NonNull android.hardware.biometrics.BiometricPrompt.AuthenticationCallback);
    method @RequiresPermission(android.Manifest.permission.USE_BIOMETRIC) public void authenticate(@NonNull android.os.CancellationSignal, @NonNull java.util.concurrent.Executor, @NonNull android.hardware.biometrics.BiometricPrompt.AuthenticationCallback);
    method @Nullable public int getAllowedAuthenticators();
    method @Nullable public CharSequence getDescription();
    method @Nullable public CharSequence getNegativeButtonText();
    method @Nullable public CharSequence getSubtitle();
    method @NonNull public CharSequence getTitle();
    method public boolean isConfirmationRequired();
    field public static final int BIOMETRIC_ACQUIRED_GOOD = 0; // 0x0
    field public static final int BIOMETRIC_ACQUIRED_IMAGER_DIRTY = 3; // 0x3
    field public static final int BIOMETRIC_ACQUIRED_INSUFFICIENT = 2; // 0x2
@@ -16825,9 +16838,10 @@ package android.hardware.biometrics {
  public static class BiometricPrompt.Builder {
    ctor public BiometricPrompt.Builder(android.content.Context);
    method @NonNull public android.hardware.biometrics.BiometricPrompt build();
    method @NonNull public android.hardware.biometrics.BiometricPrompt.Builder setAllowedAuthenticators(int);
    method @NonNull public android.hardware.biometrics.BiometricPrompt.Builder setConfirmationRequired(boolean);
    method @NonNull public android.hardware.biometrics.BiometricPrompt.Builder setDescription(@NonNull CharSequence);
    method @NonNull public android.hardware.biometrics.BiometricPrompt.Builder setDeviceCredentialAllowed(boolean);
    method @Deprecated @NonNull public android.hardware.biometrics.BiometricPrompt.Builder setDeviceCredentialAllowed(boolean);
    method @NonNull public android.hardware.biometrics.BiometricPrompt.Builder setNegativeButton(@NonNull CharSequence, @NonNull java.util.concurrent.Executor, @NonNull android.content.DialogInterface.OnClickListener);
    method @NonNull public android.hardware.biometrics.BiometricPrompt.Builder setSubtitle(@NonNull CharSequence);
    method @NonNull public android.hardware.biometrics.BiometricPrompt.Builder setTitle(@NonNull CharSequence);
+10 −0
Original line number Diff line number Diff line
@@ -2277,6 +2277,15 @@ package android.hardware {
}
package android.hardware.biometrics {
  public static interface BiometricManager.Authenticators {
    field public static final int BIOMETRIC_CONVENIENCE = 4095; // 0xfff
    field public static final int EMPTY_SET = 0; // 0x0
  }
}
package android.hardware.camera2 {
  public abstract class CameraDevice implements java.lang.AutoCloseable {
@@ -7126,6 +7135,7 @@ package android.provider {
    field public static final String NAMESPACE_APP_COMPAT = "app_compat";
    field public static final String NAMESPACE_ATTENTION_MANAGER_SERVICE = "attention_manager_service";
    field public static final String NAMESPACE_AUTOFILL = "autofill";
    field public static final String NAMESPACE_BIOMETRICS = "biometrics";
    field public static final String NAMESPACE_CONNECTIVITY = "connectivity";
    field public static final String NAMESPACE_CONTENT_CAPTURE = "content_capture";
    field @Deprecated public static final String NAMESPACE_DEX_BOOT = "dex_boot";
+1 −0
Original line number Diff line number Diff line
@@ -2433,6 +2433,7 @@ package android.provider {
    method @RequiresPermission(android.Manifest.permission.WRITE_DEVICE_CONFIG) public static boolean setProperty(@NonNull String, @NonNull String, @Nullable String, boolean);
    field public static final String NAMESPACE_ANDROID = "android";
    field public static final String NAMESPACE_AUTOFILL = "autofill";
    field public static final String NAMESPACE_BIOMETRICS = "biometrics";
    field public static final String NAMESPACE_CONTENT_CAPTURE = "content_capture";
    field public static final String NAMESPACE_PERMISSIONS = "permissions";
    field public static final String NAMESPACE_PRIVACY = "privacy";
+4 −3
Original line number Diff line number Diff line
@@ -16,8 +16,9 @@

package android.hardware.biometrics;

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

import android.annotation.UnsupportedAppUsage;
import android.app.KeyguardManager;


/**
@@ -126,8 +127,8 @@ public interface BiometricConstants {

    /**
     * The device does not have pin, pattern, or password set up. See
     * {@link BiometricPrompt.Builder#setDeviceCredentialAllowed(boolean)} and
     * {@link KeyguardManager#isDeviceSecure()}
     * {@link BiometricPrompt.Builder#setAllowedAuthenticators(int)},
     * {@link Authenticators#DEVICE_CREDENTIAL}, and {@link BiometricManager#canAuthenticate(int)}.
     */
    int BIOMETRIC_ERROR_NO_DEVICE_CREDENTIAL = 14;

+118 −9
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;

import android.annotation.IntDef;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.content.Context;
import android.content.pm.PackageManager;
@@ -65,6 +66,77 @@ public class BiometricManager {
            BIOMETRIC_ERROR_NO_HARDWARE})
    @interface BiometricError {}

    /**
     * Types of authenticators, defined at a level of granularity supported by
     * {@link BiometricManager} and {@link BiometricPrompt}.
     *
     * <p>Types may combined via bitwise OR into a single integer representing multiple
     * authenticators (e.g. <code>DEVICE_CREDENTIAL | BIOMETRIC_WEAK</code>).
     */
    public interface Authenticators {
        /**
         * An {@link IntDef} representing valid combinations of authenticator types.
         * @hide
         */
        @IntDef(flag = true, value = {
                BIOMETRIC_STRONG,
                BIOMETRIC_WEAK,
                DEVICE_CREDENTIAL,
        })
        @interface Types {}

        /**
         * Empty set with no authenticators specified.
         * @hide
         */
        @SystemApi
        int EMPTY_SET = 0x0;

        /**
         * Placeholder for the theoretical strongest biometric security tier.
         * @hide
         */
        int BIOMETRIC_MAX_STRENGTH = 0x001;

        /**
         * Any biometric (e.g. fingerprint, iris, or face) on the device that meets or exceeds the
         * requirements for <strong>Strong</strong>, as defined by the Android CDD.
         */
        int BIOMETRIC_STRONG = 0x00F;

        /**
         * Any biometric (e.g. fingerprint, iris, or face) on the device that meets or exceeds the
         * requirements for <strong>Weak</strong>, as defined by the Android CDD.
         *
         * <p>Note that this is a superset of {@link #BIOMETRIC_STRONG} and is defined such that
         * <code>BIOMETRIC_STRONG | BIOMETRIC_WEAK == BIOMETRIC_WEAK</code>.
         */
        int BIOMETRIC_WEAK = 0x0FF;

        /**
         * Any biometric (e.g. fingerprint, iris, or face) on the device that meets or exceeds the
         * requirements for <strong>Convenience</strong>, as defined by the Android CDD. This
         * is not a valid parameter to any of the {@link android.hardware.biometrics} APIs, since
         * the CDD allows only {@link #BIOMETRIC_WEAK} and stronger authenticators to participate.
         * @hide
         */
        @SystemApi
        int BIOMETRIC_CONVENIENCE = 0xFFF;

        /**
         * Placeholder for the theoretical weakest biometric security tier.
         * @hide
         */
        int BIOMETRIC_MIN_STRENGTH = 0x7FFF;

        /**
         * The non-biometric credential used to secure the device (i.e., PIN, pattern, or password).
         * This should typically only be used in combination with a biometric auth type, such as
         * {@link #BIOMETRIC_WEAK}.
         */
        int DEVICE_CREDENTIAL = 1 << 15;
    }

    private final Context mContext;
    private final IAuthService mService;
    private final boolean mHasHardware;
@@ -94,27 +166,64 @@ public class BiometricManager {
    }

    /**
     * Determine if biometrics can be used. In other words, determine if {@link BiometricPrompt}
     * can be expected to be shown (hardware available, templates enrolled, user-enabled).
     * Determine if biometrics can be used. In other words, determine if
     * {@link BiometricPrompt} can be expected to be shown (hardware available, templates enrolled,
     * user-enabled). This is the equivalent of {@link #canAuthenticate(int)} with
     * {@link Authenticators#BIOMETRIC_WEAK}
     *
     * @return {@link #BIOMETRIC_ERROR_NONE_ENROLLED} if the user does not have any strong
     *     biometrics enrolled, or {@link #BIOMETRIC_ERROR_HW_UNAVAILABLE} if none are currently
     *     supported/enabled. Returns {@link #BIOMETRIC_SUCCESS} if a strong biometric can currently
     *     be used (enrolled and available).
     *
     * @return Returns {@link #BIOMETRIC_ERROR_NONE_ENROLLED} if the user does not have any
     *     enrolled, or {@link #BIOMETRIC_ERROR_HW_UNAVAILABLE} if none are currently
     *     supported/enabled. Returns {@link #BIOMETRIC_SUCCESS} if a biometric can currently be
     *     used (enrolled and available).
     * @deprecated See {@link #canAuthenticate(int)}.
     */
    @Deprecated
    @RequiresPermission(USE_BIOMETRIC)
    public @BiometricError int canAuthenticate() {
        return canAuthenticate(mContext.getUserId());
        return canAuthenticate(Authenticators.BIOMETRIC_WEAK);
    }

    /**
     * Determine if any of the provided authenticators can be used. In other words, determine if
     * {@link BiometricPrompt} can be expected to be shown (hardware available, templates enrolled,
     * user-enabled).
     *
     * For biometric authenticators, determine if the device can currently authenticate with at
     * least the requested strength. For example, invoking this API with
     * {@link Authenticators#BIOMETRIC_WEAK} on a device that currently only has
     * {@link Authenticators#BIOMETRIC_STRONG} enrolled will return {@link #BIOMETRIC_SUCCESS}.
     *
     * Invoking this API with {@link Authenticators#DEVICE_CREDENTIAL} can be used to determine
     * if the user has a PIN/Pattern/Password set up.
     *
     * @param authenticators bit field consisting of constants defined in {@link Authenticators}.
     *                       If multiple authenticators are queried, a logical OR will be applied.
     *                       For example, if {@link Authenticators#DEVICE_CREDENTIAL} |
     *                       {@link Authenticators#BIOMETRIC_STRONG} is queried and only
     *                       {@link Authenticators#DEVICE_CREDENTIAL} is set up, this API will
     *                       return {@link #BIOMETRIC_SUCCESS}
     *
     * @return {@link #BIOMETRIC_ERROR_NONE_ENROLLED} if the user does not have any of the
     *     requested authenticators enrolled, or {@link #BIOMETRIC_ERROR_HW_UNAVAILABLE} if none are
     *     currently supported/enabled. Returns {@link #BIOMETRIC_SUCCESS} if one of the requested
     *     authenticators can currently be used (enrolled and available).
     */
    @RequiresPermission(USE_BIOMETRIC)
    public @BiometricError int canAuthenticate(@Authenticators.Types int authenticators) {
        return canAuthenticate(mContext.getUserId(), authenticators);
    }

    /**
     * @hide
     */
    @RequiresPermission(USE_BIOMETRIC_INTERNAL)
    public @BiometricError int canAuthenticate(int userId) {
    public @BiometricError int canAuthenticate(int userId,
            @Authenticators.Types int authenticators) {
        if (mService != null) {
            try {
                return mService.canAuthenticate(mContext.getOpPackageName(), userId);
                final String opPackageName = mContext.getOpPackageName();
                return mService.canAuthenticate(opPackageName, userId, authenticators);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
Loading