1 /* 2 * Copyright (C) 2011 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 android.content.pm; 18 19 import android.annotation.FlaggedApi; 20 import android.annotation.IntDef; 21 import android.annotation.NonNull; 22 import android.annotation.Nullable; 23 import android.annotation.TestApi; 24 import android.annotation.UserIdInt; 25 import android.compat.annotation.UnsupportedAppUsage; 26 import android.content.res.Resources; 27 import android.os.Parcel; 28 import android.os.Parcelable; 29 import android.os.UserHandle; 30 import android.os.UserManager; 31 import android.util.DebugUtils; 32 33 import com.android.internal.annotations.VisibleForTesting; 34 35 import java.lang.annotation.Retention; 36 import java.lang.annotation.RetentionPolicy; 37 38 /** 39 * Per-user information. 40 * 41 * <p>There are 3 base properties of users: {@link #FLAG_SYSTEM}, {@link #FLAG_FULL}, and 42 * {@link #FLAG_PROFILE}. Every user must have one of the following combination of these 43 * flags: 44 * <ul> 45 * <li>FLAG_SYSTEM (user {@link UserHandle#USER_SYSTEM} on a headless-user-0 device)</li> 46 * <li>FLAG_SYSTEM and FLAG_FULL (user {@link UserHandle#USER_SYSTEM} on a regular device)</li> 47 * <li>FLAG_FULL (non-profile secondary user)</li> 48 * <li>FLAG_PROFILE (profile users)</li> 49 * </ul> 50 * Users can have also have additional flags (such as FLAG_GUEST) as appropriate. 51 * 52 * @hide 53 */ 54 @TestApi 55 @android.ravenwood.annotation.RavenwoodKeepWholeClass 56 public class UserInfo implements Parcelable { 57 58 /** 59 * *************************** NOTE *************************** 60 * These flag values CAN NOT CHANGE because they are written 61 * directly to storage. 62 */ 63 64 /** 65 * Primary user. In practice, this is just synonymous with {@link #FLAG_SYSTEM}. 66 * 67 * <p>On many devices, this will also be the first human user. 68 * However, in {@link UserManager#isHeadlessSystemUserMode() headless system user mode}, this 69 * should be regarded as unsupported since the system user may not be a human. 70 * 71 * @deprecated For checking for user 0, use {@link #FLAG_SYSTEM}. 72 * For checking for the designated "main human user", use {@link #FLAG_MAIN}. 73 */ 74 @UnsupportedAppUsage 75 @Deprecated 76 public static final int FLAG_PRIMARY = 0x00000001; 77 78 /** 79 * User with administrative privileges. Such a user can create and 80 * delete users. 81 */ 82 public static final int FLAG_ADMIN = 0x00000002; 83 84 /** 85 * Indicates a guest user that may be transient. 86 * @deprecated Use {@link UserManager#USER_TYPE_FULL_GUEST} instead. 87 */ 88 @Deprecated 89 public static final int FLAG_GUEST = 0x00000004; 90 91 /** 92 * Indicates the user has restrictions in privileges, in addition to those for normal users. 93 * Exact meaning TBD. For instance, maybe they can't install apps or administer WiFi access pts. 94 * @deprecated Use {@link UserManager#USER_TYPE_FULL_RESTRICTED} instead. 95 */ 96 @Deprecated 97 public static final int FLAG_RESTRICTED = 0x00000008; 98 99 /** 100 * Indicates that this user has gone through its first-time initialization. 101 */ 102 public static final int FLAG_INITIALIZED = 0x00000010; 103 104 /** 105 * Indicates that this user is a profile of another user, for example holding a users 106 * corporate data. 107 * @deprecated Use {@link UserManager#USER_TYPE_PROFILE_MANAGED} instead. 108 */ 109 @Deprecated 110 public static final int FLAG_MANAGED_PROFILE = 0x00000020; 111 112 /** 113 * Indicates that this user is disabled. 114 * 115 * <p> This is currently used to indicate that a Managed Profile, when created via 116 * DevicePolicyManager, has not yet been provisioned; once the DPC provisions it, a DPM call 117 * will manually set it to enabled. 118 * 119 * <p>Users that are slated for deletion are also generally set to disabled. 120 * 121 * <p>Note: If an ephemeral user is disabled, it shouldn't be later re-enabled. Ephemeral users 122 * are disabled as their removal is in progress to indicate that they shouldn't be re-entered. 123 */ 124 public static final int FLAG_DISABLED = 0x00000040; 125 126 public static final int FLAG_QUIET_MODE = 0x00000080; 127 128 /** 129 * Indicates that this user is ephemeral. I.e. the user will be removed after leaving 130 * the foreground. 131 */ 132 public static final int FLAG_EPHEMERAL = 0x00000100; 133 134 /** 135 * User is for demo purposes only and can be removed at any time. 136 * @deprecated Use {@link UserManager#USER_TYPE_FULL_DEMO} instead. 137 */ 138 @Deprecated 139 public static final int FLAG_DEMO = 0x00000200; 140 141 /** 142 * Indicates that this user is a non-profile human user. 143 * 144 * <p>When creating a new (non-system) user, this flag will always be forced true unless the 145 * user is a {@link #FLAG_PROFILE}. If user {@link UserHandle#USER_SYSTEM} is also a 146 * human user, it must also be flagged as FULL. 147 */ 148 public static final int FLAG_FULL = 0x00000400; 149 150 /** 151 * Indicates that this user is {@link UserHandle#USER_SYSTEM}. Not applicable to created users. 152 */ 153 public static final int FLAG_SYSTEM = 0x00000800; 154 155 /** 156 * Indicates that this user is a profile human user, such as a managed profile. 157 * Mutually exclusive with {@link #FLAG_FULL}. 158 */ 159 public static final int FLAG_PROFILE = 0x00001000; 160 161 /** 162 * Indicates that this user is created in ephemeral mode via 163 * {@link IUserManager} create user. 164 * 165 * When a user is created with {@link #FLAG_EPHEMERAL}, {@link #FLAG_EPHEMERAL_ON_CREATE} 166 * is set internally within the user manager. 167 * 168 * When {@link #FLAG_EPHEMERAL_ON_CREATE} is set {@link IUserManager.setUserEphemeral} 169 * has no effect because a user that was created ephemeral can never be made non-ephemeral. 170 * 171 * {@link #FLAG_EPHEMERAL_ON_CREATE} should NOT be set by client's of user manager 172 * 173 * @hide 174 */ 175 public static final int FLAG_EPHEMERAL_ON_CREATE = 0x00002000; 176 177 /** 178 * Indicates that this user is the designated main user on the device. This user may have access 179 * to certain features which are limited to at most one user. 180 * 181 * <p>Currently, this will be the first user to go through setup on the device, but in future 182 * releases this status may be transferable or may even not be given to any users. 183 * 184 * <p>This is not necessarily the system user. For example, it will not be the system user on 185 * devices for which {@link UserManager#isHeadlessSystemUserMode()} returns true. 186 * 187 * <p>NB: Features should ideally not limit functionality to the main user. Ideally, they 188 * should either work for all users or for all admin users. If a feature should only work for 189 * select users, its determination of which user should be done intelligently or be 190 * customizable. Not all devices support a main user, and the idea of singling out one user as 191 * special is contrary to overall multiuser goals. 192 */ 193 public static final int FLAG_MAIN = 0x00004000; 194 195 /** 196 * Indicates that this user was created for the purposes of testing. 197 * 198 * <p>These users are subject to removal during tests and should not be used on actual devices 199 * used by humans. 200 * 201 * @hide 202 */ 203 public static final int FLAG_FOR_TESTING = 0x00008000; 204 205 /** 206 * @hide 207 */ 208 @IntDef(flag = true, prefix = "FLAG_", value = { 209 FLAG_PRIMARY, 210 FLAG_ADMIN, 211 FLAG_GUEST, 212 FLAG_RESTRICTED, 213 FLAG_INITIALIZED, 214 FLAG_MANAGED_PROFILE, 215 FLAG_DISABLED, 216 FLAG_QUIET_MODE, 217 FLAG_EPHEMERAL, 218 FLAG_DEMO, 219 FLAG_FULL, 220 FLAG_SYSTEM, 221 FLAG_PROFILE, 222 FLAG_EPHEMERAL_ON_CREATE, 223 FLAG_MAIN, 224 FLAG_FOR_TESTING 225 }) 226 @Retention(RetentionPolicy.SOURCE) 227 public @interface UserInfoFlag { 228 } 229 230 public static final int NO_PROFILE_GROUP_ID = UserHandle.USER_NULL; 231 232 @UnsupportedAppUsage 233 public @UserIdInt int id; 234 @UnsupportedAppUsage 235 public int serialNumber; 236 @UnsupportedAppUsage 237 public @Nullable String name; 238 @UnsupportedAppUsage 239 public String iconPath; 240 @UnsupportedAppUsage 241 public @UserInfoFlag int flags; 242 @UnsupportedAppUsage 243 public long creationTime; 244 @UnsupportedAppUsage 245 public long lastLoggedInTime; 246 public String lastLoggedInFingerprint; 247 248 /** 249 * Type of user, such as {@link UserManager#USER_TYPE_PROFILE_MANAGED}, corresponding to 250 * {@link com.android.server.pm.UserTypeDetails#getName()}. 251 */ 252 public String userType; 253 254 /** 255 * If this user is a parent user, it would be its own user id. 256 * If this user is a child user, it would be its parent user id. 257 * Otherwise, it would be {@link #NO_PROFILE_GROUP_ID}. 258 */ 259 @UnsupportedAppUsage 260 public int profileGroupId; 261 public int restrictedProfileParentId; 262 263 /** 264 * Index for distinguishing different profiles with the same parent and user type for the 265 * purpose of badging. 266 * It is used for determining which badge color/label to use (if applicable) from 267 * the options available for a particular user type. 268 */ 269 public int profileBadge; 270 271 /** User is only partially created. */ 272 @UnsupportedAppUsage 273 public boolean partial; 274 @UnsupportedAppUsage 275 public boolean guestToRemove; 276 277 /** 278 * This is used to optimize the creation of a user, i.e. OEMs might choose to pre-create a 279 * number of users at the first boot, so the actual creation later is faster. 280 * 281 * <p>A {@code preCreated} user is not a real user yet, so it should not show up on regular 282 * user operations (other than user creation per se). 283 * 284 * <p>Once the pre-created is used to create a "real" user later on, {@code preCreated} is set 285 * to {@code false}. 286 * 287 * <p><b>NOTE: Pre-created users are deprecated. This field remains to be able to recognize 288 * pre-created users in older versions, but will eventually be removed. 289 */ 290 public boolean preCreated; 291 292 /** 293 * When {@code true}, it indicates this user was created by converting a {@link #preCreated} 294 * user. 295 * 296 * <p><b>NOTE: </b>only used for debugging purposes, it's not set when marshalled to a parcel. 297 * 298 * <p><b>NOTE: Pre-created users are deprecated. This field remains to be able to recognize 299 * pre-created users in older versions, but will eventually ve removed. 300 */ 301 public boolean convertedFromPreCreated; 302 303 /** 304 * Creates a UserInfo whose user type is determined automatically by the flags according to 305 * {@link #getDefaultUserType}; can only be used for user types handled there. 306 */ 307 @UnsupportedAppUsage UserInfo(int id, String name, int flags)308 public UserInfo(int id, String name, int flags) { 309 this(id, name, null, flags); 310 } 311 312 /** 313 * Creates a UserInfo whose user type is determined automatically by the flags according to 314 * {@link #getDefaultUserType}; can only be used for user types handled there. 315 */ 316 @UnsupportedAppUsage UserInfo(int id, String name, String iconPath, int flags)317 public UserInfo(int id, String name, String iconPath, int flags) { 318 this(id, name, iconPath, flags, getDefaultUserType(flags)); 319 } 320 UserInfo(int id, String name, String iconPath, int flags, String userType)321 public UserInfo(int id, String name, String iconPath, int flags, String userType) { 322 this.id = id; 323 this.name = name; 324 this.flags = flags; 325 this.userType = userType; 326 this.iconPath = iconPath; 327 this.profileGroupId = NO_PROFILE_GROUP_ID; 328 this.restrictedProfileParentId = NO_PROFILE_GROUP_ID; 329 } 330 331 /** 332 * Get the user type (such as {@link UserManager#USER_TYPE_PROFILE_MANAGED}) that corresponds to 333 * the given {@link UserInfoFlag}s. 334 335 * <p>The userInfoFlag can contain GUEST, RESTRICTED, MANAGED_PROFILE, DEMO, or else be 336 * interpreted as a regular "secondary" user. It cannot contain more than one of these. 337 * It can contain other UserInfoFlag properties (like EPHEMERAL), which will be ignored here. 338 * 339 * @throws IllegalArgumentException if userInfoFlag is more than one type of user or if it 340 * is a SYSTEM user. 341 * 342 * @hide 343 */ getDefaultUserType(@serInfoFlag int userInfoFlag)344 public static @NonNull String getDefaultUserType(@UserInfoFlag int userInfoFlag) { 345 if ((userInfoFlag & FLAG_SYSTEM) != 0) { 346 throw new IllegalArgumentException("Cannot getDefaultUserType for flags " 347 + Integer.toHexString(userInfoFlag) + " because it corresponds to a " 348 + "SYSTEM user type."); 349 } 350 final int supportedFlagTypes = 351 FLAG_GUEST | FLAG_RESTRICTED | FLAG_MANAGED_PROFILE | FLAG_DEMO; 352 switch (userInfoFlag & supportedFlagTypes) { 353 case 0 : return UserManager.USER_TYPE_FULL_SECONDARY; 354 case FLAG_GUEST: return UserManager.USER_TYPE_FULL_GUEST; 355 case FLAG_RESTRICTED: return UserManager.USER_TYPE_FULL_RESTRICTED; 356 case FLAG_MANAGED_PROFILE: return UserManager.USER_TYPE_PROFILE_MANAGED; 357 case FLAG_DEMO: return UserManager.USER_TYPE_FULL_DEMO; 358 default: 359 throw new IllegalArgumentException("Cannot getDefaultUserType for flags " 360 + Integer.toHexString(userInfoFlag) + " because it doesn't correspond to a " 361 + "valid user type."); 362 } 363 } 364 365 /** 366 * @deprecated For checking for user 0, compare {@link #id} to {@link UserHandle#USER_SYSTEM}. 367 * For checking for the designated "main human user", use {@link #isMain()}. 368 */ 369 @UnsupportedAppUsage 370 @Deprecated isPrimary()371 public boolean isPrimary() { 372 return (flags & FLAG_PRIMARY) == FLAG_PRIMARY; 373 } 374 375 @UnsupportedAppUsage isAdmin()376 public boolean isAdmin() { 377 return (flags & FLAG_ADMIN) == FLAG_ADMIN; 378 } 379 380 @UnsupportedAppUsage isGuest()381 public boolean isGuest() { 382 return UserManager.isUserTypeGuest(userType); 383 } 384 385 @UnsupportedAppUsage isRestricted()386 public boolean isRestricted() { 387 return UserManager.isUserTypeRestricted(userType); 388 } 389 isProfile()390 public boolean isProfile() { 391 return (flags & FLAG_PROFILE) != 0; 392 } 393 394 @UnsupportedAppUsage isManagedProfile()395 public boolean isManagedProfile() { 396 return UserManager.isUserTypeManagedProfile(userType); 397 } 398 isCloneProfile()399 public boolean isCloneProfile() { 400 return UserManager.isUserTypeCloneProfile(userType); 401 } 402 403 @FlaggedApi(android.multiuser.Flags.FLAG_SUPPORT_COMMUNAL_PROFILE) isCommunalProfile()404 public boolean isCommunalProfile() { 405 return UserManager.isUserTypeCommunalProfile(userType); 406 } 407 408 @FlaggedApi(android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE) isPrivateProfile()409 public boolean isPrivateProfile() { 410 return UserManager.isUserTypePrivateProfile(userType); 411 } 412 413 @FlaggedApi(android.multiuser.Flags.FLAG_ALLOW_SUPERVISING_PROFILE) isSupervisingProfile()414 public boolean isSupervisingProfile() { 415 return UserManager.isUserTypeSupervisingProfile(userType); 416 } 417 418 /** See {@link #FLAG_DISABLED}*/ 419 @UnsupportedAppUsage isEnabled()420 public boolean isEnabled() { 421 return (flags & FLAG_DISABLED) != FLAG_DISABLED; 422 } 423 isQuietModeEnabled()424 public boolean isQuietModeEnabled() { 425 return (flags & FLAG_QUIET_MODE) == FLAG_QUIET_MODE; 426 } 427 isEphemeral()428 public boolean isEphemeral() { 429 return (flags & FLAG_EPHEMERAL) == FLAG_EPHEMERAL; 430 } 431 432 /** @hide */ 433 @TestApi isForTesting()434 public boolean isForTesting() { 435 return (flags & FLAG_FOR_TESTING) == FLAG_FOR_TESTING; 436 } 437 isInitialized()438 public boolean isInitialized() { 439 return (flags & FLAG_INITIALIZED) == FLAG_INITIALIZED; 440 } 441 isDemo()442 public boolean isDemo() { 443 return UserManager.isUserTypeDemo(userType) || (flags & FLAG_DEMO) != 0; 444 } 445 isFull()446 public boolean isFull() { 447 return (flags & FLAG_FULL) == FLAG_FULL; 448 } 449 450 /** 451 * @see #FLAG_MAIN 452 */ isMain()453 public boolean isMain() { 454 return (flags & FLAG_MAIN) == FLAG_MAIN; 455 } 456 457 /** 458 * @return true if this user can be switched to. 459 **/ 460 @android.ravenwood.annotation.RavenwoodThrow supportsSwitchTo()461 public boolean supportsSwitchTo() { 462 if (partial || !isEnabled()) { 463 // Don't support switching to disabled or partial users, which includes users with 464 // removal in progress. 465 return false; 466 } 467 if (preCreated) { 468 // Don't support switching to pre-created users until they become "real" users. 469 return false; 470 } 471 return isFull() || canSwitchToHeadlessSystemUser(); 472 } 473 474 /** 475 * @return true if user is of type {@link UserManager#USER_TYPE_SYSTEM_HEADLESS} and 476 * {@link com.android.internal.R.bool.config_canSwitchToHeadlessSystemUser} is true. 477 */ 478 @android.ravenwood.annotation.RavenwoodThrow canSwitchToHeadlessSystemUser()479 private boolean canSwitchToHeadlessSystemUser() { 480 return UserManager.USER_TYPE_SYSTEM_HEADLESS.equals(userType) && Resources.getSystem() 481 .getBoolean(com.android.internal.R.bool.config_canSwitchToHeadlessSystemUser); 482 } 483 484 /** 485 * @return true if this user can be switched to by end user through UI. 486 * @deprecated Use {@link UserInfo#supportsSwitchTo} instead. 487 */ 488 @Deprecated 489 @android.ravenwood.annotation.RavenwoodThrow supportsSwitchToByUser()490 public boolean supportsSwitchToByUser() { 491 return supportsSwitchTo(); 492 } 493 494 // TODO(b/142482943): Make this logic more specific and customizable. (canHaveProfile(userType)) 495 /* @hide */ canHaveProfile()496 public boolean canHaveProfile() { 497 if (!isFull() || isProfile() || isGuest() || isRestricted() || isDemo()) { 498 return false; 499 } 500 // NOTE: profiles used to be restricted just to the system user (and later to the main 501 // user), but from the framework point of view there is no need for such restriction, hence 502 // it's lifted 503 // TODO(b/374832167): check value of config_supportProfilesOnNonMainUser 504 return isMain() || android.multiuser.Flags.profilesForAll(); 505 } 506 507 // TODO(b/142482943): Get rid of this (after removing it from all tests) if feasible. 508 /** 509 * @deprecated This is dangerous since it doesn't set the mandatory fields. Use a different 510 * constructor instead. 511 */ 512 @Deprecated 513 @VisibleForTesting UserInfo()514 public UserInfo() { 515 } 516 UserInfo(UserInfo orig)517 public UserInfo(UserInfo orig) { 518 name = orig.name; 519 iconPath = orig.iconPath; 520 id = orig.id; 521 flags = orig.flags; 522 userType = orig.userType; 523 serialNumber = orig.serialNumber; 524 creationTime = orig.creationTime; 525 lastLoggedInTime = orig.lastLoggedInTime; 526 lastLoggedInFingerprint = orig.lastLoggedInFingerprint; 527 partial = orig.partial; 528 preCreated = orig.preCreated; 529 convertedFromPreCreated = orig.convertedFromPreCreated; 530 profileGroupId = orig.profileGroupId; 531 restrictedProfileParentId = orig.restrictedProfileParentId; 532 guestToRemove = orig.guestToRemove; 533 profileBadge = orig.profileBadge; 534 } 535 536 @UnsupportedAppUsage getUserHandle()537 public UserHandle getUserHandle() { 538 return UserHandle.of(id); 539 } 540 541 // TODO(b/142482943): Probably include mUserType here, which means updating TestDevice, etc. 542 @Override toString()543 public String toString() { 544 // NOTE: do not change this string, it's used by 'pm list users', which in turn is 545 // used and parsed by TestDevice. In other words, if you change it, you'd have to change 546 // TestDevice, TestDeviceTest, and possibly others.... 547 return "UserInfo{" + id + ":" + name + ":" + Integer.toHexString(flags) + "}"; 548 } 549 550 /** @hide */ toFullString()551 public String toFullString() { 552 return "UserInfo[id=" + id 553 + ", name=" + name 554 + ", type=" + userType 555 + ", flags=" + flagsToString(flags) 556 + (preCreated ? " (pre-created)" : "") 557 + (convertedFromPreCreated ? " (converted)" : "") 558 + (partial ? " (partial)" : "") 559 + "]"; 560 } 561 562 /** @hide */ flagsToString(int flags)563 public static String flagsToString(int flags) { 564 return DebugUtils.flagsToString(UserInfo.class, "FLAG_", flags); 565 } 566 567 @Override describeContents()568 public int describeContents() { 569 return 0; 570 } 571 572 @Override writeToParcel(Parcel dest, int parcelableFlags)573 public void writeToParcel(Parcel dest, int parcelableFlags) { 574 dest.writeInt(id); 575 dest.writeString8(name); 576 dest.writeString8(iconPath); 577 dest.writeInt(flags); 578 dest.writeString8(userType); 579 dest.writeInt(serialNumber); 580 dest.writeLong(creationTime); 581 dest.writeLong(lastLoggedInTime); 582 dest.writeString8(lastLoggedInFingerprint); 583 dest.writeBoolean(partial); 584 dest.writeBoolean(preCreated); 585 dest.writeInt(profileGroupId); 586 dest.writeBoolean(guestToRemove); 587 dest.writeInt(restrictedProfileParentId); 588 dest.writeInt(profileBadge); 589 } 590 591 @UnsupportedAppUsage 592 public static final @android.annotation.NonNull Parcelable.Creator<UserInfo> CREATOR 593 = new Parcelable.Creator<UserInfo>() { 594 public UserInfo createFromParcel(Parcel source) { 595 return new UserInfo(source); 596 } 597 public UserInfo[] newArray(int size) { 598 return new UserInfo[size]; 599 } 600 }; 601 UserInfo(Parcel source)602 private UserInfo(Parcel source) { 603 id = source.readInt(); 604 name = source.readString8(); 605 iconPath = source.readString8(); 606 flags = source.readInt(); 607 userType = source.readString8(); 608 serialNumber = source.readInt(); 609 creationTime = source.readLong(); 610 lastLoggedInTime = source.readLong(); 611 lastLoggedInFingerprint = source.readString8(); 612 partial = source.readBoolean(); 613 preCreated = source.readBoolean(); 614 profileGroupId = source.readInt(); 615 guestToRemove = source.readBoolean(); 616 restrictedProfileParentId = source.readInt(); 617 profileBadge = source.readInt(); 618 } 619 } 620