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

Commit 4535627f authored by Eric Biggers's avatar Eric Biggers Committed by Gerrit Code Review
Browse files

Merge "Fix and improve TrustManagerServiceTest" into main

parents 61024bcc 10531da3
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -75,6 +75,7 @@ import android.view.IWindowManager;
import android.view.WindowManagerGlobal;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.content.PackageMonitor;
import com.android.internal.infra.AndroidFuture;
import com.android.internal.util.DumpUtils;
@@ -1807,6 +1808,11 @@ public class TrustManagerService extends SystemService {
        }
    };

    @VisibleForTesting
    void waitForIdle() {
        mHandler.runWithScissors(() -> {}, 0);
    }

    private boolean isTrustUsuallyManagedInternal(int userId) {
        synchronized (mTrustUsuallyManagedForUser) {
            int i = mTrustUsuallyManagedForUser.indexOfKey(userId);
+121 −108
Original line number Diff line number Diff line
@@ -16,24 +16,23 @@

package com.android.server.trust;

import static android.content.pm.PackageManager.PERMISSION_GRANTED;

import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyInt;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.argThat;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;

import static com.google.common.truth.Truth.assertThat;

import static org.mockito.ArgumentMatchers.anyBoolean;

import android.Manifest;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.admin.DevicePolicyManager;
import android.app.trust.ITrustListener;
import android.app.trust.ITrustManager;
import android.content.BroadcastReceiver;
@@ -45,13 +44,15 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.pm.UserInfo;
import android.net.Uri;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.os.test.TestLooper;
import android.os.UserManager;
import android.provider.Settings;
import android.service.trust.TrustAgentService;
import android.testing.TestableContext;
@@ -61,12 +62,11 @@ import android.view.WindowManagerGlobal;
import androidx.test.core.app.ApplicationProvider;

import com.android.internal.widget.LockPatternUtils;
import com.android.modules.utils.testing.ExtendedMockitoRule;
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.SystemServiceManager;

import com.google.android.collect.Lists;

import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
@@ -74,37 +74,60 @@ import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.ArgumentMatcher;
import org.mockito.Mock;
import org.mockito.MockitoSession;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;
import java.util.Collection;
import java.util.List;

public class TrustManagerServiceTest {

    @Rule
    public MockitoRule mMockitoRule = MockitoJUnit.rule();
    public final ExtendedMockitoRule mExtendedMockitoRule = new ExtendedMockitoRule.Builder(this)
            .mockStatic(ServiceManager.class)
            .mockStatic(WindowManagerGlobal.class)
            .build();

    @Rule
    public final MockContext mMockContext = new MockContext(
            ApplicationProvider.getApplicationContext());

    private static final String URI_SCHEME_PACKAGE = "package";
    private static final int TEST_USER_ID = UserHandle.USER_SYSTEM;
    private static final int TEST_USER_ID = 50;

    private final TestLooper mLooper = new TestLooper();
    private final ArrayList<ResolveInfo> mTrustAgentResolveInfoList = new ArrayList<>();
    private final LockPatternUtils mLockPatternUtils = new LockPatternUtils(mMockContext);
    private final TrustManagerService mService = new TrustManagerService(mMockContext);
    private final ArrayList<ComponentName> mKnownTrustAgents = new ArrayList<>();
    private final ArrayList<ComponentName> mEnabledTrustAgents = new ArrayList<>();

    @Mock
    private PackageManager mPackageManagerMock;
    private @Mock ActivityManager mActivityManager;
    private @Mock DevicePolicyManager mDevicePolicyManager;
    private @Mock LockPatternUtils mLockPatternUtils;
    private @Mock PackageManager mPackageManager;
    private @Mock UserManager mUserManager;
    private @Mock IWindowManager mWindowManager;

    private HandlerThread mHandlerThread;
    private TrustManagerService.Injector mInjector;
    private TrustManagerService mService;
    private ITrustManager mTrustManager;

    @Before
    public void setUp() {
        resetTrustAgentLockSettings();
        LocalServices.addService(SystemServiceManager.class, mock(SystemServiceManager.class));
    public void setUp() throws Exception {
        when(mActivityManager.isUserRunning(TEST_USER_ID)).thenReturn(true);

        when(mLockPatternUtils.getDevicePolicyManager()).thenReturn(mDevicePolicyManager);
        when(mLockPatternUtils.isSecure(TEST_USER_ID)).thenReturn(true);
        when(mLockPatternUtils.getKnownTrustAgents(TEST_USER_ID)).thenReturn(mKnownTrustAgents);
        when(mLockPatternUtils.getEnabledTrustAgents(TEST_USER_ID)).thenReturn(mEnabledTrustAgents);
        doAnswer(invocation -> {
            mKnownTrustAgents.clear();
            mKnownTrustAgents.addAll((Collection<ComponentName>) invocation.getArgument(0));
            return null;
        }).when(mLockPatternUtils).setKnownTrustAgents(any(), eq(TEST_USER_ID));
        doAnswer(invocation -> {
            mEnabledTrustAgents.clear();
            mEnabledTrustAgents.addAll((Collection<ComponentName>) invocation.getArgument(0));
            return null;
        }).when(mLockPatternUtils).setEnabledTrustAgents(any(), eq(TEST_USER_ID));

        ArgumentMatcher<Intent> trustAgentIntentMatcher = new ArgumentMatcher<Intent>() {
            @Override
@@ -112,17 +135,42 @@ public class TrustManagerServiceTest {
                return TrustAgentService.SERVICE_INTERFACE.equals(argument.getAction());
            }
        };
        when(mPackageManagerMock.queryIntentServicesAsUser(argThat(trustAgentIntentMatcher),
        when(mPackageManager.queryIntentServicesAsUser(argThat(trustAgentIntentMatcher),
                anyInt(), anyInt())).thenReturn(mTrustAgentResolveInfoList);
        when(mPackageManagerMock.checkPermission(any(), any())).thenReturn(
        when(mPackageManager.checkPermission(any(), any())).thenReturn(
                PackageManager.PERMISSION_GRANTED);
        mMockContext.setMockPackageManager(mPackageManagerMock);

        when(mUserManager.getAliveUsers()).thenReturn(
                List.of(new UserInfo(TEST_USER_ID, "user", UserInfo.FLAG_FULL)));

        when(mWindowManager.isKeyguardLocked()).thenReturn(true);

        mMockContext.addMockSystemService(ActivityManager.class, mActivityManager);
        mMockContext.setMockPackageManager(mPackageManager);
        mMockContext.addMockSystemService(UserManager.class, mUserManager);
        doReturn(mWindowManager).when(() -> WindowManagerGlobal.getWindowManagerService());
        LocalServices.addService(SystemServiceManager.class, mock(SystemServiceManager.class));

        grantPermission(Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE);
        grantPermission(Manifest.permission.TRUST_LISTENER);

        mHandlerThread = new HandlerThread("handler");
        mHandlerThread.start();
        mInjector = new TrustManagerService.Injector(mLockPatternUtils, mHandlerThread.getLooper());
        mService = new TrustManagerService(mMockContext, mInjector);

        // Get the ITrustManager from the new TrustManagerService.
        mService.onStart();
        ArgumentCaptor<IBinder> binderArgumentCaptor = ArgumentCaptor.forClass(IBinder.class);
        verify(() -> ServiceManager.addService(eq(Context.TRUST_SERVICE),
                    binderArgumentCaptor.capture(), anyBoolean(), anyInt()));
        mTrustManager = ITrustManager.Stub.asInterface(binderArgumentCaptor.getValue());
    }

    @After
    public void tearDown() {
        resetTrustAgentLockSettings();
        LocalServices.removeServiceForTest(SystemServiceManager.class);
        mHandlerThread.quit();
    }

    @Test
@@ -142,10 +190,9 @@ public class TrustManagerServiceTest {

        bootService();

        assertThat(mLockPatternUtils.getEnabledTrustAgents(TEST_USER_ID)).containsExactly(
                systemTrustAgent1, systemTrustAgent2);
        assertThat(mLockPatternUtils.getKnownTrustAgents(TEST_USER_ID)).containsExactly(
                systemTrustAgent1, systemTrustAgent2, userTrustAgent1, userTrustAgent2);
        assertThat(mEnabledTrustAgents).containsExactly(systemTrustAgent1, systemTrustAgent2);
        assertThat(mKnownTrustAgents).containsExactly(systemTrustAgent1, systemTrustAgent2,
                    userTrustAgent1, userTrustAgent2);
    }

    @Test
@@ -162,10 +209,8 @@ public class TrustManagerServiceTest {

        bootService();

        assertThat(mLockPatternUtils.getEnabledTrustAgents(TEST_USER_ID)).containsExactly(
                defaultTrustAgent);
        assertThat(mLockPatternUtils.getKnownTrustAgents(TEST_USER_ID)).containsExactly(
                systemTrustAgent, defaultTrustAgent);
        assertThat(mEnabledTrustAgents).containsExactly(defaultTrustAgent);
        assertThat(mKnownTrustAgents).containsExactly(systemTrustAgent, defaultTrustAgent);
    }

    @Test
@@ -174,16 +219,16 @@ public class TrustManagerServiceTest {
                "com.android/.SystemTrustAgent");
        ComponentName trustAgent2 = ComponentName.unflattenFromString(
                "com.android/.AnotherSystemTrustAgent");
        initializeEnabledAgents(trustAgent1);
        mEnabledTrustAgents.add(trustAgent1);
        Settings.Secure.putIntForUser(mMockContext.getContentResolver(),
                Settings.Secure.TRUST_AGENTS_INITIALIZED, 1, TEST_USER_ID);
        addTrustAgent(trustAgent1, /* isSystemApp= */ true);
        addTrustAgent(trustAgent2, /* isSystemApp= */ true);

        bootService();

        assertThat(mLockPatternUtils.getEnabledTrustAgents(TEST_USER_ID)).containsExactly(
                trustAgent1);
        assertThat(mLockPatternUtils.getKnownTrustAgents(TEST_USER_ID)).containsExactly(
                trustAgent1, trustAgent2);
        assertThat(mEnabledTrustAgents).containsExactly(trustAgent1);
        assertThat(mKnownTrustAgents).containsExactly(trustAgent1, trustAgent2);
    }

    @Test
@@ -192,17 +237,17 @@ public class TrustManagerServiceTest {
                "com.android/.SystemTrustAgent");
        ComponentName trustAgent2 = ComponentName.unflattenFromString(
                "com.android/.AnotherSystemTrustAgent");
        initializeEnabledAgents(trustAgent1);
        initializeKnownAgents(trustAgent1);
        Settings.Secure.putIntForUser(mMockContext.getContentResolver(),
                Settings.Secure.TRUST_AGENTS_INITIALIZED, 1, TEST_USER_ID);
        Settings.Secure.putIntForUser(mMockContext.getContentResolver(),
                Settings.Secure.KNOWN_TRUST_AGENTS_INITIALIZED, 1, TEST_USER_ID);
        addTrustAgent(trustAgent1, /* isSystemApp= */ true);
        addTrustAgent(trustAgent2, /* isSystemApp= */ true);

        bootService();

        assertThat(mLockPatternUtils.getEnabledTrustAgents(TEST_USER_ID)).containsExactly(
                trustAgent1, trustAgent2);
        assertThat(mLockPatternUtils.getKnownTrustAgents(TEST_USER_ID)).containsExactly(
                trustAgent1, trustAgent2);
        assertThat(mEnabledTrustAgents).containsExactly(trustAgent1, trustAgent2);
        assertThat(mKnownTrustAgents).containsExactly(trustAgent1, trustAgent2);
    }

    @Test
@@ -214,10 +259,8 @@ public class TrustManagerServiceTest {

        mMockContext.sendPackageChangedBroadcast(newAgentComponentName);

        assertThat(mLockPatternUtils.getEnabledTrustAgents(TEST_USER_ID)).containsExactly(
                newAgentComponentName);
        assertThat(mLockPatternUtils.getKnownTrustAgents(TEST_USER_ID)).containsExactly(
                newAgentComponentName);
        assertThat(mEnabledTrustAgents).containsExactly(newAgentComponentName);
        assertThat(mKnownTrustAgents).containsExactly(newAgentComponentName);
    }

    @Test
@@ -235,10 +278,8 @@ public class TrustManagerServiceTest {

        mMockContext.sendPackageChangedBroadcast(newAgentComponentName);

        assertThat(mLockPatternUtils.getEnabledTrustAgents(TEST_USER_ID)).containsExactly(
                defaultTrustAgent);
        assertThat(mLockPatternUtils.getKnownTrustAgents(TEST_USER_ID)).containsExactly(
                defaultTrustAgent, newAgentComponentName);
        assertThat(mEnabledTrustAgents).containsExactly(defaultTrustAgent);
        assertThat(mKnownTrustAgents).containsExactly(defaultTrustAgent, newAgentComponentName);
    }

    @Test
@@ -250,9 +291,8 @@ public class TrustManagerServiceTest {

        mMockContext.sendPackageChangedBroadcast(newAgentComponentName);

        assertThat(mLockPatternUtils.getEnabledTrustAgents(TEST_USER_ID)).isEmpty();
        assertThat(mLockPatternUtils.getKnownTrustAgents(TEST_USER_ID)).containsExactly(
                newAgentComponentName);
        assertThat(mEnabledTrustAgents).isEmpty();
        assertThat(mKnownTrustAgents).containsExactly(newAgentComponentName);
    }

    @Test
@@ -265,50 +305,21 @@ public class TrustManagerServiceTest {
        addTrustAgent(systemTrustAgent2, /* isSystemApp= */ true);
        bootService();
        // Simulate user turning off systemTrustAgent2
        mLockPatternUtils.setEnabledTrustAgents(Collections.singletonList(systemTrustAgent1),
                TEST_USER_ID);
        mLockPatternUtils.setEnabledTrustAgents(List.of(systemTrustAgent1), TEST_USER_ID);

        mMockContext.sendPackageChangedBroadcast(systemTrustAgent2);

        assertThat(mLockPatternUtils.getEnabledTrustAgents(TEST_USER_ID)).containsExactly(
                systemTrustAgent1);
        assertThat(mEnabledTrustAgents).containsExactly(systemTrustAgent1);
    }

    @Test
    public void reportEnabledTrustAgentsChangedInformsListener() throws RemoteException {
        final LockPatternUtils utils = mock(LockPatternUtils.class);
        final TrustManagerService service = new TrustManagerService(mMockContext,
                new TrustManagerService.Injector(utils, mLooper.getLooper()));
        final ITrustListener trustListener = mock(ITrustListener.class);
        final IWindowManager windowManager = mock(IWindowManager.class);
        final int userId = new Random().nextInt();

        mMockContext.getTestablePermissions().setPermission(Manifest.permission.TRUST_LISTENER,
                PERMISSION_GRANTED);

        when(utils.getKnownTrustAgents(anyInt())).thenReturn(new ArrayList<>());

        MockitoSession mockSession = mockitoSession()
                .initMocks(this)
                .mockStatic(ServiceManager.class)
                .mockStatic(WindowManagerGlobal.class)
                .startMocking();

        doReturn(windowManager).when(() -> {
            WindowManagerGlobal.getWindowManagerService();
        });

        service.onStart();
        ArgumentCaptor<IBinder> binderArgumentCaptor = ArgumentCaptor.forClass(IBinder.class);
        verify(() -> ServiceManager.addService(eq(Context.TRUST_SERVICE),
                binderArgumentCaptor.capture(), anyBoolean(), anyInt()));
        ITrustManager manager = ITrustManager.Stub.asInterface(binderArgumentCaptor.getValue());
        manager.registerTrustListener(trustListener);
        mLooper.dispatchAll();
        manager.reportEnabledTrustAgentsChanged(userId);
        mLooper.dispatchAll();
        verify(trustListener).onEnabledTrustAgentsChanged(eq(userId));
        mockSession.finishMocking();
        mTrustManager.registerTrustListener(trustListener);
        mService.waitForIdle();
        mTrustManager.reportEnabledTrustAgentsChanged(TEST_USER_ID);
        mService.waitForIdle();
        verify(trustListener).onEnabledTrustAgentsChanged(TEST_USER_ID);
    }

    private void addTrustAgent(ComponentName agentComponentName, boolean isSystemApp) {
@@ -327,27 +338,16 @@ public class TrustManagerServiceTest {
        mTrustAgentResolveInfoList.add(resolveInfo);
    }

    private void initializeEnabledAgents(ComponentName... enabledAgents) {
        mLockPatternUtils.setEnabledTrustAgents(Lists.newArrayList(enabledAgents), TEST_USER_ID);
        Settings.Secure.putIntForUser(mMockContext.getContentResolver(),
                Settings.Secure.TRUST_AGENTS_INITIALIZED, 1, TEST_USER_ID);
    }

    private void initializeKnownAgents(ComponentName... knownAgents) {
        mLockPatternUtils.setKnownTrustAgents(Lists.newArrayList(knownAgents), TEST_USER_ID);
        Settings.Secure.putIntForUser(mMockContext.getContentResolver(),
                Settings.Secure.KNOWN_TRUST_AGENTS_INITIALIZED, 1, TEST_USER_ID);
    }

    private void bootService() {
        mService.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
        mService.onBootPhase(SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
        mService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
        mMockContext.sendUserStartedBroadcast();
    }

    private void resetTrustAgentLockSettings() {
        mLockPatternUtils.setEnabledTrustAgents(Collections.emptyList(), TEST_USER_ID);
        mLockPatternUtils.setKnownTrustAgents(Collections.emptyList(), TEST_USER_ID);
    private void grantPermission(String permission) {
        mMockContext.getTestablePermissions().setPermission(
                permission, PackageManager.PERMISSION_GRANTED);
    }

    /** A mock Context that allows the test process to send protected broadcasts. */
@@ -355,6 +355,8 @@ public class TrustManagerServiceTest {

        private final ArrayList<BroadcastReceiver> mPackageChangedBroadcastReceivers =
                new ArrayList<>();
        private final ArrayList<BroadcastReceiver> mUserStartedBroadcastReceivers =
                new ArrayList<>();

        MockContext(Context base) {
            super(base);
@@ -369,6 +371,9 @@ public class TrustManagerServiceTest {
            if (filter.hasAction(Intent.ACTION_PACKAGE_CHANGED)) {
                mPackageChangedBroadcastReceivers.add(receiver);
            }
            if (filter.hasAction(Intent.ACTION_USER_STARTED)) {
                mUserStartedBroadcastReceivers.add(receiver);
            }
            return super.registerReceiverAsUser(receiver, user, filter, broadcastPermission,
                    scheduler);
        }
@@ -386,5 +391,13 @@ public class TrustManagerServiceTest {
                receiver.onReceive(this, intent);
            }
        }

        void sendUserStartedBroadcast() {
            Intent intent = new Intent(Intent.ACTION_USER_STARTED)
                    .putExtra(Intent.EXTRA_USER_HANDLE, TEST_USER_ID);
            for (BroadcastReceiver receiver : mUserStartedBroadcastReceivers) {
                receiver.onReceive(this, intent);
            }
        }
    }
}