1 /* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.trust; 18 19 import static android.content.pm.PackageManager.PERMISSION_GRANTED; 20 21 import static com.android.dx.mockito.inline.extended.ExtendedMockito.any; 22 import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyInt; 23 import static com.android.dx.mockito.inline.extended.ExtendedMockito.argThat; 24 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; 25 import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq; 26 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; 27 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession; 28 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; 29 import static com.android.dx.mockito.inline.extended.ExtendedMockito.when; 30 31 import static com.google.common.truth.Truth.assertThat; 32 33 import static org.mockito.ArgumentMatchers.anyBoolean; 34 35 import android.Manifest; 36 import android.annotation.Nullable; 37 import android.app.trust.ITrustListener; 38 import android.app.trust.ITrustManager; 39 import android.content.BroadcastReceiver; 40 import android.content.ComponentName; 41 import android.content.Context; 42 import android.content.Intent; 43 import android.content.IntentFilter; 44 import android.content.pm.ApplicationInfo; 45 import android.content.pm.PackageManager; 46 import android.content.pm.ResolveInfo; 47 import android.content.pm.ServiceInfo; 48 import android.net.Uri; 49 import android.os.Handler; 50 import android.os.IBinder; 51 import android.os.RemoteException; 52 import android.os.ServiceManager; 53 import android.os.UserHandle; 54 import android.os.test.TestLooper; 55 import android.provider.Settings; 56 import android.service.trust.TrustAgentService; 57 import android.testing.TestableContext; 58 import android.view.IWindowManager; 59 import android.view.WindowManagerGlobal; 60 61 import androidx.test.core.app.ApplicationProvider; 62 63 import com.android.internal.widget.LockPatternUtils; 64 import com.android.server.LocalServices; 65 import com.android.server.SystemService; 66 import com.android.server.SystemServiceManager; 67 68 import com.google.android.collect.Lists; 69 70 import org.junit.After; 71 import org.junit.Before; 72 import org.junit.Rule; 73 import org.junit.Test; 74 import org.mockito.ArgumentCaptor; 75 import org.mockito.ArgumentMatcher; 76 import org.mockito.Mock; 77 import org.mockito.MockitoSession; 78 import org.mockito.junit.MockitoJUnit; 79 import org.mockito.junit.MockitoRule; 80 81 import java.util.ArrayList; 82 import java.util.Collections; 83 import java.util.Random; 84 85 public class TrustManagerServiceTest { 86 87 @Rule 88 public MockitoRule mMockitoRule = MockitoJUnit.rule(); 89 @Rule 90 public final MockContext mMockContext = new MockContext( 91 ApplicationProvider.getApplicationContext()); 92 93 private static final String URI_SCHEME_PACKAGE = "package"; 94 private static final int TEST_USER_ID = UserHandle.USER_SYSTEM; 95 96 private final TestLooper mLooper = new TestLooper(); 97 private final ArrayList<ResolveInfo> mTrustAgentResolveInfoList = new ArrayList<>(); 98 private final LockPatternUtils mLockPatternUtils = new LockPatternUtils(mMockContext); 99 private final TrustManagerService mService = new TrustManagerService(mMockContext); 100 101 @Mock 102 private PackageManager mPackageManagerMock; 103 104 @Before setUp()105 public void setUp() { 106 resetTrustAgentLockSettings(); 107 LocalServices.addService(SystemServiceManager.class, mock(SystemServiceManager.class)); 108 109 ArgumentMatcher<Intent> trustAgentIntentMatcher = new ArgumentMatcher<Intent>() { 110 @Override 111 public boolean matches(Intent argument) { 112 return TrustAgentService.SERVICE_INTERFACE.equals(argument.getAction()); 113 } 114 }; 115 when(mPackageManagerMock.queryIntentServicesAsUser(argThat(trustAgentIntentMatcher), 116 anyInt(), anyInt())).thenReturn(mTrustAgentResolveInfoList); 117 when(mPackageManagerMock.checkPermission(any(), any())).thenReturn( 118 PackageManager.PERMISSION_GRANTED); 119 mMockContext.setMockPackageManager(mPackageManagerMock); 120 } 121 122 @After tearDown()123 public void tearDown() { 124 resetTrustAgentLockSettings(); 125 LocalServices.removeServiceForTest(SystemServiceManager.class); 126 } 127 128 @Test firstBootCompleted_systemTrustAgentsEnabled()129 public void firstBootCompleted_systemTrustAgentsEnabled() { 130 ComponentName systemTrustAgent1 = ComponentName.unflattenFromString( 131 "com.android/.SystemTrustAgent"); 132 ComponentName systemTrustAgent2 = ComponentName.unflattenFromString( 133 "com.android/.AnotherSystemTrustAgent"); 134 ComponentName userTrustAgent1 = ComponentName.unflattenFromString( 135 "com.user/.UserTrustAgent"); 136 ComponentName userTrustAgent2 = ComponentName.unflattenFromString( 137 "com.user/.AnotherUserTrustAgent"); 138 addTrustAgent(systemTrustAgent1, /* isSystemApp= */ true); 139 addTrustAgent(systemTrustAgent2, /* isSystemApp= */ true); 140 addTrustAgent(userTrustAgent1, /* isSystemApp= */ false); 141 addTrustAgent(userTrustAgent2, /* isSystemApp= */ false); 142 143 bootService(); 144 145 assertThat(mLockPatternUtils.getEnabledTrustAgents(TEST_USER_ID)).containsExactly( 146 systemTrustAgent1, systemTrustAgent2); 147 assertThat(mLockPatternUtils.getKnownTrustAgents(TEST_USER_ID)).containsExactly( 148 systemTrustAgent1, systemTrustAgent2, userTrustAgent1, userTrustAgent2); 149 } 150 151 @Test firstBootCompleted_defaultTrustAgentEnabled()152 public void firstBootCompleted_defaultTrustAgentEnabled() { 153 ComponentName systemTrustAgent = ComponentName.unflattenFromString( 154 "com.android/.SystemTrustAgent"); 155 ComponentName defaultTrustAgent = ComponentName.unflattenFromString( 156 "com.user/.DefaultTrustAgent"); 157 addTrustAgent(systemTrustAgent, /* isSystemApp= */ true); 158 addTrustAgent(defaultTrustAgent, /* isSystemApp= */ false); 159 mMockContext.getOrCreateTestableResources().addOverride( 160 com.android.internal.R.string.config_defaultTrustAgent, 161 defaultTrustAgent.flattenToString()); 162 163 bootService(); 164 165 assertThat(mLockPatternUtils.getEnabledTrustAgents(TEST_USER_ID)).containsExactly( 166 defaultTrustAgent); 167 assertThat(mLockPatternUtils.getKnownTrustAgents(TEST_USER_ID)).containsExactly( 168 systemTrustAgent, defaultTrustAgent); 169 } 170 171 @Test serviceBooted_knownAgentsNotSet_enabledAgentsNotUpdated()172 public void serviceBooted_knownAgentsNotSet_enabledAgentsNotUpdated() { 173 ComponentName trustAgent1 = ComponentName.unflattenFromString( 174 "com.android/.SystemTrustAgent"); 175 ComponentName trustAgent2 = ComponentName.unflattenFromString( 176 "com.android/.AnotherSystemTrustAgent"); 177 initializeEnabledAgents(trustAgent1); 178 addTrustAgent(trustAgent1, /* isSystemApp= */ true); 179 addTrustAgent(trustAgent2, /* isSystemApp= */ true); 180 181 bootService(); 182 183 assertThat(mLockPatternUtils.getEnabledTrustAgents(TEST_USER_ID)).containsExactly( 184 trustAgent1); 185 assertThat(mLockPatternUtils.getKnownTrustAgents(TEST_USER_ID)).containsExactly( 186 trustAgent1, trustAgent2); 187 } 188 189 @Test serviceBooted_knownAgentsSet_enabledAgentsUpdated()190 public void serviceBooted_knownAgentsSet_enabledAgentsUpdated() { 191 ComponentName trustAgent1 = ComponentName.unflattenFromString( 192 "com.android/.SystemTrustAgent"); 193 ComponentName trustAgent2 = ComponentName.unflattenFromString( 194 "com.android/.AnotherSystemTrustAgent"); 195 initializeEnabledAgents(trustAgent1); 196 initializeKnownAgents(trustAgent1); 197 addTrustAgent(trustAgent1, /* isSystemApp= */ true); 198 addTrustAgent(trustAgent2, /* isSystemApp= */ true); 199 200 bootService(); 201 202 assertThat(mLockPatternUtils.getEnabledTrustAgents(TEST_USER_ID)).containsExactly( 203 trustAgent1, trustAgent2); 204 assertThat(mLockPatternUtils.getKnownTrustAgents(TEST_USER_ID)).containsExactly( 205 trustAgent1, trustAgent2); 206 } 207 208 @Test newSystemTrustAgent_setToEnabledAndKnown()209 public void newSystemTrustAgent_setToEnabledAndKnown() { 210 bootService(); 211 ComponentName newAgentComponentName = ComponentName.unflattenFromString( 212 "com.android/.SystemTrustAgent"); 213 addTrustAgent(newAgentComponentName, /* isSystemApp= */ true); 214 215 mMockContext.sendPackageChangedBroadcast(newAgentComponentName); 216 217 assertThat(mLockPatternUtils.getEnabledTrustAgents(TEST_USER_ID)).containsExactly( 218 newAgentComponentName); 219 assertThat(mLockPatternUtils.getKnownTrustAgents(TEST_USER_ID)).containsExactly( 220 newAgentComponentName); 221 } 222 223 @Test newSystemTrustAgent_notEnabledWhenDefaultAgentIsSet()224 public void newSystemTrustAgent_notEnabledWhenDefaultAgentIsSet() { 225 ComponentName defaultTrustAgent = ComponentName.unflattenFromString( 226 "com.user/.DefaultTrustAgent"); 227 addTrustAgent(defaultTrustAgent, /* isSystemApp= */ false); 228 mMockContext.getOrCreateTestableResources().addOverride( 229 com.android.internal.R.string.config_defaultTrustAgent, 230 defaultTrustAgent.flattenToString()); 231 bootService(); 232 ComponentName newAgentComponentName = ComponentName.unflattenFromString( 233 "com.android/.SystemTrustAgent"); 234 addTrustAgent(newAgentComponentName, /* isSystemApp= */ true); 235 236 mMockContext.sendPackageChangedBroadcast(newAgentComponentName); 237 238 assertThat(mLockPatternUtils.getEnabledTrustAgents(TEST_USER_ID)).containsExactly( 239 defaultTrustAgent); 240 assertThat(mLockPatternUtils.getKnownTrustAgents(TEST_USER_ID)).containsExactly( 241 defaultTrustAgent, newAgentComponentName); 242 } 243 244 @Test newNonSystemTrustAgent_notEnabledButMarkedAsKnown()245 public void newNonSystemTrustAgent_notEnabledButMarkedAsKnown() { 246 bootService(); 247 ComponentName newAgentComponentName = ComponentName.unflattenFromString( 248 "com.user/.UserTrustAgent"); 249 addTrustAgent(newAgentComponentName, /* isSystemApp= */ false); 250 251 mMockContext.sendPackageChangedBroadcast(newAgentComponentName); 252 253 assertThat(mLockPatternUtils.getEnabledTrustAgents(TEST_USER_ID)).isEmpty(); 254 assertThat(mLockPatternUtils.getKnownTrustAgents(TEST_USER_ID)).containsExactly( 255 newAgentComponentName); 256 } 257 258 @Test existingTrustAgentChanged_notEnabled()259 public void existingTrustAgentChanged_notEnabled() { 260 ComponentName systemTrustAgent1 = ComponentName.unflattenFromString( 261 "com.android/.SystemTrustAgent"); 262 ComponentName systemTrustAgent2 = ComponentName.unflattenFromString( 263 "com.android/.AnotherSystemTrustAgent"); 264 addTrustAgent(systemTrustAgent1, /* isSystemApp= */ true); 265 addTrustAgent(systemTrustAgent2, /* isSystemApp= */ true); 266 bootService(); 267 // Simulate user turning off systemTrustAgent2 268 mLockPatternUtils.setEnabledTrustAgents(Collections.singletonList(systemTrustAgent1), 269 TEST_USER_ID); 270 271 mMockContext.sendPackageChangedBroadcast(systemTrustAgent2); 272 273 assertThat(mLockPatternUtils.getEnabledTrustAgents(TEST_USER_ID)).containsExactly( 274 systemTrustAgent1); 275 } 276 277 @Test reportEnabledTrustAgentsChangedInformsListener()278 public void reportEnabledTrustAgentsChangedInformsListener() throws RemoteException { 279 final LockPatternUtils utils = mock(LockPatternUtils.class); 280 final TrustManagerService service = new TrustManagerService(mMockContext, 281 new TrustManagerService.Injector(utils, mLooper.getLooper())); 282 final ITrustListener trustListener = mock(ITrustListener.class); 283 final IWindowManager windowManager = mock(IWindowManager.class); 284 final int userId = new Random().nextInt(); 285 286 mMockContext.getTestablePermissions().setPermission(Manifest.permission.TRUST_LISTENER, 287 PERMISSION_GRANTED); 288 289 when(utils.getKnownTrustAgents(anyInt())).thenReturn(new ArrayList<>()); 290 291 MockitoSession mockSession = mockitoSession() 292 .initMocks(this) 293 .mockStatic(ServiceManager.class) 294 .mockStatic(WindowManagerGlobal.class) 295 .startMocking(); 296 297 doReturn(windowManager).when(() -> { 298 WindowManagerGlobal.getWindowManagerService(); 299 }); 300 301 service.onStart(); 302 ArgumentCaptor<IBinder> binderArgumentCaptor = ArgumentCaptor.forClass(IBinder.class); 303 verify(() -> ServiceManager.addService(eq(Context.TRUST_SERVICE), 304 binderArgumentCaptor.capture(), anyBoolean(), anyInt())); 305 ITrustManager manager = ITrustManager.Stub.asInterface(binderArgumentCaptor.getValue()); 306 manager.registerTrustListener(trustListener); 307 mLooper.dispatchAll(); 308 manager.reportEnabledTrustAgentsChanged(userId); 309 mLooper.dispatchAll(); 310 verify(trustListener).onEnabledTrustAgentsChanged(eq(userId)); 311 mockSession.finishMocking(); 312 } 313 addTrustAgent(ComponentName agentComponentName, boolean isSystemApp)314 private void addTrustAgent(ComponentName agentComponentName, boolean isSystemApp) { 315 ApplicationInfo applicationInfo = new ApplicationInfo(); 316 if (isSystemApp) { 317 applicationInfo.flags = ApplicationInfo.FLAG_SYSTEM; 318 } 319 320 ServiceInfo serviceInfo = new ServiceInfo(); 321 serviceInfo.packageName = agentComponentName.getPackageName(); 322 serviceInfo.name = agentComponentName.getClassName(); 323 serviceInfo.applicationInfo = applicationInfo; 324 325 ResolveInfo resolveInfo = new ResolveInfo(); 326 resolveInfo.serviceInfo = serviceInfo; 327 mTrustAgentResolveInfoList.add(resolveInfo); 328 } 329 initializeEnabledAgents(ComponentName... enabledAgents)330 private void initializeEnabledAgents(ComponentName... enabledAgents) { 331 mLockPatternUtils.setEnabledTrustAgents(Lists.newArrayList(enabledAgents), TEST_USER_ID); 332 Settings.Secure.putIntForUser(mMockContext.getContentResolver(), 333 Settings.Secure.TRUST_AGENTS_INITIALIZED, 1, TEST_USER_ID); 334 } 335 initializeKnownAgents(ComponentName... knownAgents)336 private void initializeKnownAgents(ComponentName... knownAgents) { 337 mLockPatternUtils.setKnownTrustAgents(Lists.newArrayList(knownAgents), TEST_USER_ID); 338 Settings.Secure.putIntForUser(mMockContext.getContentResolver(), 339 Settings.Secure.KNOWN_TRUST_AGENTS_INITIALIZED, 1, TEST_USER_ID); 340 } 341 bootService()342 private void bootService() { 343 mService.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY); 344 mService.onBootPhase(SystemService.PHASE_THIRD_PARTY_APPS_CAN_START); 345 mService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED); 346 } 347 resetTrustAgentLockSettings()348 private void resetTrustAgentLockSettings() { 349 mLockPatternUtils.setEnabledTrustAgents(Collections.emptyList(), TEST_USER_ID); 350 mLockPatternUtils.setKnownTrustAgents(Collections.emptyList(), TEST_USER_ID); 351 } 352 353 /** A mock Context that allows the test process to send protected broadcasts. */ 354 private static final class MockContext extends TestableContext { 355 356 private final ArrayList<BroadcastReceiver> mPackageChangedBroadcastReceivers = 357 new ArrayList<>(); 358 MockContext(Context base)359 MockContext(Context base) { 360 super(base); 361 } 362 363 @Override 364 @Nullable registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user, IntentFilter filter, @Nullable String broadcastPermission, @Nullable Handler scheduler)365 public Intent registerReceiverAsUser(BroadcastReceiver receiver, 366 UserHandle user, IntentFilter filter, @Nullable String broadcastPermission, 367 @Nullable Handler scheduler) { 368 369 if (filter.hasAction(Intent.ACTION_PACKAGE_CHANGED)) { 370 mPackageChangedBroadcastReceivers.add(receiver); 371 } 372 return super.registerReceiverAsUser(receiver, user, filter, broadcastPermission, 373 scheduler); 374 } 375 sendPackageChangedBroadcast(ComponentName changedComponent)376 void sendPackageChangedBroadcast(ComponentName changedComponent) { 377 Intent intent = new Intent( 378 Intent.ACTION_PACKAGE_CHANGED, 379 Uri.fromParts(URI_SCHEME_PACKAGE, 380 changedComponent.getPackageName(), /* fragment= */ null)) 381 .putExtra(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, 382 new String[]{changedComponent.getClassName()}) 383 .putExtra(Intent.EXTRA_USER_HANDLE, TEST_USER_ID) 384 .putExtra(Intent.EXTRA_UID, UserHandle.of(TEST_USER_ID).getUid(1234)); 385 for (BroadcastReceiver receiver : mPackageChangedBroadcastReceivers) { 386 receiver.onReceive(this, intent); 387 } 388 } 389 } 390 } 391