diff --git a/services/core/java/com/android/server/biometrics/AuthService.java b/services/core/java/com/android/server/biometrics/AuthService.java index 6f73985fbcd4d..5cd330a5753c7 100644 --- a/services/core/java/com/android/server/biometrics/AuthService.java +++ b/services/core/java/com/android/server/biometrics/AuthService.java @@ -27,6 +27,8 @@ import static android.Manifest.permission.USE_FINGERPRINT; import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE; import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT; import static android.hardware.biometrics.BiometricAuthenticator.TYPE_IRIS; +import static android.hardware.biometrics.BiometricAuthenticator.TYPE_NONE; +import static android.hardware.biometrics.BiometricConstants.BIOMETRIC_ERROR_CANCELED; import static android.hardware.biometrics.BiometricManager.Authenticators; import android.annotation.NonNull; @@ -76,7 +78,6 @@ import java.util.List; */ public class AuthService extends SystemService { private static final String TAG = "AuthService"; - private static final boolean DEBUG = false; private static final String SETTING_HIDL_DISABLED = "com.android.server.biometrics.AuthService.hidlDisabled"; private static final int DEFAULT_HIDL_DISABLED = 0; @@ -208,7 +209,6 @@ public class AuthService extends SystemService { public void authenticate(IBinder token, long sessionId, int userId, IBiometricServiceReceiver receiver, String opPackageName, PromptInfo promptInfo) throws RemoteException { - // Only allow internal clients to authenticate with a different userId. final int callingUserId = UserHandle.getCallingUserId(); final int callingUid = Binder.getCallingUid(); @@ -222,17 +222,18 @@ public class AuthService extends SystemService { } if (!checkAppOps(callingUid, opPackageName, "authenticate()")) { - Slog.e(TAG, "Denied by app ops: " + opPackageName); - return; - } - - if (!Utils.isForeground(callingUid, callingPid)) { - Slog.e(TAG, "Caller is not foreground: " + opPackageName); + authenticateFastFail("Denied by app ops: " + opPackageName, receiver); return; } if (token == null || receiver == null || opPackageName == null || promptInfo == null) { - Slog.e(TAG, "Unable to authenticate, one or more null arguments"); + authenticateFastFail( + "Unable to authenticate, one or more null arguments", receiver); + return; + } + + if (!Utils.isForeground(callingUid, callingPid)) { + authenticateFastFail("Caller is not foreground: " + opPackageName, receiver); return; } @@ -257,6 +258,17 @@ public class AuthService extends SystemService { } } + private void authenticateFastFail(String message, IBiometricServiceReceiver receiver) { + // notify caller in cases where authentication is aborted before calling into + // IBiometricService without raising an exception + Slog.e(TAG, message); + try { + receiver.onError(TYPE_NONE, BIOMETRIC_ERROR_CANCELED, 0 /*vendorCode */); + } catch (RemoteException e) { + Slog.e(TAG, "authenticateFastFail failed to notify caller", e); + } + } + @Override public void cancelAuthentication(IBinder token, String opPackageName) throws RemoteException { diff --git a/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java index 6f0c8e1004c4d..aec70f4f3df0e 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java @@ -16,6 +16,8 @@ package com.android.server.biometrics; +import static android.hardware.biometrics.BiometricAuthenticator.TYPE_NONE; +import static android.hardware.biometrics.BiometricConstants.BIOMETRIC_ERROR_CANCELED; import static android.hardware.biometrics.BiometricConstants.BIOMETRIC_SUCCESS; import static junit.framework.Assert.assertEquals; @@ -234,6 +236,27 @@ public class AuthServiceTest { eq(mReceiver), eq(TEST_OP_PACKAGE_NAME), eq(promptInfo)); + verify(mReceiver).onError(eq(TYPE_NONE), eq(BIOMETRIC_ERROR_CANCELED), anyInt()); + } + + @Test + public void testAuthenticate_missingRequiredParam() throws Exception { + mAuthService = new AuthService(mContext, mInjector); + mAuthService.onStart(); + + final PromptInfo promptInfo = new PromptInfo(); + final long sessionId = 0; + final int userId = 0; + + mAuthService.mImpl.authenticate( + null /* token */, + sessionId, + userId, + mReceiver, + TEST_OP_PACKAGE_NAME, + promptInfo); + waitForIdle(); + verify(mReceiver).onError(eq(TYPE_NONE), eq(BIOMETRIC_ERROR_CANCELED), anyInt()); } @Test @@ -259,7 +282,6 @@ public class AuthServiceTest { eq(authenticators)); } - @Test public void testHasEnrolledBiometrics_callsBiometricServiceHasEnrolledBiometrics() throws Exception {