blob: 56a62854d09e094b20c81049e3dbf9bce6c9ea44 [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 Leme7ad2f6b2019-09-11 09:23:26 -070019import android.annotation.IntDef;
Mathew Inwood5c0d3542018-08-14 13:54:31 +010020import android.annotation.UnsupportedAppUsage;
Amith Yamasani4b2e9342011-03-31 12:38:53 -070021import android.os.Parcel;
22import android.os.Parcelable;
Kenny Guy1a447532014-02-20 21:55:32 +000023import android.os.SystemProperties;
Jeff Sharkeyb049e212012-09-07 23:16:01 -070024import android.os.UserHandle;
Xiaohui Chen7cb69df2015-07-13 16:01:01 -070025import android.os.UserManager;
Felipe Leme7ad2f6b2019-09-11 09:23:26 -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.
33 * @hide
34 */
35public class UserInfo implements Parcelable {
Amith Yamasani258848d2012-08-10 17:06:33 -070036
Amith Yamasanieb437d42016-04-29 09:31:25 -070037 /** 16 bits for user type */
38 public static final int FLAG_MASK_USER_TYPE = 0x0000FFFF;
Amith Yamasani258848d2012-08-10 17:06:33 -070039
Amith Yamasani4b2e9342011-03-31 12:38:53 -070040 /**
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070041 * *************************** NOTE ***************************
42 * These flag values CAN NOT CHANGE because they are written
43 * directly to storage.
44 */
45
46 /**
Xiaohui Chen70f6c382015-04-28 14:21:43 -070047 * Primary user. Only one user can have this flag set. It identifies the first human user
48 * on a device.
Amith Yamasani4b2e9342011-03-31 12:38:53 -070049 */
Mathew Inwood5c0d3542018-08-14 13:54:31 +010050 @UnsupportedAppUsage
Amith Yamasani4b2e9342011-03-31 12:38:53 -070051 public static final int FLAG_PRIMARY = 0x00000001;
52
53 /**
54 * User with administrative privileges. Such a user can create and
55 * delete users.
56 */
57 public static final int FLAG_ADMIN = 0x00000002;
58
59 /**
60 * Indicates a guest user that may be transient.
61 */
62 public static final int FLAG_GUEST = 0x00000004;
63
Amith Yamasani258848d2012-08-10 17:06:33 -070064 /**
65 * Indicates the user has restrictions in privileges, in addition to those for normal users.
66 * Exact meaning TBD. For instance, maybe they can't install apps or administer WiFi access pts.
67 */
68 public static final int FLAG_RESTRICTED = 0x00000008;
69
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070070 /**
71 * Indicates that this user has gone through its first-time initialization.
72 */
73 public static final int FLAG_INITIALIZED = 0x00000010;
74
Kenny Guya52dc3e2014-02-11 15:33:14 +000075 /**
76 * Indicates that this user is a profile of another user, for example holding a users
77 * corporate data.
78 */
79 public static final int FLAG_MANAGED_PROFILE = 0x00000020;
80
Alexandra Gherghinadf35d572014-04-09 13:54:39 +010081 /**
82 * Indicates that this user is disabled.
Lenka Trochtova1ddda472016-02-12 10:42:12 +010083 *
84 * <p>Note: If an ephemeral user is disabled, it shouldn't be later re-enabled. Ephemeral users
85 * are disabled as their removal is in progress to indicate that they shouldn't be re-entered.
Alexandra Gherghinadf35d572014-04-09 13:54:39 +010086 */
87 public static final int FLAG_DISABLED = 0x00000040;
88
Rubin Xu0a29ecd2015-11-04 15:11:48 +000089 public static final int FLAG_QUIET_MODE = 0x00000080;
Kenny Guya52dc3e2014-02-11 15:33:14 +000090
Lenka Trochtovac4dd0212015-11-18 12:22:06 +010091 /**
92 * Indicates that this user is ephemeral. I.e. the user will be removed after leaving
93 * the foreground.
94 */
95 public static final int FLAG_EPHEMERAL = 0x00000100;
96
Amith Yamasanieb437d42016-04-29 09:31:25 -070097 /**
98 * User is for demo purposes only and can be removed at any time.
99 */
100 public static final int FLAG_DEMO = 0x00000200;
101
Felipe Leme7ad2f6b2019-09-11 09:23:26 -0700102 /**
103 * @hide
104 */
105 @IntDef(flag = true, prefix = "FLAG_", value = {
106 FLAG_PRIMARY,
107 FLAG_ADMIN,
108 FLAG_GUEST,
109 FLAG_RESTRICTED,
110 FLAG_INITIALIZED,
111 FLAG_MANAGED_PROFILE,
112 FLAG_DISABLED,
113 FLAG_QUIET_MODE,
114 FLAG_EPHEMERAL,
115 FLAG_DEMO
116 })
117 @Retention(RetentionPolicy.SOURCE)
118 public @interface UserInfoFlag {
119 }
120
Fyodor Kupolov06a484a2015-08-21 16:33:20 -0700121 public static final int NO_PROFILE_GROUP_ID = UserHandle.USER_NULL;
Kenny Guya52dc3e2014-02-11 15:33:14 +0000122
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100123 @UnsupportedAppUsage
Amith Yamasani4b2e9342011-03-31 12:38:53 -0700124 public int id;
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100125 @UnsupportedAppUsage
Amith Yamasani2a003292012-08-14 18:25:45 -0700126 public int serialNumber;
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100127 @UnsupportedAppUsage
Amith Yamasani4b2e9342011-03-31 12:38:53 -0700128 public String name;
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100129 @UnsupportedAppUsage
Amith Yamasanib8151ec2012-04-18 18:02:48 -0700130 public String iconPath;
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100131 @UnsupportedAppUsage
Amith Yamasani4b2e9342011-03-31 12:38:53 -0700132 public int flags;
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100133 @UnsupportedAppUsage
Amith Yamasani920ace02012-09-20 22:15:37 -0700134 public long creationTime;
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100135 @UnsupportedAppUsage
Amith Yamasani920ace02012-09-20 22:15:37 -0700136 public long lastLoggedInTime;
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600137 public String lastLoggedInFingerprint;
Tony Makd3986be2016-11-01 18:12:10 +0000138 /**
139 * If this user is a parent user, it would be its own user id.
140 * If this user is a child user, it would be its parent user id.
141 * Otherwise, it would be {@link #NO_PROFILE_GROUP_ID}.
142 */
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100143 @UnsupportedAppUsage
Kenny Guy2a764942014-04-02 13:29:20 +0100144 public int profileGroupId;
Fyodor Kupolov06a484a2015-08-21 16:33:20 -0700145 public int restrictedProfileParentId;
Kenny Guy02c89902016-11-15 19:36:38 +0000146 /** Which profile badge color/label to use. */
147 public int profileBadge;
Amith Yamasani4b2e9342011-03-31 12:38:53 -0700148
Dianne Hackbornd4ac8d72012-09-27 23:20:10 -0700149 /** User is only partially created. */
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100150 @UnsupportedAppUsage
Dianne Hackbornd4ac8d72012-09-27 23:20:10 -0700151 public boolean partial;
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100152 @UnsupportedAppUsage
Adam Lesinskieddeb492014-09-08 17:50:03 -0700153 public boolean guestToRemove;
Dianne Hackbornd4ac8d72012-09-27 23:20:10 -0700154
Felipe Leme7ad2f6b2019-09-11 09:23:26 -0700155 /**
156 * This is used to optimize the creation of an user, i.e. OEMs might choose to pre-create a
157 * number of users at the first boot, so the actual creation later is faster.
158 *
159 * <p>A {@code preCreated} user is not a real user yet, so it should not show up on regular
160 * user operations (other than user creation per se).
161 *
162 * <p>Once the pre-created is used to create a "real" user later on, {@code preCreate} is set to
163 * {@code false}.
164 */
165 public boolean preCreated;
166
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100167 @UnsupportedAppUsage
Amith Yamasani4b2e9342011-03-31 12:38:53 -0700168 public UserInfo(int id, String name, int flags) {
Amith Yamasanib8151ec2012-04-18 18:02:48 -0700169 this(id, name, null, flags);
170 }
171
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100172 @UnsupportedAppUsage
Amith Yamasanib8151ec2012-04-18 18:02:48 -0700173 public UserInfo(int id, String name, String iconPath, int flags) {
Amith Yamasani4b2e9342011-03-31 12:38:53 -0700174 this.id = id;
175 this.name = name;
176 this.flags = flags;
Amith Yamasanib8151ec2012-04-18 18:02:48 -0700177 this.iconPath = iconPath;
Kenny Guy2a764942014-04-02 13:29:20 +0100178 this.profileGroupId = NO_PROFILE_GROUP_ID;
Fyodor Kupolov06a484a2015-08-21 16:33:20 -0700179 this.restrictedProfileParentId = NO_PROFILE_GROUP_ID;
Amith Yamasani4b2e9342011-03-31 12:38:53 -0700180 }
181
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100182 @UnsupportedAppUsage
Amith Yamasani4b2e9342011-03-31 12:38:53 -0700183 public boolean isPrimary() {
184 return (flags & FLAG_PRIMARY) == FLAG_PRIMARY;
185 }
186
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100187 @UnsupportedAppUsage
Amith Yamasani4b2e9342011-03-31 12:38:53 -0700188 public boolean isAdmin() {
189 return (flags & FLAG_ADMIN) == FLAG_ADMIN;
190 }
191
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100192 @UnsupportedAppUsage
Amith Yamasani4b2e9342011-03-31 12:38:53 -0700193 public boolean isGuest() {
Felipe Leme7ad2f6b2019-09-11 09:23:26 -0700194 return isGuest(flags);
195 }
196
197 /**
198 * Checks if the flag denotes a guest user.
199 */
200 public static boolean isGuest(@UserInfoFlag int flags) {
Amith Yamasani4b2e9342011-03-31 12:38:53 -0700201 return (flags & FLAG_GUEST) == FLAG_GUEST;
202 }
203
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100204 @UnsupportedAppUsage
Amith Yamasani67df64b2012-12-14 12:09:36 -0800205 public boolean isRestricted() {
206 return (flags & FLAG_RESTRICTED) == FLAG_RESTRICTED;
207 }
208
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100209 @UnsupportedAppUsage
Kenny Guya52dc3e2014-02-11 15:33:14 +0000210 public boolean isManagedProfile() {
Felipe Leme7ad2f6b2019-09-11 09:23:26 -0700211 return isManagedProfile(flags);
212 }
213
214 /**
215 * Checks if the flag denotes a managed profile.
216 */
217 public static boolean isManagedProfile(@UserInfoFlag int flags) {
Kenny Guya52dc3e2014-02-11 15:33:14 +0000218 return (flags & FLAG_MANAGED_PROFILE) == FLAG_MANAGED_PROFILE;
219 }
220
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100221 @UnsupportedAppUsage
Alexandra Gherghinadf35d572014-04-09 13:54:39 +0100222 public boolean isEnabled() {
223 return (flags & FLAG_DISABLED) != FLAG_DISABLED;
224 }
225
Rubin Xu0a29ecd2015-11-04 15:11:48 +0000226 public boolean isQuietModeEnabled() {
227 return (flags & FLAG_QUIET_MODE) == FLAG_QUIET_MODE;
228 }
Lenka Trochtovac4dd0212015-11-18 12:22:06 +0100229
230 public boolean isEphemeral() {
231 return (flags & FLAG_EPHEMERAL) == FLAG_EPHEMERAL;
232 }
233
Amith Yamasani12747872015-12-07 14:19:49 -0800234 public boolean isInitialized() {
235 return (flags & FLAG_INITIALIZED) == FLAG_INITIALIZED;
236 }
237
Amith Yamasanieb437d42016-04-29 09:31:25 -0700238 public boolean isDemo() {
239 return (flags & FLAG_DEMO) == FLAG_DEMO;
240 }
241
Kenny Guy1a447532014-02-20 21:55:32 +0000242 /**
Fyodor Kupolov7db5af12015-07-31 16:50:27 -0700243 * Returns true if the user is a split system user.
244 * <p>If {@link UserManager#isSplitSystemUser split system user mode} is not enabled,
245 * the method always returns false.
246 */
247 public boolean isSystemOnly() {
Xiaohui Chena4490622015-09-22 15:29:31 -0700248 return isSystemOnly(id);
249 }
250
251 /**
252 * Returns true if the given user is a split system user.
253 * <p>If {@link UserManager#isSplitSystemUser split system user mode} is not enabled,
254 * the method always returns false.
255 */
256 public static boolean isSystemOnly(int userId) {
257 return userId == UserHandle.USER_SYSTEM && UserManager.isSplitSystemUser();
Fyodor Kupolov7db5af12015-07-31 16:50:27 -0700258 }
259
260 /**
Kenny Guy1a447532014-02-20 21:55:32 +0000261 * @return true if this user can be switched to.
262 **/
263 public boolean supportsSwitchTo() {
Lenka Trochtova1ddda472016-02-12 10:42:12 +0100264 if (isEphemeral() && !isEnabled()) {
265 // Don't support switching to an ephemeral user with removal in progress.
266 return false;
267 }
Robin Lee434a74f2016-08-04 15:58:08 +0100268 return !isManagedProfile();
Kenny Guy1a447532014-02-20 21:55:32 +0000269 }
270
Xiaohui Chen7cb69df2015-07-13 16:01:01 -0700271 /**
272 * @return true if this user can be switched to by end user through UI.
273 */
274 public boolean supportsSwitchToByUser() {
275 // Hide the system user when it does not represent a human user.
276 boolean hideSystemUser = UserManager.isSplitSystemUser();
277 return (!hideSystemUser || id != UserHandle.USER_SYSTEM) && supportsSwitchTo();
278 }
279
Nicolas Prevotb8186812015-08-06 15:00:03 +0100280 /* @hide */
281 public boolean canHaveProfile() {
282 if (isManagedProfile() || isGuest() || isRestricted()) {
283 return false;
284 }
285 if (UserManager.isSplitSystemUser()) {
286 return id != UserHandle.USER_SYSTEM;
Xiaohui Chenbd0e03b2015-08-21 09:19:49 -0700287 } else {
288 return id == UserHandle.USER_SYSTEM;
Nicolas Prevotb8186812015-08-06 15:00:03 +0100289 }
Nicolas Prevotb8186812015-08-06 15:00:03 +0100290 }
291
Amith Yamasani4b2e9342011-03-31 12:38:53 -0700292 public UserInfo() {
293 }
294
295 public UserInfo(UserInfo orig) {
296 name = orig.name;
Amith Yamasanib8151ec2012-04-18 18:02:48 -0700297 iconPath = orig.iconPath;
Amith Yamasani4b2e9342011-03-31 12:38:53 -0700298 id = orig.id;
299 flags = orig.flags;
Amith Yamasani2a003292012-08-14 18:25:45 -0700300 serialNumber = orig.serialNumber;
Amith Yamasani920ace02012-09-20 22:15:37 -0700301 creationTime = orig.creationTime;
302 lastLoggedInTime = orig.lastLoggedInTime;
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600303 lastLoggedInFingerprint = orig.lastLoggedInFingerprint;
Dianne Hackbornd4ac8d72012-09-27 23:20:10 -0700304 partial = orig.partial;
Felipe Leme7ad2f6b2019-09-11 09:23:26 -0700305 preCreated = orig.preCreated;
Kenny Guy2a764942014-04-02 13:29:20 +0100306 profileGroupId = orig.profileGroupId;
Amith Yamasani6f48d6e2016-03-23 14:28:25 -0700307 restrictedProfileParentId = orig.restrictedProfileParentId;
Adam Lesinskieddeb492014-09-08 17:50:03 -0700308 guestToRemove = orig.guestToRemove;
Kenny Guy02c89902016-11-15 19:36:38 +0000309 profileBadge = orig.profileBadge;
Amith Yamasani4b2e9342011-03-31 12:38:53 -0700310 }
311
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100312 @UnsupportedAppUsage
Jeff Sharkeyb049e212012-09-07 23:16:01 -0700313 public UserHandle getUserHandle() {
314 return new UserHandle(id);
315 }
316
Amith Yamasani4b2e9342011-03-31 12:38:53 -0700317 @Override
318 public String toString() {
Amith Yamasani0b285492011-04-14 17:35:23 -0700319 return "UserInfo{" + id + ":" + name + ":" + Integer.toHexString(flags) + "}";
Amith Yamasani4b2e9342011-03-31 12:38:53 -0700320 }
321
Felipe Leme7ad2f6b2019-09-11 09:23:26 -0700322 /** @hide */
323 public String toFullString() {
324 return "UserInfo[id=" + id
325 + ", name=" + name
326 + ", flags=" + flagsToString(flags)
327 + (preCreated ? " (pre-created)" : "")
328 + (partial ? " (partial)" : "")
329 + "]";
330 }
331
332 /** @hide */
333 public static String flagsToString(int flags) {
334 return DebugUtils.flagsToString(UserInfo.class, "FLAG_", flags);
335 }
336
337 @Override
Amith Yamasani4b2e9342011-03-31 12:38:53 -0700338 public int describeContents() {
339 return 0;
340 }
341
342 public void writeToParcel(Parcel dest, int parcelableFlags) {
343 dest.writeInt(id);
344 dest.writeString(name);
Amith Yamasanib8151ec2012-04-18 18:02:48 -0700345 dest.writeString(iconPath);
Amith Yamasani4b2e9342011-03-31 12:38:53 -0700346 dest.writeInt(flags);
Amith Yamasani2a003292012-08-14 18:25:45 -0700347 dest.writeInt(serialNumber);
Amith Yamasani920ace02012-09-20 22:15:37 -0700348 dest.writeLong(creationTime);
349 dest.writeLong(lastLoggedInTime);
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600350 dest.writeString(lastLoggedInFingerprint);
Felipe Leme7ad2f6b2019-09-11 09:23:26 -0700351 dest.writeBoolean(partial);
352 dest.writeBoolean(preCreated);
Kenny Guy2a764942014-04-02 13:29:20 +0100353 dest.writeInt(profileGroupId);
Felipe Leme7ad2f6b2019-09-11 09:23:26 -0700354 dest.writeBoolean(guestToRemove);
Fyodor Kupolov06a484a2015-08-21 16:33:20 -0700355 dest.writeInt(restrictedProfileParentId);
Kenny Guy02c89902016-11-15 19:36:38 +0000356 dest.writeInt(profileBadge);
Amith Yamasani4b2e9342011-03-31 12:38:53 -0700357 }
358
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100359 @UnsupportedAppUsage
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -0700360 public static final @android.annotation.NonNull Parcelable.Creator<UserInfo> CREATOR
Amith Yamasani4b2e9342011-03-31 12:38:53 -0700361 = new Parcelable.Creator<UserInfo>() {
362 public UserInfo createFromParcel(Parcel source) {
363 return new UserInfo(source);
364 }
365 public UserInfo[] newArray(int size) {
366 return new UserInfo[size];
367 }
368 };
369
370 private UserInfo(Parcel source) {
371 id = source.readInt();
372 name = source.readString();
Amith Yamasanib8151ec2012-04-18 18:02:48 -0700373 iconPath = source.readString();
Amith Yamasani4b2e9342011-03-31 12:38:53 -0700374 flags = source.readInt();
Amith Yamasani2a003292012-08-14 18:25:45 -0700375 serialNumber = source.readInt();
Amith Yamasani920ace02012-09-20 22:15:37 -0700376 creationTime = source.readLong();
377 lastLoggedInTime = source.readLong();
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600378 lastLoggedInFingerprint = source.readString();
Felipe Leme7ad2f6b2019-09-11 09:23:26 -0700379 partial = source.readBoolean();
Felipe Leme52843362019-10-14 09:56:06 -0700380 preCreated = source.readBoolean();
Kenny Guy2a764942014-04-02 13:29:20 +0100381 profileGroupId = source.readInt();
Felipe Leme7ad2f6b2019-09-11 09:23:26 -0700382 guestToRemove = source.readBoolean();
Fyodor Kupolov06a484a2015-08-21 16:33:20 -0700383 restrictedProfileParentId = source.readInt();
Kenny Guy02c89902016-11-15 19:36:38 +0000384 profileBadge = source.readInt();
Amith Yamasani4b2e9342011-03-31 12:38:53 -0700385 }
386}