1 /* 2 * Copyright (C) 2019 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.pm; 18 19 import static android.content.pm.UserInfo.FLAG_DEMO; 20 import static android.content.pm.UserInfo.FLAG_EPHEMERAL; 21 import static android.content.pm.UserInfo.FLAG_FULL; 22 import static android.content.pm.UserInfo.FLAG_GUEST; 23 import static android.content.pm.UserInfo.FLAG_MANAGED_PROFILE; 24 import static android.content.pm.UserInfo.FLAG_PROFILE; 25 import static android.content.pm.UserInfo.FLAG_RESTRICTED; 26 import static android.content.pm.UserInfo.FLAG_SYSTEM; 27 28 import static com.android.server.pm.UserTypeDetails.UNLIMITED_NUMBER_OF_USERS; 29 30 import static org.junit.Assert.assertEquals; 31 import static org.junit.Assert.assertFalse; 32 import static org.junit.Assert.assertNotNull; 33 import static org.junit.Assert.assertNotSame; 34 import static org.junit.Assert.assertTrue; 35 import static org.testng.Assert.assertThrows; 36 37 import android.content.pm.UserInfo; 38 import android.content.pm.UserProperties; 39 import android.content.res.Resources; 40 import android.content.res.XmlResourceParser; 41 import android.os.Bundle; 42 import android.os.UserManager; 43 import android.platform.test.annotations.Presubmit; 44 import android.util.ArrayMap; 45 46 import androidx.test.InstrumentationRegistry; 47 import androidx.test.filters.MediumTest; 48 import androidx.test.runner.AndroidJUnit4; 49 50 import com.android.frameworks.servicestests.R; 51 52 import org.junit.Before; 53 import org.junit.Test; 54 import org.junit.runner.RunWith; 55 56 import java.util.List; 57 58 /** 59 * Tests for {@link UserTypeDetails} and {@link UserTypeFactory}. 60 * 61 * <p>Run with: atest UserManagerServiceUserTypeTest 62 */ 63 @Presubmit 64 @RunWith(AndroidJUnit4.class) 65 @MediumTest 66 public class UserManagerServiceUserTypeTest { 67 68 private Resources mResources; 69 70 @Before setup()71 public void setup() { 72 mResources = InstrumentationRegistry.getTargetContext().getResources(); 73 } 74 @Test testUserTypeBuilder_createUserType()75 public void testUserTypeBuilder_createUserType() { 76 final Bundle restrictions = makeRestrictionsBundle("r1", "r2"); 77 final Bundle systemSettings = makeSettingsBundle("s1", "s2"); 78 final Bundle secureSettings = makeSettingsBundle("secure_s1", "secure_s2"); 79 final List<DefaultCrossProfileIntentFilter> filters = List.of( 80 new DefaultCrossProfileIntentFilter.Builder( 81 DefaultCrossProfileIntentFilter.Direction.TO_PARENT, 82 /* flags= */0, 83 /* letsPersonalDataIntoProfile= */false).build()); 84 final UserProperties.Builder userProps = new UserProperties.Builder() 85 .setShowInLauncher(17) 86 .setUseParentsContacts(true) 87 .setCrossProfileIntentFilterAccessControl(10) 88 .setCrossProfileIntentResolutionStrategy(1) 89 .setMediaSharedWithParent(true) 90 .setCredentialShareableWithParent(false) 91 .setAuthAlwaysRequiredToDisableQuietMode(true) 92 .setAllowStoppingUserWithDelayedLocking(true) 93 .setShowInSettings(900) 94 .setShowInSharingSurfaces(20) 95 .setShowInQuietMode(30) 96 .setInheritDevicePolicy(340) 97 .setDeleteAppWithParent(true) 98 .setAlwaysVisible(true) 99 .setCrossProfileContentSharingStrategy(1) 100 .setProfileApiVisibility(34) 101 .setItemsRestrictedOnHomeScreen(true); 102 103 final UserTypeDetails type = new UserTypeDetails.Builder() 104 .setName("a.name") 105 .setEnabled(1) 106 .setMaxAllowed(21) 107 .setBaseType(FLAG_PROFILE) 108 .setDefaultUserInfoPropertyFlags(FLAG_EPHEMERAL) 109 .setProfileParentRequired(true) 110 .setBadgeLabels(23, 24, 25) 111 .setBadgeColors(26, 27) 112 .setIconBadge(28) 113 .setBadgePlain(29) 114 .setBadgeNoBackground(30) 115 .setMaxAllowedPerParent(32) 116 .setStatusBarIcon(33) 117 .setLabels(34, 35, 36) 118 .setDefaultRestrictions(restrictions) 119 .setDefaultSystemSettings(systemSettings) 120 .setDefaultSecureSettings(secureSettings) 121 .setDefaultCrossProfileIntentFilters(filters) 122 .setDefaultUserProperties(userProps) 123 .createUserTypeDetails(); 124 125 assertEquals("a.name", type.getName()); 126 assertTrue(type.isEnabled()); 127 assertEquals(21, type.getMaxAllowed()); 128 assertEquals(FLAG_PROFILE | FLAG_EPHEMERAL, type.getDefaultUserInfoFlags()); 129 assertTrue(type.isProfileParentRequired()); 130 assertEquals(28, type.getIconBadge()); 131 assertEquals(29, type.getBadgePlain()); 132 assertEquals(30, type.getBadgeNoBackground()); 133 assertEquals(32, type.getMaxAllowedPerParent()); 134 assertEquals(33, type.getStatusBarIcon()); 135 assertEquals(34, type.getLabel(0)); 136 assertEquals(35, type.getLabel(1)); 137 assertEquals(36, type.getLabel(2)); 138 139 assertTrue(UserRestrictionsUtils.areEqual(restrictions, type.getDefaultRestrictions())); 140 assertNotSame(restrictions, type.getDefaultRestrictions()); 141 142 assertNotSame(systemSettings, type.getDefaultSystemSettings()); 143 assertEquals(systemSettings.size(), type.getDefaultSystemSettings().size()); 144 for (String key : systemSettings.keySet()) { 145 assertEquals( 146 systemSettings.getString(key), 147 type.getDefaultSystemSettings().getString(key)); 148 } 149 150 assertNotSame(secureSettings, type.getDefaultSecureSettings()); 151 assertEquals(secureSettings.size(), type.getDefaultSecureSettings().size()); 152 for (String key : secureSettings.keySet()) { 153 assertEquals( 154 secureSettings.getString(key), 155 type.getDefaultSecureSettings().getString(key)); 156 } 157 158 assertNotSame(filters, type.getDefaultCrossProfileIntentFilters()); 159 assertEquals(filters.size(), type.getDefaultCrossProfileIntentFilters().size()); 160 for (int i = 0; i < filters.size(); i++) { 161 assertEquals(filters.get(i), type.getDefaultCrossProfileIntentFilters().get(i)); 162 } 163 164 assertEquals(17, type.getDefaultUserPropertiesReference().getShowInLauncher()); 165 assertTrue(type.getDefaultUserPropertiesReference().getUseParentsContacts()); 166 assertEquals(10, type.getDefaultUserPropertiesReference() 167 .getCrossProfileIntentFilterAccessControl()); 168 assertEquals(1, type.getDefaultUserPropertiesReference() 169 .getCrossProfileIntentResolutionStrategy()); 170 assertTrue(type.getDefaultUserPropertiesReference().isMediaSharedWithParent()); 171 assertFalse(type.getDefaultUserPropertiesReference().isCredentialShareableWithParent()); 172 assertTrue(type.getDefaultUserPropertiesReference() 173 .isAuthAlwaysRequiredToDisableQuietMode()); 174 assertTrue(type.getDefaultUserPropertiesReference() 175 .getAllowStoppingUserWithDelayedLocking()); 176 assertEquals(900, type.getDefaultUserPropertiesReference().getShowInSettings()); 177 assertEquals(20, type.getDefaultUserPropertiesReference().getShowInSharingSurfaces()); 178 assertEquals(30, 179 type.getDefaultUserPropertiesReference().getShowInQuietMode()); 180 assertEquals(340, type.getDefaultUserPropertiesReference() 181 .getInheritDevicePolicy()); 182 assertTrue(type.getDefaultUserPropertiesReference().getDeleteAppWithParent()); 183 assertTrue(type.getDefaultUserPropertiesReference().getAlwaysVisible()); 184 assertEquals(1, type.getDefaultUserPropertiesReference() 185 .getCrossProfileContentSharingStrategy()); 186 assertEquals(34, type.getDefaultUserPropertiesReference().getProfileApiVisibility()); 187 assertTrue(type.getDefaultUserPropertiesReference().areItemsRestrictedOnHomeScreen()); 188 189 assertEquals(23, type.getBadgeLabel(0)); 190 assertEquals(24, type.getBadgeLabel(1)); 191 assertEquals(25, type.getBadgeLabel(2)); 192 assertEquals(25, type.getBadgeLabel(3)); 193 assertEquals(25, type.getBadgeLabel(4)); 194 assertEquals(Resources.ID_NULL, type.getBadgeLabel(-1)); 195 196 assertEquals(26, type.getBadgeColor(0)); 197 assertEquals(27, type.getBadgeColor(1)); 198 assertEquals(27, type.getBadgeColor(2)); 199 assertEquals(27, type.getBadgeColor(3)); 200 assertEquals(Resources.ID_NULL, type.getBadgeColor(-100)); 201 202 assertTrue(type.hasBadge()); 203 } 204 205 @Test testUserTypeBuilder_defaults()206 public void testUserTypeBuilder_defaults() { 207 UserTypeDetails type = new UserTypeDetails.Builder() 208 .setName("name") // Required (no default allowed) 209 .setBaseType(FLAG_FULL) // Required (no default allowed) 210 .createUserTypeDetails(); 211 212 assertTrue(type.isEnabled()); 213 assertEquals(UNLIMITED_NUMBER_OF_USERS, type.getMaxAllowed()); 214 assertEquals(UNLIMITED_NUMBER_OF_USERS, type.getMaxAllowedPerParent()); 215 assertEquals(FLAG_FULL, type.getDefaultUserInfoFlags()); 216 assertEquals(Resources.ID_NULL, type.getIconBadge()); 217 assertEquals(Resources.ID_NULL, type.getBadgePlain()); 218 assertEquals(Resources.ID_NULL, type.getBadgeNoBackground()); 219 assertEquals(Resources.ID_NULL, type.getStatusBarIcon()); 220 assertEquals(Resources.ID_NULL, type.getBadgeLabel(0)); 221 assertEquals(Resources.ID_NULL, type.getBadgeColor(0)); 222 assertEquals(Resources.ID_NULL, type.getLabel(0)); 223 assertTrue(type.getDefaultRestrictions().isEmpty()); 224 assertTrue(type.getDefaultSystemSettings().isEmpty()); 225 assertTrue(type.getDefaultSecureSettings().isEmpty()); 226 assertTrue(type.getDefaultCrossProfileIntentFilters().isEmpty()); 227 228 final UserProperties props = type.getDefaultUserPropertiesReference(); 229 assertNotNull(props); 230 assertFalse(props.getStartWithParent()); 231 assertFalse(props.getUseParentsContacts()); 232 assertEquals(UserProperties.CROSS_PROFILE_INTENT_FILTER_ACCESS_LEVEL_ALL, 233 props.getCrossProfileIntentFilterAccessControl()); 234 assertEquals(UserProperties.SHOW_IN_LAUNCHER_WITH_PARENT, props.getShowInLauncher()); 235 assertEquals(UserProperties.CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY_DEFAULT, 236 props.getCrossProfileIntentResolutionStrategy()); 237 assertFalse(props.isMediaSharedWithParent()); 238 assertFalse(props.isCredentialShareableWithParent()); 239 assertFalse(props.getDeleteAppWithParent()); 240 assertFalse(props.getAlwaysVisible()); 241 assertEquals(UserProperties.SHOW_IN_LAUNCHER_SEPARATE, props.getShowInSharingSurfaces()); 242 assertEquals(UserProperties.SHOW_IN_QUIET_MODE_PAUSED, 243 props.getShowInQuietMode()); 244 assertEquals(UserProperties.CROSS_PROFILE_CONTENT_SHARING_NO_DELEGATION, 245 props.getCrossProfileContentSharingStrategy()); 246 assertEquals(UserProperties.PROFILE_API_VISIBILITY_VISIBLE, 247 props.getProfileApiVisibility()); 248 249 assertFalse(type.hasBadge()); 250 } 251 252 @Test testUserTypeBuilder_nameIsRequired()253 public void testUserTypeBuilder_nameIsRequired() { 254 assertThrows(IllegalArgumentException.class, 255 () -> new UserTypeDetails.Builder() 256 .setMaxAllowed(21) 257 .setBaseType(FLAG_FULL) 258 .createUserTypeDetails()); 259 } 260 261 @Test testUserTypeBuilder_baseTypeIsRequired()262 public void testUserTypeBuilder_baseTypeIsRequired() { 263 assertThrows(IllegalArgumentException.class, 264 () -> new UserTypeDetails.Builder() 265 .setName("name") 266 .createUserTypeDetails()); 267 } 268 269 @Test testUserTypeBuilder_colorIsRequiredIfBadged()270 public void testUserTypeBuilder_colorIsRequiredIfBadged() { 271 assertThrows(IllegalArgumentException.class, 272 () -> getMinimalBuilder() 273 .setIconBadge(1) 274 .setBadgeLabels(2) 275 .createUserTypeDetails()); 276 } 277 278 @Test testUserTypeBuilder_badgeLabelIsRequiredIfBadged()279 public void testUserTypeBuilder_badgeLabelIsRequiredIfBadged() { 280 assertThrows(IllegalArgumentException.class, 281 () -> getMinimalBuilder() 282 .setIconBadge(1) 283 .setBadgeColors(2) 284 .createUserTypeDetails()); 285 } 286 287 @Test testCheckUserTypeConsistency()288 public void testCheckUserTypeConsistency() { 289 assertTrue(UserManagerService.checkUserTypeConsistency(FLAG_GUEST)); 290 assertTrue(UserManagerService.checkUserTypeConsistency(FLAG_GUEST | FLAG_EPHEMERAL)); 291 assertTrue(UserManagerService.checkUserTypeConsistency(FLAG_PROFILE)); 292 293 assertFalse(UserManagerService.checkUserTypeConsistency(FLAG_DEMO | FLAG_RESTRICTED)); 294 assertFalse(UserManagerService.checkUserTypeConsistency(FLAG_PROFILE | FLAG_SYSTEM)); 295 assertFalse(UserManagerService.checkUserTypeConsistency(FLAG_PROFILE | FLAG_FULL)); 296 } 297 298 @Test testGetDefaultUserType()299 public void testGetDefaultUserType() { 300 // Simple example. 301 assertEquals(UserManager.USER_TYPE_FULL_RESTRICTED, 302 UserInfo.getDefaultUserType(FLAG_RESTRICTED)); 303 304 // Type plus a non-type flag. 305 assertEquals(UserManager.USER_TYPE_FULL_GUEST, 306 UserInfo.getDefaultUserType(FLAG_GUEST | FLAG_EPHEMERAL)); 307 308 // Two types, which is illegal. 309 assertThrows(IllegalArgumentException.class, 310 () -> UserInfo.getDefaultUserType(FLAG_MANAGED_PROFILE | FLAG_GUEST)); 311 312 // No type, which defaults to {@link UserManager#USER_TYPE_FULL_SECONDARY}. 313 assertEquals(UserManager.USER_TYPE_FULL_SECONDARY, 314 UserInfo.getDefaultUserType(FLAG_EPHEMERAL)); 315 } 316 317 /** Tests {@link UserTypeFactory#customizeBuilders} for a reasonable xml file. */ 318 @Test testUserTypeFactoryCustomize_profile()319 public void testUserTypeFactoryCustomize_profile() throws Exception { 320 final String userTypeAosp1 = "android.test.1"; // Profile user that is not customized 321 final String userTypeAosp2 = "android.test.2"; // Profile user that is customized 322 final String userTypeOem1 = "custom.test.1"; // Custom-defined profile 323 324 // Mock some "AOSP defaults". 325 final Bundle restrictions = makeRestrictionsBundle("no_config_vpn", "no_config_tethering"); 326 final UserProperties.Builder props = new UserProperties.Builder() 327 .setShowInLauncher(19) 328 .setStartWithParent(true) 329 .setUseParentsContacts(true) 330 .setCrossProfileIntentFilterAccessControl(10) 331 .setCrossProfileIntentResolutionStrategy(1) 332 .setMediaSharedWithParent(false) 333 .setCredentialShareableWithParent(true) 334 .setAuthAlwaysRequiredToDisableQuietMode(false) 335 .setAllowStoppingUserWithDelayedLocking(false) 336 .setShowInSettings(20) 337 .setInheritDevicePolicy(21) 338 .setShowInSharingSurfaces(22) 339 .setShowInQuietMode(24) 340 .setDeleteAppWithParent(true) 341 .setAlwaysVisible(false) 342 .setCrossProfileContentSharingStrategy(1) 343 .setProfileApiVisibility(36) 344 .setItemsRestrictedOnHomeScreen(false); 345 346 final ArrayMap<String, UserTypeDetails.Builder> builders = new ArrayMap<>(); 347 builders.put(userTypeAosp1, new UserTypeDetails.Builder() 348 .setName(userTypeAosp1) 349 .setBaseType(FLAG_PROFILE) 350 .setMaxAllowedPerParent(31) 351 .setDefaultRestrictions(restrictions) 352 .setDefaultUserProperties(props)); 353 builders.put(userTypeAosp2, new UserTypeDetails.Builder() 354 .setName(userTypeAosp1) 355 .setBaseType(FLAG_PROFILE) 356 .setMaxAllowedPerParent(32) 357 .setIconBadge(401) 358 .setBadgeColors(402, 403, 404) 359 .setDefaultRestrictions(restrictions) 360 .setDefaultUserProperties(props)); 361 362 final XmlResourceParser parser = mResources.getXml(R.xml.usertypes_test_profile); 363 UserTypeFactory.customizeBuilders(builders, parser); 364 365 // userTypeAosp1 should not be modified. 366 UserTypeDetails aospType = builders.get(userTypeAosp1).createUserTypeDetails(); 367 assertEquals(31, aospType.getMaxAllowedPerParent()); 368 assertEquals(Resources.ID_NULL, aospType.getIconBadge()); 369 assertTrue(UserRestrictionsUtils.areEqual(restrictions, aospType.getDefaultRestrictions())); 370 assertEquals(19, aospType.getDefaultUserPropertiesReference().getShowInLauncher()); 371 assertEquals(10, aospType.getDefaultUserPropertiesReference() 372 .getCrossProfileIntentFilterAccessControl()); 373 assertEquals(1, aospType.getDefaultUserPropertiesReference() 374 .getCrossProfileIntentResolutionStrategy()); 375 assertTrue(aospType.getDefaultUserPropertiesReference().getStartWithParent()); 376 assertTrue(aospType.getDefaultUserPropertiesReference() 377 .getUseParentsContacts()); 378 assertFalse(aospType.getDefaultUserPropertiesReference().isMediaSharedWithParent()); 379 assertTrue(aospType.getDefaultUserPropertiesReference() 380 .isCredentialShareableWithParent()); 381 assertFalse(aospType.getDefaultUserPropertiesReference() 382 .isAuthAlwaysRequiredToDisableQuietMode()); 383 assertFalse(aospType.getDefaultUserPropertiesReference() 384 .getAllowStoppingUserWithDelayedLocking()); 385 assertEquals(20, aospType.getDefaultUserPropertiesReference().getShowInSettings()); 386 assertEquals(21, aospType.getDefaultUserPropertiesReference() 387 .getInheritDevicePolicy()); 388 assertEquals(22, aospType.getDefaultUserPropertiesReference().getShowInSharingSurfaces()); 389 assertEquals(24, 390 aospType.getDefaultUserPropertiesReference().getShowInQuietMode()); 391 assertTrue(aospType.getDefaultUserPropertiesReference().getDeleteAppWithParent()); 392 assertFalse(aospType.getDefaultUserPropertiesReference().getAlwaysVisible()); 393 assertEquals(1, aospType.getDefaultUserPropertiesReference() 394 .getCrossProfileContentSharingStrategy()); 395 assertEquals(36, aospType.getDefaultUserPropertiesReference().getProfileApiVisibility()); 396 assertFalse(aospType.getDefaultUserPropertiesReference().areItemsRestrictedOnHomeScreen()); 397 398 // userTypeAosp2 should be modified. 399 aospType = builders.get(userTypeAosp2).createUserTypeDetails(); 400 assertEquals(12, aospType.getMaxAllowedPerParent()); 401 assertEquals(com.android.internal.R.drawable.ic_corp_icon_badge_case, 402 aospType.getIconBadge()); 403 assertEquals(Resources.ID_NULL, aospType.getBadgePlain()); // No resId for 'garbage' 404 assertEquals(com.android.internal.R.drawable.ic_corp_badge_no_background, 405 aospType.getBadgeNoBackground()); 406 assertEquals(com.android.internal.R.drawable.ic_test_badge_experiment, 407 aospType.getStatusBarIcon()); 408 assertEquals(com.android.internal.R.string.managed_profile_label_badge, 409 aospType.getBadgeLabel(0)); 410 assertEquals(com.android.internal.R.string.managed_profile_label_badge_2, 411 aospType.getBadgeLabel(1)); 412 assertEquals(com.android.internal.R.string.managed_profile_label_badge_2, 413 aospType.getBadgeLabel(2)); 414 assertEquals(com.android.internal.R.string.managed_profile_label_badge_2, 415 aospType.getBadgeLabel(3)); 416 assertEquals(com.android.internal.R.color.profile_badge_1, 417 aospType.getBadgeColor(0)); 418 assertEquals(com.android.internal.R.color.profile_badge_2, 419 aospType.getBadgeColor(1)); 420 assertEquals(com.android.internal.R.color.profile_badge_2, 421 aospType.getBadgeColor(2)); 422 assertEquals(com.android.internal.R.color.profile_badge_2, 423 aospType.getBadgeColor(3)); 424 assertTrue(UserRestrictionsUtils.areEqual( 425 makeRestrictionsBundle("no_remove_user", "no_bluetooth"), 426 aospType.getDefaultRestrictions())); 427 assertEquals(2020, aospType.getDefaultUserPropertiesReference().getShowInLauncher()); 428 assertEquals(20, aospType.getDefaultUserPropertiesReference() 429 .getCrossProfileIntentFilterAccessControl()); 430 assertEquals(0, aospType.getDefaultUserPropertiesReference() 431 .getCrossProfileIntentResolutionStrategy()); 432 assertFalse(aospType.getDefaultUserPropertiesReference().getStartWithParent()); 433 assertFalse(aospType.getDefaultUserPropertiesReference() 434 .getUseParentsContacts()); 435 assertTrue(aospType.getDefaultUserPropertiesReference().isMediaSharedWithParent()); 436 assertFalse(aospType.getDefaultUserPropertiesReference() 437 .isCredentialShareableWithParent()); 438 assertTrue(aospType.getDefaultUserPropertiesReference() 439 .isAuthAlwaysRequiredToDisableQuietMode()); 440 assertTrue(aospType.getDefaultUserPropertiesReference() 441 .getAllowStoppingUserWithDelayedLocking()); 442 assertEquals(23, aospType.getDefaultUserPropertiesReference().getShowInSettings()); 443 assertEquals(22, 444 aospType.getDefaultUserPropertiesReference().getShowInSharingSurfaces()); 445 assertEquals(24, 446 aospType.getDefaultUserPropertiesReference().getShowInQuietMode()); 447 assertEquals(450, aospType.getDefaultUserPropertiesReference() 448 .getInheritDevicePolicy()); 449 assertFalse(aospType.getDefaultUserPropertiesReference().getDeleteAppWithParent()); 450 assertTrue(aospType.getDefaultUserPropertiesReference().getAlwaysVisible()); 451 assertEquals(0, aospType.getDefaultUserPropertiesReference() 452 .getCrossProfileContentSharingStrategy()); 453 assertEquals(36, aospType.getDefaultUserPropertiesReference().getProfileApiVisibility()); 454 assertTrue(aospType.getDefaultUserPropertiesReference().areItemsRestrictedOnHomeScreen()); 455 456 // userTypeOem1 should be created. 457 assertNotNull(builders.get(userTypeOem1)); 458 UserTypeDetails customType = builders.get(userTypeOem1).createUserTypeDetails(); 459 assertEquals(14, customType.getMaxAllowedPerParent()); 460 assertTrue(customType.isProfileParentRequired()); 461 } 462 463 /** Tests {@link UserTypeFactory#customizeBuilders} for customizing a FULL user. */ 464 @Test testUserTypeFactoryCustomize_full()465 public void testUserTypeFactoryCustomize_full() throws Exception { 466 final String userTypeFull = "android.test.1"; 467 468 // Mock "AOSP default". 469 final Bundle restrictions = makeRestrictionsBundle("no_config_vpn", "no_config_tethering"); 470 final ArrayMap<String, UserTypeDetails.Builder> builders = new ArrayMap<>(); 471 builders.put(userTypeFull, new UserTypeDetails.Builder() 472 .setName(userTypeFull) 473 .setBaseType(FLAG_FULL) 474 .setEnabled(0) 475 .setDefaultRestrictions(restrictions)); 476 477 final XmlResourceParser parser = mResources.getXml(R.xml.usertypes_test_full); 478 UserTypeFactory.customizeBuilders(builders, parser); 479 480 UserTypeDetails details = builders.get(userTypeFull).createUserTypeDetails(); 481 assertEquals(UNLIMITED_NUMBER_OF_USERS, details.getMaxAllowedPerParent()); 482 assertFalse(details.isEnabled()); 483 assertEquals(17, details.getMaxAllowed()); 484 assertTrue(UserRestrictionsUtils.areEqual( 485 makeRestrictionsBundle("no_remove_user", "no_bluetooth"), 486 details.getDefaultRestrictions())); 487 assertEquals(Resources.ID_NULL, details.getBadgeColor(0)); 488 } 489 490 /** 491 * Tests {@link UserTypeFactory#customizeBuilders} when custom user type deletes the 492 * badge-colors and restrictions. 493 */ 494 @Test testUserTypeFactoryCustomize_eraseArray()495 public void testUserTypeFactoryCustomize_eraseArray() throws Exception { 496 final String typeName = "android.test"; 497 498 final ArrayMap<String, UserTypeDetails.Builder> builders = new ArrayMap<>(); 499 builders.put(typeName, new UserTypeDetails.Builder() 500 .setName(typeName) 501 .setBaseType(FLAG_PROFILE) 502 .setMaxAllowedPerParent(1) 503 .setBadgeColors(501, 502) 504 .setDefaultRestrictions(makeRestrictionsBundle("r1"))); 505 506 final XmlResourceParser parser = mResources.getXml(R.xml.usertypes_test_eraseArray); 507 UserTypeFactory.customizeBuilders(builders, parser); 508 509 UserTypeDetails typeDetails = builders.get(typeName).createUserTypeDetails(); 510 assertEquals(2, typeDetails.getMaxAllowedPerParent()); 511 assertEquals(Resources.ID_NULL, typeDetails.getBadgeColor(0)); 512 assertEquals(Resources.ID_NULL, typeDetails.getBadgeColor(1)); 513 assertTrue(typeDetails.getDefaultRestrictions().isEmpty()); 514 } 515 516 /** Tests {@link UserTypeFactory#customizeBuilders} when custom user type has illegal name. */ 517 @Test testUserTypeFactoryCustomize_illegalOemName()518 public void testUserTypeFactoryCustomize_illegalOemName() throws Exception { 519 final String userTypeAosp = "android.aosp.legal"; 520 final String userTypeOem = "android.oem.illegal.name"; // Custom-defined profile 521 522 final ArrayMap<String, UserTypeDetails.Builder> builders = new ArrayMap<>(); 523 builders.put(userTypeAosp, new UserTypeDetails.Builder() 524 .setName(userTypeAosp) 525 .setBaseType(FLAG_PROFILE) 526 .setMaxAllowedPerParent(21)); 527 528 final XmlResourceParser parser = mResources.getXml(R.xml.usertypes_test_illegalOemName); 529 530 // parser is illegal because non-AOSP user types cannot be prefixed with "android.". 531 assertThrows(IllegalArgumentException.class, 532 () -> UserTypeFactory.customizeBuilders(builders, parser)); 533 } 534 535 /** 536 * Tests {@link UserTypeFactory#customizeBuilders} when illegally customizing a non-profile as 537 * a profile. 538 */ 539 @Test testUserTypeFactoryCustomize_illegalUserBaseType()540 public void testUserTypeFactoryCustomize_illegalUserBaseType() throws Exception { 541 final String userTypeFull = "android.test"; 542 543 final ArrayMap<String, UserTypeDetails.Builder> builders = new ArrayMap<>(); 544 builders.put(userTypeFull, new UserTypeDetails.Builder() 545 .setName(userTypeFull) 546 .setBaseType(FLAG_FULL) 547 .setMaxAllowedPerParent(21)); 548 549 XmlResourceParser parser = mResources.getXml(R.xml.usertypes_test_illegalUserBaseType); 550 551 // parser is illegal because userTypeFull is FULL but the tag is for profile-type. 552 assertThrows(IllegalArgumentException.class, 553 () -> UserTypeFactory.customizeBuilders(builders, parser)); 554 } 555 556 @Test testUserTypeFactoryVersion_versionMissing()557 public void testUserTypeFactoryVersion_versionMissing() { 558 final XmlResourceParser parser = mResources.getXml(R.xml.usertypes_test_eraseArray); 559 assertEquals(0, UserTypeFactory.getUserTypeVersion(parser)); 560 } 561 562 @Test testUserTypeFactoryVersion_versionPresent()563 public void testUserTypeFactoryVersion_versionPresent() { 564 final XmlResourceParser parser = mResources.getXml(R.xml.usertypes_test_profile); 565 assertEquals(1234, UserTypeFactory.getUserTypeVersion(parser)); 566 } 567 568 @Test testUserTypeFactoryUpgrades_validUpgrades()569 public void testUserTypeFactoryUpgrades_validUpgrades() { 570 final ArrayMap<String, UserTypeDetails.Builder> builders = new ArrayMap<>(); 571 builders.put("name", getMinimalBuilder()); 572 573 final XmlResourceParser parser = mResources.getXml(R.xml.usertypes_test_profile); 574 List<UserTypeFactory.UserTypeUpgrade> upgrades = UserTypeFactory.parseUserUpgrades(builders, 575 parser); 576 577 assertFalse(upgrades.isEmpty()); 578 UserTypeFactory.UserTypeUpgrade upgrade = upgrades.get(0); 579 assertEquals("android.test.1", upgrade.getFromType()); 580 assertEquals("android.test.2", upgrade.getToType()); 581 assertEquals(1233, upgrade.getUpToVersion()); 582 } 583 584 @Test testUserTypeFactoryUpgrades_illegalBaseTypeUpgrade()585 public void testUserTypeFactoryUpgrades_illegalBaseTypeUpgrade() { 586 final String userTypeFull = "android.test.1"; 587 final ArrayMap<String, UserTypeDetails.Builder> builders = new ArrayMap<>(); 588 builders.put(userTypeFull, new UserTypeDetails.Builder() 589 .setName(userTypeFull) 590 .setBaseType(FLAG_FULL)); 591 592 final XmlResourceParser parser = mResources.getXml(R.xml.usertypes_test_full); 593 594 // parser is illegal because the "to" upgrade type is not a profile, but a full user 595 assertThrows(IllegalArgumentException.class, 596 () -> UserTypeFactory.parseUserUpgrades(builders, parser)); 597 } 598 599 /** Returns a minimal {@link UserTypeDetails.Builder} that can legitimately be created. */ getMinimalBuilder()600 private UserTypeDetails.Builder getMinimalBuilder() { 601 return new UserTypeDetails.Builder().setName("name").setBaseType(FLAG_FULL); 602 } 603 604 /** Creates a Bundle of the given String restrictions, each set to true. */ makeRestrictionsBundle(String .... restrictions)605 public static Bundle makeRestrictionsBundle(String ... restrictions) { 606 final Bundle bundle = new Bundle(); 607 for (String restriction : restrictions) { 608 bundle.putBoolean(restriction, true); 609 } 610 return bundle; 611 } 612 613 /** Creates a Bundle of the given settings keys and puts true for the value. */ makeSettingsBundle(String .... settings)614 private static Bundle makeSettingsBundle(String ... settings) { 615 final Bundle bundle = new Bundle(); 616 for (String setting : settings) { 617 bundle.putBoolean(setting, true); 618 } 619 return bundle; 620 } 621 } 622