• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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