diff options
4 files changed, 39 insertions, 4 deletions
diff --git a/core/java/android/hardware/biometrics/BiometricPrompt.java b/core/java/android/hardware/biometrics/BiometricPrompt.java index b238d778f55a..f652f85c153b 100644 --- a/core/java/android/hardware/biometrics/BiometricPrompt.java +++ b/core/java/android/hardware/biometrics/BiometricPrompt.java @@ -73,6 +73,10 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan * @hide */ public static final String KEY_NEGATIVE_TEXT = "negative_text"; + /** + * @hide + */ + public static final String KEY_REQUIRE_CONFIRMATION = "require_confirmation"; /** * Error/help message will show for this amount of time. @@ -215,6 +219,30 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan } /** + * Optional: A hint to the system to require user confirmation after a biometric has been + * authenticated. For example, implicit modalities like Face and Iris authentication are + * passive, meaning they don't require an explicit user action to complete. When set to + * 'false', the user action (e.g. pressing a button) will not be required. BiometricPrompt + * will require confirmation by default. + * + * A typical use case for not requiring confirmation would be for low-risk transactions, + * such as re-authenticating a recently authenticated application. A typical use case for + * requiring confirmation would be for authorizing a purchase. + * + * Note that this is a hint to the system. The system may choose to ignore the flag. For + * example, if the user disables implicit authentication in Settings, or if it does not + * apply to a modality (e.g. Fingerprint). When ignored, the system will default to + * requiring confirmation. + * + * @param requireConfirmation + * @hide + */ + public Builder setRequireConfirmation(boolean requireConfirmation) { + mBundle.putBoolean(KEY_REQUIRE_CONFIRMATION, requireConfirmation); + return this; + } + + /** * Creates a {@link BiometricPrompt}. * @return a {@link BiometricPrompt} * @throws IllegalArgumentException if any of the required fields are not set. diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogImpl.java b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogImpl.java index 3167b9e0a458..94328d02ad55 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogImpl.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogImpl.java @@ -160,7 +160,10 @@ public class BiometricDialogImpl extends SystemUI implements CommandQueue.Callba @Override public void showBiometricDialog(Bundle bundle, IBiometricServiceReceiverInternal receiver, int type, boolean requireConfirmation, int userId) { - if (DEBUG) Log.d(TAG, "showBiometricDialog, type: " + type); + if (DEBUG) { + Log.d(TAG, "showBiometricDialog, type: " + type + + ", requireConfirmation: " + requireConfirmation); + } // Remove these messages as they are part of the previous client mHandler.removeMessages(MSG_BIOMETRIC_ERROR); mHandler.removeMessages(MSG_BIOMETRIC_HELP); diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java index 36ca4dcbea33..9bd8d0d579e7 100644 --- a/services/core/java/com/android/server/biometrics/BiometricService.java +++ b/services/core/java/com/android/server/biometrics/BiometricService.java @@ -706,7 +706,8 @@ public class BiometricService extends SystemService { mCurrentModality = modality; - // Actually start authentication + // Start preparing for authentication. Authentication starts when + // all modalities requested have invoked onReadyForAuthentication. authenticateInternal(token, sessionId, userId, receiver, opPackageName, bundle, callingUid, callingPid, callingUserId, modality); }); @@ -725,6 +726,9 @@ public class BiometricService extends SystemService { IBiometricServiceReceiver receiver, String opPackageName, Bundle bundle, int callingUid, int callingPid, int callingUserId, int modality) { try { + final boolean requireConfirmation = bundle.getBoolean( + BiometricPrompt.KEY_REQUIRE_CONFIRMATION, true /* default */); + // Generate random cookies to pass to the services that should prepare to start // authenticating. Store the cookie here and wait for all services to "ack" // with the cookie. Once all cookies are received, we can show the prompt @@ -748,7 +752,7 @@ public class BiometricService extends SystemService { Slog.w(TAG, "Iris unsupported"); } if ((modality & TYPE_FACE) != 0) { - mFaceService.prepareForAuthentication(true /* requireConfirmation */, + mFaceService.prepareForAuthentication(requireConfirmation, token, sessionId, userId, mInternalReceiver, opPackageName, cookie, callingUid, callingPid, callingUserId); } diff --git a/services/core/java/com/android/server/biometrics/face/FaceService.java b/services/core/java/com/android/server/biometrics/face/FaceService.java index 72f73f6aaf67..f4d8d4bdec83 100644 --- a/services/core/java/com/android/server/biometrics/face/FaceService.java +++ b/services/core/java/com/android/server/biometrics/face/FaceService.java @@ -156,7 +156,7 @@ public class FaceService extends BiometricServiceBase { mDaemonWrapper, mHalDeviceId, token, new BiometricPromptServiceListenerImpl(wrapperReceiver), mCurrentUserId, 0 /* groupId */, opId, restricted, opPackageName, cookie, - true /* requireConfirmation */); + requireConfirmation); authenticateInternal(client, opId, opPackageName, callingUid, callingPid, callingUserId); } |