diff options
| author | 2019-02-07 13:38:04 -0800 | |
|---|---|---|
| committer | 2019-02-08 11:34:42 -0800 | |
| commit | 45d1f9d311dec6dc0f5e748e8b7bfb704caf4e28 (patch) | |
| tree | 2d09251091bad5afee1d37e57c22f12b4f51d71c | |
| parent | a30095d965a634494fdd8f83a60a9c1fba43f773 (diff) | |
Rename setEnableFallback to setAllowDeviceCredential
Also adds BIOMETRIC_ERROR_NO_DEVICE_CREDENTIAL constant
Fixes: 123725101
Test: Demo app
Test: CtsVerifier Biometric Test
Change-Id: Ib4d25438946c0ce476de8ef416d07e3c58152da9
10 files changed, 63 insertions, 18 deletions
diff --git a/api/current.txt b/api/current.txt index 44e9e5e016a6..e59d714ceda1 100644 --- a/api/current.txt +++ b/api/current.txt @@ -16513,6 +16513,7 @@ package android.hardware.biometrics { field public static final int BIOMETRIC_ERROR_LOCKOUT = 7; // 0x7 field public static final int BIOMETRIC_ERROR_LOCKOUT_PERMANENT = 9; // 0x9 field public static final int BIOMETRIC_ERROR_NO_BIOMETRICS = 11; // 0xb + field public static final int BIOMETRIC_ERROR_NO_DEVICE_CREDENTIAL = 14; // 0xe field public static final int BIOMETRIC_ERROR_NO_SPACE = 4; // 0x4 field public static final int BIOMETRIC_ERROR_TIMEOUT = 3; // 0x3 field public static final int BIOMETRIC_ERROR_UNABLE_TO_PROCESS = 2; // 0x2 @@ -16535,8 +16536,8 @@ package android.hardware.biometrics { public static class BiometricPrompt.Builder { ctor public BiometricPrompt.Builder(android.content.Context); method public android.hardware.biometrics.BiometricPrompt build(); + method public android.hardware.biometrics.BiometricPrompt.Builder setAllowDeviceCredential(boolean); method public android.hardware.biometrics.BiometricPrompt.Builder setDescription(@NonNull CharSequence); - method public android.hardware.biometrics.BiometricPrompt.Builder setEnableFallback(boolean); method public android.hardware.biometrics.BiometricPrompt.Builder setNegativeButton(@NonNull CharSequence, @NonNull java.util.concurrent.Executor, @NonNull android.content.DialogInterface.OnClickListener); method public android.hardware.biometrics.BiometricPrompt.Builder setRequireConfirmation(boolean); method public android.hardware.biometrics.BiometricPrompt.Builder setSubtitle(@NonNull CharSequence); diff --git a/core/java/android/app/KeyguardManager.java b/core/java/android/app/KeyguardManager.java index f522d71afd08..17f645dfbf23 100644 --- a/core/java/android/app/KeyguardManager.java +++ b/core/java/android/app/KeyguardManager.java @@ -125,7 +125,7 @@ public class KeyguardManager { public static final int RESULT_ALTERNATE = 1; /** - * @deprecated see {@link BiometricPrompt.Builder#setEnableFallback(boolean)} + * @deprecated see {@link BiometricPrompt.Builder#setAllowDeviceCredential(boolean)} * * Get an intent to prompt the user to confirm credentials (pin, pattern, password or biometrics * if enrolled) for the current user of the device. The caller is expected to launch this diff --git a/core/java/android/hardware/biometrics/BiometricConstants.java b/core/java/android/hardware/biometrics/BiometricConstants.java index c814b7c67817..1cb7eb0d1256 100644 --- a/core/java/android/hardware/biometrics/BiometricConstants.java +++ b/core/java/android/hardware/biometrics/BiometricConstants.java @@ -17,6 +17,7 @@ package android.hardware.biometrics; import android.annotation.UnsupportedAppUsage; +import android.app.KeyguardManager; /** @@ -126,6 +127,13 @@ public interface BiometricConstants { int BIOMETRIC_ERROR_NEGATIVE_BUTTON = 13; /** + * The device does not have pin, pattern, or password set up. See + * {@link BiometricPrompt.Builder#setAllowDeviceCredential(boolean)} and + * {@link KeyguardManager#isDeviceSecure()} + */ + int BIOMETRIC_ERROR_NO_DEVICE_CREDENTIAL = 14; + + /** * @hide */ @UnsupportedAppUsage diff --git a/core/java/android/hardware/biometrics/BiometricFaceConstants.java b/core/java/android/hardware/biometrics/BiometricFaceConstants.java index b708ef12b210..459ec62d4135 100644 --- a/core/java/android/hardware/biometrics/BiometricFaceConstants.java +++ b/core/java/android/hardware/biometrics/BiometricFaceConstants.java @@ -16,6 +16,7 @@ package android.hardware.biometrics; +import android.app.KeyguardManager; import android.hardware.face.FaceManager; /** @@ -134,6 +135,13 @@ public interface BiometricFaceConstants { public static final int FACE_ERROR_NEGATIVE_BUTTON = 13; /** + * The device does not have pin, pattern, or password set up. See + * {@link BiometricPrompt.Builder#setAllowDeviceCredential(boolean)} and + * {@link KeyguardManager#isDeviceSecure()} + */ + public static final int BIOMETRIC_ERROR_NO_DEVICE_CREDENTIAL = 14; + + /** * @hide */ public static final int FACE_ERROR_VENDOR_BASE = 1000; diff --git a/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java b/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java index 041b2e673b96..6cbab471ce23 100644 --- a/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java +++ b/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java @@ -17,6 +17,7 @@ package android.hardware.biometrics; import android.annotation.UnsupportedAppUsage; +import android.app.KeyguardManager; import android.hardware.fingerprint.FingerprintManager; /** @@ -119,6 +120,14 @@ public interface BiometricFingerprintConstants { public static final int FINGERPRINT_ERROR_NEGATIVE_BUTTON = 13; /** + * The device does not have pin, pattern, or password set up. See + * {@link BiometricPrompt.Builder#setAllowDeviceCredential(boolean)} and + * {@link KeyguardManager#isDeviceSecure()} + * @hide + */ + public static final int BIOMETRIC_ERROR_NO_DEVICE_CREDENTIAL = 14; + + /** * @hide */ @UnsupportedAppUsage diff --git a/core/java/android/hardware/biometrics/BiometricPrompt.java b/core/java/android/hardware/biometrics/BiometricPrompt.java index d569a7800c37..baf972b26573 100644 --- a/core/java/android/hardware/biometrics/BiometricPrompt.java +++ b/core/java/android/hardware/biometrics/BiometricPrompt.java @@ -23,6 +23,7 @@ import android.annotation.CallbackExecutor; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; +import android.app.KeyguardManager; import android.content.Context; import android.content.DialogInterface; import android.os.Binder; @@ -80,7 +81,7 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan /** * @hide */ - public static final String KEY_ENABLE_FALLBACK = "enable_fallback"; + public static final String KEY_ALLOW_DEVICE_CREDENTIAL = "allow_device_credential"; /** * Error/help message will show for this amount of time. @@ -203,7 +204,8 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan * "Cancel" button, but may be also used to show an alternative method for authentication, * such as screen that asks for a backup password. * - * Note that this should not be set if {@link #setEnableFallback(boolean)} is set to true. + * Note that this should not be set if {@link #setAllowDeviceCredential(boolean) + * is set to true. * * @param text * @return @@ -250,7 +252,10 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan /** * The user will first be prompted to authenticate with biometrics, but also given the - * option to authenticate with their device PIN, pattern, or password. + * option to authenticate with their device PIN, pattern, or password. Developers should + * first check {@link KeyguardManager#isDeviceSecure()} before enabling this. If the device + * is not secure, {@link BiometricPrompt#BIOMETRIC_ERROR_NO_DEVICE_CREDENTIAL} will be + * returned in {@link AuthenticationCallback#onAuthenticationError(int, CharSequence)}} * * Note that {@link #setNegativeButton(CharSequence, Executor, * DialogInterface.OnClickListener)} should not be set if this is set to true. @@ -259,8 +264,8 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan * credentials (PIN, pattern, or password). * @return */ - public Builder setEnableFallback(boolean enable) { - mBundle.putBoolean(KEY_ENABLE_FALLBACK, enable); + public Builder setAllowDeviceCredential(boolean enable) { + mBundle.putBoolean(KEY_ALLOW_DEVICE_CREDENTIAL, enable); return this; } @@ -273,7 +278,7 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan final CharSequence title = mBundle.getCharSequence(KEY_TITLE); final CharSequence negative = mBundle.getCharSequence(KEY_NEGATIVE_TEXT); final boolean useDefaultTitle = mBundle.getBoolean(KEY_USE_DEFAULT_TITLE); - final boolean enableFallback = mBundle.getBoolean(KEY_ENABLE_FALLBACK); + final boolean enableFallback = mBundle.getBoolean(KEY_ALLOW_DEVICE_CREDENTIAL); if (TextUtils.isEmpty(title) && !useDefaultTitle) { throw new IllegalArgumentException("Title must be set and non-empty"); @@ -281,7 +286,7 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan throw new IllegalArgumentException("Negative text must be set and non-empty"); } else if (!TextUtils.isEmpty(negative) && enableFallback) { throw new IllegalArgumentException("Can't have both negative button behavior" - + " and fallback enabled"); + + " and device credential enabled"); } return new BiometricPrompt(mContext, mBundle, mPositiveButtonInfo, mNegativeButtonInfo); } @@ -541,8 +546,8 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan if (callback == null) { throw new IllegalArgumentException("Must supply a callback"); } - if (mBundle.getBoolean(KEY_ENABLE_FALLBACK)) { - throw new IllegalArgumentException("Fallback not supported with crypto"); + if (mBundle.getBoolean(KEY_ALLOW_DEVICE_CREDENTIAL)) { + throw new IllegalArgumentException("Device credential not supported with crypto"); } authenticateInternal(crypto, cancel, executor, callback, mContext.getUserId()); } diff --git a/core/java/android/hardware/biometrics/IBiometricService.aidl b/core/java/android/hardware/biometrics/IBiometricService.aidl index e4336d171ab6..a20e2bf3d067 100644 --- a/core/java/android/hardware/biometrics/IBiometricService.aidl +++ b/core/java/android/hardware/biometrics/IBiometricService.aidl @@ -54,7 +54,7 @@ interface IBiometricService { // TODO(b/123378871): Remove when moved. // CDCA needs to send results to BiometricService if it was invoked using BiometricPrompt's - // setEnableFallback method, since there's no way for us to intercept onActivityResult. + // setAllowDeviceCredential method, since there's no way for us to intercept onActivityResult. // CDCA is launched from BiometricService (startActivityAsUser) instead of *ForResult. void onConfirmDeviceCredentialSuccess(); // TODO(b/123378871): Remove when moved. diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index fadb28f05ef7..c803fc7e6a3a 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -1471,6 +1471,8 @@ <string name="biometric_not_recognized">Not recognized</string> <!-- Message shown when biometric authentication has been canceled [CHAR LIMIT=50] --> <string name="biometric_error_canceled">Authentication canceled</string> + <!-- Message returned to applications if BiometricPrompt setAllowDeviceCredentials is enabled but no pin, pattern, or password is set. [CHAR LIMIT=NONE] --> + <string name="biometric_error_device_not_secured">No pin, pattern, or password set</string> <!-- Message shown during fingerprint acquisision when the fingerprint cannot be recognized --> <string name="fingerprint_acquired_partial">Partial fingerprint detected. Please try again.</string> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 6d4b04c5e66a..f174504f01c4 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -2472,6 +2472,7 @@ <java-symbol type="string" name="biometric_error_user_canceled" /> <java-symbol type="string" name="biometric_not_recognized" /> <java-symbol type="string" name="biometric_error_canceled" /> + <java-symbol type="string" name="biometric_error_device_not_secured" /> <!-- Fingerprint messages --> <java-symbol type="string" name="fingerprint_error_unable_to_process" /> diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java index b50b800f0e20..bca84f7b7217 100644 --- a/services/core/java/com/android/server/biometrics/BiometricService.java +++ b/services/core/java/com/android/server/biometrics/BiometricService.java @@ -391,10 +391,11 @@ public class BiometricService extends SystemService { private final Random mRandom = new Random(); // TODO(b/123378871): Remove when moved. - // When BiometricPrompt#setEnableFallback is set to true, we need to store the client (app) - // receiver. BiometricService internally launches CDCA which invokes BiometricService to - // start authentication (normal path). When auth is success/rejected, CDCA will use an aidl - // method to poke BiometricService - the result will then be forwarded to this receiver. + // When BiometricPrompt#setAllowDeviceCredentials is set to true, we need to store the + // client (app) receiver. BiometricService internally launches CDCA which invokes + // BiometricService to start authentication (normal path). When auth is success/rejected, + // CDCA will use an aidl method to poke BiometricService - the result will then be forwarded + // to this receiver. private IBiometricServiceReceiver mConfirmDeviceCredentialReceiver; // The current authentication session, null if idle/done. We need to track both the current @@ -803,11 +804,21 @@ public class BiometricService extends SystemService { // we can't get activity results. Store the receiver somewhere so we can forward the // result back to the client. // TODO(b/123378871): Remove when moved. - if (bundle.getBoolean(BiometricPrompt.KEY_ENABLE_FALLBACK)) { + if (bundle.getBoolean(BiometricPrompt.KEY_ALLOW_DEVICE_CREDENTIAL)) { mHandler.post(() -> { - mConfirmDeviceCredentialReceiver = receiver; final KeyguardManager kgm = getContext().getSystemService( KeyguardManager.class); + if (!kgm.isDeviceSecure()) { + try { + receiver.onError(BiometricConstants.BIOMETRIC_ERROR_NO_DEVICE_CREDENTIAL, + getContext().getString( + R.string.biometric_error_device_not_secured)); + } catch (RemoteException e) { + Slog.e(TAG, "Remote exception", e); + } + return; + } + mConfirmDeviceCredentialReceiver = receiver; // Use this so we don't need to duplicate logic.. final Intent intent = kgm.createConfirmDeviceCredentialIntent(null /* title */, null /* description */); |