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.os.Parcel;
20 import android.os.Parcelable;
21 import android.os.SystemProperties;
22 import android.os.UserHandle;
23 import android.os.UserManager;
24 
25 /**
26  * Per-user information.
27  * @hide
28  */
29 public class UserInfo implements Parcelable {
30 
31     /** 8 bits for user type */
32     public static final int FLAG_MASK_USER_TYPE = 0x000000FF;
33 
34     /**
35      * *************************** NOTE ***************************
36      * These flag values CAN NOT CHANGE because they are written
37      * directly to storage.
38      */
39 
40     /**
41      * Primary user. Only one user can have this flag set. It identifies the first human user
42      * on a device.
43      */
44     public static final int FLAG_PRIMARY = 0x00000001;
45 
46     /**
47      * User with administrative privileges. Such a user can create and
48      * delete users.
49      */
50     public static final int FLAG_ADMIN   = 0x00000002;
51 
52     /**
53      * Indicates a guest user that may be transient.
54      */
55     public static final int FLAG_GUEST   = 0x00000004;
56 
57     /**
58      * Indicates the user has restrictions in privileges, in addition to those for normal users.
59      * Exact meaning TBD. For instance, maybe they can't install apps or administer WiFi access pts.
60      */
61     public static final int FLAG_RESTRICTED = 0x00000008;
62 
63     /**
64      * Indicates that this user has gone through its first-time initialization.
65      */
66     public static final int FLAG_INITIALIZED = 0x00000010;
67 
68     /**
69      * Indicates that this user is a profile of another user, for example holding a users
70      * corporate data.
71      */
72     public static final int FLAG_MANAGED_PROFILE = 0x00000020;
73 
74     /**
75      * Indicates that this user is disabled.
76      *
77      * <p>Note: If an ephemeral user is disabled, it shouldn't be later re-enabled. Ephemeral users
78      * are disabled as their removal is in progress to indicate that they shouldn't be re-entered.
79      */
80     public static final int FLAG_DISABLED = 0x00000040;
81 
82     public static final int FLAG_QUIET_MODE = 0x00000080;
83 
84     /**
85      * Indicates that this user is ephemeral. I.e. the user will be removed after leaving
86      * the foreground.
87      */
88     public static final int FLAG_EPHEMERAL = 0x00000100;
89 
90     public static final int NO_PROFILE_GROUP_ID = UserHandle.USER_NULL;
91 
92     public int id;
93     public int serialNumber;
94     public String name;
95     public String iconPath;
96     public int flags;
97     public long creationTime;
98     public long lastLoggedInTime;
99     public String lastLoggedInFingerprint;
100     public int profileGroupId;
101     public int restrictedProfileParentId;
102 
103     /** User is only partially created. */
104     public boolean partial;
105     public boolean guestToRemove;
106 
UserInfo(int id, String name, int flags)107     public UserInfo(int id, String name, int flags) {
108         this(id, name, null, flags);
109     }
110 
UserInfo(int id, String name, String iconPath, int flags)111     public UserInfo(int id, String name, String iconPath, int flags) {
112         this.id = id;
113         this.name = name;
114         this.flags = flags;
115         this.iconPath = iconPath;
116         this.profileGroupId = NO_PROFILE_GROUP_ID;
117         this.restrictedProfileParentId = NO_PROFILE_GROUP_ID;
118     }
119 
isPrimary()120     public boolean isPrimary() {
121         return (flags & FLAG_PRIMARY) == FLAG_PRIMARY;
122     }
123 
isAdmin()124     public boolean isAdmin() {
125         return (flags & FLAG_ADMIN) == FLAG_ADMIN;
126     }
127 
isGuest()128     public boolean isGuest() {
129         return (flags & FLAG_GUEST) == FLAG_GUEST;
130     }
131 
isRestricted()132     public boolean isRestricted() {
133         return (flags & FLAG_RESTRICTED) == FLAG_RESTRICTED;
134     }
135 
isManagedProfile()136     public boolean isManagedProfile() {
137         return (flags & FLAG_MANAGED_PROFILE) == FLAG_MANAGED_PROFILE;
138     }
139 
isEnabled()140     public boolean isEnabled() {
141         return (flags & FLAG_DISABLED) != FLAG_DISABLED;
142     }
143 
isQuietModeEnabled()144     public boolean isQuietModeEnabled() {
145         return (flags & FLAG_QUIET_MODE) == FLAG_QUIET_MODE;
146     }
147 
isEphemeral()148     public boolean isEphemeral() {
149         return (flags & FLAG_EPHEMERAL) == FLAG_EPHEMERAL;
150     }
151 
isInitialized()152     public boolean isInitialized() {
153         return (flags & FLAG_INITIALIZED) == FLAG_INITIALIZED;
154     }
155 
156     /**
157      * Returns true if the user is a split system user.
158      * <p>If {@link UserManager#isSplitSystemUser split system user mode} is not enabled,
159      * the method always returns false.
160      */
isSystemOnly()161     public boolean isSystemOnly() {
162         return isSystemOnly(id);
163     }
164 
165     /**
166      * Returns true if the given user is a split system user.
167      * <p>If {@link UserManager#isSplitSystemUser split system user mode} is not enabled,
168      * the method always returns false.
169      */
isSystemOnly(int userId)170     public static boolean isSystemOnly(int userId) {
171         return userId == UserHandle.USER_SYSTEM && UserManager.isSplitSystemUser();
172     }
173 
174     /**
175      * @return true if this user can be switched to.
176      **/
supportsSwitchTo()177     public boolean supportsSwitchTo() {
178         if (isEphemeral() && !isEnabled()) {
179             // Don't support switching to an ephemeral user with removal in progress.
180             return false;
181         }
182         // TODO remove fw.show_hidden_users when we have finished developing managed profiles.
183         return !isManagedProfile() || SystemProperties.getBoolean("fw.show_hidden_users", false);
184     }
185 
186     /**
187      * @return true if this user can be switched to by end user through UI.
188      */
supportsSwitchToByUser()189     public boolean supportsSwitchToByUser() {
190         // Hide the system user when it does not represent a human user.
191         boolean hideSystemUser = UserManager.isSplitSystemUser();
192         return (!hideSystemUser || id != UserHandle.USER_SYSTEM) && supportsSwitchTo();
193     }
194 
195     /* @hide */
canHaveProfile()196     public boolean canHaveProfile() {
197         if (isManagedProfile() || isGuest() || isRestricted()) {
198             return false;
199         }
200         if (UserManager.isSplitSystemUser()) {
201             return id != UserHandle.USER_SYSTEM;
202         } else {
203             return id == UserHandle.USER_SYSTEM;
204         }
205     }
206 
UserInfo()207     public UserInfo() {
208     }
209 
UserInfo(UserInfo orig)210     public UserInfo(UserInfo orig) {
211         name = orig.name;
212         iconPath = orig.iconPath;
213         id = orig.id;
214         flags = orig.flags;
215         serialNumber = orig.serialNumber;
216         creationTime = orig.creationTime;
217         lastLoggedInTime = orig.lastLoggedInTime;
218         lastLoggedInFingerprint = orig.lastLoggedInFingerprint;
219         partial = orig.partial;
220         profileGroupId = orig.profileGroupId;
221         restrictedProfileParentId = orig.restrictedProfileParentId;
222         guestToRemove = orig.guestToRemove;
223     }
224 
getUserHandle()225     public UserHandle getUserHandle() {
226         return new UserHandle(id);
227     }
228 
229     @Override
toString()230     public String toString() {
231         return "UserInfo{" + id + ":" + name + ":" + Integer.toHexString(flags) + "}";
232     }
233 
describeContents()234     public int describeContents() {
235         return 0;
236     }
237 
writeToParcel(Parcel dest, int parcelableFlags)238     public void writeToParcel(Parcel dest, int parcelableFlags) {
239         dest.writeInt(id);
240         dest.writeString(name);
241         dest.writeString(iconPath);
242         dest.writeInt(flags);
243         dest.writeInt(serialNumber);
244         dest.writeLong(creationTime);
245         dest.writeLong(lastLoggedInTime);
246         dest.writeString(lastLoggedInFingerprint);
247         dest.writeInt(partial ? 1 : 0);
248         dest.writeInt(profileGroupId);
249         dest.writeInt(guestToRemove ? 1 : 0);
250         dest.writeInt(restrictedProfileParentId);
251     }
252 
253     public static final Parcelable.Creator<UserInfo> CREATOR
254             = new Parcelable.Creator<UserInfo>() {
255         public UserInfo createFromParcel(Parcel source) {
256             return new UserInfo(source);
257         }
258         public UserInfo[] newArray(int size) {
259             return new UserInfo[size];
260         }
261     };
262 
UserInfo(Parcel source)263     private UserInfo(Parcel source) {
264         id = source.readInt();
265         name = source.readString();
266         iconPath = source.readString();
267         flags = source.readInt();
268         serialNumber = source.readInt();
269         creationTime = source.readLong();
270         lastLoggedInTime = source.readLong();
271         lastLoggedInFingerprint = source.readString();
272         partial = source.readInt() != 0;
273         profileGroupId = source.readInt();
274         guestToRemove = source.readInt() != 0;
275         restrictedProfileParentId = source.readInt();
276     }
277 }
278