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.compat.annotation.UnsupportedAppUsage; 21 import android.os.Parcel; 22 import android.os.Parcelable; 23 import android.os.UserHandle; 24 import android.os.UserManager; 25 import android.util.DebugUtils; 26 27 import java.lang.annotation.Retention; 28 import java.lang.annotation.RetentionPolicy; 29 30 /** 31 * Per-user information. 32 * @hide 33 */ 34 public class UserInfo implements Parcelable { 35 36 /** 16 bits for user type */ 37 public static final int FLAG_MASK_USER_TYPE = 0x0000FFFF; 38 39 /** 40 * *************************** NOTE *************************** 41 * These flag values CAN NOT CHANGE because they are written 42 * directly to storage. 43 */ 44 45 /** 46 * Primary user. Only one user can have this flag set. It identifies the first human user 47 * on a device. 48 */ 49 @UnsupportedAppUsage 50 public static final int FLAG_PRIMARY = 0x00000001; 51 52 /** 53 * User with administrative privileges. Such a user can create and 54 * delete users. 55 */ 56 public static final int FLAG_ADMIN = 0x00000002; 57 58 /** 59 * Indicates a guest user that may be transient. 60 */ 61 public static final int FLAG_GUEST = 0x00000004; 62 63 /** 64 * Indicates the user has restrictions in privileges, in addition to those for normal users. 65 * Exact meaning TBD. For instance, maybe they can't install apps or administer WiFi access pts. 66 */ 67 public static final int FLAG_RESTRICTED = 0x00000008; 68 69 /** 70 * Indicates that this user has gone through its first-time initialization. 71 */ 72 public static final int FLAG_INITIALIZED = 0x00000010; 73 74 /** 75 * Indicates that this user is a profile of another user, for example holding a users 76 * corporate data. 77 */ 78 public static final int FLAG_MANAGED_PROFILE = 0x00000020; 79 80 /** 81 * Indicates that this user is disabled. 82 * 83 * <p>Note: If an ephemeral user is disabled, it shouldn't be later re-enabled. Ephemeral users 84 * are disabled as their removal is in progress to indicate that they shouldn't be re-entered. 85 */ 86 public static final int FLAG_DISABLED = 0x00000040; 87 88 public static final int FLAG_QUIET_MODE = 0x00000080; 89 90 /** 91 * Indicates that this user is ephemeral. I.e. the user will be removed after leaving 92 * the foreground. 93 */ 94 public static final int FLAG_EPHEMERAL = 0x00000100; 95 96 /** 97 * User is for demo purposes only and can be removed at any time. 98 */ 99 public static final int FLAG_DEMO = 0x00000200; 100 101 /** 102 * @hide 103 */ 104 @IntDef(flag = true, prefix = "FLAG_", value = { 105 FLAG_PRIMARY, 106 FLAG_ADMIN, 107 FLAG_GUEST, 108 FLAG_RESTRICTED, 109 FLAG_INITIALIZED, 110 FLAG_MANAGED_PROFILE, 111 FLAG_DISABLED, 112 FLAG_QUIET_MODE, 113 FLAG_EPHEMERAL, 114 FLAG_DEMO 115 }) 116 @Retention(RetentionPolicy.SOURCE) 117 public @interface UserInfoFlag { 118 } 119 120 public static final int NO_PROFILE_GROUP_ID = UserHandle.USER_NULL; 121 122 @UnsupportedAppUsage 123 public int id; 124 @UnsupportedAppUsage 125 public int serialNumber; 126 @UnsupportedAppUsage 127 public String name; 128 @UnsupportedAppUsage 129 public String iconPath; 130 @UnsupportedAppUsage 131 public int flags; 132 @UnsupportedAppUsage 133 public long creationTime; 134 @UnsupportedAppUsage 135 public long lastLoggedInTime; 136 public String lastLoggedInFingerprint; 137 /** 138 * If this user is a parent user, it would be its own user id. 139 * If this user is a child user, it would be its parent user id. 140 * Otherwise, it would be {@link #NO_PROFILE_GROUP_ID}. 141 */ 142 @UnsupportedAppUsage 143 public int profileGroupId; 144 public int restrictedProfileParentId; 145 /** Which profile badge color/label to use. */ 146 public int profileBadge; 147 148 /** User is only partially created. */ 149 @UnsupportedAppUsage 150 public boolean partial; 151 @UnsupportedAppUsage 152 public boolean guestToRemove; 153 154 /** 155 * This is used to optimize the creation of an user, i.e. OEMs might choose to pre-create a 156 * number of users at the first boot, so the actual creation later is faster. 157 * 158 * <p>A {@code preCreated} user is not a real user yet, so it should not show up on regular 159 * user operations (other than user creation per se). 160 * 161 * <p>Once the pre-created is used to create a "real" user later on, {@code preCreate} is set to 162 * {@code false}. 163 */ 164 public boolean preCreated; 165 166 @UnsupportedAppUsage UserInfo(int id, String name, int flags)167 public UserInfo(int id, String name, int flags) { 168 this(id, name, null, flags); 169 } 170 171 @UnsupportedAppUsage UserInfo(int id, String name, String iconPath, int flags)172 public UserInfo(int id, String name, String iconPath, int flags) { 173 this.id = id; 174 this.name = name; 175 this.flags = flags; 176 this.iconPath = iconPath; 177 this.profileGroupId = NO_PROFILE_GROUP_ID; 178 this.restrictedProfileParentId = NO_PROFILE_GROUP_ID; 179 } 180 181 @UnsupportedAppUsage isPrimary()182 public boolean isPrimary() { 183 return (flags & FLAG_PRIMARY) == FLAG_PRIMARY; 184 } 185 186 @UnsupportedAppUsage isAdmin()187 public boolean isAdmin() { 188 return (flags & FLAG_ADMIN) == FLAG_ADMIN; 189 } 190 191 @UnsupportedAppUsage isGuest()192 public boolean isGuest() { 193 return isGuest(flags); 194 } 195 196 /** 197 * Checks if the flag denotes a guest user. 198 */ isGuest(@serInfoFlag int flags)199 public static boolean isGuest(@UserInfoFlag int flags) { 200 return (flags & FLAG_GUEST) == FLAG_GUEST; 201 } 202 203 @UnsupportedAppUsage isRestricted()204 public boolean isRestricted() { 205 return (flags & FLAG_RESTRICTED) == FLAG_RESTRICTED; 206 } 207 208 @UnsupportedAppUsage isManagedProfile()209 public boolean isManagedProfile() { 210 return isManagedProfile(flags); 211 } 212 213 /** 214 * Checks if the flag denotes a managed profile. 215 */ isManagedProfile(@serInfoFlag int flags)216 public static boolean isManagedProfile(@UserInfoFlag int flags) { 217 return (flags & FLAG_MANAGED_PROFILE) == FLAG_MANAGED_PROFILE; 218 } 219 220 @UnsupportedAppUsage isEnabled()221 public boolean isEnabled() { 222 return (flags & FLAG_DISABLED) != FLAG_DISABLED; 223 } 224 isQuietModeEnabled()225 public boolean isQuietModeEnabled() { 226 return (flags & FLAG_QUIET_MODE) == FLAG_QUIET_MODE; 227 } 228 isEphemeral()229 public boolean isEphemeral() { 230 return (flags & FLAG_EPHEMERAL) == FLAG_EPHEMERAL; 231 } 232 isInitialized()233 public boolean isInitialized() { 234 return (flags & FLAG_INITIALIZED) == FLAG_INITIALIZED; 235 } 236 isDemo()237 public boolean isDemo() { 238 return (flags & FLAG_DEMO) == FLAG_DEMO; 239 } 240 241 /** 242 * Returns true if the user is a split system user. 243 * <p>If {@link UserManager#isSplitSystemUser split system user mode} is not enabled, 244 * the method always returns false. 245 */ isSystemOnly()246 public boolean isSystemOnly() { 247 return isSystemOnly(id); 248 } 249 250 /** 251 * Returns true if the given user is a split system user. 252 * <p>If {@link UserManager#isSplitSystemUser split system user mode} is not enabled, 253 * the method always returns false. 254 */ isSystemOnly(int userId)255 public static boolean isSystemOnly(int userId) { 256 return userId == UserHandle.USER_SYSTEM && UserManager.isSplitSystemUser(); 257 } 258 259 /** 260 * @return true if this user can be switched to. 261 **/ supportsSwitchTo()262 public boolean supportsSwitchTo() { 263 if (isEphemeral() && !isEnabled()) { 264 // Don't support switching to an ephemeral user with removal in progress. 265 return false; 266 } 267 return !isManagedProfile(); 268 } 269 270 /** 271 * @return true if this user can be switched to by end user through UI. 272 */ supportsSwitchToByUser()273 public boolean supportsSwitchToByUser() { 274 // Hide the system user when it does not represent a human user. 275 boolean hideSystemUser = UserManager.isSplitSystemUser(); 276 return (!hideSystemUser || id != UserHandle.USER_SYSTEM) && supportsSwitchTo(); 277 } 278 279 /* @hide */ canHaveProfile()280 public boolean canHaveProfile() { 281 if (isManagedProfile() || isGuest() || isRestricted()) { 282 return false; 283 } 284 if (UserManager.isSplitSystemUser()) { 285 return id != UserHandle.USER_SYSTEM; 286 } else { 287 return id == UserHandle.USER_SYSTEM; 288 } 289 } 290 UserInfo()291 public UserInfo() { 292 } 293 UserInfo(UserInfo orig)294 public UserInfo(UserInfo orig) { 295 name = orig.name; 296 iconPath = orig.iconPath; 297 id = orig.id; 298 flags = orig.flags; 299 serialNumber = orig.serialNumber; 300 creationTime = orig.creationTime; 301 lastLoggedInTime = orig.lastLoggedInTime; 302 lastLoggedInFingerprint = orig.lastLoggedInFingerprint; 303 partial = orig.partial; 304 preCreated = orig.preCreated; 305 profileGroupId = orig.profileGroupId; 306 restrictedProfileParentId = orig.restrictedProfileParentId; 307 guestToRemove = orig.guestToRemove; 308 profileBadge = orig.profileBadge; 309 } 310 311 @UnsupportedAppUsage getUserHandle()312 public UserHandle getUserHandle() { 313 return new UserHandle(id); 314 } 315 316 @Override toString()317 public String toString() { 318 return "UserInfo{" + id + ":" + name + ":" + Integer.toHexString(flags) + "}"; 319 } 320 321 /** @hide */ toFullString()322 public String toFullString() { 323 return "UserInfo[id=" + id 324 + ", name=" + name 325 + ", flags=" + flagsToString(flags) 326 + (preCreated ? " (pre-created)" : "") 327 + (partial ? " (partial)" : "") 328 + "]"; 329 } 330 331 /** @hide */ flagsToString(int flags)332 public static String flagsToString(int flags) { 333 return DebugUtils.flagsToString(UserInfo.class, "FLAG_", flags); 334 } 335 336 @Override describeContents()337 public int describeContents() { 338 return 0; 339 } 340 writeToParcel(Parcel dest, int parcelableFlags)341 public void writeToParcel(Parcel dest, int parcelableFlags) { 342 dest.writeInt(id); 343 dest.writeString(name); 344 dest.writeString(iconPath); 345 dest.writeInt(flags); 346 dest.writeInt(serialNumber); 347 dest.writeLong(creationTime); 348 dest.writeLong(lastLoggedInTime); 349 dest.writeString(lastLoggedInFingerprint); 350 dest.writeBoolean(partial); 351 dest.writeBoolean(preCreated); 352 dest.writeInt(profileGroupId); 353 dest.writeBoolean(guestToRemove); 354 dest.writeInt(restrictedProfileParentId); 355 dest.writeInt(profileBadge); 356 } 357 358 @UnsupportedAppUsage 359 public static final @android.annotation.NonNull Parcelable.Creator<UserInfo> CREATOR 360 = new Parcelable.Creator<UserInfo>() { 361 public UserInfo createFromParcel(Parcel source) { 362 return new UserInfo(source); 363 } 364 public UserInfo[] newArray(int size) { 365 return new UserInfo[size]; 366 } 367 }; 368 UserInfo(Parcel source)369 private UserInfo(Parcel source) { 370 id = source.readInt(); 371 name = source.readString(); 372 iconPath = source.readString(); 373 flags = source.readInt(); 374 serialNumber = source.readInt(); 375 creationTime = source.readLong(); 376 lastLoggedInTime = source.readLong(); 377 lastLoggedInFingerprint = source.readString(); 378 partial = source.readBoolean(); 379 preCreated = source.readBoolean(); 380 profileGroupId = source.readInt(); 381 guestToRemove = source.readBoolean(); 382 restrictedProfileParentId = source.readInt(); 383 profileBadge = source.readInt(); 384 } 385 } 386