1 /*
2  * Copyright (C) 2016 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_DISABLED;
21 import static android.content.pm.UserInfo.FLAG_EPHEMERAL;
22 import static android.content.pm.UserInfo.FLAG_FULL;
23 import static android.content.pm.UserInfo.FLAG_GUEST;
24 import static android.content.pm.UserInfo.FLAG_INITIALIZED;
25 import static android.content.pm.UserInfo.FLAG_MAIN;
26 import static android.content.pm.UserInfo.FLAG_MANAGED_PROFILE;
27 import static android.content.pm.UserInfo.FLAG_PROFILE;
28 import static android.content.pm.UserInfo.FLAG_RESTRICTED;
29 import static android.content.pm.UserInfo.FLAG_SYSTEM;
30 import static android.os.UserManager.USER_TYPE_FULL_DEMO;
31 import static android.os.UserManager.USER_TYPE_FULL_GUEST;
32 import static android.os.UserManager.USER_TYPE_FULL_RESTRICTED;
33 import static android.os.UserManager.USER_TYPE_FULL_SECONDARY;
34 import static android.os.UserManager.USER_TYPE_FULL_SYSTEM;
35 import static android.os.UserManager.USER_TYPE_PROFILE_MANAGED;
36 import static android.os.UserManager.USER_TYPE_SYSTEM_HEADLESS;
37 
38 import static org.junit.Assert.assertEquals;
39 import static org.junit.Assert.assertFalse;
40 import static org.junit.Assert.assertTrue;
41 
42 import android.annotation.UserIdInt;
43 import android.app.PropertyInvalidatedCache;
44 import android.content.pm.UserInfo;
45 import android.content.pm.UserInfo.UserInfoFlag;
46 import android.content.res.Resources;
47 import android.os.Looper;
48 import android.os.Parcel;
49 import android.os.UserHandle;
50 import android.os.UserManager;
51 import android.platform.test.annotations.Presubmit;
52 import android.text.TextUtils;
53 import android.util.Xml;
54 
55 import androidx.test.InstrumentationRegistry;
56 import androidx.test.filters.MediumTest;
57 import androidx.test.runner.AndroidJUnit4;
58 
59 import com.android.frameworks.servicestests.R;
60 import com.android.server.LocalServices;
61 import com.android.server.pm.UserManagerService.UserData;
62 
63 import org.junit.Before;
64 import org.junit.Test;
65 import org.junit.runner.RunWith;
66 import org.xmlpull.v1.XmlPullParser;
67 import org.xmlpull.v1.XmlSerializer;
68 
69 import java.io.ByteArrayInputStream;
70 import java.io.ByteArrayOutputStream;
71 import java.io.DataOutputStream;
72 import java.nio.charset.StandardCharsets;
73 import java.util.List;
74 
75 /**
76  * <p>Run with:<pre>
77  * runtest -c com.android.server.pm.UserManagerServiceUserInfoTest frameworks-services
78  * </pre>
79  */
80 @Presubmit
81 @RunWith(AndroidJUnit4.class)
82 @MediumTest
83 public class UserManagerServiceUserInfoTest {
84     private UserManagerService mUserManagerService;
85     private Resources mResources;
86 
87     @Before
setup()88     public void setup() {
89         // Currently UserManagerService cannot be instantiated twice inside a VM without a cleanup
90         // TODO: Remove once UMS supports proper dependency injection
91         if (Looper.myLooper() == null) {
92             Looper.prepare();
93         }
94         // Disable binder caches in this process.
95         PropertyInvalidatedCache.disableForTestMode();
96 
97         LocalServices.removeServiceForTest(UserManagerInternal.class);
98         mUserManagerService = new UserManagerService(InstrumentationRegistry.getContext());
99 
100         // The tests assume that the device has one user and its the system user.
101         List<UserInfo> users = mUserManagerService.getUsers(/* excludeDying */ false);
102         assertEquals("Multiple users so this test can't run.", 1, users.size());
103         assertEquals("Only user present isn't the system user.",
104                 UserHandle.USER_SYSTEM, users.get(0).id);
105 
106         mResources = InstrumentationRegistry.getTargetContext().getResources();
107     }
108 
109     @Test
testWriteReadUserInfo()110     public void testWriteReadUserInfo() throws Exception {
111         UserData data = new UserData();
112         data.info = createUser();
113 
114         ByteArrayOutputStream baos = new ByteArrayOutputStream();
115         DataOutputStream out = new DataOutputStream(baos);
116         mUserManagerService.writeUserLP(data, out);
117         byte[] bytes = baos.toByteArray();
118 
119         UserData read = mUserManagerService.readUserLP(
120                 data.info.id, new ByteArrayInputStream(bytes), 0);
121 
122         assertUserInfoEquals(data.info, read.info, /* parcelCopy= */ false);
123     }
124 
125     /** Tests that device policy restrictions are written/read properly. */
126     @Test
testWriteReadDevicePolicyUserRestrictions()127     public void testWriteReadDevicePolicyUserRestrictions() throws Exception {
128         final String globalRestriction = UserManager.DISALLOW_FACTORY_RESET;
129         final String localRestriction = UserManager.DISALLOW_CONFIG_DATE_TIME;
130 
131         UserData data = new UserData();
132         data.info = createUser(100, FLAG_FULL, "A type");
133 
134         mUserManagerService.putUserInfo(data.info);
135 
136         // Set a global and user restriction so they get written out to the user file.
137         setUserRestrictions(data.info.id, globalRestriction, localRestriction, true);
138 
139         ByteArrayOutputStream baos = new ByteArrayOutputStream();
140         DataOutputStream out = new DataOutputStream(baos);
141         mUserManagerService.writeUserLP(data, out);
142         byte[] bytes = baos.toByteArray();
143 
144         // Clear the restrictions to see if they are properly read in from the user file.
145         setUserRestrictions(data.info.id, globalRestriction, localRestriction, false);
146 
147         final int userVersion = 10;
148         //read the secondary and SYSTEM user file to fetch local/global device policy restrictions.
149         mUserManagerService.readUserLP(data.info.id, new ByteArrayInputStream(bytes),
150                 userVersion);
151 
152         assertTrue(mUserManagerService.hasUserRestrictionOnAnyUser(globalRestriction));
153         assertTrue(mUserManagerService.hasUserRestrictionOnAnyUser(localRestriction));
154     }
155 
156     /** Sets a global and local restriction and verifies they were set properly **/
setUserRestrictions(int id, String global, String local, boolean enabled)157     private void setUserRestrictions(int id, String global, String local, boolean enabled) {
158         mUserManagerService.setUserRestrictionInner(UserHandle.USER_ALL, global, enabled);
159         assertEquals(mUserManagerService.hasUserRestrictionOnAnyUser(global), enabled);
160 
161         mUserManagerService.setUserRestrictionInner(id, local, enabled);
162         assertEquals(mUserManagerService.hasUserRestrictionOnAnyUser(local), enabled);
163     }
164 
165     @Test
testParcelUnparcelUserInfo()166     public void testParcelUnparcelUserInfo() throws Exception {
167         UserInfo info = createUser();
168 
169         Parcel out = Parcel.obtain();
170         info.writeToParcel(out, 0);
171         byte[] data = out.marshall();
172         out.recycle();
173 
174         Parcel in = Parcel.obtain();
175         in.unmarshall(data, 0, data.length);
176         in.setDataPosition(0);
177         UserInfo read = UserInfo.CREATOR.createFromParcel(in);
178         in.recycle();
179 
180         assertUserInfoEquals(info, read, /* parcelCopy= */ true);
181     }
182 
183     @Test
testCopyConstructor()184     public void testCopyConstructor() throws Exception {
185         UserInfo info = createUser();
186 
187         UserInfo copy = new UserInfo(info);
188 
189         assertUserInfoEquals(info, copy, /* parcelCopy= */ false);
190     }
191 
192     @Test
testGetUserName()193     public void testGetUserName() throws Exception {
194         assertFalse("System user name shouldn't be set",
195                 mUserManagerService.isUserNameSet(UserHandle.USER_SYSTEM));
196         UserInfo userInfo = mUserManagerService.getUserInfo(UserHandle.USER_SYSTEM);
197         assertFalse("A system provided name should be returned for primary user",
198                 TextUtils.isEmpty(userInfo.name));
199 
200         userInfo = createUser();
201         userInfo.partial = false;
202         final int TEST_ID = 100;
203         userInfo.id = TEST_ID;
204         mUserManagerService.putUserInfo(userInfo);
205         assertTrue("Test user name must be set", mUserManagerService.isUserNameSet(TEST_ID));
206         assertEquals("A Name", mUserManagerService.getUserInfo(TEST_ID).name);
207     }
208 
209     /** Test UMS.isUserOfType(). */
210     @Test
testIsUserOfType()211     public void testIsUserOfType() throws Exception {
212         assertTrue("System user was of invalid type",
213                 mUserManagerService.isUserOfType(UserHandle.USER_SYSTEM, USER_TYPE_SYSTEM_HEADLESS)
214                 || mUserManagerService.isUserOfType(UserHandle.USER_SYSTEM, USER_TYPE_FULL_SYSTEM));
215 
216         final int testId = 100;
217         final String typeName = "A type";
218         UserInfo userInfo = createUser(testId, 0, typeName);
219         mUserManagerService.putUserInfo(userInfo);
220         assertTrue(mUserManagerService.isUserOfType(testId, typeName));
221     }
222 
223     /** Test UserInfo.supportsSwitchTo() for partial user. */
224     @Test
testSupportSwitchTo_partial()225     public void testSupportSwitchTo_partial() throws Exception {
226         UserInfo userInfo = createUser(100, FLAG_FULL, null);
227         userInfo.partial = true;
228         assertFalse("Switching to a partial user should be disabled",
229                 userInfo.supportsSwitchTo());
230     }
231 
232     /** Test UserInfo.supportsSwitchTo() for disabled user. */
233     @Test
testSupportSwitchTo_disabled()234     public void testSupportSwitchTo_disabled() throws Exception {
235         UserInfo userInfo = createUser(100, FLAG_DISABLED, null);
236         assertFalse("Switching to a DISABLED user should be disabled",
237                 userInfo.supportsSwitchTo());
238     }
239 
240     /** Test UserInfo.supportsSwitchTo() for precreated users. */
241     @Test
testSupportSwitchTo_preCreated()242     public void testSupportSwitchTo_preCreated() throws Exception {
243         UserInfo userInfo = createUser(100, FLAG_FULL, null);
244         userInfo.preCreated = true;
245         assertFalse("Switching to a precreated user should be disabled",
246                 userInfo.supportsSwitchTo());
247 
248         userInfo.preCreated = false;
249         assertTrue("Switching to a full, real user should be allowed", userInfo.supportsSwitchTo());
250     }
251 
252     /** Test UserInfo.supportsSwitchTo() for profiles. */
253     @Test
testSupportSwitchTo_profile()254     public void testSupportSwitchTo_profile() throws Exception {
255         UserInfo userInfo = createUser(100, FLAG_PROFILE, null);
256         assertFalse("Switching to a profiles should be disabled", userInfo.supportsSwitchTo());
257     }
258 
259     /** Test UserInfo.canHaveProfile for main user */
260     @Test
testCanHaveProfile()261     public void testCanHaveProfile() throws Exception {
262         UserInfo userInfo = createUser(100, FLAG_MAIN, null);
263         assertTrue("Main users can have profile", userInfo.canHaveProfile());
264     }
265 
266     /** Tests upgradeIfNecessaryLP (but without locking) for upgrading from version 8 to 9+. */
267     @Test
testUpgradeIfNecessaryLP_9()268     public void testUpgradeIfNecessaryLP_9() {
269         final int versionToTest = 9;
270         // do not trigger a user type upgrade
271         final int userTypeVersion = UserTypeFactory.getUserTypeVersion();
272 
273         mUserManagerService.putUserInfo(createUser(100, FLAG_MANAGED_PROFILE, null));
274         mUserManagerService.putUserInfo(createUser(101,
275                 FLAG_GUEST | FLAG_EPHEMERAL | FLAG_FULL, null));
276         mUserManagerService.putUserInfo(createUser(102, FLAG_RESTRICTED | FLAG_FULL, null));
277         mUserManagerService.putUserInfo(createUser(103, FLAG_FULL, null));
278         mUserManagerService.putUserInfo(createUser(104, FLAG_SYSTEM, null));
279         mUserManagerService.putUserInfo(createUser(105, FLAG_SYSTEM | FLAG_FULL, null));
280         mUserManagerService.putUserInfo(createUser(106, FLAG_DEMO | FLAG_FULL, null));
281 
282         mUserManagerService.upgradeIfNecessaryLP(versionToTest - 1, userTypeVersion);
283 
284         assertTrue(mUserManagerService.isUserOfType(100, USER_TYPE_PROFILE_MANAGED));
285         assertTrue((mUserManagerService.getUserInfo(100).flags & FLAG_PROFILE) != 0);
286 
287         assertTrue(mUserManagerService.isUserOfType(101, USER_TYPE_FULL_GUEST));
288 
289         assertTrue(mUserManagerService.isUserOfType(102, USER_TYPE_FULL_RESTRICTED));
290         assertTrue((mUserManagerService.getUserInfo(102).flags & FLAG_PROFILE) == 0);
291 
292         assertTrue(mUserManagerService.isUserOfType(103, USER_TYPE_FULL_SECONDARY));
293         assertTrue((mUserManagerService.getUserInfo(103).flags & FLAG_PROFILE) == 0);
294 
295         assertTrue(mUserManagerService.isUserOfType(104, USER_TYPE_SYSTEM_HEADLESS));
296 
297         assertTrue(mUserManagerService.isUserOfType(105, USER_TYPE_FULL_SYSTEM));
298 
299         assertTrue(mUserManagerService.isUserOfType(106, USER_TYPE_FULL_DEMO));
300     }
301 
302     /** Tests readUserLP upgrading from version 9 to 10+. */
303     @Test
testUserRestrictionsUpgradeFromV9()304     public void testUserRestrictionsUpgradeFromV9() throws Exception {
305         final String[] localRestrictions = new String[] {
306             UserManager.DISALLOW_CAMERA,
307             UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,
308         };
309 
310         final int userId = 100;
311         UserData data = new UserData();
312         data.info = createUser(userId, FLAG_FULL, "A type");
313 
314         mUserManagerService.putUserInfo(data.info);
315 
316         for (String restriction : localRestrictions) {
317             assertFalse(mUserManagerService.hasBaseUserRestriction(restriction, userId));
318             assertFalse(mUserManagerService.hasUserRestriction(restriction, userId));
319         }
320 
321         // Convert the xml resource to the system storage xml format.
322         ByteArrayOutputStream baos = new ByteArrayOutputStream();
323         DataOutputStream os = new DataOutputStream(baos);
324         XmlPullParser in = mResources.getXml(R.xml.user_100_v9);
325         XmlSerializer out = Xml.newBinarySerializer();
326         out.setOutput(os, StandardCharsets.UTF_8.name());
327         Xml.copy(in, out);
328         byte[] userBytes = baos.toByteArray();
329         baos.reset();
330 
331         final int userVersion = 9;
332         mUserManagerService.readUserLP(data.info.id, new ByteArrayInputStream(userBytes),
333                 userVersion);
334 
335         for (String restriction : localRestrictions) {
336             assertFalse(mUserManagerService.hasBaseUserRestriction(restriction, userId));
337             assertTrue(mUserManagerService.hasUserRestriction(restriction, userId));
338         }
339     }
340 
341     /** Creates a UserInfo with the given flags and userType. */
createUser(@serIdInt int userId, @UserInfoFlag int flags, String userType)342     private UserInfo createUser(@UserIdInt int userId, @UserInfoFlag int flags, String userType) {
343         return new UserInfo(userId, "A Name", "A path", flags, userType);
344     }
345 
createUser()346     private UserInfo createUser() {
347         UserInfo user = new UserInfo(/*id*/ 21, "A Name", "A path", /*flags*/ 0x0ff0ff, "A type");
348         user.serialNumber = 5;
349         user.creationTime = 4L << 32;
350         user.lastLoggedInTime = 5L << 32;
351         user.lastLoggedInFingerprint = "afingerprint";
352         user.profileGroupId = 45;
353         user.restrictedProfileParentId = 4;
354         user.profileBadge = 2;
355         user.partial = true;
356         user.guestToRemove = true;
357         user.preCreated = true;
358         user.convertedFromPreCreated = true;
359         return user;
360     }
361 
assertUserInfoEquals(UserInfo one, UserInfo two, boolean parcelCopy)362     private void assertUserInfoEquals(UserInfo one, UserInfo two, boolean parcelCopy) {
363         assertEquals("Id not preserved", one.id, two.id);
364         assertEquals("Name not preserved", one.name, two.name);
365         assertEquals("Icon path not preserved", one.iconPath, two.iconPath);
366         assertEquals("Flags not preserved", one.flags, two.flags);
367         assertEquals("UserType not preserved", one.userType, two.userType);
368         assertEquals("profile group not preserved", one.profileGroupId,
369                 two.profileGroupId);
370         assertEquals("restricted profile parent not preserved", one.restrictedProfileParentId,
371                 two.restrictedProfileParentId);
372         assertEquals("profile badge not preserved", one.profileBadge, two.profileBadge);
373         assertEquals("partial not preserved", one.partial, two.partial);
374         assertEquals("guestToRemove not preserved", one.guestToRemove, two.guestToRemove);
375         assertEquals("preCreated not preserved", one.preCreated, two.preCreated);
376         if (parcelCopy) {
377             assertFalse("convertedFromPreCreated should not be set", two.convertedFromPreCreated);
378         } else {
379             assertEquals("convertedFromPreCreated not preserved", one.convertedFromPreCreated,
380                     two.convertedFromPreCreated);
381         }
382     }
383 
384     /** Tests upgrading profile types */
385     @Test
testUpgradeProfileType_updateTypeAndFlags()386     public void testUpgradeProfileType_updateTypeAndFlags() {
387         final int userId = 42;
388         final String newUserTypeName = "new.user.type";
389         final String oldUserTypeName = USER_TYPE_PROFILE_MANAGED;
390 
391         UserTypeDetails.Builder oldUserTypeBuilder = new UserTypeDetails.Builder()
392                 .setName(oldUserTypeName)
393                 .setBaseType(FLAG_PROFILE)
394                 .setDefaultUserInfoPropertyFlags(FLAG_MANAGED_PROFILE)
395                 .setMaxAllowedPerParent(32)
396                 .setIconBadge(401)
397                 .setBadgeColors(402, 403, 404)
398                 .setBadgeLabels(23, 24, 25);
399         UserTypeDetails oldUserType = oldUserTypeBuilder.createUserTypeDetails();
400 
401         UserInfo userInfo = createUser(userId,
402                 oldUserType.getDefaultUserInfoFlags() | FLAG_INITIALIZED, oldUserTypeName);
403         mUserManagerService.putUserInfo(userInfo);
404 
405         UserTypeDetails.Builder newUserTypeBuilder = new UserTypeDetails.Builder()
406                 .setName(newUserTypeName)
407                 .setBaseType(FLAG_PROFILE)
408                 .setMaxAllowedPerParent(32)
409                 .setIconBadge(401)
410                 .setBadgeColors(402, 403, 404)
411                 .setBadgeLabels(23, 24, 25);
412         UserTypeDetails newUserType = newUserTypeBuilder.createUserTypeDetails();
413 
414         mUserManagerService.upgradeProfileToTypeLU(userInfo, newUserType);
415 
416         assertTrue(mUserManagerService.isUserOfType(userId, newUserTypeName));
417         assertTrue((mUserManagerService.getUserInfo(userId).flags & FLAG_PROFILE) != 0);
418         assertTrue((mUserManagerService.getUserInfo(userId).flags & FLAG_MANAGED_PROFILE) == 0);
419         assertTrue((mUserManagerService.getUserInfo(userId).flags & FLAG_INITIALIZED) != 0);
420     }
421 
422     @Test
testUpgradeProfileType_updateRestrictions()423     public void testUpgradeProfileType_updateRestrictions() {
424         final int userId = 42;
425         final String newUserTypeName = "new.user.type";
426         final String oldUserTypeName = USER_TYPE_PROFILE_MANAGED;
427 
428         UserTypeDetails.Builder oldUserTypeBuilder = new UserTypeDetails.Builder()
429                 .setName(oldUserTypeName)
430                 .setBaseType(FLAG_PROFILE)
431                 .setDefaultUserInfoPropertyFlags(FLAG_MANAGED_PROFILE)
432                 .setMaxAllowedPerParent(32)
433                 .setIconBadge(401)
434                 .setBadgeColors(402, 403, 404)
435                 .setBadgeLabels(23, 24, 25);
436         UserTypeDetails oldUserType = oldUserTypeBuilder.createUserTypeDetails();
437 
438         UserInfo userInfo = createUser(userId, oldUserType.getDefaultUserInfoFlags(),
439                 oldUserTypeName);
440         mUserManagerService.putUserInfo(userInfo);
441         mUserManagerService.setUserRestriction(UserManager.DISALLOW_CAMERA, true, userId);
442         mUserManagerService.setUserRestriction(UserManager.DISALLOW_PRINTING, true, userId);
443 
444         UserTypeDetails.Builder newUserTypeBuilder = new UserTypeDetails.Builder()
445                 .setName(newUserTypeName)
446                 .setBaseType(FLAG_PROFILE)
447                 .setMaxAllowedPerParent(32)
448                 .setIconBadge(401)
449                 .setBadgeColors(402, 403, 404)
450                 .setBadgeLabels(23, 24, 25)
451                 .setDefaultRestrictions(
452                         UserManagerServiceUserTypeTest.makeRestrictionsBundle(
453                                 UserManager.DISALLOW_WALLPAPER));
454         UserTypeDetails newUserType = newUserTypeBuilder.createUserTypeDetails();
455 
456         mUserManagerService.upgradeProfileToTypeLU(userInfo, newUserType);
457 
458         assertTrue(mUserManagerService.getUserRestrictions(userId).getBoolean(
459                 UserManager.DISALLOW_PRINTING));
460         assertTrue(mUserManagerService.getUserRestrictions(userId).getBoolean(
461                 UserManager.DISALLOW_CAMERA));
462         assertTrue(mUserManagerService.getUserRestrictions(userId).getBoolean(
463                 UserManager.DISALLOW_WALLPAPER));
464     }
465 }
466