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