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 aec70f4f3df0e..6216c66aa54f7 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java @@ -16,16 +16,23 @@ package com.android.server.biometrics; +import static android.Manifest.permission.MANAGE_BIOMETRIC; +import static android.Manifest.permission.TEST_BIOMETRIC; +import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL; 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; +import static org.junit.Assert.assertThrows; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -53,11 +60,14 @@ import androidx.test.filters.SmallTest; import com.android.internal.R; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mock; -import org.mockito.MockitoAnnotations; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; +import org.mockito.stubbing.Stubber; import java.util.List; @@ -65,11 +75,13 @@ import java.util.List; @SmallTest public class AuthServiceTest { - private static final String TAG = "AuthServiceTest"; private static final String TEST_OP_PACKAGE_NAME = "test_package"; private AuthService mAuthService; + @Rule + public MockitoRule mockitorule = MockitoJUnit.rule(); + @Mock private Context mContext; @Mock @@ -97,8 +109,6 @@ public class AuthServiceTest { @Before public void setUp() { - MockitoAnnotations.initMocks(this); - // Placeholder test config final String[] config = { "0:2:15", // ID0:Fingerprint:Strong @@ -123,10 +133,13 @@ public class AuthServiceTest { when(mInjector.getIrisService()).thenReturn(mIrisService); when(mInjector.getAppOps(any())).thenReturn(mAppOpsManager); when(mInjector.isHidlDisabled(any())).thenReturn(false); + + setInternalAndTestBiometricPermissions(mContext, false /* hasPermission */); } @Test public void testRegisterNullService_doesNotRegister() throws Exception { + setInternalAndTestBiometricPermissions(mContext, true /* hasPermission */); // Config contains Fingerprint, Iris, Face, but services are all null @@ -259,6 +272,40 @@ public class AuthServiceTest { verify(mReceiver).onError(eq(TYPE_NONE), eq(BIOMETRIC_ERROR_CANCELED), anyInt()); } + @Test + public void testAuthenticate_throwsWhenUsingTestConfigurations() { + final PromptInfo promptInfo = mock(PromptInfo.class); + when(promptInfo.containsPrivateApiConfigurations()).thenReturn(false); + when(promptInfo.containsTestConfigurations()).thenReturn(true); + + testAuthenticate_throwsWhenUsingTestConfigurations(promptInfo); + } + + @Test + public void testAuthenticate_throwsWhenUsingPrivateApis() { + final PromptInfo promptInfo = mock(PromptInfo.class); + when(promptInfo.containsPrivateApiConfigurations()).thenReturn(true); + when(promptInfo.containsTestConfigurations()).thenReturn(false); + + testAuthenticate_throwsWhenUsingTestConfigurations(promptInfo); + } + + private void testAuthenticate_throwsWhenUsingTestConfigurations(PromptInfo promptInfo) { + mAuthService = new AuthService(mContext, mInjector); + mAuthService.onStart(); + + assertThrows(SecurityException.class, () -> { + mAuthService.mImpl.authenticate( + null /* token */, + 10 /* sessionId */, + 2 /* userId */, + mReceiver, + TEST_OP_PACKAGE_NAME, + promptInfo); + waitForIdle(); + }); + } + @Test public void testCanAuthenticate_callsBiometricServiceCanAuthenticate() throws Exception { mAuthService = new AuthService(mContext, mInjector); @@ -283,8 +330,10 @@ public class AuthServiceTest { } @Test - public void testHasEnrolledBiometrics_callsBiometricServiceHasEnrolledBiometrics() throws - Exception { + public void testHasEnrolledBiometrics_callsBiometricServiceHasEnrolledBiometrics() + throws Exception { + setInternalAndTestBiometricPermissions(mContext, true /* hasPermission */); + mAuthService = new AuthService(mContext, mInjector); mAuthService.onStart(); @@ -307,6 +356,8 @@ public class AuthServiceTest { @Test public void testRegisterKeyguardCallback_callsBiometricServiceRegisterKeyguardCallback() throws Exception { + setInternalAndTestBiometricPermissions(mContext, true /* hasPermission */); + mAuthService = new AuthService(mContext, mInjector); mAuthService.onStart(); @@ -320,6 +371,20 @@ public class AuthServiceTest { eq(callback), eq(UserHandle.getCallingUserId())); } + private static void setInternalAndTestBiometricPermissions( + Context context, boolean hasPermission) { + for (String p : List.of(TEST_BIOMETRIC, MANAGE_BIOMETRIC, USE_BIOMETRIC_INTERNAL)) { + when(context.checkCallingPermission(eq(p))).thenReturn(hasPermission + ? PackageManager.PERMISSION_GRANTED : PackageManager.PERMISSION_DENIED); + when(context.checkCallingOrSelfPermission(eq(p))).thenReturn(hasPermission + ? PackageManager.PERMISSION_GRANTED : PackageManager.PERMISSION_DENIED); + final Stubber doPermCheck = + hasPermission ? doNothing() : doThrow(SecurityException.class); + doPermCheck.when(context).enforceCallingPermission(eq(p), any()); + doPermCheck.when(context).enforceCallingOrSelfPermission(eq(p), any()); + } + } + private static void waitForIdle() { InstrumentationRegistry.getInstrumentation().waitForIdleSync(); }