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