Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2107d6cd authored by Joe Bolinger's avatar Joe Bolinger Committed by Android (Google) Code Review
Browse files

Merge "Add tests for use of private and test API configurations in authenticate operations."

parents 0b9b6f13 26dbe0cf
Loading
Loading
Loading
Loading
+71 −6
Original line number Diff line number Diff line
@@ -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();
    }