• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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