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