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 public static final int FLAG_MAIN = 0x00004000; 188 189 /** 190 * Indicates that this user was created for the purposes of testing. 191 * 192 * <p>These users are subject to removal during tests and should not be used on actual devices 193 * used by humans. 194 * 195 * @hide 196 */ 197 public static final int FLAG_FOR_TESTING = 0x00008000; 198 199 /** 200 * @hide 201 */ 202 @IntDef(flag = true, prefix = "FLAG_", value = { 203 FLAG_PRIMARY, 204 FLAG_ADMIN, 205 FLAG_GUEST, 206 FLAG_RESTRICTED, 207 FLAG_INITIALIZED, 208 FLAG_MANAGED_PROFILE, 209 FLAG_DISABLED, 210 FLAG_QUIET_MODE, 211 FLAG_EPHEMERAL, 212 FLAG_DEMO, 213 FLAG_FULL, 214 FLAG_SYSTEM, 215 FLAG_PROFILE, 216 FLAG_EPHEMERAL_ON_CREATE, 217 FLAG_MAIN, 218 FLAG_FOR_TESTING 219 }) 220 @Retention(RetentionPolicy.SOURCE) 221 public @interface UserInfoFlag { 222 } 223 224 public static final int NO_PROFILE_GROUP_ID = UserHandle.USER_NULL; 225 226 @UnsupportedAppUsage 227 public @UserIdInt int id; 228 @UnsupportedAppUsage 229 public int serialNumber; 230 @UnsupportedAppUsage 231 public @Nullable String name; 232 @UnsupportedAppUsage 233 public String iconPath; 234 @UnsupportedAppUsage 235 public @UserInfoFlag int flags; 236 @UnsupportedAppUsage 237 public long creationTime; 238 @UnsupportedAppUsage 239 public long lastLoggedInTime; 240 public String lastLoggedInFingerprint; 241 242 /** 243 * Type of user, such as {@link UserManager#USER_TYPE_PROFILE_MANAGED}, corresponding to 244 * {@link com.android.server.pm.UserTypeDetails#getName()}. 245 */ 246 public String userType; 247 248 /** 249 * If this user is a parent user, it would be its own user id. 250 * If this user is a child user, it would be its parent user id. 251 * Otherwise, it would be {@link #NO_PROFILE_GROUP_ID}. 252 */ 253 @UnsupportedAppUsage 254 public int profileGroupId; 255 public int restrictedProfileParentId; 256 257 /** 258 * Index for distinguishing different profiles with the same parent and user type for the 259 * purpose of badging. 260 * It is used for determining which badge color/label to use (if applicable) from 261 * the options available for a particular user type. 262 */ 263 public int profileBadge; 264 265 /** User is only partially created. */ 266 @UnsupportedAppUsage 267 public boolean partial; 268 @UnsupportedAppUsage 269 public boolean guestToRemove; 270 271 /** 272 * This is used to optimize the creation of a user, i.e. OEMs might choose to pre-create a 273 * number of users at the first boot, so the actual creation later is faster. 274 * 275 * <p>A {@code preCreated} user is not a real user yet, so it should not show up on regular 276 * user operations (other than user creation per se). 277 * 278 * <p>Once the pre-created is used to create a "real" user later on, {@code preCreated} is set 279 * to {@code false}. 280 * 281 * <p><b>NOTE: Pre-created users are deprecated. This field remains to be able to recognize 282 * pre-created users in older versions, but will eventually be removed. 283 */ 284 public boolean preCreated; 285 286 /** 287 * When {@code true}, it indicates this user was created by converting a {@link #preCreated} 288 * user. 289 * 290 * <p><b>NOTE: </b>only used for debugging purposes, it's not set when marshalled to a parcel. 291 * 292 * <p><b>NOTE: Pre-created users are deprecated. This field remains to be able to recognize 293 * pre-created users in older versions, but will eventually ve removed. 294 */ 295 public boolean convertedFromPreCreated; 296 297 /** 298 * Creates a UserInfo whose user type is determined automatically by the flags according to 299 * {@link #getDefaultUserType}; can only be used for user types handled there. 300 */ 301 @UnsupportedAppUsage UserInfo(int id, String name, int flags)302 public UserInfo(int id, String name, int flags) { 303 this(id, name, null, flags); 304 } 305 306 /** 307 * Creates a UserInfo whose user type is determined automatically by the flags according to 308 * {@link #getDefaultUserType}; can only be used for user types handled there. 309 */ 310 @UnsupportedAppUsage UserInfo(int id, String name, String iconPath, int flags)311 public UserInfo(int id, String name, String iconPath, int flags) { 312 this(id, name, iconPath, flags, getDefaultUserType(flags)); 313 } 314 UserInfo(int id, String name, String iconPath, int flags, String userType)315 public UserInfo(int id, String name, String iconPath, int flags, String userType) { 316 this.id = id; 317 this.name = name; 318 this.flags = flags; 319 this.userType = userType; 320 this.iconPath = iconPath; 321 this.profileGroupId = NO_PROFILE_GROUP_ID; 322 this.restrictedProfileParentId = NO_PROFILE_GROUP_ID; 323 } 324 325 /** 326 * Get the user type (such as {@link UserManager#USER_TYPE_PROFILE_MANAGED}) that corresponds to 327 * the given {@link UserInfoFlag}s. 328 329 * <p>The userInfoFlag can contain GUEST, RESTRICTED, MANAGED_PROFILE, DEMO, or else be 330 * interpreted as a regular "secondary" user. It cannot contain more than one of these. 331 * It can contain other UserInfoFlag properties (like EPHEMERAL), which will be ignored here. 332 * 333 * @throws IllegalArgumentException if userInfoFlag is more than one type of user or if it 334 * is a SYSTEM user. 335 * 336 * @hide 337 */ getDefaultUserType(@serInfoFlag int userInfoFlag)338 public static @NonNull String getDefaultUserType(@UserInfoFlag int userInfoFlag) { 339 if ((userInfoFlag & FLAG_SYSTEM) != 0) { 340 throw new IllegalArgumentException("Cannot getDefaultUserType for flags " 341 + Integer.toHexString(userInfoFlag) + " because it corresponds to a " 342 + "SYSTEM user type."); 343 } 344 final int supportedFlagTypes = 345 FLAG_GUEST | FLAG_RESTRICTED | FLAG_MANAGED_PROFILE | FLAG_DEMO; 346 switch (userInfoFlag & supportedFlagTypes) { 347 case 0 : return UserManager.USER_TYPE_FULL_SECONDARY; 348 case FLAG_GUEST: return UserManager.USER_TYPE_FULL_GUEST; 349 case FLAG_RESTRICTED: return UserManager.USER_TYPE_FULL_RESTRICTED; 350 case FLAG_MANAGED_PROFILE: return UserManager.USER_TYPE_PROFILE_MANAGED; 351 case FLAG_DEMO: return UserManager.USER_TYPE_FULL_DEMO; 352 default: 353 throw new IllegalArgumentException("Cannot getDefaultUserType for flags " 354 + Integer.toHexString(userInfoFlag) + " because it doesn't correspond to a " 355 + "valid user type."); 356 } 357 } 358 359 /** 360 * @deprecated For checking for user 0, compare {@link #id} to {@link UserHandle#USER_SYSTEM}. 361 * For checking for the designated "main human user", use {@link #isMain()}. 362 */ 363 @UnsupportedAppUsage 364 @Deprecated isPrimary()365 public boolean isPrimary() { 366 return (flags & FLAG_PRIMARY) == FLAG_PRIMARY; 367 } 368 369 @UnsupportedAppUsage isAdmin()370 public boolean isAdmin() { 371 return (flags & FLAG_ADMIN) == FLAG_ADMIN; 372 } 373 374 @UnsupportedAppUsage isGuest()375 public boolean isGuest() { 376 return UserManager.isUserTypeGuest(userType); 377 } 378 379 @UnsupportedAppUsage isRestricted()380 public boolean isRestricted() { 381 return UserManager.isUserTypeRestricted(userType); 382 } 383 isProfile()384 public boolean isProfile() { 385 return (flags & FLAG_PROFILE) != 0; 386 } 387 388 @UnsupportedAppUsage isManagedProfile()389 public boolean isManagedProfile() { 390 return UserManager.isUserTypeManagedProfile(userType); 391 } 392 isCloneProfile()393 public boolean isCloneProfile() { 394 return UserManager.isUserTypeCloneProfile(userType); 395 } 396 397 @FlaggedApi(android.multiuser.Flags.FLAG_SUPPORT_COMMUNAL_PROFILE) isCommunalProfile()398 public boolean isCommunalProfile() { 399 return UserManager.isUserTypeCommunalProfile(userType); 400 } 401 402 @FlaggedApi(android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE) isPrivateProfile()403 public boolean isPrivateProfile() { 404 return UserManager.isUserTypePrivateProfile(userType); 405 } 406 407 /** See {@link #FLAG_DISABLED}*/ 408 @UnsupportedAppUsage isEnabled()409 public boolean isEnabled() { 410 return (flags & FLAG_DISABLED) != FLAG_DISABLED; 411 } 412 isQuietModeEnabled()413 public boolean isQuietModeEnabled() { 414 return (flags & FLAG_QUIET_MODE) == FLAG_QUIET_MODE; 415 } 416 isEphemeral()417 public boolean isEphemeral() { 418 return (flags & FLAG_EPHEMERAL) == FLAG_EPHEMERAL; 419 } 420 421 /** @hide */ 422 @TestApi isForTesting()423 public boolean isForTesting() { 424 return (flags & FLAG_FOR_TESTING) == FLAG_FOR_TESTING; 425 } 426 isInitialized()427 public boolean isInitialized() { 428 return (flags & FLAG_INITIALIZED) == FLAG_INITIALIZED; 429 } 430 isDemo()431 public boolean isDemo() { 432 return UserManager.isUserTypeDemo(userType) || (flags & FLAG_DEMO) != 0; 433 } 434 isFull()435 public boolean isFull() { 436 return (flags & FLAG_FULL) == FLAG_FULL; 437 } 438 439 /** 440 * @see #FLAG_MAIN 441 */ isMain()442 public boolean isMain() { 443 return (flags & FLAG_MAIN) == FLAG_MAIN; 444 } 445 446 /** 447 * @return true if this user can be switched to. 448 **/ 449 @android.ravenwood.annotation.RavenwoodThrow supportsSwitchTo()450 public boolean supportsSwitchTo() { 451 if (partial || !isEnabled()) { 452 // Don't support switching to disabled or partial users, which includes users with 453 // removal in progress. 454 return false; 455 } 456 if (preCreated) { 457 // Don't support switching to pre-created users until they become "real" users. 458 return false; 459 } 460 return isFull() || canSwitchToHeadlessSystemUser(); 461 } 462 463 /** 464 * @return true if user is of type {@link UserManager#USER_TYPE_SYSTEM_HEADLESS} and 465 * {@link com.android.internal.R.bool.config_canSwitchToHeadlessSystemUser} is true. 466 */ 467 @android.ravenwood.annotation.RavenwoodThrow canSwitchToHeadlessSystemUser()468 private boolean canSwitchToHeadlessSystemUser() { 469 return UserManager.USER_TYPE_SYSTEM_HEADLESS.equals(userType) && Resources.getSystem() 470 .getBoolean(com.android.internal.R.bool.config_canSwitchToHeadlessSystemUser); 471 } 472 473 /** 474 * @return true if this user can be switched to by end user through UI. 475 * @deprecated Use {@link UserInfo#supportsSwitchTo} instead. 476 */ 477 @Deprecated 478 @android.ravenwood.annotation.RavenwoodThrow supportsSwitchToByUser()479 public boolean supportsSwitchToByUser() { 480 return supportsSwitchTo(); 481 } 482 483 // TODO(b/142482943): Make this logic more specific and customizable. (canHaveProfile(userType)) 484 /* @hide */ canHaveProfile()485 public boolean canHaveProfile() { 486 if (isProfile() || isGuest() || isRestricted()) { 487 return false; 488 } 489 return isMain(); 490 } 491 492 // TODO(b/142482943): Get rid of this (after removing it from all tests) if feasible. 493 /** 494 * @deprecated This is dangerous since it doesn't set the mandatory fields. Use a different 495 * constructor instead. 496 */ 497 @Deprecated 498 @VisibleForTesting UserInfo()499 public UserInfo() { 500 } 501 UserInfo(UserInfo orig)502 public UserInfo(UserInfo orig) { 503 name = orig.name; 504 iconPath = orig.iconPath; 505 id = orig.id; 506 flags = orig.flags; 507 userType = orig.userType; 508 serialNumber = orig.serialNumber; 509 creationTime = orig.creationTime; 510 lastLoggedInTime = orig.lastLoggedInTime; 511 lastLoggedInFingerprint = orig.lastLoggedInFingerprint; 512 partial = orig.partial; 513 preCreated = orig.preCreated; 514 convertedFromPreCreated = orig.convertedFromPreCreated; 515 profileGroupId = orig.profileGroupId; 516 restrictedProfileParentId = orig.restrictedProfileParentId; 517 guestToRemove = orig.guestToRemove; 518 profileBadge = orig.profileBadge; 519 } 520 521 @UnsupportedAppUsage getUserHandle()522 public UserHandle getUserHandle() { 523 return UserHandle.of(id); 524 } 525 526 // TODO(b/142482943): Probably include mUserType here, which means updating TestDevice, etc. 527 @Override toString()528 public String toString() { 529 // NOTE: do not change this string, it's used by 'pm list users', which in turn is 530 // used and parsed by TestDevice. In other words, if you change it, you'd have to change 531 // TestDevice, TestDeviceTest, and possibly others.... 532 return "UserInfo{" + id + ":" + name + ":" + Integer.toHexString(flags) + "}"; 533 } 534 535 /** @hide */ toFullString()536 public String toFullString() { 537 return "UserInfo[id=" + id 538 + ", name=" + name 539 + ", type=" + userType 540 + ", flags=" + flagsToString(flags) 541 + (preCreated ? " (pre-created)" : "") 542 + (convertedFromPreCreated ? " (converted)" : "") 543 + (partial ? " (partial)" : "") 544 + "]"; 545 } 546 547 /** @hide */ flagsToString(int flags)548 public static String flagsToString(int flags) { 549 return DebugUtils.flagsToString(UserInfo.class, "FLAG_", flags); 550 } 551 552 @Override describeContents()553 public int describeContents() { 554 return 0; 555 } 556 557 @Override writeToParcel(Parcel dest, int parcelableFlags)558 public void writeToParcel(Parcel dest, int parcelableFlags) { 559 dest.writeInt(id); 560 dest.writeString8(name); 561 dest.writeString8(iconPath); 562 dest.writeInt(flags); 563 dest.writeString8(userType); 564 dest.writeInt(serialNumber); 565 dest.writeLong(creationTime); 566 dest.writeLong(lastLoggedInTime); 567 dest.writeString8(lastLoggedInFingerprint); 568 dest.writeBoolean(partial); 569 dest.writeBoolean(preCreated); 570 dest.writeInt(profileGroupId); 571 dest.writeBoolean(guestToRemove); 572 dest.writeInt(restrictedProfileParentId); 573 dest.writeInt(profileBadge); 574 } 575 576 @UnsupportedAppUsage 577 public static final @android.annotation.NonNull Parcelable.Creator<UserInfo> CREATOR 578 = new Parcelable.Creator<UserInfo>() { 579 public UserInfo createFromParcel(Parcel source) { 580 return new UserInfo(source); 581 } 582 public UserInfo[] newArray(int size) { 583 return new UserInfo[size]; 584 } 585 }; 586 UserInfo(Parcel source)587 private UserInfo(Parcel source) { 588 id = source.readInt(); 589 name = source.readString8(); 590 iconPath = source.readString8(); 591 flags = source.readInt(); 592 userType = source.readString8(); 593 serialNumber = source.readInt(); 594 creationTime = source.readLong(); 595 lastLoggedInTime = source.readLong(); 596 lastLoggedInFingerprint = source.readString8(); 597 partial = source.readBoolean(); 598 preCreated = source.readBoolean(); 599 profileGroupId = source.readInt(); 600 guestToRemove = source.readBoolean(); 601 restrictedProfileParentId = source.readInt(); 602 profileBadge = source.readInt(); 603 } 604 } 605