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

Commit f52c7481 authored by Curtis Belmonte's avatar Curtis Belmonte
Browse files

Add authenticator-aware string methods to BiometricManager

Adds methods to BiometricManager to return localized strings that may be
used by apps that utilize biometric authentication. These methods should
provide strings that are appropriate for the specific authenticators
that are present on a device and that will actually be used for
authentication in practice. This should alleviate the issue of apps
needing to use overly broad, less user-friendly strings in order to
cover all possible authentication types that may be used.

Test: atest BiometricManagerTest
Test: Manually checked strings using biometric test app

Bug: 162973174
Bug: 180732913
Change-Id: Icd16d8a3b0339e4a963d47e4eb213fa7df83412c
parent 0442bbca
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -17535,6 +17535,9 @@ package android.hardware.biometrics {
  public class BiometricManager {
    method @Deprecated @RequiresPermission(android.Manifest.permission.USE_BIOMETRIC) public int canAuthenticate();
    method @RequiresPermission(android.Manifest.permission.USE_BIOMETRIC) public int canAuthenticate(int);
    method @Nullable @RequiresPermission(android.Manifest.permission.USE_BIOMETRIC) public CharSequence getButtonLabel(int);
    method @Nullable @RequiresPermission(android.Manifest.permission.USE_BIOMETRIC) public CharSequence getPromptMessage(int);
    method @Nullable @RequiresPermission(android.Manifest.permission.USE_BIOMETRIC) public CharSequence getSettingName(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
+5 −2
Original line number Diff line number Diff line
@@ -62,10 +62,13 @@ public interface BiometricAuthenticator {
     * @hide
     */
    int TYPE_FACE = 1 << 3;
    @IntDef({TYPE_NONE,

    @IntDef(flag = true, value = {
            TYPE_NONE,
            TYPE_CREDENTIAL,
            TYPE_FINGERPRINT,
            TYPE_IRIS})
            TYPE_IRIS
    })
    @Retention(RetentionPolicy.SOURCE)
    @interface Modality {}

+123 −8
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import static android.Manifest.permission.WRITE_DEVICE_CONFIG;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.SystemService;
@@ -193,15 +194,15 @@ public class BiometricManager {
        int DEVICE_CREDENTIAL = 1 << 15;
    }

    private final Context mContext;
    private final IAuthService mService;
    @NonNull private final Context mContext;
    @NonNull private final IAuthService mService;

    /**
     * @hide
     * @param context
     * @param service
     */
    public BiometricManager(Context context, IAuthService service) {
    public BiometricManager(@NonNull Context context, @NonNull IAuthService service) {
        mContext = context;
        mService = service;
    }
@@ -274,7 +275,8 @@ public class BiometricManager {
     */
    @Deprecated
    @RequiresPermission(USE_BIOMETRIC)
    public @BiometricError int canAuthenticate() {
    @BiometricError
    public int canAuthenticate() {
        return canAuthenticate(Authenticators.BIOMETRIC_WEAK);
    }

@@ -304,7 +306,8 @@ public class BiometricManager {
     *     authenticators can currently be used (enrolled and available).
     */
    @RequiresPermission(USE_BIOMETRIC)
    public @BiometricError int canAuthenticate(@Authenticators.Types int authenticators) {
    @BiometricError
    public int canAuthenticate(@Authenticators.Types int authenticators) {
        return canAuthenticate(mContext.getUserId(), authenticators);
    }

@@ -312,8 +315,10 @@ public class BiometricManager {
     * @hide
     */
    @RequiresPermission(USE_BIOMETRIC_INTERNAL)
    public @BiometricError int canAuthenticate(int userId,
            @Authenticators.Types int authenticators) {
    @BiometricError
    public int canAuthenticate(
            int userId, @Authenticators.Types int authenticators) {

        if (mService != null) {
            try {
                final String opPackageName = mContext.getOpPackageName();
@@ -322,7 +327,7 @@ public class BiometricManager {
                throw e.rethrowFromSystemServer();
            }
        } else {
            Slog.w(TAG, "hasEnrolledBiometrics(): Service not connected");
            Slog.w(TAG, "canAuthenticate(): Service not connected");
            return BIOMETRIC_ERROR_HW_UNAVAILABLE;
        }
    }
@@ -404,5 +409,115 @@ public class BiometricManager {
        }
    }

    /**
     * Provides a localized string that may be used as the label for a button that invokes
     * {@link BiometricPrompt}.
     *
     * <p>When possible, this method should use the given authenticator requirements to more
     * precisely specify the authentication type that will be used. For example, if
     * <strong>Class 3</strong> biometric authentication is requested on a device with a
     * <strong>Class 3</strong> fingerprint sensor and a <strong>Class 2</strong> face sensor, the
     * returned string should indicate that fingerprint authentication will be used.
     *
     * <p>This method should also try to specify which authentication method(s) will be used in
     * practice when multiple authenticators meet the given requirements. For example, if biometric
     * authentication is requested on a device with both face and fingerprint sensors but the user
     * has selected face as their preferred method, the returned string should indicate that face
     * authentication will be used.
     *
     * @param authenticators A bit field representing the types of {@link Authenticators} that may
     *                       be used for authentication.
     * @return The label for a button that invokes {@link BiometricPrompt} for authentication.
     */
    @RequiresPermission(USE_BIOMETRIC)
    @Nullable
    public CharSequence getButtonLabel(@Authenticators.Types int authenticators) {
        if (mService != null) {
            final int userId = mContext.getUserId();
            final String opPackageName = mContext.getOpPackageName();
            try {
                return mService.getButtonLabel(userId, opPackageName, authenticators);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        } else {
            Slog.w(TAG, "getButtonLabel(): Service not connected");
            return null;
        }
    }

    /**
     * Provides a localized string that may be shown while the user is authenticating with
     * {@link BiometricPrompt}.
     *
     * <p>When possible, this method should use the given authenticator requirements to more
     * precisely specify the authentication type that will be used. For example, if
     * <strong>Class 3</strong> biometric authentication is requested on a device with a
     * <strong>Class 3</strong> fingerprint sensor and a <strong>Class 2</strong> face sensor, the
     * returned string should indicate that fingerprint authentication will be used.
     *
     * <p>This method should also try to specify which authentication method(s) will be used in
     * practice when multiple authenticators meet the given requirements. For example, if biometric
     * authentication is requested on a device with both face and fingerprint sensors but the user
     * has selected face as their preferred method, the returned string should indicate that face
     * authentication will be used.
     *
     * @param authenticators A bit field representing the types of {@link Authenticators} that may
     *                       be used for authentication.
     * @return The label for a button that invokes {@link BiometricPrompt} for authentication.
     */
    @RequiresPermission(USE_BIOMETRIC)
    @Nullable
    public CharSequence getPromptMessage(@Authenticators.Types int authenticators) {
        if (mService != null) {
            final int userId = mContext.getUserId();
            final String opPackageName = mContext.getOpPackageName();
            try {
                return mService.getPromptMessage(userId, opPackageName, authenticators);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        } else {
            Slog.w(TAG, "getPromptMessage(): Service not connected");
            return null;
        }
    }

    /**
     * Provides a localized string that may be shown as the title for an app setting that enables
     * biometric authentication.
     *
     * <p>When possible, this method should use the given authenticator requirements to more
     * precisely specify the authentication type that will be used. For example, if
     * <strong>Class 3</strong> biometric authentication is requested on a device with a
     * <strong>Class 3</strong> fingerprint sensor and a <strong>Class 2</strong> face sensor, the
     * returned string should indicate that fingerprint authentication will be used.
     *
     * <p>This method should <em>not</em> try to specify which authentication method(s) will be used
     * in practice when multiple authenticators meet the given requirements. For example, if
     * biometric authentication is requested on a device with both face and fingerprint sensors, the
     * returned string should indicate that either face or fingerprint authentication may be used,
     * regardless of whether the user has enrolled or selected either as their preferred method.
     *
     * @param authenticators A bit field representing the types of {@link Authenticators} that may
     *                       be used for authentication.
     * @return The label for a button that invokes {@link BiometricPrompt} for authentication.
     */
    @RequiresPermission(USE_BIOMETRIC)
    @Nullable
    public CharSequence getSettingName(@Authenticators.Types int authenticators) {
        if (mService != null) {
            final int userId = mContext.getUserId();
            final String opPackageName = mContext.getOpPackageName();
            try {
                return mService.getSettingName(userId, opPackageName, authenticators);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        } else {
            Slog.w(TAG, "getSettingName(): Service not connected");
            return null;
        }
    }
}
+12 −0
Original line number Diff line number Diff line
@@ -68,4 +68,16 @@ interface IAuthService {
    // the requirements for integrating with Keystore. The AuthenticatorID are known in Keystore
    // land as SIDs, and are used during key generation.
    long[] getAuthenticatorIds();

    // Provides a localized string that may be used as the label for a button that invokes
    // BiometricPrompt.
    CharSequence getButtonLabel(int userId, String opPackageName, int authenticators);

    // Provides a localized string that may be shown while the user is authenticating with
    // BiometricPrompt.
    CharSequence getPromptMessage(int userId, String opPackageName, int authenticators);

    // Provides a localized string that may be shown as the title for an app setting that enables
    // biometric authentication.
    CharSequence getSettingName(int userId, String opPackageName, int authenticators);
}
+6 −0
Original line number Diff line number Diff line
@@ -75,4 +75,10 @@ interface IBiometricService {
    long[] getAuthenticatorIds(int callingUserId);

    int getCurrentStrength(int sensorId);

    // Returns a bit field of the modality (or modalities) that are will be used for authentication.
    int getCurrentModality(String opPackageName, int userId, int callingUserId, int authenticators);

    // Returns a bit field of the authentication modalities that are supported by this device.
    int getSupportedModalities(int authenticators);
}
Loading