summaryrefslogtreecommitdiff
path: root/core/java/android
diff options
context:
space:
mode:
authorKevin Chyn <kchyn@google.com>2018-11-21 16:35:04 -0800
committerKevin Chyn <kchyn@google.com>2018-11-27 16:26:19 -0800
commite92cdae2773ff29502781670e35eaf882d5e36c6 (patch)
tree2d64b9e0adcede8551f063470b49ecfa3fb7f68d /core/java/android
parent2ca566b525dba8b9da8a917ca999c2df0caa0de0 (diff)
1/n: Move BiometricDialog management to BiometricService
The BiometricDialog management was done in AuthenticationClient, but this is not great for the following reasons 1) The dialog lifecycle should not be 1:1 tied to the client monitor, since this restricts flexibility 2) Devices with multiple biometrics implemented on BiometricDialog will require extra work. Moving the dialog management up one layer should solve this limitation BiometricService now sends both its own receiver and the client's receiver to the appropriate <Biometric>Service. When the client is actually started by the <Biometric>Service, it will forward the client's (BiometricPrompt's) receiver to BiometricService. Lifecycle management is currently still in <Biometric>Service since the platform still uses <Biometric>Service directly. AuthenticationClient for BP is now started with the wrapper receiver, which allows BiometricService to handle messages before deciding if it should forward the message to the client. Moving lifecycle management to BiometricService is currently not a great idea since framework doesn't always go through BiometricService. Also merged IBiometricPromptReceiver with IBiometricServiceReceiver Bug: 111461540 Test: Negative button works (error received by demo app) Test: Cancelling via back or tapping gray area works (error received by demo app), and hardware is no longer authenticating Test: Dismissing BP via negative button or gray area returns only a single error and is not followed by ERROR_CANCELED (as expected) Test: Error messages are delayed when BP is showing, not delayed when BP is not showing (pre-auth check errors e.g. no hardware) Test: Lockout works Test: Lockout counter resets upon successful auth Test: Keys are unlocked properly for both implicit and explicit modes TODO: Figure out multi-modal BiometricService / <Biometric>Service synchronization. Likely we keep the bundle in BiometricService and send random numbers (identifier) to <Biometric>Service. When each <Biometric>Service is ready, it should return the number. Once BiometricService receives all identifiers, it can then notify all <Biometric>Service to start authenticating. Change-Id: I2b6fa57ed3c3cbccc7b0be30279f80fa46a8e917
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/hardware/biometrics/BiometricAuthenticator.java6
-rw-r--r--core/java/android/hardware/biometrics/BiometricPrompt.java51
-rw-r--r--core/java/android/hardware/biometrics/IBiometricPromptReceiver.aidl24
-rw-r--r--core/java/android/hardware/biometrics/IBiometricService.aidl9
-rw-r--r--core/java/android/hardware/biometrics/IBiometricServiceReceiver.aidl25
-rw-r--r--core/java/android/hardware/face/IFaceService.aidl9
-rw-r--r--core/java/android/hardware/fingerprint/IFingerprintService.aidl9
7 files changed, 64 insertions, 69 deletions
diff --git a/core/java/android/hardware/biometrics/BiometricAuthenticator.java b/core/java/android/hardware/biometrics/BiometricAuthenticator.java
index 79e15a7a9a2d..d09819876cd1 100644
--- a/core/java/android/hardware/biometrics/BiometricAuthenticator.java
+++ b/core/java/android/hardware/biometrics/BiometricAuthenticator.java
@@ -32,17 +32,17 @@ public interface BiometricAuthenticator {
/**
* @hide
*/
- int TYPE_FINGERPRINT = 1;
+ int TYPE_FINGERPRINT = 1 << 0;
/**
* @hide
*/
- int TYPE_IRIS = 2;
+ int TYPE_IRIS = 1 << 1;
/**
* @hide
*/
- int TYPE_FACE = 3;
+ int TYPE_FACE = 1 << 2;
/**
* Container for biometric data
diff --git a/core/java/android/hardware/biometrics/BiometricPrompt.java b/core/java/android/hardware/biometrics/BiometricPrompt.java
index bd149fd05f59..1eb98c77fbd5 100644
--- a/core/java/android/hardware/biometrics/BiometricPrompt.java
+++ b/core/java/android/hardware/biometrics/BiometricPrompt.java
@@ -251,27 +251,11 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
private Executor mExecutor;
private AuthenticationCallback mAuthenticationCallback;
- IBiometricPromptReceiver mDialogReceiver = new IBiometricPromptReceiver.Stub() {
- @Override
- public void onDialogDismissed(int reason) {
- // Check the reason and invoke OnClickListener(s) if necessary
- if (reason == DISMISSED_REASON_POSITIVE) {
- mPositiveButtonInfo.executor.execute(() -> {
- mPositiveButtonInfo.listener.onClick(null, DialogInterface.BUTTON_POSITIVE);
- });
- } else if (reason == DISMISSED_REASON_NEGATIVE) {
- mNegativeButtonInfo.executor.execute(() -> {
- mNegativeButtonInfo.listener.onClick(null, DialogInterface.BUTTON_NEGATIVE);
- });
- }
- }
- };
-
- IBiometricServiceReceiver mBiometricServiceReceiver =
+ private final IBiometricServiceReceiver mBiometricServiceReceiver =
new IBiometricServiceReceiver.Stub() {
@Override
- public void onAuthenticationSucceeded(long deviceId) throws RemoteException {
+ public void onAuthenticationSucceeded() throws RemoteException {
mExecutor.execute(() -> {
final AuthenticationResult result = new AuthenticationResult(mCryptoObject);
mAuthenticationCallback.onAuthenticationSucceeded(result);
@@ -279,14 +263,20 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
}
@Override
- public void onAuthenticationFailed(long deviceId) throws RemoteException {
+ public void onAuthenticationSucceededInternal(boolean requireConfirmation, byte[] bytes)
+ throws RemoteException {
+ throw new UnsupportedOperationException("Operation not supported!");
+ }
+
+ @Override
+ public void onAuthenticationFailed() throws RemoteException {
mExecutor.execute(() -> {
mAuthenticationCallback.onAuthenticationFailed();
});
}
@Override
- public void onError(long deviceId, int error, String message)
+ public void onError(int error, String message)
throws RemoteException {
mExecutor.execute(() -> {
mAuthenticationCallback.onAuthenticationError(error, message);
@@ -294,11 +284,25 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
}
@Override
- public void onAcquired(long deviceId, int acquireInfo, String message) {
+ public void onAcquired(int acquireInfo, String message) {
mExecutor.execute(() -> {
mAuthenticationCallback.onAuthenticationHelp(acquireInfo, message);
});
}
+
+ @Override
+ public void onDialogDismissed(int reason) {
+ // Check the reason and invoke OnClickListener(s) if necessary
+ if (reason == DISMISSED_REASON_POSITIVE) {
+ mPositiveButtonInfo.executor.execute(() -> {
+ mPositiveButtonInfo.listener.onClick(null, DialogInterface.BUTTON_POSITIVE);
+ });
+ } else if (reason == DISMISSED_REASON_NEGATIVE) {
+ mNegativeButtonInfo.executor.execute(() -> {
+ mNegativeButtonInfo.listener.onClick(null, DialogInterface.BUTTON_NEGATIVE);
+ });
+ }
+ }
};
private BiometricPrompt(Context context, Bundle bundle,
@@ -557,9 +561,8 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
mExecutor = executor;
mAuthenticationCallback = callback;
final long sessionId = crypto != null ? crypto.getOpId() : 0;
- mService.authenticate(mToken, sessionId, userId,
- mBiometricServiceReceiver, 0 /* flags */, mContext.getOpPackageName(),
- mBundle, mDialogReceiver);
+ mService.authenticate(mToken, sessionId, userId, mBiometricServiceReceiver,
+ 0 /* flags */, mContext.getOpPackageName(), mBundle);
} catch (RemoteException e) {
Log.e(TAG, "Remote exception while authenticating", e);
mExecutor.execute(() -> {
diff --git a/core/java/android/hardware/biometrics/IBiometricPromptReceiver.aidl b/core/java/android/hardware/biometrics/IBiometricPromptReceiver.aidl
deleted file mode 100644
index 27d25b86b859..000000000000
--- a/core/java/android/hardware/biometrics/IBiometricPromptReceiver.aidl
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.hardware.biometrics;
-
-/**
- * Communication channel from the BiometricPrompt (SysUI) back to AuthenticationClient.
- * @hide
- */
-oneway interface IBiometricPromptReceiver {
- void onDialogDismissed(int reason);
-}
diff --git a/core/java/android/hardware/biometrics/IBiometricService.aidl b/core/java/android/hardware/biometrics/IBiometricService.aidl
index e17feff0160a..6b2a53fd9b20 100644
--- a/core/java/android/hardware/biometrics/IBiometricService.aidl
+++ b/core/java/android/hardware/biometrics/IBiometricService.aidl
@@ -18,7 +18,6 @@ package android.hardware.biometrics;
import android.os.Bundle;
import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback;
-import android.hardware.biometrics.IBiometricPromptReceiver;
import android.hardware.biometrics.IBiometricServiceReceiver;
/**
@@ -32,8 +31,7 @@ interface IBiometricService {
// Requests authentication. The service choose the appropriate biometric to use, and show
// the corresponding BiometricDialog.
void authenticate(IBinder token, long sessionId, int userId,
- IBiometricServiceReceiver receiver, int flags, String opPackageName,
- in Bundle bundle, IBiometricPromptReceiver dialogReceiver);
+ IBiometricServiceReceiver receiver, int flags, String opPackageName, in Bundle bundle);
// Cancel authentication for the given sessionId
void cancelAuthentication(IBinder token, String opPackageName);
@@ -46,4 +44,9 @@ interface IBiometricService {
// Explicitly set the active user.
void setActiveUser(int userId);
+
+ // Notify BiometricService when <Biometric>Service starts a new client. Client lifecycle
+ // is still managed in <Biometric>Service.
+ void onAuthenticationStarted(in Bundle bundle, IBiometricServiceReceiver receiver, int type,
+ boolean requireConfirmation, int userId);
}
diff --git a/core/java/android/hardware/biometrics/IBiometricServiceReceiver.aidl b/core/java/android/hardware/biometrics/IBiometricServiceReceiver.aidl
index a6e3696eeb10..3b8067bf11be 100644
--- a/core/java/android/hardware/biometrics/IBiometricServiceReceiver.aidl
+++ b/core/java/android/hardware/biometrics/IBiometricServiceReceiver.aidl
@@ -16,12 +16,27 @@
package android.hardware.biometrics;
/**
- * Communication channel from the BiometricService back to BiometricPrompt.
+ * Communication channel from
+ * 1) BiometricDialogImpl (SysUI) back to BiometricService
+ * 2) <Biometric>Service back to BiometricService
+ * 3) BiometricService back to BiometricPrompt
+ * BiometricPrompt sends a receiver to BiometricService, BiometricService contains another
+ * "trampoline" receiver which intercepts messages from <Biometric>Service and does some
+ * logic before forwarding results as necessary to BiometricPrompt.
* @hide
*/
oneway interface IBiometricServiceReceiver {
- void onAuthenticationSucceeded(long deviceId);
- void onAuthenticationFailed(long deviceId);
- void onError(long deviceId, int error, String message);
- void onAcquired(long deviceId, int acquiredInfo, String message);
+ // Notify BiometricPrompt that authentication was successful
+ void onAuthenticationSucceeded();
+ // Notify BiometricService that authentication was successful. If user confirmation is required,
+ // the auth token must be submitted into KeyStore.
+ void onAuthenticationSucceededInternal(boolean requireConfirmation, in byte[] token);
+ // Noties that authentication failed.
+ void onAuthenticationFailed();
+ // Notifies that an error has occurred.
+ void onError(int error, String message);
+ // Notifies that a biometric has been acquired.
+ void onAcquired(int acquiredInfo, String message);
+ // Notifies that the SystemUI dialog has been dismissed.
+ void onDialogDismissed(int reason);
}
diff --git a/core/java/android/hardware/face/IFaceService.aidl b/core/java/android/hardware/face/IFaceService.aidl
index 47df8e8f9729..2f9e4855eddc 100644
--- a/core/java/android/hardware/face/IFaceService.aidl
+++ b/core/java/android/hardware/face/IFaceService.aidl
@@ -16,7 +16,6 @@
package android.hardware.face;
import android.os.Bundle;
-import android.hardware.biometrics.IBiometricPromptReceiver;
import android.hardware.biometrics.IBiometricServiceReceiver;
import android.hardware.biometrics.IBiometricServiceLockoutResetCallback;
import android.hardware.face.IFaceServiceReceiver;
@@ -35,16 +34,16 @@ interface IFaceService {
// This method invokes the BiometricDialog. The arguments are almost the same as above,
// but should only be called from (BiometricPromptService).
void authenticateFromService(boolean requireConfirmation, IBinder token, long sessionId,
- int userId, IBiometricServiceReceiver receiver, int flags, String opPackageName,
- in Bundle bundle, IBiometricPromptReceiver dialogReceiver,
- int callingUid, int callingPid, int callingUserId);
+ int userId, IBiometricServiceReceiver clientRceiver,
+ IBiometricServiceReceiver wrapperReceiver, int flags, String opPackageName,
+ in Bundle bundle, int callingUid, int callingPid, int callingUserId);
// Cancel authentication for the given sessionId
void cancelAuthentication(IBinder token, String opPackageName);
// Same as above, with extra arguments.
void cancelAuthenticationFromService(IBinder token, String opPackageName,
- int callingUid, int callingPid, int callingUserId);
+ int callingUid, int callingPid, int callingUserId, boolean fromClient);
// Start face enrollment
void enroll(IBinder token, in byte [] cryptoToken, int userId, IFaceServiceReceiver receiver,
diff --git a/core/java/android/hardware/fingerprint/IFingerprintService.aidl b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
index 2662a11c2dd4..cfe30b1dc74a 100644
--- a/core/java/android/hardware/fingerprint/IFingerprintService.aidl
+++ b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
@@ -16,7 +16,6 @@
package android.hardware.fingerprint;
import android.os.Bundle;
-import android.hardware.biometrics.IBiometricPromptReceiver;
import android.hardware.biometrics.IBiometricServiceReceiver;
import android.hardware.biometrics.IBiometricServiceLockoutResetCallback;
import android.hardware.fingerprint.IFingerprintClientActiveCallback;
@@ -40,9 +39,9 @@ interface IFingerprintService {
// called from BiometricPromptService. The additional uid, pid, userId arguments should be
// determined by BiometricPromptService.
void authenticateFromService(IBinder token, long sessionId, int userId,
- IBiometricServiceReceiver receiver, int flags, String opPackageName,
- in Bundle bundle, IBiometricPromptReceiver dialogReceiver,
- int callingUid, int callingPid, int callingUserId);
+ IBiometricServiceReceiver clientReceiver, IBiometricServiceReceiver wrapperReceiver,
+ int flags, String opPackageName, in Bundle bundle, int callingUid, int callingPid,
+ int callingUserId);
// Cancel authentication for the given sessionId
void cancelAuthentication(IBinder token, String opPackageName);
@@ -50,7 +49,7 @@ interface IFingerprintService {
// Same as above, except this is protected by the MANAGE_BIOMETRIC signature permission. Takes
// an additional uid, pid, userid.
void cancelAuthenticationFromService(IBinder token, String opPackageName,
- int callingUid, int callingPid, int callingUserId);
+ int callingUid, int callingPid, int callingUserId, boolean fromClient);
// Start fingerprint enrollment
void enroll(IBinder token, in byte [] cryptoToken, int groupId, IFingerprintServiceReceiver receiver,