summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/hardware/biometrics/BiometricAuthenticator.java13
-rw-r--r--core/java/android/hardware/biometrics/BiometricConstants.java7
-rw-r--r--core/java/android/hardware/biometrics/BiometricPrompt.java20
-rw-r--r--core/java/android/hardware/biometrics/IBiometricServiceReceiver.aidl2
-rw-r--r--core/java/android/hardware/biometrics/IBiometricServiceReceiverInternal.aidl2
-rw-r--r--core/java/com/android/internal/statusbar/IStatusBar.aidl8
-rw-r--r--core/java/com/android/internal/statusbar/IStatusBarService.aidl8
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java56
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java33
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java59
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java14
-rw-r--r--services/core/java/com/android/server/biometrics/BiometricService.java97
-rw-r--r--services/core/java/com/android/server/biometrics/face/FaceService.java4
-rw-r--r--services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java4
-rw-r--r--services/core/java/com/android/server/statusbar/StatusBarManagerService.java8
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java112
16 files changed, 279 insertions, 168 deletions
diff --git a/core/java/android/hardware/biometrics/BiometricAuthenticator.java b/core/java/android/hardware/biometrics/BiometricAuthenticator.java
index 0ec812fe0350..698876b9c59e 100644
--- a/core/java/android/hardware/biometrics/BiometricAuthenticator.java
+++ b/core/java/android/hardware/biometrics/BiometricAuthenticator.java
@@ -36,23 +36,30 @@ public interface BiometricAuthenticator {
* @hide
*/
int TYPE_NONE = 0;
+
+ /**
+ * Constant representing credential (PIN, pattern, or password).
+ * @hide
+ */
+ int TYPE_CREDENTIAL = 1 << 0;
+
/**
* Constant representing fingerprint.
* @hide
*/
- int TYPE_FINGERPRINT = 1 << 0;
+ int TYPE_FINGERPRINT = 1 << 1;
/**
* Constant representing iris.
* @hide
*/
- int TYPE_IRIS = 1 << 1;
+ int TYPE_IRIS = 1 << 2;
/**
* Constant representing face.
* @hide
*/
- int TYPE_FACE = 1 << 2;
+ int TYPE_FACE = 1 << 3;
/**
* Container for biometric data
diff --git a/core/java/android/hardware/biometrics/BiometricConstants.java b/core/java/android/hardware/biometrics/BiometricConstants.java
index 27c04b407315..c8bf570e1bc8 100644
--- a/core/java/android/hardware/biometrics/BiometricConstants.java
+++ b/core/java/android/hardware/biometrics/BiometricConstants.java
@@ -134,6 +134,13 @@ public interface BiometricConstants {
int BIOMETRIC_ERROR_NO_DEVICE_CREDENTIAL = 14;
/**
+ * This constant is only used by SystemUI. It notifies SystemUI that authentication was paused
+ * because the authentication attempt was unsuccessful.
+ * @hide
+ */
+ int BIOMETRIC_PAUSED_REJECTED = 100;
+
+ /**
* @hide
*/
@UnsupportedAppUsage
diff --git a/core/java/android/hardware/biometrics/BiometricPrompt.java b/core/java/android/hardware/biometrics/BiometricPrompt.java
index cf86e25112d2..9c51b5246749 100644
--- a/core/java/android/hardware/biometrics/BiometricPrompt.java
+++ b/core/java/android/hardware/biometrics/BiometricPrompt.java
@@ -26,6 +26,8 @@ import android.annotation.RequiresPermission;
import android.app.KeyguardManager;
import android.content.Context;
import android.content.DialogInterface;
+import android.hardware.face.FaceManager;
+import android.hardware.fingerprint.FingerprintManager;
import android.os.Binder;
import android.os.Bundle;
import android.os.CancellationSignal;
@@ -339,9 +341,23 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
}
@Override
- public void onError(int error, String message) throws RemoteException {
+ public void onError(int modality, int error, int vendorCode) throws RemoteException {
mExecutor.execute(() -> {
- mAuthenticationCallback.onAuthenticationError(error, message);
+ String errorMessage;
+ switch (modality) {
+ case TYPE_FACE:
+ errorMessage = FaceManager.getErrorString(mContext, error, vendorCode);
+ break;
+
+ case TYPE_FINGERPRINT:
+ errorMessage = FingerprintManager.getErrorString(mContext, error,
+ vendorCode);
+ break;
+
+ default:
+ errorMessage = "";
+ }
+ mAuthenticationCallback.onAuthenticationError(error, errorMessage);
});
}
diff --git a/core/java/android/hardware/biometrics/IBiometricServiceReceiver.aidl b/core/java/android/hardware/biometrics/IBiometricServiceReceiver.aidl
index 22ef33e86e17..c960049438f1 100644
--- a/core/java/android/hardware/biometrics/IBiometricServiceReceiver.aidl
+++ b/core/java/android/hardware/biometrics/IBiometricServiceReceiver.aidl
@@ -25,7 +25,7 @@ oneway interface IBiometricServiceReceiver {
// Noties that authentication failed.
void onAuthenticationFailed();
// Notify BiometricPrompt that an error has occurred.
- void onError(int error, String message);
+ void onError(int modality, int error, int vendorCode);
// Notifies that a biometric has been acquired.
void onAcquired(int acquiredInfo, String message);
// Notifies that the SystemUI dialog has been dismissed.
diff --git a/core/java/android/hardware/biometrics/IBiometricServiceReceiverInternal.aidl b/core/java/android/hardware/biometrics/IBiometricServiceReceiverInternal.aidl
index 66b6e896fc13..61310f302fe4 100644
--- a/core/java/android/hardware/biometrics/IBiometricServiceReceiverInternal.aidl
+++ b/core/java/android/hardware/biometrics/IBiometricServiceReceiverInternal.aidl
@@ -31,7 +31,7 @@ oneway interface IBiometricServiceReceiverInternal {
void onAuthenticationFailed();
// Notify BiometricService than an error has occured. Forward to the correct receiver depending
// on the cookie.
- void onError(int cookie, int error, String message);
+ void onError(int cookie, int modality, int error, int vendorCode);
// Notifies that a biometric has been acquired.
void onAcquired(int acquiredInfo, String message);
// Notifies that the SystemUI dialog has been dismissed.
diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl
index c8ba52a63151..23c6acc606fd 100644
--- a/core/java/com/android/internal/statusbar/IStatusBar.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl
@@ -154,12 +154,12 @@ oneway interface IStatusBar
// Used to show the authentication dialog (Biometrics, Device Credential)
void showAuthenticationDialog(in Bundle bundle, IBiometricServiceReceiverInternal receiver,
int biometricModality, boolean requireConfirmation, int userId, String opPackageName);
- // Used to notify the authentication dialog that a biometric has been authenticated or rejected
- void onBiometricAuthenticated(boolean authenticated, String failureReason);
+ // Used to notify the authentication dialog that a biometric has been authenticated
+ void onBiometricAuthenticated();
// Used to set a temporary message, e.g. fingerprint not recognized, finger moved too fast, etc
void onBiometricHelp(String message);
- // Used to set a message - the dialog will dismiss after a certain amount of time
- void onBiometricError(int errorCode, String error);
+ // Used to show an error - the dialog will dismiss after a certain amount of time
+ void onBiometricError(int modality, int error, int vendorCode);
// Used to hide the authentication dialog, e.g. when the application cancels authentication
void hideAuthenticationDialog();
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index 659134adec78..499a4d2fb949 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -104,12 +104,12 @@ interface IStatusBarService
// Used to show the authentication dialog (Biometrics, Device Credential)
void showAuthenticationDialog(in Bundle bundle, IBiometricServiceReceiverInternal receiver,
int biometricModality, boolean requireConfirmation, int userId, String opPackageName);
- // Used to notify the authentication dialog that a biometric has been authenticated or rejected
- void onBiometricAuthenticated(boolean authenticated, String failureReason);
+ // Used to notify the authentication dialog that a biometric has been authenticated
+ void onBiometricAuthenticated();
// Used to set a temporary message, e.g. fingerprint not recognized, finger moved too fast, etc
void onBiometricHelp(String message);
- // Used to set a message - the dialog will dismiss after a certain amount of time
- void onBiometricError(int errorCode, String error);
+ // Used to show an error - the dialog will dismiss after a certain amount of time
+ void onBiometricError(int modality, int error, int vendorCode);
// Used to hide the authentication dialog, e.g. when the application cancels authentication
void hideAuthenticationDialog();
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index cdc2623d34fd..b75873100025 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -16,6 +16,9 @@
package com.android.systemui.biometrics;
+import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE;
+import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
+
import android.app.ActivityManager;
import android.app.ActivityTaskManager;
import android.app.IActivityTaskManager;
@@ -27,6 +30,8 @@ import android.hardware.biometrics.Authenticator;
import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.BiometricPrompt;
import android.hardware.biometrics.IBiometricServiceReceiverInternal;
+import android.hardware.face.FaceManager;
+import android.hardware.fingerprint.FingerprintManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
@@ -34,6 +39,7 @@ import android.os.RemoteException;
import android.util.Log;
import android.view.WindowManager;
+import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.SomeArgs;
import com.android.systemui.SystemUI;
@@ -229,15 +235,8 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
}
@Override
- public void onBiometricAuthenticated(boolean authenticated, String failureReason) {
- if (DEBUG) Log.d(TAG, "onBiometricAuthenticated: " + authenticated
- + " reason: " + failureReason);
-
- if (authenticated) {
- mCurrentDialog.onAuthenticationSucceeded();
- } else {
- mCurrentDialog.onAuthenticationFailed(failureReason);
- }
+ public void onBiometricAuthenticated() {
+ mCurrentDialog.onAuthenticationSucceeded();
}
@Override
@@ -247,16 +246,45 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
mCurrentDialog.onHelp(message);
}
+ private String getErrorString(int modality, int error, int vendorCode) {
+ switch (modality) {
+ case TYPE_FACE:
+ return FaceManager.getErrorString(mContext, error, vendorCode);
+
+ case TYPE_FINGERPRINT:
+ return FingerprintManager.getErrorString(mContext, error, vendorCode);
+
+ default:
+ return "";
+ }
+ }
+
@Override
- public void onBiometricError(int errorCode, String error) {
- if (DEBUG) Log.d(TAG, "onBiometricError: " + errorCode + ", " + error);
+ public void onBiometricError(int modality, int error, int vendorCode) {
+ if (DEBUG) {
+ Log.d(TAG, String.format("onBiometricError(%d, %d, %d)", modality, error, vendorCode));
+ }
+
+ final boolean isLockout = (error == BiometricConstants.BIOMETRIC_ERROR_LOCKOUT)
+ || (error == BiometricConstants.BIOMETRIC_ERROR_LOCKOUT_PERMANENT);
+
+ // TODO(b/141025588): Create separate methods for handling hard and soft errors.
+ final boolean isSoftError = (error == BiometricConstants.BIOMETRIC_PAUSED_REJECTED
+ || error == BiometricConstants.BIOMETRIC_ERROR_TIMEOUT);
- final boolean isLockout = errorCode == BiometricConstants.BIOMETRIC_ERROR_LOCKOUT
- || errorCode == BiometricConstants.BIOMETRIC_ERROR_LOCKOUT_PERMANENT;
if (mCurrentDialog.isAllowDeviceCredentials() && isLockout) {
+ if (DEBUG) Log.d(TAG, "onBiometricError, lockout");
mCurrentDialog.animateToCredentialUI();
+ } else if (isSoftError) {
+ final String errorMessage = (error == BiometricConstants.BIOMETRIC_PAUSED_REJECTED)
+ ? mContext.getString(R.string.biometric_not_recognized)
+ : getErrorString(modality, error, vendorCode);
+ if (DEBUG) Log.d(TAG, "onBiometricError, soft error: " + errorMessage);
+ mCurrentDialog.onAuthenticationFailed(errorMessage);
} else {
- mCurrentDialog.onError(error);
+ final String errorMessage = getErrorString(modality, error, vendorCode);
+ if (DEBUG) Log.d(TAG, "onBiometricError, hard error: " + errorMessage);
+ mCurrentDialog.onError(errorMessage);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index d6a8f906197d..2b1c807c245a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -273,9 +273,9 @@ public class CommandQueue extends IStatusBar.Stub implements CallbackController<
default void showAuthenticationDialog(Bundle bundle,
IBiometricServiceReceiverInternal receiver, int biometricModality,
boolean requireConfirmation, int userId, String opPackageName) { }
- default void onBiometricAuthenticated(boolean authenticated, String failureReason) { }
+ default void onBiometricAuthenticated() { }
default void onBiometricHelp(String message) { }
- default void onBiometricError(int errorCode, String error) { }
+ default void onBiometricError(int modality, int error, int vendorCode) { }
default void hideAuthenticationDialog() { }
/**
@@ -757,12 +757,9 @@ public class CommandQueue extends IStatusBar.Stub implements CallbackController<
}
@Override
- public void onBiometricAuthenticated(boolean authenticated, String failureReason) {
+ public void onBiometricAuthenticated() {
synchronized (mLock) {
- SomeArgs args = SomeArgs.obtain();
- args.arg1 = authenticated;
- args.arg2 = failureReason;
- mHandler.obtainMessage(MSG_BIOMETRIC_AUTHENTICATED, args).sendToTarget();
+ mHandler.obtainMessage(MSG_BIOMETRIC_AUTHENTICATED).sendToTarget();
}
}
@@ -774,9 +771,13 @@ public class CommandQueue extends IStatusBar.Stub implements CallbackController<
}
@Override
- public void onBiometricError(int errorCode, String error) {
+ public void onBiometricError(int modality, int error, int vendorCode) {
synchronized (mLock) {
- mHandler.obtainMessage(MSG_BIOMETRIC_ERROR, errorCode, 0, error).sendToTarget();
+ SomeArgs args = SomeArgs.obtain();
+ args.argi1 = modality;
+ args.argi2 = error;
+ args.argi3 = vendorCode;
+ mHandler.obtainMessage(MSG_BIOMETRIC_ERROR, args).sendToTarget();
}
}
@@ -1045,13 +1046,9 @@ public class CommandQueue extends IStatusBar.Stub implements CallbackController<
break;
}
case MSG_BIOMETRIC_AUTHENTICATED: {
- SomeArgs someArgs = (SomeArgs) msg.obj;
for (int i = 0; i < mCallbacks.size(); i++) {
- mCallbacks.get(i).onBiometricAuthenticated(
- (boolean) someArgs.arg1 /* authenticated */,
- (String) someArgs.arg2 /* failureReason */);
+ mCallbacks.get(i).onBiometricAuthenticated();
}
- someArgs.recycle();
break;
}
case MSG_BIOMETRIC_HELP:
@@ -1060,9 +1057,15 @@ public class CommandQueue extends IStatusBar.Stub implements CallbackController<
}
break;
case MSG_BIOMETRIC_ERROR:
+ SomeArgs someArgs = (SomeArgs) msg.obj;
for (int i = 0; i < mCallbacks.size(); i++) {
- mCallbacks.get(i).onBiometricError(msg.arg1, (String) msg.obj);
+ mCallbacks.get(i).onBiometricError(
+ someArgs.argi1 /* modality */,
+ someArgs.argi2 /* error */,
+ someArgs.argi3 /* vendorCode */
+ );
}
+ someArgs.recycle();
break;
case MSG_BIOMETRIC_HIDE:
for (int i = 0; i < mCallbacks.size(); i++) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
index e1eb3b0c81b2..b089b740fc47 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
@@ -38,15 +38,18 @@ import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.hardware.biometrics.Authenticator;
+import android.hardware.biometrics.BiometricAuthenticator;
import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.BiometricPrompt;
import android.hardware.biometrics.IBiometricServiceReceiverInternal;
+import android.hardware.face.FaceManager;
import android.os.Bundle;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableContext;
import android.testing.TestableLooper.RunWithLooper;
+import com.android.internal.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.phone.StatusBar;
@@ -89,9 +92,9 @@ public class AuthControllerTest extends SysuiTestCase {
when(context.getPackageManager()).thenReturn(mPackageManager);
when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FACE))
- .thenReturn(true);
+ .thenReturn(true);
when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT))
- .thenReturn(true);
+ .thenReturn(true);
when(mDialog1.getOpPackageName()).thenReturn("Dialog1");
when(mDialog2.getOpPackageName()).thenReturn("Dialog2");
@@ -170,20 +173,34 @@ public class AuthControllerTest extends SysuiTestCase {
@Test
public void testOnAuthenticationSucceededInvoked_whenSystemRequested() {
showDialog(Authenticator.TYPE_BIOMETRIC, BiometricPrompt.TYPE_FACE);
- mAuthController.onBiometricAuthenticated(true, null /* failureReason */);
+ mAuthController.onBiometricAuthenticated();
verify(mDialog1).onAuthenticationSucceeded();
}
@Test
- public void testOnAuthenticationFailedInvoked_whenSystemRequested() {
+ public void testOnAuthenticationFailedInvoked_whenBiometricRejected() {
showDialog(Authenticator.TYPE_BIOMETRIC, BiometricPrompt.TYPE_FACE);
- final String failureReason = "failure reason";
- mAuthController.onBiometricAuthenticated(false, failureReason);
+ mAuthController.onBiometricError(BiometricAuthenticator.TYPE_NONE,
+ BiometricConstants.BIOMETRIC_PAUSED_REJECTED,
+ 0 /* vendorCode */);
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
verify(mDialog1).onAuthenticationFailed(captor.capture());
- assertEquals(captor.getValue(), failureReason);
+ assertEquals(captor.getValue(), mContext.getString(R.string.biometric_not_recognized));
+ }
+
+ @Test
+ public void testOnAuthenticationFailedInvoked_whenBiometricTimedOut() {
+ showDialog(Authenticator.TYPE_BIOMETRIC, BiometricPrompt.TYPE_FACE);
+ final int error = BiometricConstants.BIOMETRIC_ERROR_TIMEOUT;
+ final int vendorCode = 0;
+ mAuthController.onBiometricError(BiometricAuthenticator.TYPE_FACE, error, vendorCode);
+
+ ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
+ verify(mDialog1).onAuthenticationFailed(captor.capture());
+
+ assertEquals(captor.getValue(), FaceManager.getErrorString(mContext, error, vendorCode));
}
@Test
@@ -199,27 +216,27 @@ public class AuthControllerTest extends SysuiTestCase {
}
@Test
- public void testOnErrorInvoked_whenSystemRequested() {
+ public void testOnErrorInvoked_whenSystemRequested() throws Exception {
showDialog(Authenticator.TYPE_BIOMETRIC, BiometricPrompt.TYPE_FACE);
final int error = 1;
- final String errMessage = "error message";
- mAuthController.onBiometricError(error, errMessage);
+ final int vendorCode = 0;
+ mAuthController.onBiometricError(BiometricAuthenticator.TYPE_FACE, error, vendorCode);
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
verify(mDialog1).onError(captor.capture());
- assertEquals(captor.getValue(), errMessage);
+ assertEquals(captor.getValue(), FaceManager.getErrorString(mContext, error, vendorCode));
}
@Test
public void testErrorLockout_whenCredentialAllowed_AnimatesToCredentialUI() {
showDialog(Authenticator.TYPE_BIOMETRIC, BiometricPrompt.TYPE_FACE);
final int error = BiometricConstants.BIOMETRIC_ERROR_LOCKOUT;
- final String errorString = "lockout";
+ final int vendorCode = 0;
when(mDialog1.isAllowDeviceCredentials()).thenReturn(true);
- mAuthController.onBiometricError(error, errorString);
+ mAuthController.onBiometricError(BiometricAuthenticator.TYPE_FACE, error, vendorCode);
verify(mDialog1, never()).onError(anyString());
verify(mDialog1).animateToCredentialUI();
}
@@ -228,11 +245,11 @@ public class AuthControllerTest extends SysuiTestCase {
public void testErrorLockoutPermanent_whenCredentialAllowed_AnimatesToCredentialUI() {
showDialog(Authenticator.TYPE_BIOMETRIC, BiometricPrompt.TYPE_FACE);
final int error = BiometricConstants.BIOMETRIC_ERROR_LOCKOUT_PERMANENT;
- final String errorString = "lockout_permanent";
+ final int vendorCode = 0;
when(mDialog1.isAllowDeviceCredentials()).thenReturn(true);
- mAuthController.onBiometricError(error, errorString);
+ mAuthController.onBiometricError(BiometricAuthenticator.TYPE_FACE, error, vendorCode);
verify(mDialog1, never()).onError(anyString());
verify(mDialog1).animateToCredentialUI();
}
@@ -241,12 +258,12 @@ public class AuthControllerTest extends SysuiTestCase {
public void testErrorLockout_whenCredentialNotAllowed_sendsOnError() {
showDialog(Authenticator.TYPE_BIOMETRIC, BiometricPrompt.TYPE_FACE);
final int error = BiometricConstants.BIOMETRIC_ERROR_LOCKOUT;
- final String errorString = "lockout";
+ final int vendorCode = 0;
when(mDialog1.isAllowDeviceCredentials()).thenReturn(false);
- mAuthController.onBiometricError(error, errorString);
- verify(mDialog1).onError(eq(errorString));
+ mAuthController.onBiometricError(BiometricAuthenticator.TYPE_FACE, error, vendorCode);
+ verify(mDialog1).onError(eq(FaceManager.getErrorString(mContext, error, vendorCode)));
verify(mDialog1, never()).animateToCredentialUI();
}
@@ -254,12 +271,12 @@ public class AuthControllerTest extends SysuiTestCase {
public void testErrorLockoutPermanent_whenCredentialNotAllowed_sendsOnError() {
showDialog(Authenticator.TYPE_BIOMETRIC, BiometricPrompt.TYPE_FACE);
final int error = BiometricConstants.BIOMETRIC_ERROR_LOCKOUT_PERMANENT;
- final String errorString = "lockout_permanent";
+ final int vendorCode = 0;
when(mDialog1.isAllowDeviceCredentials()).thenReturn(false);
- mAuthController.onBiometricError(error, errorString);
- verify(mDialog1).onError(eq(errorString));
+ mAuthController.onBiometricError(BiometricAuthenticator.TYPE_FACE, error, vendorCode);
+ verify(mDialog1).onError(eq(FaceManager.getErrorString(mContext, error, vendorCode)));
verify(mDialog1, never()).animateToCredentialUI();
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java
index 1bd01e166ddb..ccb754cc240d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java
@@ -379,10 +379,9 @@ public class CommandQueueTest extends SysuiTestCase {
@Test
public void testOnBiometricAuthenticated() {
- String failureReason = "test_failure_reason";
- mCommandQueue.onBiometricAuthenticated(true /* authenticated */, failureReason);
+ mCommandQueue.onBiometricAuthenticated();
waitForIdleSync();
- verify(mCallbacks).onBiometricAuthenticated(eq(true), eq(failureReason));
+ verify(mCallbacks).onBiometricAuthenticated();
}
@Test
@@ -395,11 +394,12 @@ public class CommandQueueTest extends SysuiTestCase {
@Test
public void testOnBiometricError() {
- final int errorCode = 1;
- String errorMessage = "test_error_message";
- mCommandQueue.onBiometricError(errorCode, errorMessage);
+ final int modality = 1;
+ final int error = 2;
+ final int vendorCode = 3;
+ mCommandQueue.onBiometricError(modality, error, vendorCode);
waitForIdleSync();
- verify(mCallbacks).onBiometricError(eq(errorCode), eq(errorMessage));
+ verify(mCallbacks).onBiometricError(eq(modality), eq(error), eq(vendorCode));
}
@Test
diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java
index 2b45f1970ef4..619c21e7646b 100644
--- a/services/core/java/com/android/server/biometrics/BiometricService.java
+++ b/services/core/java/com/android/server/biometrics/BiometricService.java
@@ -168,7 +168,7 @@ public class BiometricService extends SystemService {
byte[] mTokenEscrow;
// Waiting for SystemUI to complete animation
int mErrorEscrow;
- String mErrorStringEscrow;
+ int mVendorCodeEscrow;
// Timestamp when authentication started
private long mStartTimeMs;
@@ -254,7 +254,7 @@ public class BiometricService extends SystemService {
}
case MSG_ON_AUTHENTICATION_REJECTED: {
- handleAuthenticationRejected((String) msg.obj /* failureReason */);
+ handleAuthenticationRejected();
break;
}
@@ -262,8 +262,9 @@ public class BiometricService extends SystemService {
SomeArgs args = (SomeArgs) msg.obj;
handleOnError(
args.argi1 /* cookie */,
- args.argi2 /* error */,
- (String) args.arg1 /* message */);
+ args.argi2 /* modality */,
+ args.argi3 /* error */,
+ args.argi4 /* vendorCode */);
args.recycle();
break;
}
@@ -323,7 +324,12 @@ public class BiometricService extends SystemService {
}
case MSG_ON_AUTHENTICATION_TIMED_OUT: {
- handleAuthenticationTimedOut((String) msg.obj /* errorMessage */);
+ SomeArgs args = (SomeArgs) msg.obj;
+ handleAuthenticationTimedOut(
+ args.argi1 /* modality */,
+ args.argi2 /* error */,
+ args.argi3 /* vendorCode */);
+ args.recycle();
break;
}
@@ -515,23 +521,28 @@ public class BiometricService extends SystemService {
@Override
public void onAuthenticationFailed()
throws RemoteException {
- String failureReason = getContext().getString(R.string.biometric_not_recognized);
- Slog.v(TAG, "onAuthenticationFailed: " + failureReason);
- mHandler.obtainMessage(MSG_ON_AUTHENTICATION_REJECTED, failureReason).sendToTarget();
+ Slog.v(TAG, "onAuthenticationFailed");
+ mHandler.obtainMessage(MSG_ON_AUTHENTICATION_REJECTED).sendToTarget();
}
@Override
- public void onError(int cookie, int error, String message) throws RemoteException {
+ public void onError(int cookie, int modality, int error, int vendorCode)
+ throws RemoteException {
// Determine if error is hard or soft error. Certain errors (such as TIMEOUT) are
// soft errors and we should allow the user to try authenticating again instead of
// dismissing BiometricPrompt.
if (error == BiometricConstants.BIOMETRIC_ERROR_TIMEOUT) {
- mHandler.obtainMessage(MSG_ON_AUTHENTICATION_TIMED_OUT, message).sendToTarget();
+ SomeArgs args = SomeArgs.obtain();
+ args.argi1 = modality;
+ args.argi2 = error;
+ args.argi3 = vendorCode;
+ mHandler.obtainMessage(MSG_ON_AUTHENTICATION_TIMED_OUT, args).sendToTarget();
} else {
SomeArgs args = SomeArgs.obtain();
args.argi1 = cookie;
- args.argi2 = error;
- args.arg1 = message;
+ args.argi2 = modality;
+ args.argi3 = error;
+ args.argi4 = vendorCode;
mHandler.obtainMessage(MSG_ON_ERROR, args).sendToTarget();
}
}
@@ -1088,14 +1099,14 @@ public class BiometricService extends SystemService {
// Notify SysUI that the biometric has been authenticated. SysUI already knows
// the implicit/explicit state and will react accordingly.
- mStatusBarService.onBiometricAuthenticated(true, null /* failureReason */);
+ mStatusBarService.onBiometricAuthenticated();
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception", e);
}
}
- private void handleAuthenticationRejected(String failureReason) {
- Slog.v(TAG, "handleAuthenticationRejected: " + failureReason);
+ private void handleAuthenticationRejected() {
+ Slog.v(TAG, "handleAuthenticationRejected()");
try {
// Should never happen, log this to catch bad HAL behavior (e.g. auth succeeded
// after user dismissed/canceled dialog).
@@ -1104,7 +1115,8 @@ public class BiometricService extends SystemService {
return;
}
- mStatusBarService.onBiometricAuthenticated(false, failureReason);
+ mStatusBarService.onBiometricError(TYPE_NONE,
+ BiometricConstants.BIOMETRIC_PAUSED_REJECTED, 0 /* vendorCode */);
// TODO: This logic will need to be updated if BP is multi-modal
if ((mCurrentAuthSession.mModality & TYPE_FACE) != 0) {
@@ -1119,8 +1131,9 @@ public class BiometricService extends SystemService {
}
}
- private void handleAuthenticationTimedOut(String message) {
- Slog.v(TAG, "handleAuthenticationTimedOut: " + message);
+ private void handleAuthenticationTimedOut(int modality, int error, int vendorCode) {
+ Slog.v(TAG, String.format("handleAuthenticationTimedOut(%d, %d, %d)", modality, error,
+ vendorCode));
try {
// Should never happen, log this to catch bad HAL behavior (e.g. auth succeeded
// after user dismissed/canceled dialog).
@@ -1129,14 +1142,14 @@ public class BiometricService extends SystemService {
return;
}
- mStatusBarService.onBiometricAuthenticated(false, message);
+ mStatusBarService.onBiometricError(modality, error, vendorCode);
mCurrentAuthSession.mState = STATE_AUTH_PAUSED;
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception", e);
}
}
- private void handleOnError(int cookie, int error, String message) {
+ private void handleOnError(int cookie, int modality, int error, int vendorCode) {
Slog.d(TAG, "handleOnError: " + error + " cookie: " + cookie);
// Errors can either be from the current auth session or the pending auth session.
// The pending auth session may receive errors such as ERROR_LOCKOUT before
@@ -1147,7 +1160,7 @@ public class BiometricService extends SystemService {
try {
if (mCurrentAuthSession != null && mCurrentAuthSession.containsCookie(cookie)) {
mCurrentAuthSession.mErrorEscrow = error;
- mCurrentAuthSession.mErrorStringEscrow = message;
+ mCurrentAuthSession.mVendorCodeEscrow = vendorCode;
if (mCurrentAuthSession.mState == STATE_AUTH_STARTED) {
final boolean errorLockout = error == BiometricConstants.BIOMETRIC_ERROR_LOCKOUT
@@ -1155,20 +1168,20 @@ public class BiometricService extends SystemService {
if (mCurrentAuthSession.isAllowDeviceCredential() && errorLockout) {
// SystemUI handles transition from biometric to device credential.
mCurrentAuthSession.mState = STATE_SHOWING_DEVICE_CREDENTIAL;
- mStatusBarService.onBiometricError(error, message);
+ mStatusBarService.onBiometricError(modality, error, vendorCode);
} else {
mCurrentAuthSession.mState = STATE_ERROR_PENDING_SYSUI;
if (error == BiometricConstants.BIOMETRIC_ERROR_CANCELED) {
mStatusBarService.hideAuthenticationDialog();
} else {
- mStatusBarService.onBiometricError(error, message);
+ mStatusBarService.onBiometricError(modality, error, vendorCode);
}
}
} else if (mCurrentAuthSession.mState == STATE_AUTH_PAUSED) {
// In the "try again" state, we should forward canceled errors to
// the client and and clean up. The only error we should get here is
// ERROR_CANCELED due to another client kicking us out.
- mCurrentAuthSession.mClientReceiver.onError(error, message);
+ mCurrentAuthSession.mClientReceiver.onError(modality, error, vendorCode);
mStatusBarService.hideAuthenticationDialog();
mCurrentAuthSession = null;
} else if (mCurrentAuthSession.mState == STATE_SHOWING_DEVICE_CREDENTIAL) {
@@ -1204,7 +1217,7 @@ public class BiometricService extends SystemService {
mCurrentAuthSession.mUserId,
mCurrentAuthSession.mOpPackageName);
} else {
- mPendingAuthSession.mClientReceiver.onError(error, message);
+ mPendingAuthSession.mClientReceiver.onError(modality, error, vendorCode);
mPendingAuthSession = null;
}
} else {
@@ -1268,8 +1281,10 @@ public class BiometricService extends SystemService {
case BiometricPrompt.DISMISSED_REASON_USER_CANCEL:
mCurrentAuthSession.mClientReceiver.onError(
+ mCurrentAuthSession.mModality,
BiometricConstants.BIOMETRIC_ERROR_USER_CANCELED,
- getContext().getString(R.string.biometric_error_user_canceled));
+ 0 /* vendorCode */
+ );
// Cancel authentication. Skip the token/package check since we are cancelling
// from system server. The interface is permission protected so this is fine.
cancelInternal(null /* token */, null /* package */, false /* fromClient */);
@@ -1277,8 +1292,11 @@ public class BiometricService extends SystemService {
case BiometricPrompt.DISMISSED_REASON_SERVER_REQUESTED:
case BiometricPrompt.DISMISSED_REASON_ERROR:
- mCurrentAuthSession.mClientReceiver.onError(mCurrentAuthSession.mErrorEscrow,
- mCurrentAuthSession.mErrorStringEscrow);
+ mCurrentAuthSession.mClientReceiver.onError(
+ mCurrentAuthSession.mModality,
+ mCurrentAuthSession.mErrorEscrow,
+ mCurrentAuthSession.mVendorCodeEscrow
+ );
break;
default:
@@ -1413,23 +1431,7 @@ public class BiometricService extends SystemService {
} else if (error != BiometricConstants.BIOMETRIC_SUCCESS) {
// Check for errors, notify callback, and return
try {
- final String hardwareUnavailable =
- getContext().getString(R.string.biometric_error_hw_unavailable);
- switch (error) {
- case BiometricConstants.BIOMETRIC_ERROR_HW_NOT_PRESENT:
- receiver.onError(error, hardwareUnavailable);
- break;
- case BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE:
- receiver.onError(error, hardwareUnavailable);
- break;
- case BiometricConstants.BIOMETRIC_ERROR_NO_BIOMETRICS:
- receiver.onError(error,
- getErrorString(modality, error, 0 /* vendorCode */));
- break;
- default:
- Slog.e(TAG, "Unhandled error");
- break;
- }
+ receiver.onError(modality, error, 0 /* vendorCode */);
} catch (RemoteException e) {
Slog.e(TAG, "Unable to send error", e);
}
@@ -1521,11 +1523,10 @@ public class BiometricService extends SystemService {
try {
// Send error to client
mCurrentAuthSession.mClientReceiver.onError(
+ mCurrentAuthSession.mModality,
BiometricConstants.BIOMETRIC_ERROR_CANCELED,
- getContext().getString(
- com.android.internal.R.string.biometric_error_user_canceled)
+ 0 /* vendorCode */
);
-
mCurrentAuthSession = null;
mStatusBarService.hideAuthenticationDialog();
} catch (RemoteException e) {
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 de6ee8b20c0e..a0c8e2325f77 100644
--- a/services/core/java/com/android/server/biometrics/face/FaceService.java
+++ b/services/core/java/com/android/server/biometrics/face/FaceService.java
@@ -20,6 +20,7 @@ import static android.Manifest.permission.INTERACT_ACROSS_USERS;
import static android.Manifest.permission.MANAGE_BIOMETRIC;
import static android.Manifest.permission.RESET_FACE_LOCKOUT;
import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
+import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE;
import android.app.ActivityManager;
import android.app.AppOpsManager;
@@ -752,8 +753,7 @@ public class FaceService extends BiometricServiceBase {
public void onError(long deviceId, int error, int vendorCode, int cookie)
throws RemoteException {
if (getWrapperReceiver() != null) {
- getWrapperReceiver().onError(cookie, error,
- FaceManager.getErrorString(getContext(), error, vendorCode));
+ getWrapperReceiver().onError(cookie, TYPE_FACE, error, vendorCode);
}
}
}
diff --git a/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java
index d59fcbf7c4d8..44797ad97b37 100644
--- a/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java
@@ -22,6 +22,7 @@ import static android.Manifest.permission.MANAGE_FINGERPRINT;
import static android.Manifest.permission.RESET_FINGERPRINT_LOCKOUT;
import static android.Manifest.permission.USE_BIOMETRIC;
import static android.Manifest.permission.USE_FINGERPRINT;
+import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
import android.app.ActivityManager;
import android.app.AlarmManager;
@@ -480,8 +481,7 @@ public class FingerprintService extends BiometricServiceBase {
public void onError(long deviceId, int error, int vendorCode, int cookie)
throws RemoteException {
if (getWrapperReceiver() != null) {
- getWrapperReceiver().onError(cookie, error,
- FingerprintManager.getErrorString(getContext(), error, vendorCode));
+ getWrapperReceiver().onError(cookie, TYPE_FINGERPRINT, error, vendorCode);
}
}
}
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 65bb2342d504..6f927a5465f0 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -623,11 +623,11 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
}
@Override
- public void onBiometricAuthenticated(boolean authenticated, String failureReason) {
+ public void onBiometricAuthenticated() {
enforceBiometricDialog();
if (mBar != null) {
try {
- mBar.onBiometricAuthenticated(authenticated, failureReason);
+ mBar.onBiometricAuthenticated();
} catch (RemoteException ex) {
}
}
@@ -645,11 +645,11 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
}
@Override
- public void onBiometricError(int errorCode, String error) {
+ public void onBiometricError(int modality, int error, int vendorCode) {
enforceBiometricDialog();
if (mBar != null) {
try {
- mBar.onBiometricError(errorCode, error);
+ mBar.onBiometricError(modality, error, vendorCode);
} catch (RemoteException ex) {
}
}
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
index dd86123ec423..ec47a959de30 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
@@ -143,7 +143,9 @@ public class BiometricServiceTest {
false /* allowDeviceCredential */);
waitForIdle();
verify(mReceiver1).onError(
- eq(BiometricConstants.BIOMETRIC_ERROR_HW_NOT_PRESENT), eq(ERROR_HW_UNAVAILABLE));
+ eq(BiometricAuthenticator.TYPE_NONE),
+ eq(BiometricConstants.BIOMETRIC_ERROR_HW_NOT_PRESENT),
+ eq(0 /* vendorCode */));
}
@Test
@@ -158,7 +160,9 @@ public class BiometricServiceTest {
false /* allowDeviceCredential */);
waitForIdle();
verify(mReceiver1).onError(
- eq(BiometricConstants.BIOMETRIC_ERROR_NO_BIOMETRICS), any());
+ eq(BiometricAuthenticator.TYPE_FINGERPRINT),
+ eq(BiometricConstants.BIOMETRIC_ERROR_NO_BIOMETRICS),
+ eq(0 /* vendorCode */));
}
@Test
@@ -175,7 +179,9 @@ public class BiometricServiceTest {
false /* allowDeviceCredential */);
waitForIdle();
verify(mReceiver1).onError(
- eq(BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE), eq(ERROR_HW_UNAVAILABLE));
+ eq(BiometricAuthenticator.TYPE_NONE),
+ eq(BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE),
+ eq(0 /* vendorCode */));
}
@Test
@@ -194,7 +200,9 @@ public class BiometricServiceTest {
false /* allowDeviceCredential */);
waitForIdle();
verify(mReceiver1).onError(
- eq(BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE), eq(ERROR_HW_UNAVAILABLE));
+ eq(BiometricAuthenticator.TYPE_NONE),
+ eq(BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE),
+ eq(0 /* vendorCode */));
// Enrolled, not disabled in settings, user requires confirmation in settings
resetReceiver();
@@ -204,7 +212,7 @@ public class BiometricServiceTest {
invokeAuthenticate(mBiometricService.mImpl, mReceiver1, false /* requireConfirmation */,
false /* allowDeviceCredential */);
waitForIdle();
- verify(mReceiver1, never()).onError(anyInt(), any(String.class));
+ verify(mReceiver1, never()).onError(anyInt(), anyInt(), anyInt());
verify(mBiometricService.mAuthenticators.get(0).impl).prepareForAuthentication(
eq(true) /* requireConfirmation */,
any(IBinder.class),
@@ -254,7 +262,7 @@ public class BiometricServiceTest {
// Invokes <Modality>Service#prepareForAuthentication
ArgumentCaptor<Integer> cookieCaptor = ArgumentCaptor.forClass(Integer.class);
- verify(mReceiver1, never()).onError(anyInt(), any(String.class));
+ verify(mReceiver1, never()).onError(anyInt(), anyInt(), anyInt());
verify(mBiometricService.mAuthenticators.get(0).impl).prepareForAuthentication(
anyBoolean() /* requireConfirmation */,
any(IBinder.class),
@@ -297,8 +305,7 @@ public class BiometricServiceTest {
assertEquals(mBiometricService.mCurrentAuthSession.mState,
BiometricService.STATE_AUTHENTICATED_PENDING_SYSUI);
// Notify SystemUI hardware authenticated
- verify(mBiometricService.mStatusBarService).onBiometricAuthenticated(
- eq(true) /* authenticated */, eq(null) /* failureReason */);
+ verify(mBiometricService.mStatusBarService).onBiometricAuthenticated();
// SystemUI sends callback with dismissed reason
mBiometricService.mInternalReceiver.onDialogDismissed(
@@ -369,8 +376,10 @@ public class BiometricServiceTest {
mBiometricService.mInternalReceiver.onAuthenticationFailed();
waitForIdle();
- verify(mBiometricService.mStatusBarService)
- .onBiometricAuthenticated(eq(false), eq(ERROR_NOT_RECOGNIZED));
+ verify(mBiometricService.mStatusBarService).onBiometricError(
+ eq(BiometricAuthenticator.TYPE_NONE),
+ eq(BiometricConstants.BIOMETRIC_PAUSED_REJECTED),
+ eq(0 /* vendorCode */));
verify(mReceiver1).onAuthenticationFailed();
assertEquals(mBiometricService.mCurrentAuthSession.mState,
BiometricService.STATE_AUTH_PAUSED);
@@ -386,8 +395,10 @@ public class BiometricServiceTest {
mBiometricService.mInternalReceiver.onAuthenticationFailed();
waitForIdle();
- verify(mBiometricService.mStatusBarService)
- .onBiometricAuthenticated(eq(false), eq(ERROR_NOT_RECOGNIZED));
+ verify(mBiometricService.mStatusBarService).onBiometricError(
+ eq(BiometricAuthenticator.TYPE_NONE),
+ eq(BiometricConstants.BIOMETRIC_PAUSED_REJECTED),
+ eq(0 /* vendorCode */));
verify(mReceiver1).onAuthenticationFailed();
assertEquals(mBiometricService.mCurrentAuthSession.mState,
BiometricService.STATE_AUTH_STARTED);
@@ -412,15 +423,15 @@ public class BiometricServiceTest {
BiometricService.STATE_AUTH_STARTED);
mBiometricService.mInternalReceiver.onError(
getCookieForCurrentSession(mBiometricService.mCurrentAuthSession),
- BiometricConstants.BIOMETRIC_ERROR_CANCELED, ERROR_CANCELED);
+ BiometricAuthenticator.TYPE_FINGERPRINT,
+ BiometricConstants.BIOMETRIC_ERROR_CANCELED, 0 /* vendorCode */);
waitForIdle();
// Auth session doesn't become null until SystemUI responds that the animation is completed
assertNotNull(mBiometricService.mCurrentAuthSession);
// ERROR_CANCELED is not sent until SystemUI responded that animation is completed
- verify(mReceiver1, never()).onError(
- anyInt(), anyString());
- verify(mReceiver2, never()).onError(anyInt(), any(String.class));
+ verify(mReceiver1, never()).onError(anyInt(), anyInt(), anyInt());
+ verify(mReceiver2, never()).onError(anyInt(), anyInt(), anyInt());
// SystemUI dialog closed
verify(mBiometricService.mStatusBarService).hideAuthenticationDialog();
@@ -430,8 +441,9 @@ public class BiometricServiceTest {
.onDialogDismissed(BiometricPrompt.DISMISSED_REASON_SERVER_REQUESTED);
waitForIdle();
verify(mReceiver1).onError(
+ eq(BiometricAuthenticator.TYPE_FINGERPRINT),
eq(BiometricConstants.BIOMETRIC_ERROR_CANCELED),
- eq(ERROR_CANCELED));
+ eq(0 /* vendorCode */));
assertNull(mBiometricService.mCurrentAuthSession);
}
@@ -443,14 +455,17 @@ public class BiometricServiceTest {
mBiometricService.mInternalReceiver.onError(
getCookieForCurrentSession(mBiometricService.mCurrentAuthSession),
+ BiometricAuthenticator.TYPE_FACE,
BiometricConstants.BIOMETRIC_ERROR_TIMEOUT,
- ERROR_TIMEOUT);
+ 0 /* vendorCode */);
waitForIdle();
assertEquals(mBiometricService.mCurrentAuthSession.mState,
BiometricService.STATE_AUTH_PAUSED);
- verify(mBiometricService.mStatusBarService)
- .onBiometricAuthenticated(eq(false), eq(ERROR_TIMEOUT));
+ verify(mBiometricService.mStatusBarService).onBiometricError(
+ eq(BiometricAuthenticator.TYPE_FACE),
+ eq(BiometricConstants.BIOMETRIC_ERROR_TIMEOUT),
+ eq(0 /* vendorCode */));
// Timeout does not count as fail as per BiometricPrompt documentation.
verify(mReceiver1, never()).onAuthenticationFailed();
@@ -489,18 +504,21 @@ public class BiometricServiceTest {
mBiometricService.mInternalReceiver.onError(
getCookieForCurrentSession(mBiometricService.mCurrentAuthSession),
+ BiometricAuthenticator.TYPE_FACE,
BiometricConstants.BIOMETRIC_ERROR_TIMEOUT,
- ERROR_TIMEOUT);
+ 0 /* vendorCode */);
mBiometricService.mInternalReceiver.onError(
getCookieForCurrentSession(mBiometricService.mCurrentAuthSession),
+ BiometricAuthenticator.TYPE_FACE,
BiometricConstants.BIOMETRIC_ERROR_CANCELED,
- ERROR_CANCELED);
+ 0 /* vendorCode */);
waitForIdle();
// Client receives error immediately
verify(mReceiver1).onError(
+ eq(BiometricAuthenticator.TYPE_FACE),
eq(BiometricConstants.BIOMETRIC_ERROR_CANCELED),
- eq(ERROR_CANCELED));
+ eq(0 /* vendorCode */));
// Dialog is hidden immediately
verify(mBiometricService.mStatusBarService).hideAuthenticationDialog();
// Auth session is over
@@ -519,26 +537,29 @@ public class BiometricServiceTest {
mBiometricService.mInternalReceiver.onError(
getCookieForCurrentSession(mBiometricService.mCurrentAuthSession),
+ BiometricAuthenticator.TYPE_FINGERPRINT,
BiometricConstants.BIOMETRIC_ERROR_UNABLE_TO_PROCESS,
- ERROR_UNABLE_TO_PROCESS);
+ 0 /* vendorCode */);
waitForIdle();
// Sends error to SystemUI and does not notify client yet
assertEquals(mBiometricService.mCurrentAuthSession.mState,
BiometricService.STATE_ERROR_PENDING_SYSUI);
verify(mBiometricService.mStatusBarService).onBiometricError(
+ eq(BiometricAuthenticator.TYPE_FINGERPRINT),
eq(BiometricConstants.BIOMETRIC_ERROR_UNABLE_TO_PROCESS),
- eq(ERROR_UNABLE_TO_PROCESS));
+ eq(0 /* vendorCode */));
verify(mBiometricService.mStatusBarService, never()).hideAuthenticationDialog();
- verify(mReceiver1, never()).onError(anyInt(), anyString());
+ verify(mReceiver1, never()).onError(anyInt(), anyInt(), anyInt());
// SystemUI animation completed, client is notified, auth session is over
mBiometricService.mInternalReceiver
.onDialogDismissed(BiometricPrompt.DISMISSED_REASON_ERROR);
waitForIdle();
verify(mReceiver1).onError(
+ eq(BiometricAuthenticator.TYPE_FINGERPRINT),
eq(BiometricConstants.BIOMETRIC_ERROR_UNABLE_TO_PROCESS),
- eq(ERROR_UNABLE_TO_PROCESS));
+ eq(0 /* vendorCode */));
assertNull(mBiometricService.mCurrentAuthSession);
}
@@ -551,8 +572,9 @@ public class BiometricServiceTest {
mBiometricService.mInternalReceiver.onError(
getCookieForPendingSession(mBiometricService.mPendingAuthSession),
+ BiometricAuthenticator.TYPE_FACE,
BiometricConstants.BIOMETRIC_ERROR_LOCKOUT,
- ERROR_LOCKOUT);
+ 0 /* vendorCode */);
waitForIdle();
// Pending auth session becomes current auth session, since device credential should
@@ -583,8 +605,9 @@ public class BiometricServiceTest {
mBiometricService.mInternalReceiver.onError(
getCookieForPendingSession(mBiometricService.mPendingAuthSession),
+ BiometricAuthenticator.TYPE_FINGERPRINT,
BiometricConstants.BIOMETRIC_ERROR_LOCKOUT,
- ERROR_LOCKOUT);
+ 0 /* vendorCode */);
waitForIdle();
// Error is sent to client
@@ -651,17 +674,18 @@ public class BiometricServiceTest {
assertEquals(BiometricService.STATE_SHOWING_DEVICE_CREDENTIAL,
mBiometricService.mCurrentAuthSession.mState);
- verify(mReceiver1, never()).onError(anyInt(), anyString());
+ verify(mReceiver1, never()).onError(anyInt(), anyInt(), anyInt());
mBiometricService.mInternalReceiver.onError(
getCookieForCurrentSession(mBiometricService.mCurrentAuthSession),
+ BiometricAuthenticator.TYPE_FINGERPRINT,
BiometricConstants.BIOMETRIC_ERROR_CANCELED,
- ERROR_CANCELED);
+ 0 /* vendorCode */);
waitForIdle();
assertEquals(BiometricService.STATE_SHOWING_DEVICE_CREDENTIAL,
mBiometricService.mCurrentAuthSession.mState);
- verify(mReceiver1, never()).onError(anyInt(), anyString());
+ verify(mReceiver1, never()).onError(anyInt(), anyInt(), anyInt());
}
@Test
@@ -675,15 +699,17 @@ public class BiometricServiceTest {
mBiometricService.mInternalReceiver.onError(
getCookieForCurrentSession(mBiometricService.mCurrentAuthSession),
+ BiometricAuthenticator.TYPE_FINGERPRINT,
BiometricConstants.BIOMETRIC_ERROR_LOCKOUT,
- ERROR_LOCKOUT);
+ 0 /* vendorCode */);
waitForIdle();
assertEquals(BiometricService.STATE_SHOWING_DEVICE_CREDENTIAL,
mBiometricService.mCurrentAuthSession.mState);
verify(mBiometricService.mStatusBarService).onBiometricError(
+ eq(BiometricAuthenticator.TYPE_FINGERPRINT),
eq(BiometricConstants.BIOMETRIC_ERROR_LOCKOUT),
- eq(ERROR_LOCKOUT));
+ eq(0 /* vendorCode */));
}
@Test
@@ -697,15 +723,17 @@ public class BiometricServiceTest {
mBiometricService.mInternalReceiver.onError(
getCookieForCurrentSession(mBiometricService.mCurrentAuthSession),
+ BiometricAuthenticator.TYPE_FINGERPRINT,
BiometricConstants.BIOMETRIC_ERROR_UNABLE_TO_PROCESS,
- ERROR_UNABLE_TO_PROCESS);
+ 0 /* vendorCode */);
waitForIdle();
assertEquals(BiometricService.STATE_ERROR_PENDING_SYSUI,
mBiometricService.mCurrentAuthSession.mState);
verify(mBiometricService.mStatusBarService).onBiometricError(
+ eq(BiometricAuthenticator.TYPE_FINGERPRINT),
eq(BiometricConstants.BIOMETRIC_ERROR_UNABLE_TO_PROCESS),
- eq(ERROR_UNABLE_TO_PROCESS));
+ eq(0 /* vendorCode */));
}
@Test
@@ -719,8 +747,9 @@ public class BiometricServiceTest {
.onDialogDismissed(BiometricPrompt.DISMISSED_REASON_USER_CANCEL);
waitForIdle();
verify(mReceiver1).onError(
+ eq(BiometricAuthenticator.TYPE_FINGERPRINT),
eq(BiometricConstants.BIOMETRIC_ERROR_USER_CANCELED),
- eq(ERROR_USER_CANCELED));
+ eq(0 /* vendorCode */));
verify(mBiometricService.mAuthenticators.get(0).impl).cancelAuthenticationFromService(
any(),
any(),
@@ -739,8 +768,9 @@ public class BiometricServiceTest {
mBiometricService.mInternalReceiver.onError(
getCookieForCurrentSession(mBiometricService.mCurrentAuthSession),
+ BiometricAuthenticator.TYPE_FACE,
BiometricConstants.BIOMETRIC_ERROR_TIMEOUT,
- ERROR_TIMEOUT);
+ 0 /* vendorCode */);
mBiometricService.mInternalReceiver.onDialogDismissed(
BiometricPrompt.DISMISSED_REASON_NEGATIVE);
waitForIdle();
@@ -764,8 +794,9 @@ public class BiometricServiceTest {
mBiometricService.mInternalReceiver.onError(
getCookieForCurrentSession(mBiometricService.mCurrentAuthSession),
+ BiometricAuthenticator.TYPE_FACE,
BiometricConstants.BIOMETRIC_ERROR_TIMEOUT,
- ERROR_TIMEOUT);
+ 0 /* vendorCode */);
mBiometricService.mInternalReceiver.onDialogDismissed(
BiometricPrompt.DISMISSED_REASON_USER_CANCEL);
waitForIdle();
@@ -803,8 +834,9 @@ public class BiometricServiceTest {
anyInt(),
anyBoolean());
verify(mReceiver1).onError(
+ eq(BiometricAuthenticator.TYPE_FACE),
eq(BiometricConstants.BIOMETRIC_ERROR_USER_CANCELED),
- eq(ERROR_USER_CANCELED));
+ eq(0 /* vendorCode */));
assertNull(mBiometricService.mCurrentAuthSession);
}