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