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