blob: df652f190d0480231bc23da08e2ba33dcc82d67c [file] [log] [blame]
Amith Yamasani4b2e9342011-03-31 12:38:53 -07001/*
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
17package android.content.pm;
18
Felipe Lemee5434c32019-08-13 09:28:33 -070019import android.annotation.IntDef;
Mathew Inwood5c0d3542018-08-14 13:54:31 +010020import android.annotation.UnsupportedAppUsage;
Felipe Lemee5434c32019-08-13 09:28:33 -070021import android.annotation.UserIdInt;
Amith Yamasani4b2e9342011-03-31 12:38:53 -070022import android.os.Parcel;
23import android.os.Parcelable;
Jeff Sharkeyb049e212012-09-07 23:16:01 -070024import android.os.UserHandle;
Xiaohui Chen7cb69df2015-07-13 16:01:01 -070025import android.os.UserManager;
Felipe Lemee5434c32019-08-13 09:28:33 -070026import android.util.DebugUtils;
27
28import java.lang.annotation.Retention;
29import java.lang.annotation.RetentionPolicy;
Amith Yamasani4b2e9342011-03-31 12:38:53 -070030
31/**
32 * Per-user information.
Bookatz75f0a072019-08-05 14:12:16 -070033 *
34 * <p>There are 3 base properties of users: {@link #FLAG_SYSTEM}, {@link #FLAG_FULL}, and
35 * {@link #FLAG_MANAGED_PROFILE}. Every user must have one of the following combination of these
36 * flags:
37 * <ul>
38 * <li>FLAG_SYSTEM (user {@link UserHandle#USER_SYSTEM} on a headless-user-0 device)</li>
39 * <li>FLAG_SYSTEM and FLAG_FULL (user {@link UserHandle#USER_SYSTEM} on a regular device)</li>
40 * <li>FLAG_FULL (non-profile secondary user)</li>
41 * <li>FLAG_MANAGED_PROFILE (profile users)</li>
42 * </ul>
43 * Users can have also have additional flags (such as FLAG_GUEST) as appropriate.
44 *
Amith Yamasani4b2e9342011-03-31 12:38:53 -070045 * @hide
46 */
47public class UserInfo implements Parcelable {
Amith Yamasani258848d2012-08-10 17:06:33 -070048
Amith Yamasanieb437d42016-04-29 09:31:25 -070049 /** 16 bits for user type */
50 public static final int FLAG_MASK_USER_TYPE = 0x0000FFFF;
Amith Yamasani258848d2012-08-10 17:06:33 -070051
Amith Yamasani4b2e9342011-03-31 12:38:53 -070052 /**
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070053 * *************************** NOTE ***************************
54 * These flag values CAN NOT CHANGE because they are written
55 * directly to storage.
56 */
57
58 /**
Xiaohui Chen70f6c382015-04-28 14:21:43 -070059 * Primary user. Only one user can have this flag set. It identifies the first human user
Ying Zheng215116f2019-09-11 12:50:09 -070060 * on a device. This flag is not supported in headless system user mode.
Amith Yamasani4b2e9342011-03-31 12:38:53 -070061 */
Mathew Inwood5c0d3542018-08-14 13:54:31 +010062 @UnsupportedAppUsage
Amith Yamasani4b2e9342011-03-31 12:38:53 -070063 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 */
74 public static final int FLAG_GUEST = 0x00000004;
75
Amith Yamasani258848d2012-08-10 17:06:33 -070076 /**
77 * Indicates the user has restrictions in privileges, in addition to those for normal users.
78 * Exact meaning TBD. For instance, maybe they can't install apps or administer WiFi access pts.
79 */
80 public static final int FLAG_RESTRICTED = 0x00000008;
81
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070082 /**
83 * Indicates that this user has gone through its first-time initialization.
84 */
85 public static final int FLAG_INITIALIZED = 0x00000010;
86
Kenny Guya52dc3e2014-02-11 15:33:14 +000087 /**
88 * Indicates that this user is a profile of another user, for example holding a users
89 * corporate data.
90 */
91 public static final int FLAG_MANAGED_PROFILE = 0x00000020;
92
Alexandra Gherghinadf35d572014-04-09 13:54:39 +010093 /**
94 * Indicates that this user is disabled.
Lenka Trochtova1ddda472016-02-12 10:42:12 +010095 *
96 * <p>Note: If an ephemeral user is disabled, it shouldn't be later re-enabled. Ephemeral users
97 * are disabled as their removal is in progress to indicate that they shouldn't be re-entered.
Alexandra Gherghinadf35d572014-04-09 13:54:39 +010098 */
99 public static final int FLAG_DISABLED = 0x00000040;
100
Rubin Xu0a29ecd2015-11-04 15:11:48 +0000101 public static final int FLAG_QUIET_MODE = 0x00000080;
Kenny Guya52dc3e2014-02-11 15:33:14 +0000102
Lenka Trochtovac4dd0212015-11-18 12:22:06 +0100103 /**
104 * Indicates that this user is ephemeral. I.e. the user will be removed after leaving
105 * the foreground.
106 */
107 public static final int FLAG_EPHEMERAL = 0x00000100;
108
Amith Yamasanieb437d42016-04-29 09:31:25 -0700109 /**
110 * User is for demo purposes only and can be removed at any time.
111 */
112 public static final int FLAG_DEMO = 0x00000200;
113
Bookatz75f0a072019-08-05 14:12:16 -0700114 /**
115 * Indicates that this user is a non-profile human user.
116 *
117 * <p>When creating a new (non-system) user, this flag will always be forced true unless the
118 * user is a {@link #FLAG_MANAGED_PROFILE}. If user {@link UserHandle#USER_SYSTEM} is also a
119 * human user, it must also be flagged as FULL.
120 */
121 public static final int FLAG_FULL = 0x00000400;
122
123 /**
124 * Indicates that this user is {@link UserHandle#USER_SYSTEM}. Not applicable to created users.
125 */
126 public static final int FLAG_SYSTEM = 0x00000800;
127
Felipe Lemee5434c32019-08-13 09:28:33 -0700128 /**
Bookatz04d7ae52019-08-05 14:07:12 -0700129 * Indicates that this user is some sort of profile. Right now, the only profile type is
130 * {@link #FLAG_MANAGED_PROFILE}, but this can include other types of profiles too if any
131 * are created in the future. This is therefore not a flag, but an OR of several flags.
132 */
133 public static final int PROFILE_FLAGS_MASK = FLAG_MANAGED_PROFILE;
134
135 /**
Felipe Lemee5434c32019-08-13 09:28:33 -0700136 * @hide
137 */
138 @IntDef(flag = true, prefix = "FLAG_", value = {
139 FLAG_PRIMARY,
140 FLAG_ADMIN,
141 FLAG_GUEST,
142 FLAG_RESTRICTED,
143 FLAG_INITIALIZED,
144 FLAG_MANAGED_PROFILE,
145 FLAG_DISABLED,
146 FLAG_QUIET_MODE,
147 FLAG_EPHEMERAL,
148 FLAG_DEMO,
149 FLAG_FULL,
150 FLAG_SYSTEM
151 })
152 @Retention(RetentionPolicy.SOURCE)
153 public @interface UserInfoFlag {
154 }
155
Fyodor Kupolov06a484a2015-08-21 16:33:20 -0700156 public static final int NO_PROFILE_GROUP_ID = UserHandle.USER_NULL;
Kenny Guya52dc3e2014-02-11 15:33:14 +0000157
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100158 @UnsupportedAppUsage
Felipe Lemee5434c32019-08-13 09:28:33 -0700159 public @UserIdInt int id;
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100160 @UnsupportedAppUsage
Amith Yamasani2a003292012-08-14 18:25:45 -0700161 public int serialNumber;
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100162 @UnsupportedAppUsage
Amith Yamasani4b2e9342011-03-31 12:38:53 -0700163 public String name;
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100164 @UnsupportedAppUsage
Amith Yamasanib8151ec2012-04-18 18:02:48 -0700165 public String iconPath;
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100166 @UnsupportedAppUsage
Felipe Lemee5434c32019-08-13 09:28:33 -0700167 public @UserInfoFlag int flags;
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100168 @UnsupportedAppUsage
Amith Yamasani920ace02012-09-20 22:15:37 -0700169 public long creationTime;
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100170 @UnsupportedAppUsage
Amith Yamasani920ace02012-09-20 22:15:37 -0700171 public long lastLoggedInTime;
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600172 public String lastLoggedInFingerprint;
Tony Makd3986be2016-11-01 18:12:10 +0000173 /**
174 * If this user is a parent user, it would be its own user id.
175 * If this user is a child user, it would be its parent user id.
176 * Otherwise, it would be {@link #NO_PROFILE_GROUP_ID}.
177 */
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100178 @UnsupportedAppUsage
Kenny Guy2a764942014-04-02 13:29:20 +0100179 public int profileGroupId;
Fyodor Kupolov06a484a2015-08-21 16:33:20 -0700180 public int restrictedProfileParentId;
Kenny Guy02c89902016-11-15 19:36:38 +0000181 /** Which profile badge color/label to use. */
182 public int profileBadge;
Amith Yamasani4b2e9342011-03-31 12:38:53 -0700183
Dianne Hackbornd4ac8d72012-09-27 23:20:10 -0700184 /** User is only partially created. */
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100185 @UnsupportedAppUsage
Dianne Hackbornd4ac8d72012-09-27 23:20:10 -0700186 public boolean partial;
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100187 @UnsupportedAppUsage
Adam Lesinskieddeb492014-09-08 17:50:03 -0700188 public boolean guestToRemove;
Dianne Hackbornd4ac8d72012-09-27 23:20:10 -0700189
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100190 @UnsupportedAppUsage
Amith Yamasani4b2e9342011-03-31 12:38:53 -0700191 public UserInfo(int id, String name, int flags) {
Amith Yamasanib8151ec2012-04-18 18:02:48 -0700192 this(id, name, null, flags);
193 }
194
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100195 @UnsupportedAppUsage
Amith Yamasanib8151ec2012-04-18 18:02:48 -0700196 public UserInfo(int id, String name, String iconPath, int flags) {
Amith Yamasani4b2e9342011-03-31 12:38:53 -0700197 this.id = id;
198 this.name = name;
199 this.flags = flags;
Amith Yamasanib8151ec2012-04-18 18:02:48 -0700200 this.iconPath = iconPath;
Kenny Guy2a764942014-04-02 13:29:20 +0100201 this.profileGroupId = NO_PROFILE_GROUP_ID;
Fyodor Kupolov06a484a2015-08-21 16:33:20 -0700202 this.restrictedProfileParentId = NO_PROFILE_GROUP_ID;
Amith Yamasani4b2e9342011-03-31 12:38:53 -0700203 }
204
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100205 @UnsupportedAppUsage
Amith Yamasani4b2e9342011-03-31 12:38:53 -0700206 public boolean isPrimary() {
207 return (flags & FLAG_PRIMARY) == FLAG_PRIMARY;
208 }
209
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100210 @UnsupportedAppUsage
Amith Yamasani4b2e9342011-03-31 12:38:53 -0700211 public boolean isAdmin() {
212 return (flags & FLAG_ADMIN) == FLAG_ADMIN;
213 }
214
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100215 @UnsupportedAppUsage
Amith Yamasani4b2e9342011-03-31 12:38:53 -0700216 public boolean isGuest() {
217 return (flags & FLAG_GUEST) == FLAG_GUEST;
218 }
219
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100220 @UnsupportedAppUsage
Amith Yamasani67df64b2012-12-14 12:09:36 -0800221 public boolean isRestricted() {
222 return (flags & FLAG_RESTRICTED) == FLAG_RESTRICTED;
223 }
224
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100225 @UnsupportedAppUsage
Kenny Guya52dc3e2014-02-11 15:33:14 +0000226 public boolean isManagedProfile() {
227 return (flags & FLAG_MANAGED_PROFILE) == FLAG_MANAGED_PROFILE;
228 }
229
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100230 @UnsupportedAppUsage
Alexandra Gherghinadf35d572014-04-09 13:54:39 +0100231 public boolean isEnabled() {
232 return (flags & FLAG_DISABLED) != FLAG_DISABLED;
233 }
234
Rubin Xu0a29ecd2015-11-04 15:11:48 +0000235 public boolean isQuietModeEnabled() {
236 return (flags & FLAG_QUIET_MODE) == FLAG_QUIET_MODE;
237 }
Lenka Trochtovac4dd0212015-11-18 12:22:06 +0100238
239 public boolean isEphemeral() {
240 return (flags & FLAG_EPHEMERAL) == FLAG_EPHEMERAL;
241 }
242
Amith Yamasani12747872015-12-07 14:19:49 -0800243 public boolean isInitialized() {
244 return (flags & FLAG_INITIALIZED) == FLAG_INITIALIZED;
245 }
246
Amith Yamasanieb437d42016-04-29 09:31:25 -0700247 public boolean isDemo() {
248 return (flags & FLAG_DEMO) == FLAG_DEMO;
249 }
250
Felipe Lemee5434c32019-08-13 09:28:33 -0700251 public boolean isFull() {
252 return (flags & FLAG_FULL) == FLAG_FULL;
253 }
254
Kenny Guy1a447532014-02-20 21:55:32 +0000255 /**
Fyodor Kupolov7db5af12015-07-31 16:50:27 -0700256 * Returns true if the user is a split system user.
257 * <p>If {@link UserManager#isSplitSystemUser split system user mode} is not enabled,
258 * the method always returns false.
259 */
260 public boolean isSystemOnly() {
Xiaohui Chena4490622015-09-22 15:29:31 -0700261 return isSystemOnly(id);
262 }
263
264 /**
265 * Returns true if the given user is a split system user.
266 * <p>If {@link UserManager#isSplitSystemUser split system user mode} is not enabled,
267 * the method always returns false.
268 */
269 public static boolean isSystemOnly(int userId) {
270 return userId == UserHandle.USER_SYSTEM && UserManager.isSplitSystemUser();
Fyodor Kupolov7db5af12015-07-31 16:50:27 -0700271 }
272
273 /**
Kenny Guy1a447532014-02-20 21:55:32 +0000274 * @return true if this user can be switched to.
275 **/
276 public boolean supportsSwitchTo() {
Lenka Trochtova1ddda472016-02-12 10:42:12 +0100277 if (isEphemeral() && !isEnabled()) {
278 // Don't support switching to an ephemeral user with removal in progress.
279 return false;
280 }
Robin Lee434a74f2016-08-04 15:58:08 +0100281 return !isManagedProfile();
Kenny Guy1a447532014-02-20 21:55:32 +0000282 }
283
Xiaohui Chen7cb69df2015-07-13 16:01:01 -0700284 /**
285 * @return true if this user can be switched to by end user through UI.
286 */
287 public boolean supportsSwitchToByUser() {
288 // Hide the system user when it does not represent a human user.
289 boolean hideSystemUser = UserManager.isSplitSystemUser();
290 return (!hideSystemUser || id != UserHandle.USER_SYSTEM) && supportsSwitchTo();
291 }
292
Nicolas Prevotb8186812015-08-06 15:00:03 +0100293 /* @hide */
294 public boolean canHaveProfile() {
295 if (isManagedProfile() || isGuest() || isRestricted()) {
296 return false;
297 }
Eric Jeonge7ead1b2019-07-18 09:37:08 -0700298 if (UserManager.isSplitSystemUser() || UserManager.isHeadlessSystemUserMode()) {
Nicolas Prevotb8186812015-08-06 15:00:03 +0100299 return id != UserHandle.USER_SYSTEM;
Xiaohui Chenbd0e03b2015-08-21 09:19:49 -0700300 } else {
301 return id == UserHandle.USER_SYSTEM;
Nicolas Prevotb8186812015-08-06 15:00:03 +0100302 }
Nicolas Prevotb8186812015-08-06 15:00:03 +0100303 }
304
Amith Yamasani4b2e9342011-03-31 12:38:53 -0700305 public UserInfo() {
306 }
307
308 public UserInfo(UserInfo orig) {
309 name = orig.name;
Amith Yamasanib8151ec2012-04-18 18:02:48 -0700310 iconPath = orig.iconPath;
Amith Yamasani4b2e9342011-03-31 12:38:53 -0700311 id = orig.id;
312 flags = orig.flags;
Amith Yamasani2a003292012-08-14 18:25:45 -0700313 serialNumber = orig.serialNumber;
Amith Yamasani920ace02012-09-20 22:15:37 -0700314 creationTime = orig.creationTime;
315 lastLoggedInTime = orig.lastLoggedInTime;
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600316 lastLoggedInFingerprint = orig.lastLoggedInFingerprint;
Dianne Hackbornd4ac8d72012-09-27 23:20:10 -0700317 partial = orig.partial;
Kenny Guy2a764942014-04-02 13:29:20 +0100318 profileGroupId = orig.profileGroupId;
Amith Yamasani6f48d6e2016-03-23 14:28:25 -0700319 restrictedProfileParentId = orig.restrictedProfileParentId;
Adam Lesinskieddeb492014-09-08 17:50:03 -0700320 guestToRemove = orig.guestToRemove;
Kenny Guy02c89902016-11-15 19:36:38 +0000321 profileBadge = orig.profileBadge;
Amith Yamasani4b2e9342011-03-31 12:38:53 -0700322 }
323
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100324 @UnsupportedAppUsage
Jeff Sharkeyb049e212012-09-07 23:16:01 -0700325 public UserHandle getUserHandle() {
326 return new UserHandle(id);
327 }
328
Amith Yamasani4b2e9342011-03-31 12:38:53 -0700329 @Override
330 public String toString() {
Felipe Lemee5434c32019-08-13 09:28:33 -0700331 // NOTE: do not change this string, it's used by 'pm list users', which in turn is
332 // used and parsed by TestDevice. In other words, if you change it, you'd have to change
333 // TestDevice, TestDeviceTest, and possibly others....
Amith Yamasani0b285492011-04-14 17:35:23 -0700334 return "UserInfo{" + id + ":" + name + ":" + Integer.toHexString(flags) + "}";
Amith Yamasani4b2e9342011-03-31 12:38:53 -0700335 }
336
Felipe Lemee5434c32019-08-13 09:28:33 -0700337 /** @hide */
Felipe Leme501a5142019-08-15 16:23:47 -0700338 public String toFullString() {
339 return "UserInfo[id=" + id
340 + ", name=" + name
341 + ", flags=" + flagsToString(flags)
342 + "]";
343 }
344
345 /** @hide */
Felipe Lemee5434c32019-08-13 09:28:33 -0700346 public static String flagsToString(int flags) {
347 return DebugUtils.flagsToString(UserInfo.class, "FLAG_", flags);
348 }
349
350 @Override
Amith Yamasani4b2e9342011-03-31 12:38:53 -0700351 public int describeContents() {
352 return 0;
353 }
354
Felipe Lemee5434c32019-08-13 09:28:33 -0700355 @Override
Amith Yamasani4b2e9342011-03-31 12:38:53 -0700356 public void writeToParcel(Parcel dest, int parcelableFlags) {
357 dest.writeInt(id);
358 dest.writeString(name);
Amith Yamasanib8151ec2012-04-18 18:02:48 -0700359 dest.writeString(iconPath);
Amith Yamasani4b2e9342011-03-31 12:38:53 -0700360 dest.writeInt(flags);
Amith Yamasani2a003292012-08-14 18:25:45 -0700361 dest.writeInt(serialNumber);
Amith Yamasani920ace02012-09-20 22:15:37 -0700362 dest.writeLong(creationTime);
363 dest.writeLong(lastLoggedInTime);
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600364 dest.writeString(lastLoggedInFingerprint);
Dianne Hackbornd4ac8d72012-09-27 23:20:10 -0700365 dest.writeInt(partial ? 1 : 0);
Kenny Guy2a764942014-04-02 13:29:20 +0100366 dest.writeInt(profileGroupId);
Adam Lesinskieddeb492014-09-08 17:50:03 -0700367 dest.writeInt(guestToRemove ? 1 : 0);
Fyodor Kupolov06a484a2015-08-21 16:33:20 -0700368 dest.writeInt(restrictedProfileParentId);
Kenny Guy02c89902016-11-15 19:36:38 +0000369 dest.writeInt(profileBadge);
Amith Yamasani4b2e9342011-03-31 12:38:53 -0700370 }
371
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100372 @UnsupportedAppUsage
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -0700373 public static final @android.annotation.NonNull Parcelable.Creator<UserInfo> CREATOR
Amith Yamasani4b2e9342011-03-31 12:38:53 -0700374 = new Parcelable.Creator<UserInfo>() {
375 public UserInfo createFromParcel(Parcel source) {
376 return new UserInfo(source);
377 }
378 public UserInfo[] newArray(int size) {
379 return new UserInfo[size];
380 }
381 };
382
383 private UserInfo(Parcel source) {
384 id = source.readInt();
385 name = source.readString();
Amith Yamasanib8151ec2012-04-18 18:02:48 -0700386 iconPath = source.readString();
Amith Yamasani4b2e9342011-03-31 12:38:53 -0700387 flags = source.readInt();
Amith Yamasani2a003292012-08-14 18:25:45 -0700388 serialNumber = source.readInt();
Amith Yamasani920ace02012-09-20 22:15:37 -0700389 creationTime = source.readLong();
390 lastLoggedInTime = source.readLong();
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600391 lastLoggedInFingerprint = source.readString();
Dianne Hackbornd4ac8d72012-09-27 23:20:10 -0700392 partial = source.readInt() != 0;
Kenny Guy2a764942014-04-02 13:29:20 +0100393 profileGroupId = source.readInt();
Adam Lesinskieddeb492014-09-08 17:50:03 -0700394 guestToRemove = source.readInt() != 0;
Fyodor Kupolov06a484a2015-08-21 16:33:20 -0700395 restrictedProfileParentId = source.readInt();
Kenny Guy02c89902016-11-15 19:36:38 +0000396 profileBadge = source.readInt();
Amith Yamasani4b2e9342011-03-31 12:38:53 -0700397 }
398}