diff options
-rw-r--r-- | services/core/java/com/android/server/trust/TrustManagerService.java | 6 | ||||
-rw-r--r-- | services/tests/mockingservicestests/src/com/android/server/trust/TrustManagerServiceTest.java | 229 |
2 files changed, 127 insertions, 108 deletions
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java index 1ebad9bfbc8b..d2d2a0cba085 100644 --- a/services/core/java/com/android/server/trust/TrustManagerService.java +++ b/services/core/java/com/android/server/trust/TrustManagerService.java @@ -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); diff --git a/services/tests/mockingservicestests/src/com/android/server/trust/TrustManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/trust/TrustManagerServiceTest.java index 9851bc1b4be3..c42c735e3c9d 100644 --- a/services/tests/mockingservicestests/src/com/android/server/trust/TrustManagerServiceTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/trust/TrustManagerServiceTest.java @@ -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<>(); + + private @Mock ActivityManager mActivityManager; + private @Mock DevicePolicyManager mDevicePolicyManager; + private @Mock LockPatternUtils mLockPatternUtils; + private @Mock PackageManager mPackageManager; + private @Mock UserManager mUserManager; + private @Mock IWindowManager mWindowManager; - @Mock - private PackageManager mPackageManagerMock; + 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); + } + } } } |