1 /* 2 * Copyright (C) 2017 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 package com.android.server.notification; 17 18 import static com.android.server.notification.ManagedServices.APPROVAL_BY_COMPONENT; 19 import static com.android.server.notification.ManagedServices.APPROVAL_BY_PACKAGE; 20 21 import static junit.framework.Assert.assertEquals; 22 import static junit.framework.Assert.assertFalse; 23 import static junit.framework.Assert.assertTrue; 24 25 import static org.mockito.Matchers.any; 26 import static org.mockito.Matchers.anyInt; 27 import static org.mockito.Matchers.eq; 28 import static org.mockito.Mockito.never; 29 import static org.mockito.Mockito.times; 30 import static org.mockito.Mockito.verify; 31 import static org.mockito.Mockito.when; 32 33 import android.content.ComponentName; 34 import android.content.Context; 35 import android.content.Intent; 36 import android.content.pm.IPackageManager; 37 import android.content.pm.PackageManager; 38 import android.content.pm.ResolveInfo; 39 import android.content.pm.ServiceInfo; 40 import android.content.pm.UserInfo; 41 import android.os.Build; 42 import android.os.IBinder; 43 import android.os.IInterface; 44 import android.os.UserHandle; 45 import android.os.UserManager; 46 import android.provider.Settings; 47 import android.text.TextUtils; 48 import android.util.ArrayMap; 49 import android.util.Xml; 50 51 import com.android.internal.util.FastXmlSerializer; 52 53 import com.google.android.collect.Lists; 54 55 import org.junit.Before; 56 import org.junit.Test; 57 import org.mockito.Mock; 58 import org.mockito.MockitoAnnotations; 59 import org.mockito.invocation.InvocationOnMock; 60 import org.mockito.stubbing.Answer; 61 import org.xmlpull.v1.XmlPullParser; 62 import org.xmlpull.v1.XmlSerializer; 63 64 import java.io.BufferedInputStream; 65 import java.io.BufferedOutputStream; 66 import java.io.ByteArrayInputStream; 67 import java.io.ByteArrayOutputStream; 68 import java.util.ArrayList; 69 import java.util.List; 70 71 public class ManagedServicesTest extends NotificationTestCase { 72 73 @Mock 74 private IPackageManager mIpm; 75 @Mock 76 private PackageManager mPm; 77 @Mock 78 private UserManager mUm; 79 @Mock 80 private ManagedServices.UserProfiles mUserProfiles; 81 Object mLock = new Object(); 82 83 UserInfo mZero = new UserInfo(0, "zero", 0); 84 UserInfo mTen = new UserInfo(10, "ten", 0); 85 86 private static final String SETTING = "setting"; 87 private static final String SECONDARY_SETTING = "secondary_setting"; 88 89 private ArrayMap<Integer, String> mExpectedPrimaryPackages; 90 private ArrayMap<Integer, String> mExpectedPrimaryComponentNames; 91 private ArrayMap<Integer, String> mExpectedSecondaryPackages; 92 private ArrayMap<Integer, String> mExpectedSecondaryComponentNames; 93 94 // type : user : list of approved 95 private ArrayMap<Integer, ArrayMap<Integer, String>> mExpectedPrimary = new ArrayMap<>(); 96 private ArrayMap<Integer, ArrayMap<Integer, String>> mExpectedSecondary = new ArrayMap<>(); 97 98 @Before 99 public void setUp() throws Exception { 100 MockitoAnnotations.initMocks(this); 101 102 getContext().setMockPackageManager(mPm); 103 getContext().addMockSystemService(Context.USER_SERVICE, mUm); 104 105 List<UserInfo> users = new ArrayList<>(); 106 users.add(mZero); 107 users.add(mTen); 108 users.add(new UserInfo(11, "11", 0)); 109 users.add(new UserInfo(12, "12", 0)); 110 for (UserInfo user : users) { 111 when(mUm.getUserInfo(eq(user.id))).thenReturn(user); 112 } 113 when(mUm.getUsers()).thenReturn(users); 114 when(mUserProfiles.getCurrentProfileIds()).thenReturn(new int[] {0, 10, 11, 12}); 115 116 mExpectedPrimaryPackages = new ArrayMap<>(); 117 mExpectedPrimaryPackages.put(0, "this.is.a.package.name:another.package"); 118 mExpectedPrimaryPackages.put(10, "this.is.another.package"); 119 mExpectedPrimaryPackages.put(11, ""); 120 mExpectedPrimaryPackages.put(12, "bananas!"); 121 mExpectedPrimaryComponentNames = new ArrayMap<>(); 122 mExpectedPrimaryComponentNames.put(0, "this.is.a.package.name/Ba:another.package/B1"); 123 mExpectedPrimaryComponentNames.put(10, "this.is.another.package/M1"); 124 mExpectedPrimaryComponentNames.put(11, ""); 125 mExpectedPrimaryComponentNames.put(12, "bananas!/Bananas!"); 126 mExpectedPrimary.put(APPROVAL_BY_PACKAGE, mExpectedPrimaryPackages); 127 mExpectedPrimary.put(APPROVAL_BY_COMPONENT, mExpectedPrimaryComponentNames); 128 129 mExpectedSecondaryComponentNames = new ArrayMap<>(); 130 mExpectedSecondaryComponentNames.put(0, "secondary/component.Name"); 131 mExpectedSecondaryComponentNames.put(10, 132 "this.is.another.package/with.Component:component/2:package/component2"); 133 mExpectedSecondaryPackages = new ArrayMap<>(); 134 mExpectedSecondaryPackages.put(0, "secondary"); 135 mExpectedSecondaryPackages.put(10, 136 "this.is.another.package:component:package"); 137 mExpectedSecondary.put(APPROVAL_BY_PACKAGE, mExpectedSecondaryPackages); 138 mExpectedSecondary.put(APPROVAL_BY_COMPONENT, mExpectedSecondaryComponentNames); 139 } 140 141 @Test 142 public void testBackupAndRestore_migration() throws Exception { 143 for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) { 144 ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, 145 mIpm, approvalLevel); 146 147 for (int userId : mExpectedPrimary.get(approvalLevel).keySet()) { 148 service.onSettingRestored( 149 service.getConfig().secureSettingName, 150 mExpectedPrimary.get(approvalLevel).get(userId), 151 Build.VERSION_CODES.O, userId); 152 } 153 verifyExpectedApprovedEntries(service, true); 154 155 for (int userId : mExpectedSecondary.get(approvalLevel).keySet()) { 156 service.onSettingRestored(service.getConfig().secondarySettingName, 157 mExpectedSecondary.get(approvalLevel).get(userId), Build.VERSION_CODES.O, 158 userId); 159 } 160 verifyExpectedApprovedEntries(service); 161 } 162 } 163 164 @Test 165 public void testBackupAndRestore_migration_preO() throws Exception { 166 ArrayMap backupPrimaryPackages = new ArrayMap<>(); 167 backupPrimaryPackages.put(0, "backup.0:backup:0a"); 168 backupPrimaryPackages.put(10, "10.backup"); 169 backupPrimaryPackages.put(11, "eleven"); 170 backupPrimaryPackages.put(12, ""); 171 ArrayMap backupPrimaryComponentNames = new ArrayMap<>(); 172 backupPrimaryComponentNames.put(0, "backup.first/whatever:a/b"); 173 backupPrimaryComponentNames.put(10, "again/M1"); 174 backupPrimaryComponentNames.put(11, "orange/youglad:itisnot/banana"); 175 backupPrimaryComponentNames.put(12, ""); 176 ArrayMap<Integer, ArrayMap<Integer, String>> backupPrimary = new ArrayMap<>(); 177 backupPrimary.put(APPROVAL_BY_PACKAGE, backupPrimaryPackages); 178 backupPrimary.put(APPROVAL_BY_COMPONENT, backupPrimaryComponentNames); 179 180 ArrayMap backupSecondaryComponentNames = new ArrayMap<>(); 181 backupSecondaryComponentNames.put(0, "secondary.1/component.Name"); 182 backupSecondaryComponentNames.put(10, 183 "this.is.another.package.backup/with.Component:component.backup/2"); 184 ArrayMap backupSecondaryPackages = new ArrayMap<>(); 185 backupSecondaryPackages.put(0, ""); 186 backupSecondaryPackages.put(10, 187 "this.is.another.package.backup:package.backup"); 188 ArrayMap<Integer, ArrayMap<Integer, String>> backupSecondary = new ArrayMap<>(); 189 backupSecondary.put(APPROVAL_BY_PACKAGE, backupSecondaryPackages); 190 backupSecondary.put(APPROVAL_BY_COMPONENT, backupSecondaryComponentNames); 191 192 for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) { 193 ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, 194 mIpm, approvalLevel); 195 196 // not an expected flow but a way to get data into the settings 197 for (int userId : mExpectedPrimary.get(approvalLevel).keySet()) { 198 service.onSettingRestored( 199 service.getConfig().secureSettingName, 200 mExpectedPrimary.get(approvalLevel).get(userId), 201 Build.VERSION_CODES.O, userId); 202 } 203 204 for (int userId : mExpectedSecondary.get(approvalLevel).keySet()) { 205 service.onSettingRestored(service.getConfig().secondarySettingName, 206 mExpectedSecondary.get(approvalLevel).get(userId), Build.VERSION_CODES.O, 207 userId); 208 } 209 210 // actual test 211 for (int userId : backupPrimary.get(approvalLevel).keySet()) { 212 service.onSettingRestored( 213 service.getConfig().secureSettingName, 214 backupPrimary.get(approvalLevel).get(userId), 215 Build.VERSION_CODES.N_MR1, userId); 216 } 217 verifyExpectedApprovedEntries(service, true); 218 219 for (int userId : backupSecondary.get(approvalLevel).keySet()) { 220 service.onSettingRestored(service.getConfig().secondarySettingName, 221 backupSecondary.get(approvalLevel).get(userId), 222 Build.VERSION_CODES.N_MR1, userId); 223 } 224 verifyExpectedApprovedEntries(service); 225 verifyExpectedApprovedEntries(service, backupPrimary.get(approvalLevel)); 226 verifyExpectedApprovedEntries(service, backupSecondary.get(approvalLevel)); 227 } 228 } 229 230 @Test 231 public void testReadXml_migrationFromSettings() throws Exception { 232 for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) { 233 ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, 234 mIpm, approvalLevel); 235 236 // approved services aren't in xml 237 XmlPullParser parser = Xml.newPullParser(); 238 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(new byte[]{})), 239 null); 240 writeExpectedValuesToSettings(approvalLevel); 241 242 service.migrateToXml(); 243 244 verifyExpectedApprovedEntries(service); 245 } 246 } 247 248 @Test 249 public void testReadXml() throws Exception { 250 for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) { 251 ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, 252 mIpm, approvalLevel); 253 254 loadXml(service); 255 256 verifyExpectedApprovedEntries(service); 257 258 int[] invalidUsers = new int[] {98, 99}; 259 for (int invalidUser : invalidUsers) { 260 assertFalse("service type " + service.mApprovalLevel + ":" 261 + invalidUser + " is allowed for user " + invalidUser, 262 service.isPackageOrComponentAllowed( 263 String.valueOf(invalidUser), invalidUser)); 264 } 265 } 266 } 267 268 @Test 269 public void testWriteXml_trimsMissingServices() throws Exception { 270 for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) { 271 ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, 272 mIpm, approvalLevel); 273 loadXml(service); 274 275 // remove missing 276 mExpectedPrimaryPackages.put(0, "another.package"); 277 mExpectedPrimaryPackages.remove(12); 278 mExpectedPrimaryComponentNames.put(0, "another.package/B1"); 279 mExpectedPrimaryComponentNames.remove(12); 280 mExpectedSecondaryPackages.put(10, "this.is.another.package:component"); 281 mExpectedSecondaryComponentNames.put( 282 10, "this.is.another.package/with.Component:component/2"); 283 284 for (UserInfo userInfo : mUm.getUsers()) { 285 List<String> entriesExpectedToHaveServices = new ArrayList<>(); 286 if (mExpectedPrimary.get(approvalLevel).containsKey(userInfo.id)) { 287 for (String packageOrComponent : 288 mExpectedPrimary.get(approvalLevel).get(userInfo.id).split(":")) { 289 if (!TextUtils.isEmpty(packageOrComponent)) { 290 entriesExpectedToHaveServices.add( 291 service.getPackageName(packageOrComponent)); 292 } 293 } 294 } 295 if (mExpectedSecondary.get(approvalLevel).containsKey(userInfo.id)) { 296 for (String packageOrComponent : 297 mExpectedSecondary.get(approvalLevel).get(userInfo.id).split(":")) { 298 if (!TextUtils.isEmpty(packageOrComponent)) { 299 entriesExpectedToHaveServices.add( 300 service.getPackageName(packageOrComponent)); 301 } 302 } 303 } 304 addExpectedServices(service, entriesExpectedToHaveServices, userInfo.id); 305 } 306 307 XmlSerializer serializer = new FastXmlSerializer(); 308 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 309 serializer.setOutput(new BufferedOutputStream(baos), "utf-8"); 310 serializer.startDocument(null, true); 311 service.writeXml(serializer, true); 312 serializer.endDocument(); 313 serializer.flush(); 314 315 XmlPullParser parser = Xml.newPullParser(); 316 parser.setInput(new BufferedInputStream( 317 new ByteArrayInputStream(baos.toByteArray())), null); 318 parser.nextTag(); 319 service.readXml(parser); 320 321 verifyExpectedApprovedEntries(service); 322 assertFalse(service.isPackageOrComponentAllowed("this.is.a.package.name", 0)); 323 assertFalse(service.isPackageOrComponentAllowed("bananas!", 12)); 324 assertFalse(service.isPackageOrComponentAllowed("package/component2", 10)); 325 } 326 } 327 328 @Test 329 public void testWriteXml_writesSetting() throws Exception { 330 for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) { 331 ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, 332 mIpm, approvalLevel); 333 loadXml(service); 334 335 XmlSerializer serializer = new FastXmlSerializer(); 336 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 337 serializer.setOutput(new BufferedOutputStream(baos), "utf-8"); 338 serializer.startDocument(null, true); 339 service.writeXml(serializer, false); 340 serializer.endDocument(); 341 serializer.flush(); 342 343 for (int userId : mUserProfiles.getCurrentProfileIds()) { 344 List<String> expected = 345 stringToList(mExpectedPrimary.get(approvalLevel).get(userId)); 346 List<String> actual = stringToList(Settings.Secure.getStringForUser( 347 getContext().getContentResolver(), 348 service.getConfig().secureSettingName, userId)); 349 assertContentsInAnyOrder(actual, expected); 350 } 351 } 352 } 353 354 @Test 355 public void rebindServices_onlyBindsExactMatchesIfComponent() throws Exception { 356 // If the primary and secondary lists contain component names, only those components within 357 // the package should be matched 358 ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, 359 mIpm, 360 ManagedServices.APPROVAL_BY_COMPONENT); 361 362 List<String> packages = new ArrayList<>(); 363 packages.add("package"); 364 packages.add("anotherPackage"); 365 addExpectedServices(service, packages, 0); 366 367 // only 2 components are approved per package 368 mExpectedPrimaryComponentNames.clear(); 369 mExpectedPrimaryComponentNames.put(0, "package/C1:package/C2"); 370 mExpectedSecondaryComponentNames.clear(); 371 mExpectedSecondaryComponentNames.put(0, "anotherPackage/C1:anotherPackage/C2"); 372 373 loadXml(service); 374 375 // verify the 2 components per package are enabled (bound) 376 verifyExpectedBoundEntries(service, true); 377 verifyExpectedBoundEntries(service, false); 378 379 // verify the last component per package is not enabled/we don't try to bind to it 380 for (String pkg : packages) { 381 ComponentName unapprovedAdditionalComponent = 382 ComponentName.unflattenFromString(pkg + "/C3"); 383 assertFalse( 384 service.isComponentEnabledForCurrentProfiles( 385 unapprovedAdditionalComponent)); 386 verify(mIpm, never()).getServiceInfo( 387 eq(unapprovedAdditionalComponent), anyInt(), anyInt()); 388 } 389 } 390 391 @Test 392 public void rebindServices_bindsEverythingInAPackage() throws Exception { 393 // If the primary and secondary lists contain packages, all components within those packages 394 // should be bound 395 ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, mIpm, 396 APPROVAL_BY_PACKAGE); 397 398 List<String> packages = new ArrayList<>(); 399 packages.add("package"); 400 packages.add("packagea"); 401 addExpectedServices(service, packages, 0); 402 403 // 2 approved packages 404 mExpectedPrimaryPackages.clear(); 405 mExpectedPrimaryPackages.put(0, "package"); 406 mExpectedSecondaryPackages.clear(); 407 mExpectedSecondaryPackages.put(0, "packagea"); 408 409 loadXml(service); 410 411 // verify the 3 components per package are enabled (bound) 412 verifyExpectedBoundEntries(service, true); 413 verifyExpectedBoundEntries(service, false); 414 } 415 416 @Test 417 public void testPackageUninstall_packageNoLongerInApprovedList() throws Exception { 418 for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) { 419 ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, 420 mIpm, approvalLevel); 421 writeExpectedValuesToSettings(approvalLevel); 422 service.migrateToXml(); 423 424 mExpectedPrimaryPackages.put(0, "another.package"); 425 mExpectedPrimaryComponentNames.put(0, "another.package/B1"); 426 service.onPackagesChanged(true, new String[]{"this.is.a.package.name"}, new int[]{103}); 427 428 verifyExpectedApprovedEntries(service); 429 } 430 } 431 432 @Test 433 public void testPackageUninstall_componentNoLongerInApprovedList() throws Exception { 434 for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) { 435 ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, 436 mIpm, approvalLevel); 437 writeExpectedValuesToSettings(approvalLevel); 438 service.migrateToXml(); 439 440 mExpectedSecondaryComponentNames.put(10, "component/2"); 441 mExpectedSecondaryPackages.put(10, "component"); 442 service.onPackagesChanged(true, new String[]{"this.is.another.package"}, new int[]{ 443 UserHandle.PER_USER_RANGE + 1}); 444 445 verifyExpectedApprovedEntries(service); 446 } 447 } 448 449 @Test 450 public void testSetPackageOrComponentEnabled() throws Exception { 451 for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) { 452 ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, 453 mIpm, approvalLevel); 454 ArrayMap<Integer, ArrayList<String>> expectedEnabled = new ArrayMap<>(); 455 expectedEnabled.put(0, 456 Lists.newArrayList(new String[]{"package/Comp", "package/C2", "again/M4"})); 457 expectedEnabled.put(10, 458 Lists.newArrayList(new String[]{"user10package/B", "user10/Component", 459 "user10package1/K", "user10.3/Component", "user10package2/L", 460 "user10.4/Component"})); 461 462 for (int userId : expectedEnabled.keySet()) { 463 ArrayList<String> expectedForUser = expectedEnabled.get(userId); 464 for (int i = 0; i < expectedForUser.size(); i++) { 465 boolean primary = i % 2 == 0; 466 service.setPackageOrComponentEnabled(expectedForUser.get(i), userId, primary, 467 true); 468 } 469 } 470 471 // verify everything added is approved 472 for (int userId : expectedEnabled.keySet()) { 473 ArrayList<String> expectedForUser = expectedEnabled.get(userId); 474 for (int i = 0; i < expectedForUser.size(); i++) { 475 String verifyValue = (approvalLevel == APPROVAL_BY_COMPONENT) 476 ? expectedForUser.get(i) 477 : service.getPackageName(expectedForUser.get(i)); 478 assertTrue("Not allowed: user: " + userId + " entry: " + verifyValue 479 + " for approval level " + approvalLevel, 480 service.isPackageOrComponentAllowed(verifyValue, userId)); 481 } 482 } 483 484 ArrayMap<Integer, ArrayList<String>> expectedNoAccess = new ArrayMap<>(); 485 for (int userId : expectedEnabled.keySet()) { 486 ArrayList<String> expectedForUser = expectedEnabled.get(userId); 487 for (int i = expectedForUser.size() - 1; i >= 0; i--) { 488 ArrayList<String> removed = new ArrayList<>(); 489 if (i % 3 == 0) { 490 String revokeAccessFor = expectedForUser.remove(i); 491 removed.add(revokeAccessFor); 492 service.setPackageOrComponentEnabled( 493 revokeAccessFor, userId, i % 2 == 0, false); 494 } 495 expectedNoAccess.put(userId, removed); 496 } 497 } 498 499 // verify everything still there is approved 500 for (int userId : expectedEnabled.keySet()) { 501 ArrayList<String> expectedForUser = expectedEnabled.get(userId); 502 for (int i = 0; i < expectedForUser.size(); i++) { 503 String verifyValue = (approvalLevel == APPROVAL_BY_COMPONENT) 504 ? expectedForUser.get(i) 505 : service.getPackageName(expectedForUser.get(i)); 506 assertTrue("Not allowed: user: " + userId + " entry: " + verifyValue, 507 service.isPackageOrComponentAllowed(verifyValue, userId)); 508 } 509 } 510 // verify everything removed isn't 511 for (int userId : expectedNoAccess.keySet()) { 512 ArrayList<String> notExpectedForUser = expectedNoAccess.get(userId); 513 for (int i = 0; i < notExpectedForUser.size(); i++) { 514 assertFalse( 515 "Is allowed: user: " + userId + " entry: " + notExpectedForUser.get(i), 516 service.isPackageOrComponentAllowed(notExpectedForUser.get(i), userId)); 517 } 518 } 519 } 520 } 521 522 @Test 523 public void testGetAllowedPackages() throws Exception { 524 for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) { 525 ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, 526 mIpm, approvalLevel); 527 loadXml(service); 528 529 List<String> allowedPackagesForUser0 = new ArrayList<>(); 530 allowedPackagesForUser0.add("this.is.a.package.name"); 531 allowedPackagesForUser0.add("another.package"); 532 allowedPackagesForUser0.add("secondary"); 533 534 List<String> actual = service.getAllowedPackages(0); 535 assertEquals(3, actual.size()); 536 for (String pkg : allowedPackagesForUser0) { 537 assertTrue(actual.contains(pkg)); 538 } 539 540 List<String> allowedPackagesForUser10 = new ArrayList<>(); 541 allowedPackagesForUser10.add("this.is.another.package"); 542 allowedPackagesForUser10.add("package"); 543 allowedPackagesForUser10.add("this.is.another.package"); 544 allowedPackagesForUser10.add("component"); 545 546 actual = service.getAllowedPackages(10); 547 assertEquals(4, actual.size()); 548 for (String pkg : allowedPackagesForUser10) { 549 assertTrue(actual.contains(pkg)); 550 } 551 } 552 } 553 554 @Test 555 public void testGetAllowedComponents() throws Exception { 556 ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, mIpm, 557 APPROVAL_BY_COMPONENT); 558 loadXml(service); 559 560 List<ComponentName> expected = new ArrayList<>(); 561 expected.add(ComponentName.unflattenFromString("this.is.another.package/M1")); 562 expected.add(ComponentName.unflattenFromString("this.is.another.package/with.Component")); 563 expected.add(ComponentName.unflattenFromString("component/2")); 564 expected.add(ComponentName.unflattenFromString("package/component2")); 565 566 List<ComponentName> actual = service.getAllowedComponents(10); 567 568 assertContentsInAnyOrder(expected, actual); 569 570 assertEquals(expected.size(), actual.size()); 571 572 for (ComponentName cn : expected) { 573 assertTrue("Actual missing " + cn, actual.contains(cn)); 574 } 575 576 for (ComponentName cn : actual) { 577 assertTrue("Actual contains extra " + cn, expected.contains(cn)); 578 } 579 } 580 581 @Test 582 public void testGetAllowedComponents_approvalByPackage() throws Exception { 583 ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, mIpm, 584 APPROVAL_BY_PACKAGE); 585 loadXml(service); 586 587 assertEquals(0, service.getAllowedComponents(10).size()); 588 } 589 590 @Test 591 public void testOnUserRemoved() throws Exception { 592 for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) { 593 ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, 594 mIpm, approvalLevel); 595 loadXml(service); 596 597 ArrayMap<Integer, String> verifyMap = mExpectedPrimary.get(service.mApprovalLevel); 598 String user0 = verifyMap.remove(0); 599 verifyMap = mExpectedSecondary.get(service.mApprovalLevel); 600 user0 = user0 + ":" + verifyMap.remove(0); 601 602 service.onUserRemoved(0); 603 604 for (String verifyValue : user0.split(":")) { 605 if (!TextUtils.isEmpty(verifyValue)) { 606 assertFalse("service type " + service.mApprovalLevel + ":" + verifyValue 607 + " is still allowed", 608 service.isPackageOrComponentAllowed(verifyValue, 0)); 609 } 610 } 611 612 verifyExpectedApprovedEntries(service); 613 } 614 } 615 616 private void loadXml(ManagedServices service) throws Exception { 617 final StringBuffer xml = new StringBuffer(); 618 xml.append("<" + service.getConfig().xmlTag + ">\n"); 619 for (int userId : mExpectedPrimary.get(service.mApprovalLevel).keySet()) { 620 xml.append(getXmlEntry( 621 mExpectedPrimary.get(service.mApprovalLevel).get(userId), userId, true)); 622 } 623 for (int userId : mExpectedSecondary.get(service.mApprovalLevel).keySet()) { 624 xml.append(getXmlEntry( 625 mExpectedSecondary.get(service.mApprovalLevel).get(userId), userId, false)); 626 } 627 xml.append("<" + ManagedServices.TAG_MANAGED_SERVICES + " " 628 + ManagedServices.ATT_USER_ID + "=\"99\" " 629 + ManagedServices.ATT_IS_PRIMARY + "=\"true\" " 630 + ManagedServices.ATT_APPROVED_LIST + "=\"99\" />\n"); 631 xml.append("<" + ManagedServices.TAG_MANAGED_SERVICES + " " 632 + ManagedServices.ATT_USER_ID + "=\"98\" " 633 + ManagedServices.ATT_IS_PRIMARY + "=\"false\" " 634 + ManagedServices.ATT_APPROVED_LIST + "=\"98\" />\n"); 635 xml.append("</" + service.getConfig().xmlTag + ">"); 636 637 XmlPullParser parser = Xml.newPullParser(); 638 parser.setInput(new BufferedInputStream( 639 new ByteArrayInputStream(xml.toString().getBytes())), null); 640 parser.nextTag(); 641 service.readXml(parser); 642 } 643 644 private void addExpectedServices(final ManagedServices service, final List<String> packages, 645 int userId) { 646 when(mPm.queryIntentServicesAsUser(any(), anyInt(), eq(userId))). 647 thenAnswer(new Answer<List<ResolveInfo>>() { 648 @Override 649 public List<ResolveInfo> answer(InvocationOnMock invocationOnMock) 650 throws Throwable { 651 Object[] args = invocationOnMock.getArguments(); 652 Intent invocationIntent = (Intent) args[0]; 653 if (invocationIntent != null) { 654 if (invocationIntent.getAction().equals( 655 service.getConfig().serviceInterface) 656 && packages.contains(invocationIntent.getPackage())) { 657 List<ResolveInfo> dummyServices = new ArrayList<>(); 658 for (int i = 1; i <= 3; i ++) { 659 ResolveInfo resolveInfo = new ResolveInfo(); 660 ServiceInfo serviceInfo = new ServiceInfo(); 661 serviceInfo.packageName = invocationIntent.getPackage(); 662 serviceInfo.name = "C"+i; 663 serviceInfo.permission = service.getConfig().bindPermission; 664 resolveInfo.serviceInfo = serviceInfo; 665 dummyServices.add(resolveInfo); 666 } 667 return dummyServices; 668 } 669 } 670 return new ArrayList<>(); 671 } 672 }); 673 } 674 675 private List<String> stringToList(String list) { 676 if (list == null) { 677 list = ""; 678 } 679 return new ArrayList<>(Lists.newArrayList(list.split( 680 ManagedServices.ENABLED_SERVICES_SEPARATOR))); 681 } 682 683 private void assertContentsInAnyOrder(List<?> expected, List<?> actual) { 684 assertEquals(expected.size(), actual.size()); 685 686 for (Object o : expected) { 687 assertTrue("Actual missing " + o, actual.contains(o)); 688 } 689 690 for (Object o : actual) { 691 assertTrue("Actual contains extra " + o, expected.contains(o)); 692 } 693 } 694 695 private void verifyExpectedBoundEntries(ManagedServices service, boolean primary) 696 throws Exception { 697 ArrayMap<Integer, String> verifyMap = primary ? mExpectedPrimary.get(service.mApprovalLevel) 698 : mExpectedSecondary.get(service.mApprovalLevel); 699 for (int userId : verifyMap.keySet()) { 700 for (String packageOrComponent : verifyMap.get(userId).split(":")) { 701 if (!TextUtils.isEmpty(packageOrComponent)) { 702 if (service.mApprovalLevel == APPROVAL_BY_PACKAGE) { 703 assertTrue(packageOrComponent, 704 service.isComponentEnabledForPackage(packageOrComponent)); 705 for (int i = 1; i <= 3; i ++) { 706 ComponentName componentName = ComponentName.unflattenFromString( 707 packageOrComponent +"/C" + i); 708 assertTrue(service.isComponentEnabledForCurrentProfiles( 709 componentName)); 710 verify(mIpm, times(1)).getServiceInfo( 711 eq(componentName), anyInt(), anyInt()); 712 } 713 } else { 714 ComponentName componentName = 715 ComponentName.unflattenFromString(packageOrComponent); 716 assertTrue(service.isComponentEnabledForCurrentProfiles(componentName)); 717 verify(mIpm, times(1)).getServiceInfo( 718 eq(componentName), anyInt(), anyInt()); 719 } 720 } 721 } 722 } 723 } 724 725 private void verifyExpectedApprovedEntries(ManagedServices service) { 726 verifyExpectedApprovedEntries(service, true); 727 verifyExpectedApprovedEntries(service, false); 728 } 729 730 private void verifyExpectedApprovedEntries(ManagedServices service, boolean primary) { 731 ArrayMap<Integer, String> verifyMap = primary 732 ? mExpectedPrimary.get(service.mApprovalLevel) 733 : mExpectedSecondary.get(service.mApprovalLevel); 734 verifyExpectedApprovedEntries(service, verifyMap); 735 } 736 737 private void verifyExpectedApprovedEntries(ManagedServices service, 738 ArrayMap<Integer, String> verifyMap) { 739 for (int userId : verifyMap.keySet()) { 740 for (String verifyValue : verifyMap.get(userId).split(":")) { 741 if (!TextUtils.isEmpty(verifyValue)) { 742 assertTrue("service type " + service.mApprovalLevel + ":" 743 + verifyValue + " is not allowed for user " + userId, 744 service.isPackageOrComponentAllowed(verifyValue, userId)); 745 } 746 } 747 } 748 } 749 750 private void writeExpectedValuesToSettings(int approvalLevel) { 751 for (int userId : mExpectedPrimary.get(approvalLevel).keySet()) { 752 Settings.Secure.putStringForUser(getContext().getContentResolver(), SETTING, 753 mExpectedPrimary.get(approvalLevel).get(userId), userId); 754 } 755 for (int userId : mExpectedSecondary.get(approvalLevel).keySet()) { 756 Settings.Secure.putStringForUser(getContext().getContentResolver(), SECONDARY_SETTING, 757 mExpectedSecondary.get(approvalLevel).get(userId), userId); 758 } 759 } 760 761 private String getXmlEntry(String approved, int userId, boolean isPrimary) { 762 return "<" + ManagedServices.TAG_MANAGED_SERVICES + " " 763 + ManagedServices.ATT_USER_ID + "=\"" + userId +"\" " 764 + ManagedServices.ATT_IS_PRIMARY + "=\"" + isPrimary +"\" " 765 + ManagedServices.ATT_APPROVED_LIST + "=\"" + approved +"\" " 766 + "/>\n"; 767 } 768 769 class TestManagedServices extends ManagedServices { 770 771 public TestManagedServices(Context context, Object mutex, UserProfiles userProfiles, 772 IPackageManager pm, int approvedServiceType) { 773 super(context, mutex, userProfiles, pm); 774 mApprovalLevel = approvedServiceType; 775 } 776 777 @Override 778 protected Config getConfig() { 779 final Config c = new Config(); 780 c.xmlTag = "test"; 781 c.secureSettingName = SETTING; 782 c.secondarySettingName = SECONDARY_SETTING; 783 c.bindPermission = "permission"; 784 c.serviceInterface = "serviceInterface"; 785 return c; 786 } 787 788 @Override 789 protected IInterface asInterface(IBinder binder) { 790 return null; 791 } 792 793 @Override 794 protected boolean checkType(IInterface service) { 795 return false; 796 } 797 798 @Override 799 protected void onServiceAdded(ManagedServiceInfo info) { 800 801 } 802 } 803 } 804