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