1 /* 2 * Copyright (C) 2013 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.contentcapture; 18 19 import static com.google.common.truth.Truth.assertThat; 20 21 import static org.mockito.ArgumentMatchers.anyInt; 22 import static org.mockito.ArgumentMatchers.anyString; 23 import static org.mockito.Mockito.never; 24 import static org.mockito.Mockito.verify; 25 import static org.mockito.Mockito.verifyNoMoreInteractions; 26 import static org.mockito.Mockito.verifyZeroInteractions; 27 import static org.mockito.Mockito.when; 28 29 import android.annotation.NonNull; 30 import android.content.ComponentName; 31 import android.content.ContentCaptureOptions; 32 import android.content.Context; 33 import android.content.pm.PackageManager; 34 import android.content.pm.ParceledListSlice; 35 import android.content.pm.UserInfo; 36 import android.service.contentcapture.ContentCaptureServiceInfo; 37 import android.view.contentcapture.ContentCaptureEvent; 38 39 import androidx.test.core.app.ApplicationProvider; 40 import androidx.test.ext.junit.runners.AndroidJUnit4; 41 import androidx.test.filters.SmallTest; 42 43 import com.android.server.LocalServices; 44 import com.android.server.contentprotection.ContentProtectionBlocklistManager; 45 import com.android.server.contentprotection.ContentProtectionConsentManager; 46 import com.android.server.contentprotection.RemoteContentProtectionService; 47 import com.android.server.pm.UserManagerInternal; 48 49 import com.google.common.collect.ImmutableList; 50 51 import org.junit.Before; 52 import org.junit.Rule; 53 import org.junit.Test; 54 import org.junit.runner.RunWith; 55 import org.mockito.Mock; 56 import org.mockito.junit.MockitoJUnit; 57 import org.mockito.junit.MockitoRule; 58 59 /** 60 * Test for {@link ContentCaptureManagerService}. 61 * 62 * <p>Run with: {@code atest 63 * FrameworksServicesTests:com.android.server.contentcapture.ContentCaptureManagerServiceTest} 64 */ 65 @RunWith(AndroidJUnit4.class) 66 @SmallTest 67 @SuppressWarnings("GuardedBy") // Service not really running, no need to expose locks 68 public class ContentCaptureManagerServiceTest { 69 70 private static final int USER_ID = 1234; 71 72 private static final String PACKAGE_NAME = "com.test.package"; 73 74 private static final ComponentName COMPONENT_NAME = 75 new ComponentName(PACKAGE_NAME, "TestClass"); 76 77 private static final ContentCaptureEvent EVENT = 78 new ContentCaptureEvent(/* sessionId= */ 100, /* type= */ 200); 79 80 private static final ParceledListSlice<ContentCaptureEvent> PARCELED_EVENTS = 81 new ParceledListSlice<>(ImmutableList.of(EVENT)); 82 83 private static final Context sContext = ApplicationProvider.getApplicationContext(); 84 85 @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule(); 86 87 @Mock private UserManagerInternal mMockUserManagerInternal; 88 89 @Mock private ContentProtectionBlocklistManager mMockContentProtectionBlocklistManager; 90 91 @Mock private ContentCaptureServiceInfo mMockContentCaptureServiceInfo; 92 93 @Mock private RemoteContentProtectionService mMockRemoteContentProtectionService; 94 95 @Mock private ContentProtectionConsentManager mMockContentProtectionConsentManager; 96 97 private boolean mDevCfgEnableContentProtectionReceiver; 98 99 private int mContentProtectionBlocklistManagersCreated; 100 101 private int mContentProtectionServiceInfosCreated; 102 103 private int mRemoteContentProtectionServicesCreated; 104 105 private int mContentProtectionConsentManagersCreated; 106 107 private String mConfigDefaultContentProtectionService = COMPONENT_NAME.flattenToString(); 108 109 private boolean mContentProtectionServiceInfoConstructorShouldThrow; 110 111 private ContentCaptureManagerService mContentCaptureManagerService; 112 113 @Before setup()114 public void setup() { 115 when(mMockUserManagerInternal.getUserInfos()).thenReturn(new UserInfo[0]); 116 LocalServices.removeServiceForTest(UserManagerInternal.class); 117 LocalServices.addService(UserManagerInternal.class, mMockUserManagerInternal); 118 mContentCaptureManagerService = new TestContentCaptureManagerService(); 119 } 120 121 @Test constructor_contentProtection_flagDisabled_noManagers()122 public void constructor_contentProtection_flagDisabled_noManagers() { 123 assertThat(mContentProtectionBlocklistManagersCreated).isEqualTo(0); 124 assertThat(mContentProtectionServiceInfosCreated).isEqualTo(0); 125 assertThat(mContentProtectionConsentManagersCreated).isEqualTo(0); 126 verifyZeroInteractions(mMockContentProtectionBlocklistManager); 127 verifyZeroInteractions(mMockContentProtectionConsentManager); 128 } 129 130 @Test constructor_contentProtection_componentNameNull_noManagers()131 public void constructor_contentProtection_componentNameNull_noManagers() { 132 mConfigDefaultContentProtectionService = null; 133 134 mContentCaptureManagerService = new TestContentCaptureManagerService(); 135 136 assertThat(mContentProtectionBlocklistManagersCreated).isEqualTo(0); 137 assertThat(mContentProtectionServiceInfosCreated).isEqualTo(0); 138 assertThat(mContentProtectionConsentManagersCreated).isEqualTo(0); 139 verifyZeroInteractions(mMockContentProtectionBlocklistManager); 140 verifyZeroInteractions(mMockContentProtectionConsentManager); 141 } 142 143 @Test constructor_contentProtection_componentNameBlank_noManagers()144 public void constructor_contentProtection_componentNameBlank_noManagers() { 145 mConfigDefaultContentProtectionService = " "; 146 147 mContentCaptureManagerService = new TestContentCaptureManagerService(); 148 149 assertThat(mContentProtectionBlocklistManagersCreated).isEqualTo(0); 150 assertThat(mContentProtectionServiceInfosCreated).isEqualTo(0); 151 assertThat(mContentProtectionConsentManagersCreated).isEqualTo(0); 152 verifyZeroInteractions(mMockContentProtectionBlocklistManager); 153 verifyZeroInteractions(mMockContentProtectionConsentManager); 154 } 155 156 @Test constructor_contentProtection_enabled_createsManagers()157 public void constructor_contentProtection_enabled_createsManagers() { 158 mDevCfgEnableContentProtectionReceiver = true; 159 160 mContentCaptureManagerService = new TestContentCaptureManagerService(); 161 162 assertThat(mContentProtectionBlocklistManagersCreated).isEqualTo(1); 163 assertThat(mContentProtectionConsentManagersCreated).isEqualTo(1); 164 assertThat(mContentProtectionServiceInfosCreated).isEqualTo(0); 165 verify(mMockContentProtectionBlocklistManager).updateBlocklist(anyInt()); 166 verifyZeroInteractions(mMockContentProtectionConsentManager); 167 } 168 169 @Test setFineTuneParamsFromDeviceConfig_doesNotUpdateContentProtectionBlocklist()170 public void setFineTuneParamsFromDeviceConfig_doesNotUpdateContentProtectionBlocklist() { 171 mDevCfgEnableContentProtectionReceiver = true; 172 mContentCaptureManagerService = new TestContentCaptureManagerService(); 173 mContentCaptureManagerService.mDevCfgContentProtectionAppsBlocklistSize += 100; 174 verify(mMockContentProtectionBlocklistManager).updateBlocklist(anyInt()); 175 176 mContentCaptureManagerService.setFineTuneParamsFromDeviceConfig(); 177 178 verifyNoMoreInteractions(mMockContentProtectionBlocklistManager); 179 } 180 181 @Test getOptions_contentCaptureDisabled_contentProtectionDisabled()182 public void getOptions_contentCaptureDisabled_contentProtectionDisabled() { 183 mDevCfgEnableContentProtectionReceiver = true; 184 mContentCaptureManagerService = new TestContentCaptureManagerService(); 185 186 ContentCaptureOptions actual = 187 mContentCaptureManagerService.mGlobalContentCaptureOptions.getOptions( 188 USER_ID, PACKAGE_NAME); 189 190 assertThat(actual).isNull(); 191 verify(mMockContentProtectionConsentManager).isConsentGranted(USER_ID); 192 verify(mMockContentProtectionBlocklistManager, never()).isAllowed(anyString()); 193 } 194 195 @Test getOptions_contentCaptureDisabled_contentProtectionEnabled()196 public void getOptions_contentCaptureDisabled_contentProtectionEnabled() { 197 when(mMockContentProtectionConsentManager.isConsentGranted(USER_ID)).thenReturn(true); 198 when(mMockContentProtectionBlocklistManager.isAllowed(PACKAGE_NAME)).thenReturn(true); 199 mDevCfgEnableContentProtectionReceiver = true; 200 mContentCaptureManagerService = new TestContentCaptureManagerService(); 201 202 ContentCaptureOptions actual = 203 mContentCaptureManagerService.mGlobalContentCaptureOptions.getOptions( 204 USER_ID, PACKAGE_NAME); 205 206 assertThat(actual).isNotNull(); 207 assertThat(actual.enableReceiver).isFalse(); 208 assertThat(actual.contentProtectionOptions).isNotNull(); 209 assertThat(actual.contentProtectionOptions.enableReceiver).isTrue(); 210 assertThat(actual.whitelistedComponents).isNull(); 211 } 212 213 @Test getOptions_contentCaptureEnabled_contentProtectionDisabled()214 public void getOptions_contentCaptureEnabled_contentProtectionDisabled() { 215 mDevCfgEnableContentProtectionReceiver = true; 216 mContentCaptureManagerService = new TestContentCaptureManagerService(); 217 mContentCaptureManagerService.mGlobalContentCaptureOptions.setWhitelist( 218 USER_ID, ImmutableList.of(PACKAGE_NAME), /* components= */ null); 219 220 ContentCaptureOptions actual = 221 mContentCaptureManagerService.mGlobalContentCaptureOptions.getOptions( 222 USER_ID, PACKAGE_NAME); 223 224 assertThat(actual).isNotNull(); 225 assertThat(actual.enableReceiver).isTrue(); 226 assertThat(actual.contentProtectionOptions).isNotNull(); 227 assertThat(actual.contentProtectionOptions.enableReceiver).isFalse(); 228 assertThat(actual.whitelistedComponents).isNull(); 229 verify(mMockContentProtectionConsentManager).isConsentGranted(USER_ID); 230 verify(mMockContentProtectionBlocklistManager, never()).isAllowed(anyString()); 231 } 232 233 @Test getOptions_contentCaptureEnabled_contentProtectionEnabled()234 public void getOptions_contentCaptureEnabled_contentProtectionEnabled() { 235 when(mMockContentProtectionConsentManager.isConsentGranted(USER_ID)).thenReturn(true); 236 when(mMockContentProtectionBlocklistManager.isAllowed(PACKAGE_NAME)).thenReturn(true); 237 mDevCfgEnableContentProtectionReceiver = true; 238 mContentCaptureManagerService = new TestContentCaptureManagerService(); 239 mContentCaptureManagerService.mGlobalContentCaptureOptions.setWhitelist( 240 USER_ID, ImmutableList.of(PACKAGE_NAME), /* components= */ null); 241 242 ContentCaptureOptions actual = 243 mContentCaptureManagerService.mGlobalContentCaptureOptions.getOptions( 244 USER_ID, PACKAGE_NAME); 245 246 assertThat(actual).isNotNull(); 247 assertThat(actual.enableReceiver).isTrue(); 248 assertThat(actual.contentProtectionOptions).isNotNull(); 249 assertThat(actual.contentProtectionOptions.enableReceiver).isTrue(); 250 assertThat(actual.whitelistedComponents).isNull(); 251 } 252 253 @Test isWhitelisted_packageName_contentCaptureDisabled_contentProtectionNotGranted()254 public void isWhitelisted_packageName_contentCaptureDisabled_contentProtectionNotGranted() { 255 mDevCfgEnableContentProtectionReceiver = true; 256 mContentCaptureManagerService = new TestContentCaptureManagerService(); 257 258 boolean actual = 259 mContentCaptureManagerService.mGlobalContentCaptureOptions.isWhitelisted( 260 USER_ID, PACKAGE_NAME); 261 262 assertThat(actual).isFalse(); 263 verify(mMockContentProtectionConsentManager).isConsentGranted(USER_ID); 264 verify(mMockContentProtectionBlocklistManager, never()).isAllowed(anyString()); 265 } 266 267 @Test isWhitelisted_packageName_contentCaptureDisabled_contentProtectionDisabled()268 public void isWhitelisted_packageName_contentCaptureDisabled_contentProtectionDisabled() { 269 when(mMockContentProtectionConsentManager.isConsentGranted(USER_ID)).thenReturn(true); 270 mDevCfgEnableContentProtectionReceiver = true; 271 mContentCaptureManagerService = new TestContentCaptureManagerService(); 272 273 boolean actual = 274 mContentCaptureManagerService.mGlobalContentCaptureOptions.isWhitelisted( 275 USER_ID, PACKAGE_NAME); 276 277 assertThat(actual).isFalse(); 278 verify(mMockContentProtectionBlocklistManager).isAllowed(PACKAGE_NAME); 279 } 280 281 @Test isWhitelisted_packageName_contentCaptureDisabled_contentProtectionEnabled()282 public void isWhitelisted_packageName_contentCaptureDisabled_contentProtectionEnabled() { 283 when(mMockContentProtectionConsentManager.isConsentGranted(USER_ID)).thenReturn(true); 284 when(mMockContentProtectionBlocklistManager.isAllowed(PACKAGE_NAME)).thenReturn(true); 285 mDevCfgEnableContentProtectionReceiver = true; 286 mContentCaptureManagerService = new TestContentCaptureManagerService(); 287 288 boolean actual = 289 mContentCaptureManagerService.mGlobalContentCaptureOptions.isWhitelisted( 290 USER_ID, PACKAGE_NAME); 291 292 assertThat(actual).isTrue(); 293 } 294 295 @Test isWhitelisted_packageName_contentCaptureEnabled_contentProtectionNotChecked()296 public void isWhitelisted_packageName_contentCaptureEnabled_contentProtectionNotChecked() { 297 mDevCfgEnableContentProtectionReceiver = true; 298 mContentCaptureManagerService = new TestContentCaptureManagerService(); 299 mContentCaptureManagerService.mGlobalContentCaptureOptions.setWhitelist( 300 USER_ID, ImmutableList.of(PACKAGE_NAME), /* components= */ null); 301 302 boolean actual = 303 mContentCaptureManagerService.mGlobalContentCaptureOptions.isWhitelisted( 304 USER_ID, PACKAGE_NAME); 305 306 assertThat(actual).isTrue(); 307 verify(mMockContentProtectionConsentManager, never()).isConsentGranted(anyInt()); 308 verify(mMockContentProtectionBlocklistManager, never()).isAllowed(anyString()); 309 } 310 311 @Test isWhitelisted_componentName_contentCaptureDisabled_contentProtectionNotGranted()312 public void isWhitelisted_componentName_contentCaptureDisabled_contentProtectionNotGranted() { 313 mDevCfgEnableContentProtectionReceiver = true; 314 mContentCaptureManagerService = new TestContentCaptureManagerService(); 315 316 boolean actual = 317 mContentCaptureManagerService.mGlobalContentCaptureOptions.isWhitelisted( 318 USER_ID, COMPONENT_NAME); 319 320 assertThat(actual).isFalse(); 321 verify(mMockContentProtectionConsentManager).isConsentGranted(USER_ID); 322 verify(mMockContentProtectionBlocklistManager, never()).isAllowed(anyString()); 323 } 324 325 @Test isWhitelisted_componentName_contentCaptureDisabled_contentProtectionDisabled()326 public void isWhitelisted_componentName_contentCaptureDisabled_contentProtectionDisabled() { 327 when(mMockContentProtectionConsentManager.isConsentGranted(USER_ID)).thenReturn(true); 328 mDevCfgEnableContentProtectionReceiver = true; 329 mContentCaptureManagerService = new TestContentCaptureManagerService(); 330 331 boolean actual = 332 mContentCaptureManagerService.mGlobalContentCaptureOptions.isWhitelisted( 333 USER_ID, COMPONENT_NAME); 334 335 assertThat(actual).isFalse(); 336 verify(mMockContentProtectionBlocklistManager).isAllowed(PACKAGE_NAME); 337 } 338 339 @Test isWhitelisted_componentName_contentCaptureDisabled_contentProtectionEnabled()340 public void isWhitelisted_componentName_contentCaptureDisabled_contentProtectionEnabled() { 341 when(mMockContentProtectionConsentManager.isConsentGranted(USER_ID)).thenReturn(true); 342 when(mMockContentProtectionBlocklistManager.isAllowed(PACKAGE_NAME)).thenReturn(true); 343 mDevCfgEnableContentProtectionReceiver = true; 344 mContentCaptureManagerService = new TestContentCaptureManagerService(); 345 346 boolean actual = 347 mContentCaptureManagerService.mGlobalContentCaptureOptions.isWhitelisted( 348 USER_ID, COMPONENT_NAME); 349 350 assertThat(actual).isTrue(); 351 } 352 353 @Test isWhitelisted_componentName_contentCaptureEnabled_contentProtectionNotChecked()354 public void isWhitelisted_componentName_contentCaptureEnabled_contentProtectionNotChecked() { 355 mDevCfgEnableContentProtectionReceiver = true; 356 mContentCaptureManagerService = new TestContentCaptureManagerService(); 357 mContentCaptureManagerService.mGlobalContentCaptureOptions.setWhitelist( 358 USER_ID, /* packageNames= */ null, ImmutableList.of(COMPONENT_NAME)); 359 360 boolean actual = 361 mContentCaptureManagerService.mGlobalContentCaptureOptions.isWhitelisted( 362 USER_ID, COMPONENT_NAME); 363 364 assertThat(actual).isTrue(); 365 verify(mMockContentProtectionConsentManager, never()).isConsentGranted(anyInt()); 366 verify(mMockContentProtectionBlocklistManager, never()).isAllowed(anyString()); 367 } 368 369 @Test isContentProtectionReceiverEnabled_withoutManagers()370 public void isContentProtectionReceiverEnabled_withoutManagers() { 371 boolean actual = 372 mContentCaptureManagerService.mGlobalContentCaptureOptions.isWhitelisted( 373 USER_ID, PACKAGE_NAME); 374 375 assertThat(actual).isFalse(); 376 verify(mMockContentProtectionConsentManager, never()).isConsentGranted(anyInt()); 377 verify(mMockContentProtectionBlocklistManager, never()).isAllowed(anyString()); 378 } 379 380 @Test isContentProtectionReceiverEnabled_disabledWithFlag()381 public void isContentProtectionReceiverEnabled_disabledWithFlag() { 382 mDevCfgEnableContentProtectionReceiver = true; 383 mContentCaptureManagerService = new TestContentCaptureManagerService(); 384 mContentCaptureManagerService.mDevCfgEnableContentProtectionReceiver = false; 385 386 boolean actual = 387 mContentCaptureManagerService.mGlobalContentCaptureOptions.isWhitelisted( 388 USER_ID, PACKAGE_NAME); 389 390 assertThat(actual).isFalse(); 391 verify(mMockContentProtectionConsentManager, never()).isConsentGranted(anyInt()); 392 verify(mMockContentProtectionBlocklistManager, never()).isAllowed(anyString()); 393 } 394 395 @Test onLoginDetected_disabledAfterConstructor()396 public void onLoginDetected_disabledAfterConstructor() { 397 mDevCfgEnableContentProtectionReceiver = true; 398 mContentCaptureManagerService = new TestContentCaptureManagerService(); 399 mContentCaptureManagerService.mDevCfgEnableContentProtectionReceiver = false; 400 401 mContentCaptureManagerService 402 .getContentCaptureManagerServiceStub() 403 .onLoginDetected(PARCELED_EVENTS); 404 405 assertThat(mContentProtectionServiceInfosCreated).isEqualTo(0); 406 assertThat(mRemoteContentProtectionServicesCreated).isEqualTo(0); 407 verifyZeroInteractions(mMockRemoteContentProtectionService); 408 } 409 410 @Test onLoginDetected_invalidPermissions()411 public void onLoginDetected_invalidPermissions() { 412 mDevCfgEnableContentProtectionReceiver = true; 413 mContentProtectionServiceInfoConstructorShouldThrow = true; 414 mContentCaptureManagerService = new TestContentCaptureManagerService(); 415 416 mContentCaptureManagerService 417 .getContentCaptureManagerServiceStub() 418 .onLoginDetected(PARCELED_EVENTS); 419 420 assertThat(mContentProtectionServiceInfosCreated).isEqualTo(1); 421 assertThat(mRemoteContentProtectionServicesCreated).isEqualTo(0); 422 verifyZeroInteractions(mMockRemoteContentProtectionService); 423 } 424 425 @Test onLoginDetected_enabled()426 public void onLoginDetected_enabled() { 427 mDevCfgEnableContentProtectionReceiver = true; 428 mContentCaptureManagerService = new TestContentCaptureManagerService(); 429 430 mContentCaptureManagerService 431 .getContentCaptureManagerServiceStub() 432 .onLoginDetected(PARCELED_EVENTS); 433 434 assertThat(mContentProtectionServiceInfosCreated).isEqualTo(1); 435 assertThat(mRemoteContentProtectionServicesCreated).isEqualTo(1); 436 verify(mMockRemoteContentProtectionService).onLoginDetected(PARCELED_EVENTS); 437 } 438 439 private class TestContentCaptureManagerService extends ContentCaptureManagerService { 440 TestContentCaptureManagerService()441 TestContentCaptureManagerService() { 442 super(sContext); 443 this.mDevCfgEnableContentProtectionReceiver = 444 ContentCaptureManagerServiceTest.this.mDevCfgEnableContentProtectionReceiver; 445 } 446 447 @Override getEnableContentProtectionReceiverLocked()448 protected boolean getEnableContentProtectionReceiverLocked() { 449 return ContentCaptureManagerServiceTest.this.mDevCfgEnableContentProtectionReceiver; 450 } 451 452 @Override createContentProtectionBlocklistManager()453 protected ContentProtectionBlocklistManager createContentProtectionBlocklistManager() { 454 mContentProtectionBlocklistManagersCreated++; 455 return mMockContentProtectionBlocklistManager; 456 } 457 458 @Override getContentProtectionServiceFlatComponentName()459 protected String getContentProtectionServiceFlatComponentName() { 460 return mConfigDefaultContentProtectionService; 461 } 462 463 @Override createContentProtectionServiceInfo( @onNull ComponentName componentName)464 protected ContentCaptureServiceInfo createContentProtectionServiceInfo( 465 @NonNull ComponentName componentName) throws PackageManager.NameNotFoundException { 466 mContentProtectionServiceInfosCreated++; 467 if (mContentProtectionServiceInfoConstructorShouldThrow) { 468 throw new RuntimeException("TEST RUNTIME EXCEPTION"); 469 } 470 return mMockContentCaptureServiceInfo; 471 } 472 473 @Override createRemoteContentProtectionService( @onNull ComponentName componentName)474 protected RemoteContentProtectionService createRemoteContentProtectionService( 475 @NonNull ComponentName componentName) { 476 mRemoteContentProtectionServicesCreated++; 477 return mMockRemoteContentProtectionService; 478 } 479 480 @Override createContentProtectionConsentManager()481 protected ContentProtectionConsentManager createContentProtectionConsentManager() { 482 mContentProtectionConsentManagersCreated++; 483 return mMockContentProtectionConsentManager; 484 } 485 } 486 } 487