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 com.android.server.pm;
18 
19 import android.app.Activity;
20 import android.app.ActivityManager;
21 import android.app.ActivityManagerNative;
22 import android.app.IStopUserCallback;
23 import android.content.BroadcastReceiver;
24 import android.content.Context;
25 import android.content.Intent;
26 import android.content.pm.ApplicationInfo;
27 import android.content.pm.PackageManager;
28 import android.content.pm.PackageManager.NameNotFoundException;
29 import android.content.pm.UserInfo;
30 import android.graphics.Bitmap;
31 import android.os.Binder;
32 import android.os.Bundle;
33 import android.os.Environment;
34 import android.os.FileUtils;
35 import android.os.Handler;
36 import android.os.IUserManager;
37 import android.os.Message;
38 import android.os.ParcelFileDescriptor;
39 import android.os.Parcelable;
40 import android.os.Process;
41 import android.os.RemoteException;
42 import android.os.ServiceManager;
43 import android.os.UserHandle;
44 import android.os.UserManager;
45 import android.os.storage.StorageManager;
46 import android.os.storage.VolumeInfo;
47 import android.system.ErrnoException;
48 import android.system.Os;
49 import android.system.OsConstants;
50 import android.util.AtomicFile;
51 import android.util.Log;
52 import android.util.Slog;
53 import android.util.SparseArray;
54 import android.util.SparseBooleanArray;
55 import android.util.TimeUtils;
56 import android.util.Xml;
57 
58 import com.google.android.collect.Sets;
59 
60 import com.android.internal.annotations.VisibleForTesting;
61 import com.android.internal.app.IAppOpsService;
62 import com.android.internal.util.ArrayUtils;
63 import com.android.internal.util.FastXmlSerializer;
64 import com.android.internal.util.XmlUtils;
65 
66 import org.xmlpull.v1.XmlPullParser;
67 import org.xmlpull.v1.XmlPullParserException;
68 import org.xmlpull.v1.XmlSerializer;
69 
70 import java.io.BufferedOutputStream;
71 import java.io.File;
72 import java.io.FileDescriptor;
73 import java.io.FileInputStream;
74 import java.io.FileNotFoundException;
75 import java.io.FileOutputStream;
76 import java.io.IOException;
77 import java.io.PrintWriter;
78 import java.nio.charset.StandardCharsets;
79 import java.util.ArrayList;
80 import java.util.List;
81 import java.util.Set;
82 
83 import libcore.io.IoUtils;
84 
85 public class UserManagerService extends IUserManager.Stub {
86 
87     private static final String LOG_TAG = "UserManagerService";
88 
89     private static final boolean DBG = false;
90 
91     private static final String TAG_NAME = "name";
92     private static final String ATTR_FLAGS = "flags";
93     private static final String ATTR_ICON_PATH = "icon";
94     private static final String ATTR_ID = "id";
95     private static final String ATTR_CREATION_TIME = "created";
96     private static final String ATTR_LAST_LOGGED_IN_TIME = "lastLoggedIn";
97     private static final String ATTR_SERIAL_NO = "serialNumber";
98     private static final String ATTR_NEXT_SERIAL_NO = "nextSerialNumber";
99     private static final String ATTR_PARTIAL = "partial";
100     private static final String ATTR_GUEST_TO_REMOVE = "guestToRemove";
101     private static final String ATTR_USER_VERSION = "version";
102     private static final String ATTR_PROFILE_GROUP_ID = "profileGroupId";
103     private static final String TAG_GUEST_RESTRICTIONS = "guestRestrictions";
104     private static final String TAG_USERS = "users";
105     private static final String TAG_USER = "user";
106     private static final String TAG_RESTRICTIONS = "restrictions";
107     private static final String TAG_ENTRY = "entry";
108     private static final String TAG_VALUE = "value";
109     private static final String ATTR_KEY = "key";
110     private static final String ATTR_VALUE_TYPE = "type";
111     private static final String ATTR_MULTIPLE = "m";
112 
113     private static final String ATTR_TYPE_STRING_ARRAY = "sa";
114     private static final String ATTR_TYPE_STRING = "s";
115     private static final String ATTR_TYPE_BOOLEAN = "b";
116     private static final String ATTR_TYPE_INTEGER = "i";
117     private static final String ATTR_TYPE_BUNDLE = "B";
118     private static final String ATTR_TYPE_BUNDLE_ARRAY = "BA";
119 
120     private static final String USER_INFO_DIR = "system" + File.separator + "users";
121     private static final String USER_LIST_FILENAME = "userlist.xml";
122     private static final String USER_PHOTO_FILENAME = "photo.png";
123     private static final String USER_PHOTO_FILENAME_TMP = USER_PHOTO_FILENAME + ".tmp";
124 
125     private static final String RESTRICTIONS_FILE_PREFIX = "res_";
126     private static final String XML_SUFFIX = ".xml";
127 
128     private static final int MIN_USER_ID = 10;
129 
130     private static final int USER_VERSION = 5;
131 
132     private static final long EPOCH_PLUS_30_YEARS = 30L * 365 * 24 * 60 * 60 * 1000L; // ms
133 
134     // Maximum number of managed profiles permitted is 1. This cannot be increased
135     // without first making sure that the rest of the framework is prepared for it.
136     private static final int MAX_MANAGED_PROFILES = 1;
137 
138     /**
139      * Flag indicating whether device credentials are shared among same-user profiles.
140      */
141     private static final boolean CONFIG_PROFILES_SHARE_CREDENTIAL = true;
142 
143     // Set of user restrictions, which can only be enforced by the system
144     private static final Set<String> SYSTEM_CONTROLLED_RESTRICTIONS = Sets.newArraySet(
145             UserManager.DISALLOW_RECORD_AUDIO);
146 
147     static final int WRITE_USER_MSG = 1;
148     static final int WRITE_USER_DELAY = 2*1000;  // 2 seconds
149 
150     private static final String XATTR_SERIAL = "user.serial";
151 
152     private final Context mContext;
153     private final PackageManagerService mPm;
154     private final Object mInstallLock;
155     private final Object mPackagesLock;
156 
157     private final Handler mHandler;
158 
159     private final File mUsersDir;
160     private final File mUserListFile;
161 
162     private final SparseArray<UserInfo> mUsers = new SparseArray<UserInfo>();
163     private final SparseArray<Bundle> mUserRestrictions = new SparseArray<Bundle>();
164     private final Bundle mGuestRestrictions = new Bundle();
165 
166     /**
167      * Set of user IDs being actively removed. Removed IDs linger in this set
168      * for several seconds to work around a VFS caching issue.
169      */
170     // @GuardedBy("mPackagesLock")
171     private final SparseBooleanArray mRemovingUserIds = new SparseBooleanArray();
172 
173     private int[] mUserIds;
174     private int mNextSerialNumber;
175     private int mUserVersion = 0;
176 
177     private IAppOpsService mAppOpsService;
178 
179     private static UserManagerService sInstance;
180 
getInstance()181     public static UserManagerService getInstance() {
182         synchronized (UserManagerService.class) {
183             return sInstance;
184         }
185     }
186 
187     /**
188      * Available for testing purposes.
189      */
UserManagerService(File dataDir, File baseUserPath)190     UserManagerService(File dataDir, File baseUserPath) {
191         this(null, null, new Object(), new Object(), dataDir, baseUserPath);
192     }
193 
194     /**
195      * Called by package manager to create the service.  This is closely
196      * associated with the package manager, and the given lock is the
197      * package manager's own lock.
198      */
UserManagerService(Context context, PackageManagerService pm, Object installLock, Object packagesLock)199     UserManagerService(Context context, PackageManagerService pm,
200             Object installLock, Object packagesLock) {
201         this(context, pm, installLock, packagesLock,
202                 Environment.getDataDirectory(),
203                 new File(Environment.getDataDirectory(), "user"));
204     }
205 
206     /**
207      * Available for testing purposes.
208      */
UserManagerService(Context context, PackageManagerService pm, Object installLock, Object packagesLock, File dataDir, File baseUserPath)209     private UserManagerService(Context context, PackageManagerService pm,
210             Object installLock, Object packagesLock,
211             File dataDir, File baseUserPath) {
212         mContext = context;
213         mPm = pm;
214         mInstallLock = installLock;
215         mPackagesLock = packagesLock;
216         mHandler = new MainHandler();
217         synchronized (mInstallLock) {
218             synchronized (mPackagesLock) {
219                 mUsersDir = new File(dataDir, USER_INFO_DIR);
220                 mUsersDir.mkdirs();
221                 // Make zeroth user directory, for services to migrate their files to that location
222                 File userZeroDir = new File(mUsersDir, "0");
223                 userZeroDir.mkdirs();
224                 FileUtils.setPermissions(mUsersDir.toString(),
225                         FileUtils.S_IRWXU|FileUtils.S_IRWXG
226                         |FileUtils.S_IROTH|FileUtils.S_IXOTH,
227                         -1, -1);
228                 mUserListFile = new File(mUsersDir, USER_LIST_FILENAME);
229                 initDefaultGuestRestrictions();
230                 readUserListLocked();
231                 sInstance = this;
232             }
233         }
234     }
235 
systemReady()236     void systemReady() {
237         synchronized (mInstallLock) {
238             synchronized (mPackagesLock) {
239                 // Prune out any partially created/partially removed users.
240                 ArrayList<UserInfo> partials = new ArrayList<UserInfo>();
241                 for (int i = 0; i < mUsers.size(); i++) {
242                     UserInfo ui = mUsers.valueAt(i);
243                     if ((ui.partial || ui.guestToRemove) && i != 0) {
244                         partials.add(ui);
245                     }
246                 }
247                 for (int i = 0; i < partials.size(); i++) {
248                     UserInfo ui = partials.get(i);
249                     Slog.w(LOG_TAG, "Removing partially created user " + ui.id
250                             + " (name=" + ui.name + ")");
251                     removeUserStateLocked(ui.id);
252                 }
253             }
254         }
255         onUserForeground(UserHandle.USER_OWNER);
256         mAppOpsService = IAppOpsService.Stub.asInterface(
257                 ServiceManager.getService(Context.APP_OPS_SERVICE));
258         for (int i = 0; i < mUserIds.length; ++i) {
259             try {
260                 mAppOpsService.setUserRestrictions(mUserRestrictions.get(mUserIds[i]), mUserIds[i]);
261             } catch (RemoteException e) {
262                 Log.w(LOG_TAG, "Unable to notify AppOpsService of UserRestrictions");
263             }
264         }
265     }
266 
267     @Override
getUsers(boolean excludeDying)268     public List<UserInfo> getUsers(boolean excludeDying) {
269         checkManageUsersPermission("query users");
270         synchronized (mPackagesLock) {
271             ArrayList<UserInfo> users = new ArrayList<UserInfo>(mUsers.size());
272             for (int i = 0; i < mUsers.size(); i++) {
273                 UserInfo ui = mUsers.valueAt(i);
274                 if (ui.partial) {
275                     continue;
276                 }
277                 if (!excludeDying || !mRemovingUserIds.get(ui.id)) {
278                     users.add(ui);
279                 }
280             }
281             return users;
282         }
283     }
284 
285     @Override
getProfiles(int userId, boolean enabledOnly)286     public List<UserInfo> getProfiles(int userId, boolean enabledOnly) {
287         if (userId != UserHandle.getCallingUserId()) {
288             checkManageUsersPermission("getting profiles related to user " + userId);
289         }
290         final long ident = Binder.clearCallingIdentity();
291         try {
292             synchronized (mPackagesLock) {
293                 return getProfilesLocked(userId, enabledOnly);
294             }
295         } finally {
296             Binder.restoreCallingIdentity(ident);
297         }
298     }
299 
300     /** Assume permissions already checked and caller's identity cleared */
getProfilesLocked(int userId, boolean enabledOnly)301     private List<UserInfo> getProfilesLocked(int userId, boolean enabledOnly) {
302         UserInfo user = getUserInfoLocked(userId);
303         ArrayList<UserInfo> users = new ArrayList<UserInfo>(mUsers.size());
304         if (user == null) {
305             // Probably a dying user
306             return users;
307         }
308         for (int i = 0; i < mUsers.size(); i++) {
309             UserInfo profile = mUsers.valueAt(i);
310             if (!isProfileOf(user, profile)) {
311                 continue;
312             }
313             if (enabledOnly && !profile.isEnabled()) {
314                 continue;
315             }
316             if (mRemovingUserIds.get(profile.id)) {
317                 continue;
318             }
319             users.add(profile);
320         }
321         return users;
322     }
323 
324     @Override
getCredentialOwnerProfile(int userHandle)325     public int getCredentialOwnerProfile(int userHandle) {
326         checkManageUsersPermission("get the credential owner");
327         if (CONFIG_PROFILES_SHARE_CREDENTIAL) {
328             synchronized (mPackagesLock) {
329                 UserInfo profileParent = getProfileParentLocked(userHandle);
330                 if (profileParent != null) {
331                     return profileParent.id;
332                 }
333             }
334         }
335 
336         return userHandle;
337     }
338 
339     @Override
getProfileParent(int userHandle)340     public UserInfo getProfileParent(int userHandle) {
341         checkManageUsersPermission("get the profile parent");
342         synchronized (mPackagesLock) {
343             return getProfileParentLocked(userHandle);
344         }
345     }
346 
getProfileParentLocked(int userHandle)347     private UserInfo getProfileParentLocked(int userHandle) {
348         UserInfo profile = getUserInfoLocked(userHandle);
349         if (profile == null) {
350             return null;
351         }
352         int parentUserId = profile.profileGroupId;
353         if (parentUserId == UserInfo.NO_PROFILE_GROUP_ID) {
354             return null;
355         } else {
356             return getUserInfoLocked(parentUserId);
357         }
358     }
359 
isProfileOf(UserInfo user, UserInfo profile)360     private boolean isProfileOf(UserInfo user, UserInfo profile) {
361         return user.id == profile.id ||
362                 (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID
363                 && user.profileGroupId == profile.profileGroupId);
364     }
365 
366     @Override
setUserEnabled(int userId)367     public void setUserEnabled(int userId) {
368         checkManageUsersPermission("enable user");
369         synchronized (mPackagesLock) {
370             UserInfo info = getUserInfoLocked(userId);
371             if (info != null && !info.isEnabled()) {
372                 info.flags ^= UserInfo.FLAG_DISABLED;
373                 writeUserLocked(info);
374             }
375         }
376     }
377 
378     @Override
getUserInfo(int userId)379     public UserInfo getUserInfo(int userId) {
380         checkManageUsersPermission("query user");
381         synchronized (mPackagesLock) {
382             return getUserInfoLocked(userId);
383         }
384     }
385 
386     @Override
isRestricted()387     public boolean isRestricted() {
388         synchronized (mPackagesLock) {
389             return getUserInfoLocked(UserHandle.getCallingUserId()).isRestricted();
390         }
391     }
392 
393     /*
394      * Should be locked on mUsers before calling this.
395      */
getUserInfoLocked(int userId)396     private UserInfo getUserInfoLocked(int userId) {
397         UserInfo ui = mUsers.get(userId);
398         // If it is partial and not in the process of being removed, return as unknown user.
399         if (ui != null && ui.partial && !mRemovingUserIds.get(userId)) {
400             Slog.w(LOG_TAG, "getUserInfo: unknown user #" + userId);
401             return null;
402         }
403         return ui;
404     }
405 
406     /** Called by PackageManagerService */
exists(int userId)407     public boolean exists(int userId) {
408         synchronized (mPackagesLock) {
409             return mUsers.get(userId) != null;
410         }
411     }
412 
413     @Override
setUserName(int userId, String name)414     public void setUserName(int userId, String name) {
415         checkManageUsersPermission("rename users");
416         boolean changed = false;
417         synchronized (mPackagesLock) {
418             UserInfo info = mUsers.get(userId);
419             if (info == null || info.partial) {
420                 Slog.w(LOG_TAG, "setUserName: unknown user #" + userId);
421                 return;
422             }
423             if (name != null && !name.equals(info.name)) {
424                 info.name = name;
425                 writeUserLocked(info);
426                 changed = true;
427             }
428         }
429         if (changed) {
430             sendUserInfoChangedBroadcast(userId);
431         }
432     }
433 
434     @Override
setUserIcon(int userId, Bitmap bitmap)435     public void setUserIcon(int userId, Bitmap bitmap) {
436         checkManageUsersPermission("update users");
437         long ident = Binder.clearCallingIdentity();
438         try {
439             synchronized (mPackagesLock) {
440                 UserInfo info = mUsers.get(userId);
441                 if (info == null || info.partial) {
442                     Slog.w(LOG_TAG, "setUserIcon: unknown user #" + userId);
443                     return;
444                 }
445                 writeBitmapLocked(info, bitmap);
446                 writeUserLocked(info);
447             }
448             sendUserInfoChangedBroadcast(userId);
449         } finally {
450             Binder.restoreCallingIdentity(ident);
451         }
452     }
453 
sendUserInfoChangedBroadcast(int userId)454     private void sendUserInfoChangedBroadcast(int userId) {
455         Intent changedIntent = new Intent(Intent.ACTION_USER_INFO_CHANGED);
456         changedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
457         changedIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
458         mContext.sendBroadcastAsUser(changedIntent, UserHandle.ALL);
459     }
460 
461     @Override
getUserIcon(int userId)462     public ParcelFileDescriptor getUserIcon(int userId) {
463         String iconPath;
464         synchronized (mPackagesLock) {
465             UserInfo info = mUsers.get(userId);
466             if (info == null || info.partial) {
467                 Slog.w(LOG_TAG, "getUserIcon: unknown user #" + userId);
468                 return null;
469             }
470             int callingGroupId = mUsers.get(UserHandle.getCallingUserId()).profileGroupId;
471             if (callingGroupId == UserInfo.NO_PROFILE_GROUP_ID
472                     || callingGroupId != info.profileGroupId) {
473                 checkManageUsersPermission("get the icon of a user who is not related");
474             }
475             if (info.iconPath == null) {
476                 return null;
477             }
478             iconPath = info.iconPath;
479         }
480 
481         try {
482             return ParcelFileDescriptor.open(
483                     new File(iconPath), ParcelFileDescriptor.MODE_READ_ONLY);
484         } catch (FileNotFoundException e) {
485             Log.e(LOG_TAG, "Couldn't find icon file", e);
486         }
487         return null;
488     }
489 
makeInitialized(int userId)490     public void makeInitialized(int userId) {
491         checkManageUsersPermission("makeInitialized");
492         synchronized (mPackagesLock) {
493             UserInfo info = mUsers.get(userId);
494             if (info == null || info.partial) {
495                 Slog.w(LOG_TAG, "makeInitialized: unknown user #" + userId);
496             }
497             if ((info.flags&UserInfo.FLAG_INITIALIZED) == 0) {
498                 info.flags |= UserInfo.FLAG_INITIALIZED;
499                 scheduleWriteUserLocked(info);
500             }
501         }
502     }
503 
504     /**
505      * If default guest restrictions haven't been initialized yet, add the basic
506      * restrictions.
507      */
initDefaultGuestRestrictions()508     private void initDefaultGuestRestrictions() {
509         if (mGuestRestrictions.isEmpty()) {
510             mGuestRestrictions.putBoolean(UserManager.DISALLOW_OUTGOING_CALLS, true);
511             mGuestRestrictions.putBoolean(UserManager.DISALLOW_SMS, true);
512         }
513     }
514 
515     @Override
getDefaultGuestRestrictions()516     public Bundle getDefaultGuestRestrictions() {
517         checkManageUsersPermission("getDefaultGuestRestrictions");
518         synchronized (mPackagesLock) {
519             return new Bundle(mGuestRestrictions);
520         }
521     }
522 
523     @Override
setDefaultGuestRestrictions(Bundle restrictions)524     public void setDefaultGuestRestrictions(Bundle restrictions) {
525         checkManageUsersPermission("setDefaultGuestRestrictions");
526         synchronized (mPackagesLock) {
527             mGuestRestrictions.clear();
528             mGuestRestrictions.putAll(restrictions);
529             writeUserListLocked();
530         }
531     }
532 
533     @Override
hasUserRestriction(String restrictionKey, int userId)534     public boolean hasUserRestriction(String restrictionKey, int userId) {
535         synchronized (mPackagesLock) {
536             Bundle restrictions = mUserRestrictions.get(userId);
537             return restrictions != null && restrictions.getBoolean(restrictionKey);
538         }
539     }
540 
541     @Override
getUserRestrictions(int userId)542     public Bundle getUserRestrictions(int userId) {
543         // checkManageUsersPermission("getUserRestrictions");
544 
545         synchronized (mPackagesLock) {
546             Bundle restrictions = mUserRestrictions.get(userId);
547             return restrictions != null ? new Bundle(restrictions) : new Bundle();
548         }
549     }
550 
551     @Override
setUserRestriction(String key, boolean value, int userId)552     public void setUserRestriction(String key, boolean value, int userId) {
553         checkManageUsersPermission("setUserRestriction");
554         synchronized (mPackagesLock) {
555             if (!SYSTEM_CONTROLLED_RESTRICTIONS.contains(key)) {
556                 Bundle restrictions = getUserRestrictions(userId);
557                 restrictions.putBoolean(key, value);
558                 setUserRestrictionsInternalLocked(restrictions, userId);
559             }
560         }
561     }
562 
563     @Override
setSystemControlledUserRestriction(String key, boolean value, int userId)564     public void setSystemControlledUserRestriction(String key, boolean value, int userId) {
565         checkSystemOrRoot("setSystemControlledUserRestriction");
566         synchronized (mPackagesLock) {
567             Bundle restrictions = getUserRestrictions(userId);
568             restrictions.putBoolean(key, value);
569             setUserRestrictionsInternalLocked(restrictions, userId);
570         }
571     }
572 
573     @Override
setUserRestrictions(Bundle restrictions, int userId)574     public void setUserRestrictions(Bundle restrictions, int userId) {
575         checkManageUsersPermission("setUserRestrictions");
576         if (restrictions == null) return;
577 
578         synchronized (mPackagesLock) {
579             final Bundle oldUserRestrictions = mUserRestrictions.get(userId);
580             // Restore the original state of system controlled restrictions from oldUserRestrictions
581             for (String key : SYSTEM_CONTROLLED_RESTRICTIONS) {
582                 restrictions.remove(key);
583                 if (oldUserRestrictions.containsKey(key)) {
584                     restrictions.putBoolean(key, oldUserRestrictions.getBoolean(key));
585                 }
586             }
587             setUserRestrictionsInternalLocked(restrictions, userId);
588         }
589     }
590 
setUserRestrictionsInternalLocked(Bundle restrictions, int userId)591     private void setUserRestrictionsInternalLocked(Bundle restrictions, int userId) {
592         final Bundle userRestrictions = mUserRestrictions.get(userId);
593         userRestrictions.clear();
594         userRestrictions.putAll(restrictions);
595         long token = Binder.clearCallingIdentity();
596         try {
597         mAppOpsService.setUserRestrictions(userRestrictions, userId);
598         } catch (RemoteException e) {
599             Log.w(LOG_TAG, "Unable to notify AppOpsService of UserRestrictions");
600         } finally {
601             Binder.restoreCallingIdentity(token);
602         }
603         scheduleWriteUserLocked(mUsers.get(userId));
604     }
605 
606     /**
607      * Check if we've hit the limit of how many users can be created.
608      */
isUserLimitReachedLocked()609     private boolean isUserLimitReachedLocked() {
610         return getAliveUsersExcludingGuestsCountLocked() >= UserManager.getMaxSupportedUsers();
611     }
612 
613     @Override
canAddMoreManagedProfiles()614     public boolean canAddMoreManagedProfiles() {
615         checkManageUsersPermission("check if more managed profiles can be added.");
616         if (ActivityManager.isLowRamDeviceStatic()) {
617             return false;
618         }
619         if (!mContext.getPackageManager().hasSystemFeature(
620                 PackageManager.FEATURE_MANAGED_USERS)) {
621             return false;
622         }
623         synchronized(mPackagesLock) {
624             // Limit number of managed profiles that can be created
625             if (numberOfUsersOfTypeLocked(UserInfo.FLAG_MANAGED_PROFILE, true)
626                     >= MAX_MANAGED_PROFILES) {
627                 return false;
628             }
629             int usersCount = getAliveUsersExcludingGuestsCountLocked();
630             // We allow creating a managed profile in the special case where there is only one user.
631             return usersCount == 1 || usersCount < UserManager.getMaxSupportedUsers();
632         }
633     }
634 
getAliveUsersExcludingGuestsCountLocked()635     private int getAliveUsersExcludingGuestsCountLocked() {
636         int aliveUserCount = 0;
637         final int totalUserCount = mUsers.size();
638         // Skip over users being removed
639         for (int i = 0; i < totalUserCount; i++) {
640             UserInfo user = mUsers.valueAt(i);
641             if (!mRemovingUserIds.get(user.id)
642                     && !user.isGuest() && !user.partial) {
643                 aliveUserCount++;
644             }
645         }
646         return aliveUserCount;
647     }
648 
649     /**
650      * Enforces that only the system UID or root's UID or apps that have the
651      * {@link android.Manifest.permission#MANAGE_USERS MANAGE_USERS}
652      * permission can make certain calls to the UserManager.
653      *
654      * @param message used as message if SecurityException is thrown
655      * @throws SecurityException if the caller is not system or root
656      */
checkManageUsersPermission(String message)657     private static final void checkManageUsersPermission(String message) {
658         final int uid = Binder.getCallingUid();
659         if (uid != Process.SYSTEM_UID && uid != 0
660                 && ActivityManager.checkComponentPermission(
661                         android.Manifest.permission.MANAGE_USERS,
662                         uid, -1, true) != PackageManager.PERMISSION_GRANTED) {
663             throw new SecurityException("You need MANAGE_USERS permission to: " + message);
664         }
665     }
666 
checkSystemOrRoot(String message)667     private static void checkSystemOrRoot(String message) {
668         final int uid = Binder.getCallingUid();
669         if (uid != Process.SYSTEM_UID && uid != 0) {
670             throw new SecurityException("Only system may call: " + message);
671         }
672     }
673 
writeBitmapLocked(UserInfo info, Bitmap bitmap)674     private void writeBitmapLocked(UserInfo info, Bitmap bitmap) {
675         try {
676             File dir = new File(mUsersDir, Integer.toString(info.id));
677             File file = new File(dir, USER_PHOTO_FILENAME);
678             File tmp = new File(dir, USER_PHOTO_FILENAME_TMP);
679             if (!dir.exists()) {
680                 dir.mkdir();
681                 FileUtils.setPermissions(
682                         dir.getPath(),
683                         FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
684                         -1, -1);
685             }
686             FileOutputStream os;
687             if (bitmap.compress(Bitmap.CompressFormat.PNG, 100, os = new FileOutputStream(tmp))
688                     && tmp.renameTo(file)) {
689                 info.iconPath = file.getAbsolutePath();
690             }
691             try {
692                 os.close();
693             } catch (IOException ioe) {
694                 // What the ... !
695             }
696             tmp.delete();
697         } catch (FileNotFoundException e) {
698             Slog.w(LOG_TAG, "Error setting photo for user ", e);
699         }
700     }
701 
702     /**
703      * Returns an array of user ids. This array is cached here for quick access, so do not modify or
704      * cache it elsewhere.
705      * @return the array of user ids.
706      */
getUserIds()707     public int[] getUserIds() {
708         synchronized (mPackagesLock) {
709             return mUserIds;
710         }
711     }
712 
getUserIdsLPr()713     int[] getUserIdsLPr() {
714         return mUserIds;
715     }
716 
readUserListLocked()717     private void readUserListLocked() {
718         if (!mUserListFile.exists()) {
719             fallbackToSingleUserLocked();
720             return;
721         }
722         FileInputStream fis = null;
723         AtomicFile userListFile = new AtomicFile(mUserListFile);
724         try {
725             fis = userListFile.openRead();
726             XmlPullParser parser = Xml.newPullParser();
727             parser.setInput(fis, StandardCharsets.UTF_8.name());
728             int type;
729             while ((type = parser.next()) != XmlPullParser.START_TAG
730                     && type != XmlPullParser.END_DOCUMENT) {
731                 ;
732             }
733 
734             if (type != XmlPullParser.START_TAG) {
735                 Slog.e(LOG_TAG, "Unable to read user list");
736                 fallbackToSingleUserLocked();
737                 return;
738             }
739 
740             mNextSerialNumber = -1;
741             if (parser.getName().equals(TAG_USERS)) {
742                 String lastSerialNumber = parser.getAttributeValue(null, ATTR_NEXT_SERIAL_NO);
743                 if (lastSerialNumber != null) {
744                     mNextSerialNumber = Integer.parseInt(lastSerialNumber);
745                 }
746                 String versionNumber = parser.getAttributeValue(null, ATTR_USER_VERSION);
747                 if (versionNumber != null) {
748                     mUserVersion = Integer.parseInt(versionNumber);
749                 }
750             }
751 
752             while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
753                 if (type == XmlPullParser.START_TAG) {
754                     final String name = parser.getName();
755                     if (name.equals(TAG_USER)) {
756                         String id = parser.getAttributeValue(null, ATTR_ID);
757                         UserInfo user = readUserLocked(Integer.parseInt(id));
758 
759                         if (user != null) {
760                             mUsers.put(user.id, user);
761                             if (mNextSerialNumber < 0 || mNextSerialNumber <= user.id) {
762                                 mNextSerialNumber = user.id + 1;
763                             }
764                         }
765                     } else if (name.equals(TAG_GUEST_RESTRICTIONS)) {
766                         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
767                                 && type != XmlPullParser.END_TAG) {
768                             if (type == XmlPullParser.START_TAG) {
769                                 if (parser.getName().equals(TAG_RESTRICTIONS)) {
770                                     readRestrictionsLocked(parser, mGuestRestrictions);
771                                 }
772                                 break;
773                             }
774                         }
775                     }
776                 }
777             }
778             updateUserIdsLocked();
779             upgradeIfNecessaryLocked();
780         } catch (IOException ioe) {
781             fallbackToSingleUserLocked();
782         } catch (XmlPullParserException pe) {
783             fallbackToSingleUserLocked();
784         } finally {
785             if (fis != null) {
786                 try {
787                     fis.close();
788                 } catch (IOException e) {
789                 }
790             }
791         }
792     }
793 
794     /**
795      * Upgrade steps between versions, either for fixing bugs or changing the data format.
796      */
upgradeIfNecessaryLocked()797     private void upgradeIfNecessaryLocked() {
798         int userVersion = mUserVersion;
799         if (userVersion < 1) {
800             // Assign a proper name for the owner, if not initialized correctly before
801             UserInfo user = mUsers.get(UserHandle.USER_OWNER);
802             if ("Primary".equals(user.name)) {
803                 user.name = mContext.getResources().getString(com.android.internal.R.string.owner_name);
804                 scheduleWriteUserLocked(user);
805             }
806             userVersion = 1;
807         }
808 
809         if (userVersion < 2) {
810             // Owner should be marked as initialized
811             UserInfo user = mUsers.get(UserHandle.USER_OWNER);
812             if ((user.flags & UserInfo.FLAG_INITIALIZED) == 0) {
813                 user.flags |= UserInfo.FLAG_INITIALIZED;
814                 scheduleWriteUserLocked(user);
815             }
816             userVersion = 2;
817         }
818 
819 
820         if (userVersion < 4) {
821             userVersion = 4;
822         }
823 
824         if (userVersion < 5) {
825             initDefaultGuestRestrictions();
826             userVersion = 5;
827         }
828 
829         if (userVersion < USER_VERSION) {
830             Slog.w(LOG_TAG, "User version " + mUserVersion + " didn't upgrade as expected to "
831                     + USER_VERSION);
832         } else {
833             mUserVersion = userVersion;
834             writeUserListLocked();
835         }
836     }
837 
fallbackToSingleUserLocked()838     private void fallbackToSingleUserLocked() {
839         // Create the primary user
840         UserInfo primary = new UserInfo(UserHandle.USER_OWNER,
841                 mContext.getResources().getString(com.android.internal.R.string.owner_name), null,
842                 UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY | UserInfo.FLAG_INITIALIZED);
843         mUsers.put(0, primary);
844         mNextSerialNumber = MIN_USER_ID;
845         mUserVersion = USER_VERSION;
846 
847         Bundle restrictions = new Bundle();
848         mUserRestrictions.append(UserHandle.USER_OWNER, restrictions);
849 
850         updateUserIdsLocked();
851         initDefaultGuestRestrictions();
852 
853         writeUserListLocked();
854         writeUserLocked(primary);
855     }
856 
scheduleWriteUserLocked(UserInfo userInfo)857     private void scheduleWriteUserLocked(UserInfo userInfo) {
858         if (!mHandler.hasMessages(WRITE_USER_MSG, userInfo)) {
859             Message msg = mHandler.obtainMessage(WRITE_USER_MSG, userInfo);
860             mHandler.sendMessageDelayed(msg, WRITE_USER_DELAY);
861         }
862     }
863 
864     /*
865      * Writes the user file in this format:
866      *
867      * <user flags="20039023" id="0">
868      *   <name>Primary</name>
869      * </user>
870      */
writeUserLocked(UserInfo userInfo)871     private void writeUserLocked(UserInfo userInfo) {
872         FileOutputStream fos = null;
873         AtomicFile userFile = new AtomicFile(new File(mUsersDir, userInfo.id + XML_SUFFIX));
874         try {
875             fos = userFile.startWrite();
876             final BufferedOutputStream bos = new BufferedOutputStream(fos);
877 
878             // XmlSerializer serializer = XmlUtils.serializerInstance();
879             final XmlSerializer serializer = new FastXmlSerializer();
880             serializer.setOutput(bos, StandardCharsets.UTF_8.name());
881             serializer.startDocument(null, true);
882             serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
883 
884             serializer.startTag(null, TAG_USER);
885             serializer.attribute(null, ATTR_ID, Integer.toString(userInfo.id));
886             serializer.attribute(null, ATTR_SERIAL_NO, Integer.toString(userInfo.serialNumber));
887             serializer.attribute(null, ATTR_FLAGS, Integer.toString(userInfo.flags));
888             serializer.attribute(null, ATTR_CREATION_TIME, Long.toString(userInfo.creationTime));
889             serializer.attribute(null, ATTR_LAST_LOGGED_IN_TIME,
890                     Long.toString(userInfo.lastLoggedInTime));
891             if (userInfo.iconPath != null) {
892                 serializer.attribute(null,  ATTR_ICON_PATH, userInfo.iconPath);
893             }
894             if (userInfo.partial) {
895                 serializer.attribute(null, ATTR_PARTIAL, "true");
896             }
897             if (userInfo.guestToRemove) {
898                 serializer.attribute(null, ATTR_GUEST_TO_REMOVE, "true");
899             }
900             if (userInfo.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
901                 serializer.attribute(null, ATTR_PROFILE_GROUP_ID,
902                         Integer.toString(userInfo.profileGroupId));
903             }
904 
905             serializer.startTag(null, TAG_NAME);
906             serializer.text(userInfo.name);
907             serializer.endTag(null, TAG_NAME);
908             Bundle restrictions = mUserRestrictions.get(userInfo.id);
909             if (restrictions != null) {
910                 writeRestrictionsLocked(serializer, restrictions);
911             }
912             serializer.endTag(null, TAG_USER);
913 
914             serializer.endDocument();
915             userFile.finishWrite(fos);
916         } catch (Exception ioe) {
917             Slog.e(LOG_TAG, "Error writing user info " + userInfo.id + "\n" + ioe);
918             userFile.failWrite(fos);
919         }
920     }
921 
922     /*
923      * Writes the user list file in this format:
924      *
925      * <users nextSerialNumber="3">
926      *   <user id="0"></user>
927      *   <user id="2"></user>
928      * </users>
929      */
writeUserListLocked()930     private void writeUserListLocked() {
931         FileOutputStream fos = null;
932         AtomicFile userListFile = new AtomicFile(mUserListFile);
933         try {
934             fos = userListFile.startWrite();
935             final BufferedOutputStream bos = new BufferedOutputStream(fos);
936 
937             // XmlSerializer serializer = XmlUtils.serializerInstance();
938             final XmlSerializer serializer = new FastXmlSerializer();
939             serializer.setOutput(bos, StandardCharsets.UTF_8.name());
940             serializer.startDocument(null, true);
941             serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
942 
943             serializer.startTag(null, TAG_USERS);
944             serializer.attribute(null, ATTR_NEXT_SERIAL_NO, Integer.toString(mNextSerialNumber));
945             serializer.attribute(null, ATTR_USER_VERSION, Integer.toString(mUserVersion));
946 
947             serializer.startTag(null, TAG_GUEST_RESTRICTIONS);
948             writeRestrictionsLocked(serializer, mGuestRestrictions);
949             serializer.endTag(null, TAG_GUEST_RESTRICTIONS);
950             for (int i = 0; i < mUsers.size(); i++) {
951                 UserInfo user = mUsers.valueAt(i);
952                 serializer.startTag(null, TAG_USER);
953                 serializer.attribute(null, ATTR_ID, Integer.toString(user.id));
954                 serializer.endTag(null, TAG_USER);
955             }
956 
957             serializer.endTag(null, TAG_USERS);
958 
959             serializer.endDocument();
960             userListFile.finishWrite(fos);
961         } catch (Exception e) {
962             userListFile.failWrite(fos);
963             Slog.e(LOG_TAG, "Error writing user list");
964         }
965     }
966 
writeRestrictionsLocked(XmlSerializer serializer, Bundle restrictions)967     private void writeRestrictionsLocked(XmlSerializer serializer, Bundle restrictions)
968             throws IOException {
969         serializer.startTag(null, TAG_RESTRICTIONS);
970         writeBoolean(serializer, restrictions, UserManager.DISALLOW_CONFIG_WIFI);
971         writeBoolean(serializer, restrictions, UserManager.DISALLOW_MODIFY_ACCOUNTS);
972         writeBoolean(serializer, restrictions, UserManager.DISALLOW_INSTALL_APPS);
973         writeBoolean(serializer, restrictions, UserManager.DISALLOW_UNINSTALL_APPS);
974         writeBoolean(serializer, restrictions, UserManager.DISALLOW_SHARE_LOCATION);
975         writeBoolean(serializer, restrictions,
976                 UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES);
977         writeBoolean(serializer, restrictions, UserManager.DISALLOW_CONFIG_BLUETOOTH);
978         writeBoolean(serializer, restrictions, UserManager.DISALLOW_USB_FILE_TRANSFER);
979         writeBoolean(serializer, restrictions, UserManager.DISALLOW_CONFIG_CREDENTIALS);
980         writeBoolean(serializer, restrictions, UserManager.DISALLOW_REMOVE_USER);
981         writeBoolean(serializer, restrictions, UserManager.DISALLOW_DEBUGGING_FEATURES);
982         writeBoolean(serializer, restrictions, UserManager.DISALLOW_CONFIG_VPN);
983         writeBoolean(serializer, restrictions, UserManager.DISALLOW_CONFIG_TETHERING);
984         writeBoolean(serializer, restrictions, UserManager.DISALLOW_NETWORK_RESET);
985         writeBoolean(serializer, restrictions, UserManager.DISALLOW_FACTORY_RESET);
986         writeBoolean(serializer, restrictions, UserManager.DISALLOW_ADD_USER);
987         writeBoolean(serializer, restrictions, UserManager.ENSURE_VERIFY_APPS);
988         writeBoolean(serializer, restrictions, UserManager.DISALLOW_CONFIG_CELL_BROADCASTS);
989         writeBoolean(serializer, restrictions, UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS);
990         writeBoolean(serializer, restrictions, UserManager.DISALLOW_APPS_CONTROL);
991         writeBoolean(serializer, restrictions, UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA);
992         writeBoolean(serializer, restrictions, UserManager.DISALLOW_UNMUTE_MICROPHONE);
993         writeBoolean(serializer, restrictions, UserManager.DISALLOW_ADJUST_VOLUME);
994         writeBoolean(serializer, restrictions, UserManager.DISALLOW_OUTGOING_CALLS);
995         writeBoolean(serializer, restrictions, UserManager.DISALLOW_SMS);
996         writeBoolean(serializer, restrictions, UserManager.DISALLOW_FUN);
997         writeBoolean(serializer, restrictions, UserManager.DISALLOW_CREATE_WINDOWS);
998         writeBoolean(serializer, restrictions, UserManager.DISALLOW_CROSS_PROFILE_COPY_PASTE);
999         writeBoolean(serializer, restrictions, UserManager.DISALLOW_OUTGOING_BEAM);
1000         writeBoolean(serializer, restrictions, UserManager.DISALLOW_WALLPAPER);
1001         writeBoolean(serializer, restrictions, UserManager.DISALLOW_SAFE_BOOT);
1002         writeBoolean(serializer, restrictions, UserManager.ALLOW_PARENT_PROFILE_APP_LINKING);
1003         serializer.endTag(null, TAG_RESTRICTIONS);
1004     }
1005 
readUserLocked(int id)1006     private UserInfo readUserLocked(int id) {
1007         int flags = 0;
1008         int serialNumber = id;
1009         String name = null;
1010         String iconPath = null;
1011         long creationTime = 0L;
1012         long lastLoggedInTime = 0L;
1013         int profileGroupId = UserInfo.NO_PROFILE_GROUP_ID;
1014         boolean partial = false;
1015         boolean guestToRemove = false;
1016         Bundle restrictions = new Bundle();
1017 
1018         FileInputStream fis = null;
1019         try {
1020             AtomicFile userFile =
1021                     new AtomicFile(new File(mUsersDir, Integer.toString(id) + XML_SUFFIX));
1022             fis = userFile.openRead();
1023             XmlPullParser parser = Xml.newPullParser();
1024             parser.setInput(fis, StandardCharsets.UTF_8.name());
1025             int type;
1026             while ((type = parser.next()) != XmlPullParser.START_TAG
1027                     && type != XmlPullParser.END_DOCUMENT) {
1028                 ;
1029             }
1030 
1031             if (type != XmlPullParser.START_TAG) {
1032                 Slog.e(LOG_TAG, "Unable to read user " + id);
1033                 return null;
1034             }
1035 
1036             if (type == XmlPullParser.START_TAG && parser.getName().equals(TAG_USER)) {
1037                 int storedId = readIntAttribute(parser, ATTR_ID, -1);
1038                 if (storedId != id) {
1039                     Slog.e(LOG_TAG, "User id does not match the file name");
1040                     return null;
1041                 }
1042                 serialNumber = readIntAttribute(parser, ATTR_SERIAL_NO, id);
1043                 flags = readIntAttribute(parser, ATTR_FLAGS, 0);
1044                 iconPath = parser.getAttributeValue(null, ATTR_ICON_PATH);
1045                 creationTime = readLongAttribute(parser, ATTR_CREATION_TIME, 0);
1046                 lastLoggedInTime = readLongAttribute(parser, ATTR_LAST_LOGGED_IN_TIME, 0);
1047                 profileGroupId = readIntAttribute(parser, ATTR_PROFILE_GROUP_ID,
1048                         UserInfo.NO_PROFILE_GROUP_ID);
1049                 String valueString = parser.getAttributeValue(null, ATTR_PARTIAL);
1050                 if ("true".equals(valueString)) {
1051                     partial = true;
1052                 }
1053                 valueString = parser.getAttributeValue(null, ATTR_GUEST_TO_REMOVE);
1054                 if ("true".equals(valueString)) {
1055                     guestToRemove = true;
1056                 }
1057 
1058                 int outerDepth = parser.getDepth();
1059                 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1060                        && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1061                     if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1062                         continue;
1063                     }
1064                     String tag = parser.getName();
1065                     if (TAG_NAME.equals(tag)) {
1066                         type = parser.next();
1067                         if (type == XmlPullParser.TEXT) {
1068                             name = parser.getText();
1069                         }
1070                     } else if (TAG_RESTRICTIONS.equals(tag)) {
1071                         readRestrictionsLocked(parser, restrictions);
1072                     }
1073                 }
1074             }
1075 
1076             UserInfo userInfo = new UserInfo(id, name, iconPath, flags);
1077             userInfo.serialNumber = serialNumber;
1078             userInfo.creationTime = creationTime;
1079             userInfo.lastLoggedInTime = lastLoggedInTime;
1080             userInfo.partial = partial;
1081             userInfo.guestToRemove = guestToRemove;
1082             userInfo.profileGroupId = profileGroupId;
1083             mUserRestrictions.append(id, restrictions);
1084             return userInfo;
1085 
1086         } catch (IOException ioe) {
1087         } catch (XmlPullParserException pe) {
1088         } finally {
1089             if (fis != null) {
1090                 try {
1091                     fis.close();
1092                 } catch (IOException e) {
1093                 }
1094             }
1095         }
1096         return null;
1097     }
1098 
readRestrictionsLocked(XmlPullParser parser, Bundle restrictions)1099     private void readRestrictionsLocked(XmlPullParser parser, Bundle restrictions)
1100             throws IOException {
1101         readBoolean(parser, restrictions, UserManager.DISALLOW_CONFIG_WIFI);
1102         readBoolean(parser, restrictions, UserManager.DISALLOW_MODIFY_ACCOUNTS);
1103         readBoolean(parser, restrictions, UserManager.DISALLOW_INSTALL_APPS);
1104         readBoolean(parser, restrictions, UserManager.DISALLOW_UNINSTALL_APPS);
1105         readBoolean(parser, restrictions, UserManager.DISALLOW_SHARE_LOCATION);
1106         readBoolean(parser, restrictions,
1107                 UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES);
1108         readBoolean(parser, restrictions, UserManager.DISALLOW_CONFIG_BLUETOOTH);
1109         readBoolean(parser, restrictions, UserManager.DISALLOW_USB_FILE_TRANSFER);
1110         readBoolean(parser, restrictions, UserManager.DISALLOW_CONFIG_CREDENTIALS);
1111         readBoolean(parser, restrictions, UserManager.DISALLOW_REMOVE_USER);
1112         readBoolean(parser, restrictions, UserManager.DISALLOW_DEBUGGING_FEATURES);
1113         readBoolean(parser, restrictions, UserManager.DISALLOW_CONFIG_VPN);
1114         readBoolean(parser, restrictions, UserManager.DISALLOW_CONFIG_TETHERING);
1115         readBoolean(parser, restrictions, UserManager.DISALLOW_NETWORK_RESET);
1116         readBoolean(parser, restrictions, UserManager.DISALLOW_FACTORY_RESET);
1117         readBoolean(parser, restrictions, UserManager.DISALLOW_ADD_USER);
1118         readBoolean(parser, restrictions, UserManager.ENSURE_VERIFY_APPS);
1119         readBoolean(parser, restrictions, UserManager.DISALLOW_CONFIG_CELL_BROADCASTS);
1120         readBoolean(parser, restrictions, UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS);
1121         readBoolean(parser, restrictions, UserManager.DISALLOW_APPS_CONTROL);
1122         readBoolean(parser, restrictions,
1123                 UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA);
1124         readBoolean(parser, restrictions, UserManager.DISALLOW_UNMUTE_MICROPHONE);
1125         readBoolean(parser, restrictions, UserManager.DISALLOW_ADJUST_VOLUME);
1126         readBoolean(parser, restrictions, UserManager.DISALLOW_OUTGOING_CALLS);
1127         readBoolean(parser, restrictions, UserManager.DISALLOW_SMS);
1128         readBoolean(parser, restrictions, UserManager.DISALLOW_FUN);
1129         readBoolean(parser, restrictions, UserManager.DISALLOW_CREATE_WINDOWS);
1130         readBoolean(parser, restrictions, UserManager.DISALLOW_CROSS_PROFILE_COPY_PASTE);
1131         readBoolean(parser, restrictions, UserManager.DISALLOW_OUTGOING_BEAM);
1132         readBoolean(parser, restrictions, UserManager.DISALLOW_WALLPAPER);
1133         readBoolean(parser, restrictions, UserManager.DISALLOW_SAFE_BOOT);
1134         readBoolean(parser, restrictions, UserManager.ALLOW_PARENT_PROFILE_APP_LINKING);
1135     }
1136 
readBoolean(XmlPullParser parser, Bundle restrictions, String restrictionKey)1137     private void readBoolean(XmlPullParser parser, Bundle restrictions,
1138             String restrictionKey) {
1139         String value = parser.getAttributeValue(null, restrictionKey);
1140         if (value != null) {
1141             restrictions.putBoolean(restrictionKey, Boolean.parseBoolean(value));
1142         }
1143     }
1144 
writeBoolean(XmlSerializer xml, Bundle restrictions, String restrictionKey)1145     private void writeBoolean(XmlSerializer xml, Bundle restrictions, String restrictionKey)
1146             throws IOException {
1147         if (restrictions.containsKey(restrictionKey)) {
1148             xml.attribute(null, restrictionKey,
1149                     Boolean.toString(restrictions.getBoolean(restrictionKey)));
1150         }
1151     }
1152 
readIntAttribute(XmlPullParser parser, String attr, int defaultValue)1153     private int readIntAttribute(XmlPullParser parser, String attr, int defaultValue) {
1154         String valueString = parser.getAttributeValue(null, attr);
1155         if (valueString == null) return defaultValue;
1156         try {
1157             return Integer.parseInt(valueString);
1158         } catch (NumberFormatException nfe) {
1159             return defaultValue;
1160         }
1161     }
1162 
readLongAttribute(XmlPullParser parser, String attr, long defaultValue)1163     private long readLongAttribute(XmlPullParser parser, String attr, long defaultValue) {
1164         String valueString = parser.getAttributeValue(null, attr);
1165         if (valueString == null) return defaultValue;
1166         try {
1167             return Long.parseLong(valueString);
1168         } catch (NumberFormatException nfe) {
1169             return defaultValue;
1170         }
1171     }
1172 
isPackageInstalled(String pkg, int userId)1173     private boolean isPackageInstalled(String pkg, int userId) {
1174         final ApplicationInfo info = mPm.getApplicationInfo(pkg,
1175                 PackageManager.GET_UNINSTALLED_PACKAGES,
1176                 userId);
1177         if (info == null || (info.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
1178             return false;
1179         }
1180         return true;
1181     }
1182 
1183     /**
1184      * Removes all the restrictions files (res_<packagename>) for a given user.
1185      * Does not do any permissions checking.
1186      */
cleanAppRestrictions(int userId)1187     private void cleanAppRestrictions(int userId) {
1188         synchronized (mPackagesLock) {
1189             File dir = Environment.getUserSystemDirectory(userId);
1190             String[] files = dir.list();
1191             if (files == null) return;
1192             for (String fileName : files) {
1193                 if (fileName.startsWith(RESTRICTIONS_FILE_PREFIX)) {
1194                     File resFile = new File(dir, fileName);
1195                     if (resFile.exists()) {
1196                         resFile.delete();
1197                     }
1198                 }
1199             }
1200         }
1201     }
1202 
1203     /**
1204      * Removes the app restrictions file for a specific package and user id, if it exists.
1205      */
cleanAppRestrictionsForPackage(String pkg, int userId)1206     private void cleanAppRestrictionsForPackage(String pkg, int userId) {
1207         synchronized (mPackagesLock) {
1208             File dir = Environment.getUserSystemDirectory(userId);
1209             File resFile = new File(dir, packageToRestrictionsFileName(pkg));
1210             if (resFile.exists()) {
1211                 resFile.delete();
1212             }
1213         }
1214     }
1215 
1216     @Override
createProfileForUser(String name, int flags, int userId)1217     public UserInfo createProfileForUser(String name, int flags, int userId) {
1218         checkManageUsersPermission("Only the system can create users");
1219         if (userId != UserHandle.USER_OWNER) {
1220             Slog.w(LOG_TAG, "Only user owner can have profiles");
1221             return null;
1222         }
1223         return createUserInternal(name, flags, userId);
1224     }
1225 
1226     @Override
createUser(String name, int flags)1227     public UserInfo createUser(String name, int flags) {
1228         checkManageUsersPermission("Only the system can create users");
1229         return createUserInternal(name, flags, UserHandle.USER_NULL);
1230     }
1231 
createUserInternal(String name, int flags, int parentId)1232     private UserInfo createUserInternal(String name, int flags, int parentId) {
1233         if (getUserRestrictions(UserHandle.getCallingUserId()).getBoolean(
1234                 UserManager.DISALLOW_ADD_USER, false)) {
1235             Log.w(LOG_TAG, "Cannot add user. DISALLOW_ADD_USER is enabled.");
1236             return null;
1237         }
1238         if (ActivityManager.isLowRamDeviceStatic()) {
1239             return null;
1240         }
1241         final boolean isGuest = (flags & UserInfo.FLAG_GUEST) != 0;
1242         final boolean isManagedProfile = (flags & UserInfo.FLAG_MANAGED_PROFILE) != 0;
1243         final long ident = Binder.clearCallingIdentity();
1244         UserInfo userInfo = null;
1245         final int userId;
1246         try {
1247             synchronized (mInstallLock) {
1248                 synchronized (mPackagesLock) {
1249                     UserInfo parent = null;
1250                     if (parentId != UserHandle.USER_NULL) {
1251                         parent = getUserInfoLocked(parentId);
1252                         if (parent == null) return null;
1253                     }
1254                     if (isManagedProfile && !canAddMoreManagedProfiles()) {
1255                         return null;
1256                     }
1257                     if (!isGuest && !isManagedProfile && isUserLimitReachedLocked()) {
1258                         // If we're not adding a guest user or a managed profile and the limit has
1259                         // been reached, cannot add a user.
1260                         return null;
1261                     }
1262                     // If we're adding a guest and there already exists one, bail.
1263                     if (isGuest && findCurrentGuestUserLocked() != null) {
1264                         return null;
1265                     }
1266                     userId = getNextAvailableIdLocked();
1267                     userInfo = new UserInfo(userId, name, null, flags);
1268                     userInfo.serialNumber = mNextSerialNumber++;
1269                     long now = System.currentTimeMillis();
1270                     userInfo.creationTime = (now > EPOCH_PLUS_30_YEARS) ? now : 0;
1271                     userInfo.partial = true;
1272                     Environment.getUserSystemDirectory(userInfo.id).mkdirs();
1273                     mUsers.put(userId, userInfo);
1274                     writeUserListLocked();
1275                     if (parent != null) {
1276                         if (parent.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID) {
1277                             parent.profileGroupId = parent.id;
1278                             scheduleWriteUserLocked(parent);
1279                         }
1280                         userInfo.profileGroupId = parent.profileGroupId;
1281                     }
1282                     final StorageManager storage = mContext.getSystemService(StorageManager.class);
1283                     for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
1284                         final String volumeUuid = vol.getFsUuid();
1285                         try {
1286                             final File userDir = Environment.getDataUserDirectory(volumeUuid,
1287                                     userId);
1288                             prepareUserDirectory(userDir);
1289                             enforceSerialNumber(userDir, userInfo.serialNumber);
1290                         } catch (IOException e) {
1291                             Log.wtf(LOG_TAG, "Failed to create user directory on " + volumeUuid, e);
1292                         }
1293                     }
1294                     mPm.createNewUserLILPw(userId);
1295                     userInfo.partial = false;
1296                     scheduleWriteUserLocked(userInfo);
1297                     updateUserIdsLocked();
1298                     Bundle restrictions = new Bundle();
1299                     mUserRestrictions.append(userId, restrictions);
1300                 }
1301             }
1302             mPm.newUserCreated(userId);
1303             if (userInfo != null) {
1304                 Intent addedIntent = new Intent(Intent.ACTION_USER_ADDED);
1305                 addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userInfo.id);
1306                 mContext.sendBroadcastAsUser(addedIntent, UserHandle.ALL,
1307                         android.Manifest.permission.MANAGE_USERS);
1308             }
1309         } finally {
1310             Binder.restoreCallingIdentity(ident);
1311         }
1312         return userInfo;
1313     }
1314 
numberOfUsersOfTypeLocked(int flags, boolean excludeDying)1315     private int numberOfUsersOfTypeLocked(int flags, boolean excludeDying) {
1316         int count = 0;
1317         for (int i = mUsers.size() - 1; i >= 0; i--) {
1318             UserInfo user = mUsers.valueAt(i);
1319             if (!excludeDying || !mRemovingUserIds.get(user.id)) {
1320                 if ((user.flags & flags) != 0) {
1321                     count++;
1322                 }
1323             }
1324         }
1325         return count;
1326     }
1327 
1328     /**
1329      * Find the current guest user. If the Guest user is partial,
1330      * then do not include it in the results as it is about to die.
1331      * This is different than {@link #numberOfUsersOfTypeLocked(int, boolean)} due to
1332      * the special handling of Guests being removed.
1333      */
findCurrentGuestUserLocked()1334     private UserInfo findCurrentGuestUserLocked() {
1335         final int size = mUsers.size();
1336         for (int i = 0; i < size; i++) {
1337             final UserInfo user = mUsers.valueAt(i);
1338             if (user.isGuest() && !user.guestToRemove && !mRemovingUserIds.get(user.id)) {
1339                 return user;
1340             }
1341         }
1342         return null;
1343     }
1344 
1345     /**
1346      * Mark this guest user for deletion to allow us to create another guest
1347      * and switch to that user before actually removing this guest.
1348      * @param userHandle the userid of the current guest
1349      * @return whether the user could be marked for deletion
1350      */
markGuestForDeletion(int userHandle)1351     public boolean markGuestForDeletion(int userHandle) {
1352         checkManageUsersPermission("Only the system can remove users");
1353         if (getUserRestrictions(UserHandle.getCallingUserId()).getBoolean(
1354                 UserManager.DISALLOW_REMOVE_USER, false)) {
1355             Log.w(LOG_TAG, "Cannot remove user. DISALLOW_REMOVE_USER is enabled.");
1356             return false;
1357         }
1358 
1359         long ident = Binder.clearCallingIdentity();
1360         try {
1361             final UserInfo user;
1362             synchronized (mPackagesLock) {
1363                 user = mUsers.get(userHandle);
1364                 if (userHandle == 0 || user == null || mRemovingUserIds.get(userHandle)) {
1365                     return false;
1366                 }
1367                 if (!user.isGuest()) {
1368                     return false;
1369                 }
1370                 // We set this to a guest user that is to be removed. This is a temporary state
1371                 // where we are allowed to add new Guest users, even if this one is still not
1372                 // removed. This user will still show up in getUserInfo() calls.
1373                 // If we don't get around to removing this Guest user, it will be purged on next
1374                 // startup.
1375                 user.guestToRemove = true;
1376                 // Mark it as disabled, so that it isn't returned any more when
1377                 // profiles are queried.
1378                 user.flags |= UserInfo.FLAG_DISABLED;
1379                 writeUserLocked(user);
1380             }
1381         } finally {
1382             Binder.restoreCallingIdentity(ident);
1383         }
1384         return true;
1385     }
1386 
1387     /**
1388      * Removes a user and all data directories created for that user. This method should be called
1389      * after the user's processes have been terminated.
1390      * @param userHandle the user's id
1391      */
removeUser(int userHandle)1392     public boolean removeUser(int userHandle) {
1393         checkManageUsersPermission("Only the system can remove users");
1394         if (getUserRestrictions(UserHandle.getCallingUserId()).getBoolean(
1395                 UserManager.DISALLOW_REMOVE_USER, false)) {
1396             Log.w(LOG_TAG, "Cannot remove user. DISALLOW_REMOVE_USER is enabled.");
1397             return false;
1398         }
1399 
1400         long ident = Binder.clearCallingIdentity();
1401         try {
1402             final UserInfo user;
1403             synchronized (mPackagesLock) {
1404                 user = mUsers.get(userHandle);
1405                 if (userHandle == 0 || user == null || mRemovingUserIds.get(userHandle)) {
1406                     return false;
1407                 }
1408 
1409                 // We remember deleted user IDs to prevent them from being
1410                 // reused during the current boot; they can still be reused
1411                 // after a reboot.
1412                 mRemovingUserIds.put(userHandle, true);
1413 
1414                 try {
1415                     mAppOpsService.removeUser(userHandle);
1416                 } catch (RemoteException e) {
1417                     Log.w(LOG_TAG, "Unable to notify AppOpsService of removing user", e);
1418                 }
1419                 // Set this to a partially created user, so that the user will be purged
1420                 // on next startup, in case the runtime stops now before stopping and
1421                 // removing the user completely.
1422                 user.partial = true;
1423                 // Mark it as disabled, so that it isn't returned any more when
1424                 // profiles are queried.
1425                 user.flags |= UserInfo.FLAG_DISABLED;
1426                 writeUserLocked(user);
1427             }
1428 
1429             if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID
1430                     && user.isManagedProfile()) {
1431                 // Send broadcast to notify system that the user removed was a
1432                 // managed user.
1433                 sendProfileRemovedBroadcast(user.profileGroupId, user.id);
1434             }
1435 
1436             if (DBG) Slog.i(LOG_TAG, "Stopping user " + userHandle);
1437             int res;
1438             try {
1439                 res = ActivityManagerNative.getDefault().stopUser(userHandle,
1440                         new IStopUserCallback.Stub() {
1441                             @Override
1442                             public void userStopped(int userId) {
1443                                 finishRemoveUser(userId);
1444                             }
1445                             @Override
1446                             public void userStopAborted(int userId) {
1447                             }
1448                         });
1449             } catch (RemoteException e) {
1450                 return false;
1451             }
1452             return res == ActivityManager.USER_OP_SUCCESS;
1453         } finally {
1454             Binder.restoreCallingIdentity(ident);
1455         }
1456     }
1457 
finishRemoveUser(final int userHandle)1458     void finishRemoveUser(final int userHandle) {
1459         if (DBG) Slog.i(LOG_TAG, "finishRemoveUser " + userHandle);
1460         // Let other services shutdown any activity and clean up their state before completely
1461         // wiping the user's system directory and removing from the user list
1462         long ident = Binder.clearCallingIdentity();
1463         try {
1464             Intent addedIntent = new Intent(Intent.ACTION_USER_REMOVED);
1465             addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userHandle);
1466             mContext.sendOrderedBroadcastAsUser(addedIntent, UserHandle.ALL,
1467                     android.Manifest.permission.MANAGE_USERS,
1468 
1469                     new BroadcastReceiver() {
1470                         @Override
1471                         public void onReceive(Context context, Intent intent) {
1472                             if (DBG) {
1473                                 Slog.i(LOG_TAG,
1474                                         "USER_REMOVED broadcast sent, cleaning up user data "
1475                                         + userHandle);
1476                             }
1477                             new Thread() {
1478                                 public void run() {
1479                                     synchronized (mInstallLock) {
1480                                         synchronized (mPackagesLock) {
1481                                             removeUserStateLocked(userHandle);
1482                                         }
1483                                     }
1484                                 }
1485                             }.start();
1486                         }
1487                     },
1488 
1489                     null, Activity.RESULT_OK, null, null);
1490         } finally {
1491             Binder.restoreCallingIdentity(ident);
1492         }
1493     }
1494 
removeUserStateLocked(final int userHandle)1495     private void removeUserStateLocked(final int userHandle) {
1496         // Cleanup package manager settings
1497         mPm.cleanUpUserLILPw(this, userHandle);
1498 
1499         // Remove this user from the list
1500         mUsers.remove(userHandle);
1501         // Remove user file
1502         AtomicFile userFile = new AtomicFile(new File(mUsersDir, userHandle + XML_SUFFIX));
1503         userFile.delete();
1504         // Update the user list
1505         writeUserListLocked();
1506         updateUserIdsLocked();
1507         removeDirectoryRecursive(Environment.getUserSystemDirectory(userHandle));
1508     }
1509 
removeDirectoryRecursive(File parent)1510     private void removeDirectoryRecursive(File parent) {
1511         if (parent.isDirectory()) {
1512             String[] files = parent.list();
1513             for (String filename : files) {
1514                 File child = new File(parent, filename);
1515                 removeDirectoryRecursive(child);
1516             }
1517         }
1518         parent.delete();
1519     }
1520 
sendProfileRemovedBroadcast(int parentUserId, int removedUserId)1521     private void sendProfileRemovedBroadcast(int parentUserId, int removedUserId) {
1522         Intent managedProfileIntent = new Intent(Intent.ACTION_MANAGED_PROFILE_REMOVED);
1523         managedProfileIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY |
1524                 Intent.FLAG_RECEIVER_FOREGROUND);
1525         managedProfileIntent.putExtra(Intent.EXTRA_USER, new UserHandle(removedUserId));
1526         mContext.sendBroadcastAsUser(managedProfileIntent, new UserHandle(parentUserId), null);
1527     }
1528 
1529     @Override
getApplicationRestrictions(String packageName)1530     public Bundle getApplicationRestrictions(String packageName) {
1531         return getApplicationRestrictionsForUser(packageName, UserHandle.getCallingUserId());
1532     }
1533 
1534     @Override
getApplicationRestrictionsForUser(String packageName, int userId)1535     public Bundle getApplicationRestrictionsForUser(String packageName, int userId) {
1536         if (UserHandle.getCallingUserId() != userId
1537                 || !UserHandle.isSameApp(Binder.getCallingUid(), getUidForPackage(packageName))) {
1538             checkManageUsersPermission("Only system can get restrictions for other users/apps");
1539         }
1540         synchronized (mPackagesLock) {
1541             // Read the restrictions from XML
1542             return readApplicationRestrictionsLocked(packageName, userId);
1543         }
1544     }
1545 
1546     @Override
setApplicationRestrictions(String packageName, Bundle restrictions, int userId)1547     public void setApplicationRestrictions(String packageName, Bundle restrictions,
1548             int userId) {
1549         if (UserHandle.getCallingUserId() != userId
1550                 || !UserHandle.isSameApp(Binder.getCallingUid(), getUidForPackage(packageName))) {
1551             checkManageUsersPermission("Only system can set restrictions for other users/apps");
1552         }
1553         synchronized (mPackagesLock) {
1554             if (restrictions == null || restrictions.isEmpty()) {
1555                 cleanAppRestrictionsForPackage(packageName, userId);
1556             } else {
1557                 // Write the restrictions to XML
1558                 writeApplicationRestrictionsLocked(packageName, restrictions, userId);
1559             }
1560         }
1561 
1562         if (isPackageInstalled(packageName, userId)) {
1563             // Notify package of changes via an intent - only sent to explicitly registered receivers.
1564             Intent changeIntent = new Intent(Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED);
1565             changeIntent.setPackage(packageName);
1566             changeIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
1567             mContext.sendBroadcastAsUser(changeIntent, new UserHandle(userId));
1568         }
1569     }
1570 
1571     @Override
removeRestrictions()1572     public void removeRestrictions() {
1573         checkManageUsersPermission("Only system can remove restrictions");
1574         final int userHandle = UserHandle.getCallingUserId();
1575         removeRestrictionsForUser(userHandle, true);
1576     }
1577 
removeRestrictionsForUser(final int userHandle, boolean unhideApps)1578     private void removeRestrictionsForUser(final int userHandle, boolean unhideApps) {
1579         synchronized (mPackagesLock) {
1580             // Remove all user restrictions
1581             setUserRestrictions(new Bundle(), userHandle);
1582             // Remove any app restrictions
1583             cleanAppRestrictions(userHandle);
1584         }
1585         if (unhideApps) {
1586             unhideAllInstalledAppsForUser(userHandle);
1587         }
1588     }
1589 
unhideAllInstalledAppsForUser(final int userHandle)1590     private void unhideAllInstalledAppsForUser(final int userHandle) {
1591         mHandler.post(new Runnable() {
1592             @Override
1593             public void run() {
1594                 List<ApplicationInfo> apps =
1595                         mPm.getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES,
1596                                 userHandle).getList();
1597                 final long ident = Binder.clearCallingIdentity();
1598                 try {
1599                     for (ApplicationInfo appInfo : apps) {
1600                         if ((appInfo.flags & ApplicationInfo.FLAG_INSTALLED) != 0
1601                                 && (appInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HIDDEN)
1602                                         != 0) {
1603                             mPm.setApplicationHiddenSettingAsUser(appInfo.packageName, false,
1604                                     userHandle);
1605                         }
1606                     }
1607                 } finally {
1608                     Binder.restoreCallingIdentity(ident);
1609                 }
1610             }
1611         });
1612     }
getUidForPackage(String packageName)1613     private int getUidForPackage(String packageName) {
1614         long ident = Binder.clearCallingIdentity();
1615         try {
1616             return mContext.getPackageManager().getApplicationInfo(packageName,
1617                     PackageManager.GET_UNINSTALLED_PACKAGES).uid;
1618         } catch (NameNotFoundException nnfe) {
1619             return -1;
1620         } finally {
1621             Binder.restoreCallingIdentity(ident);
1622         }
1623     }
1624 
readApplicationRestrictionsLocked(String packageName, int userId)1625     private Bundle readApplicationRestrictionsLocked(String packageName,
1626             int userId) {
1627         AtomicFile restrictionsFile =
1628                 new AtomicFile(new File(Environment.getUserSystemDirectory(userId),
1629                         packageToRestrictionsFileName(packageName)));
1630         return readApplicationRestrictionsLocked(restrictionsFile);
1631     }
1632 
1633     @VisibleForTesting
readApplicationRestrictionsLocked(AtomicFile restrictionsFile)1634     static Bundle readApplicationRestrictionsLocked(AtomicFile restrictionsFile) {
1635         final Bundle restrictions = new Bundle();
1636         final ArrayList<String> values = new ArrayList<>();
1637         if (!restrictionsFile.getBaseFile().exists()) {
1638             return restrictions;
1639         }
1640 
1641         FileInputStream fis = null;
1642         try {
1643             fis = restrictionsFile.openRead();
1644             XmlPullParser parser = Xml.newPullParser();
1645             parser.setInput(fis, StandardCharsets.UTF_8.name());
1646             XmlUtils.nextElement(parser);
1647             if (parser.getEventType() != XmlPullParser.START_TAG) {
1648                 Slog.e(LOG_TAG, "Unable to read restrictions file "
1649                         + restrictionsFile.getBaseFile());
1650                 return restrictions;
1651             }
1652             while (parser.next() != XmlPullParser.END_DOCUMENT) {
1653                 readEntry(restrictions, values, parser);
1654             }
1655         } catch (IOException|XmlPullParserException e) {
1656             Log.w(LOG_TAG, "Error parsing " + restrictionsFile.getBaseFile(), e);
1657         } finally {
1658             IoUtils.closeQuietly(fis);
1659         }
1660         return restrictions;
1661     }
1662 
readEntry(Bundle restrictions, ArrayList<String> values, XmlPullParser parser)1663     private static void readEntry(Bundle restrictions, ArrayList<String> values,
1664             XmlPullParser parser) throws XmlPullParserException, IOException {
1665         int type = parser.getEventType();
1666         if (type == XmlPullParser.START_TAG && parser.getName().equals(TAG_ENTRY)) {
1667             String key = parser.getAttributeValue(null, ATTR_KEY);
1668             String valType = parser.getAttributeValue(null, ATTR_VALUE_TYPE);
1669             String multiple = parser.getAttributeValue(null, ATTR_MULTIPLE);
1670             if (multiple != null) {
1671                 values.clear();
1672                 int count = Integer.parseInt(multiple);
1673                 while (count > 0 && (type = parser.next()) != XmlPullParser.END_DOCUMENT) {
1674                     if (type == XmlPullParser.START_TAG
1675                             && parser.getName().equals(TAG_VALUE)) {
1676                         values.add(parser.nextText().trim());
1677                         count--;
1678                     }
1679                 }
1680                 String [] valueStrings = new String[values.size()];
1681                 values.toArray(valueStrings);
1682                 restrictions.putStringArray(key, valueStrings);
1683             } else if (ATTR_TYPE_BUNDLE.equals(valType)) {
1684                 restrictions.putBundle(key, readBundleEntry(parser, values));
1685             } else if (ATTR_TYPE_BUNDLE_ARRAY.equals(valType)) {
1686                 final int outerDepth = parser.getDepth();
1687                 ArrayList<Bundle> bundleList = new ArrayList<>();
1688                 while (XmlUtils.nextElementWithin(parser, outerDepth)) {
1689                     Bundle childBundle = readBundleEntry(parser, values);
1690                     bundleList.add(childBundle);
1691                 }
1692                 restrictions.putParcelableArray(key,
1693                         bundleList.toArray(new Bundle[bundleList.size()]));
1694             } else {
1695                 String value = parser.nextText().trim();
1696                 if (ATTR_TYPE_BOOLEAN.equals(valType)) {
1697                     restrictions.putBoolean(key, Boolean.parseBoolean(value));
1698                 } else if (ATTR_TYPE_INTEGER.equals(valType)) {
1699                     restrictions.putInt(key, Integer.parseInt(value));
1700                 } else {
1701                     restrictions.putString(key, value);
1702                 }
1703             }
1704         }
1705     }
1706 
readBundleEntry(XmlPullParser parser, ArrayList<String> values)1707     private static Bundle readBundleEntry(XmlPullParser parser, ArrayList<String> values)
1708             throws IOException, XmlPullParserException {
1709         Bundle childBundle = new Bundle();
1710         final int outerDepth = parser.getDepth();
1711         while (XmlUtils.nextElementWithin(parser, outerDepth)) {
1712             readEntry(childBundle, values, parser);
1713         }
1714         return childBundle;
1715     }
1716 
writeApplicationRestrictionsLocked(String packageName, Bundle restrictions, int userId)1717     private void writeApplicationRestrictionsLocked(String packageName,
1718             Bundle restrictions, int userId) {
1719         AtomicFile restrictionsFile = new AtomicFile(
1720                 new File(Environment.getUserSystemDirectory(userId),
1721                         packageToRestrictionsFileName(packageName)));
1722         writeApplicationRestrictionsLocked(restrictions, restrictionsFile);
1723     }
1724 
1725     @VisibleForTesting
writeApplicationRestrictionsLocked(Bundle restrictions, AtomicFile restrictionsFile)1726     static void writeApplicationRestrictionsLocked(Bundle restrictions,
1727             AtomicFile restrictionsFile) {
1728         FileOutputStream fos = null;
1729         try {
1730             fos = restrictionsFile.startWrite();
1731             final BufferedOutputStream bos = new BufferedOutputStream(fos);
1732 
1733             final XmlSerializer serializer = new FastXmlSerializer();
1734             serializer.setOutput(bos, StandardCharsets.UTF_8.name());
1735             serializer.startDocument(null, true);
1736             serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
1737 
1738             serializer.startTag(null, TAG_RESTRICTIONS);
1739             writeBundle(restrictions, serializer);
1740             serializer.endTag(null, TAG_RESTRICTIONS);
1741 
1742             serializer.endDocument();
1743             restrictionsFile.finishWrite(fos);
1744         } catch (Exception e) {
1745             restrictionsFile.failWrite(fos);
1746             Slog.e(LOG_TAG, "Error writing application restrictions list", e);
1747         }
1748     }
1749 
writeBundle(Bundle restrictions, XmlSerializer serializer)1750     private static void writeBundle(Bundle restrictions, XmlSerializer serializer)
1751             throws IOException {
1752         for (String key : restrictions.keySet()) {
1753             Object value = restrictions.get(key);
1754             serializer.startTag(null, TAG_ENTRY);
1755             serializer.attribute(null, ATTR_KEY, key);
1756 
1757             if (value instanceof Boolean) {
1758                 serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_BOOLEAN);
1759                 serializer.text(value.toString());
1760             } else if (value instanceof Integer) {
1761                 serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_INTEGER);
1762                 serializer.text(value.toString());
1763             } else if (value == null || value instanceof String) {
1764                 serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_STRING);
1765                 serializer.text(value != null ? (String) value : "");
1766             } else if (value instanceof Bundle) {
1767                 serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_BUNDLE);
1768                 writeBundle((Bundle) value, serializer);
1769             } else if (value instanceof Parcelable[]) {
1770                 serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_BUNDLE_ARRAY);
1771                 Parcelable[] array = (Parcelable[]) value;
1772                 for (Parcelable parcelable : array) {
1773                     if (!(parcelable instanceof Bundle)) {
1774                         throw new IllegalArgumentException("bundle-array can only hold Bundles");
1775                     }
1776                     serializer.startTag(null, TAG_ENTRY);
1777                     serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_BUNDLE);
1778                     writeBundle((Bundle) parcelable, serializer);
1779                     serializer.endTag(null, TAG_ENTRY);
1780                 }
1781             } else {
1782                 serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_STRING_ARRAY);
1783                 String[] values = (String[]) value;
1784                 serializer.attribute(null, ATTR_MULTIPLE, Integer.toString(values.length));
1785                 for (String choice : values) {
1786                     serializer.startTag(null, TAG_VALUE);
1787                     serializer.text(choice != null ? choice : "");
1788                     serializer.endTag(null, TAG_VALUE);
1789                 }
1790             }
1791             serializer.endTag(null, TAG_ENTRY);
1792         }
1793     }
1794 
1795     @Override
getUserSerialNumber(int userHandle)1796     public int getUserSerialNumber(int userHandle) {
1797         synchronized (mPackagesLock) {
1798             if (!exists(userHandle)) return -1;
1799             return getUserInfoLocked(userHandle).serialNumber;
1800         }
1801     }
1802 
1803     @Override
getUserHandle(int userSerialNumber)1804     public int getUserHandle(int userSerialNumber) {
1805         synchronized (mPackagesLock) {
1806             for (int userId : mUserIds) {
1807                 UserInfo info = getUserInfoLocked(userId);
1808                 if (info != null && info.serialNumber == userSerialNumber) return userId;
1809             }
1810             // Not found
1811             return -1;
1812         }
1813     }
1814 
1815     @Override
getUserCreationTime(int userHandle)1816     public long getUserCreationTime(int userHandle) {
1817         int callingUserId = UserHandle.getCallingUserId();
1818         UserInfo userInfo = null;
1819         synchronized (mPackagesLock) {
1820             if (callingUserId == userHandle) {
1821                 userInfo = getUserInfoLocked(userHandle);
1822             } else {
1823                 UserInfo parent = getProfileParentLocked(userHandle);
1824                 if (parent != null && parent.id == callingUserId) {
1825                     userInfo = getUserInfoLocked(userHandle);
1826                 }
1827             }
1828         }
1829         if (userInfo == null) {
1830             throw new SecurityException("userHandle can only be the calling user or a managed "
1831                     + "profile associated with this user");
1832         }
1833         return userInfo.creationTime;
1834     }
1835 
1836     /**
1837      * Caches the list of user ids in an array, adjusting the array size when necessary.
1838      */
updateUserIdsLocked()1839     private void updateUserIdsLocked() {
1840         int num = 0;
1841         for (int i = 0; i < mUsers.size(); i++) {
1842             if (!mUsers.valueAt(i).partial) {
1843                 num++;
1844             }
1845         }
1846         final int[] newUsers = new int[num];
1847         int n = 0;
1848         for (int i = 0; i < mUsers.size(); i++) {
1849             if (!mUsers.valueAt(i).partial) {
1850                 newUsers[n++] = mUsers.keyAt(i);
1851             }
1852         }
1853         mUserIds = newUsers;
1854     }
1855 
1856     /**
1857      * Make a note of the last started time of a user and do some cleanup.
1858      * @param userId the user that was just foregrounded
1859      */
onUserForeground(int userId)1860     public void onUserForeground(int userId) {
1861         synchronized (mPackagesLock) {
1862             UserInfo user = mUsers.get(userId);
1863             long now = System.currentTimeMillis();
1864             if (user == null || user.partial) {
1865                 Slog.w(LOG_TAG, "userForeground: unknown user #" + userId);
1866                 return;
1867             }
1868             if (now > EPOCH_PLUS_30_YEARS) {
1869                 user.lastLoggedInTime = now;
1870                 scheduleWriteUserLocked(user);
1871             }
1872         }
1873     }
1874 
1875     /**
1876      * Returns the next available user id, filling in any holes in the ids.
1877      * TODO: May not be a good idea to recycle ids, in case it results in confusion
1878      * for data and battery stats collection, or unexpected cross-talk.
1879      * @return
1880      */
getNextAvailableIdLocked()1881     private int getNextAvailableIdLocked() {
1882         synchronized (mPackagesLock) {
1883             int i = MIN_USER_ID;
1884             while (i < Integer.MAX_VALUE) {
1885                 if (mUsers.indexOfKey(i) < 0 && !mRemovingUserIds.get(i)) {
1886                     break;
1887                 }
1888                 i++;
1889             }
1890             return i;
1891         }
1892     }
1893 
packageToRestrictionsFileName(String packageName)1894     private String packageToRestrictionsFileName(String packageName) {
1895         return RESTRICTIONS_FILE_PREFIX + packageName + XML_SUFFIX;
1896     }
1897 
1898     /**
1899      * Create new {@code /data/user/[id]} directory and sets default
1900      * permissions.
1901      */
prepareUserDirectory(File file)1902     public static void prepareUserDirectory(File file) throws IOException {
1903         if (!file.exists()) {
1904             if (!file.mkdir()) {
1905                 throw new IOException("Failed to create " + file);
1906             }
1907         }
1908         if (FileUtils.setPermissions(file.getAbsolutePath(), 0771, Process.SYSTEM_UID,
1909                 Process.SYSTEM_UID) != 0) {
1910             throw new IOException("Failed to prepare " + file);
1911         }
1912     }
1913 
1914     /**
1915      * Enforce that serial number stored in user directory inode matches the
1916      * given expected value. Gracefully sets the serial number if currently
1917      * undefined.
1918      *
1919      * @throws IOException when problem extracting serial number, or serial
1920      *             number is mismatched.
1921      */
enforceSerialNumber(File file, int serialNumber)1922     public static void enforceSerialNumber(File file, int serialNumber) throws IOException {
1923         final int foundSerial = getSerialNumber(file);
1924         Slog.v(LOG_TAG, "Found " + file + " with serial number " + foundSerial);
1925 
1926         if (foundSerial == -1) {
1927             Slog.d(LOG_TAG, "Serial number missing on " + file + "; assuming current is valid");
1928             try {
1929                 setSerialNumber(file, serialNumber);
1930             } catch (IOException e) {
1931                 Slog.w(LOG_TAG, "Failed to set serial number on " + file, e);
1932             }
1933 
1934         } else if (foundSerial != serialNumber) {
1935             throw new IOException("Found serial number " + foundSerial
1936                     + " doesn't match expected " + serialNumber);
1937         }
1938     }
1939 
1940     /**
1941      * Set serial number stored in user directory inode.
1942      *
1943      * @throws IOException if serial number was already set
1944      */
setSerialNumber(File file, int serialNumber)1945     private static void setSerialNumber(File file, int serialNumber)
1946             throws IOException {
1947         try {
1948             final byte[] buf = Integer.toString(serialNumber).getBytes(StandardCharsets.UTF_8);
1949             Os.setxattr(file.getAbsolutePath(), XATTR_SERIAL, buf, OsConstants.XATTR_CREATE);
1950         } catch (ErrnoException e) {
1951             throw e.rethrowAsIOException();
1952         }
1953     }
1954 
1955     /**
1956      * Return serial number stored in user directory inode.
1957      *
1958      * @return parsed serial number, or -1 if not set
1959      */
getSerialNumber(File file)1960     private static int getSerialNumber(File file) throws IOException {
1961         try {
1962             final byte[] buf = new byte[256];
1963             final int len = Os.getxattr(file.getAbsolutePath(), XATTR_SERIAL, buf);
1964             final String serial = new String(buf, 0, len);
1965             try {
1966                 return Integer.parseInt(serial);
1967             } catch (NumberFormatException e) {
1968                 throw new IOException("Bad serial number: " + serial);
1969             }
1970         } catch (ErrnoException e) {
1971             if (e.errno == OsConstants.ENODATA) {
1972                 return -1;
1973             } else {
1974                 throw e.rethrowAsIOException();
1975             }
1976         }
1977     }
1978 
1979     @Override
dump(FileDescriptor fd, PrintWriter pw, String[] args)1980     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1981         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
1982                 != PackageManager.PERMISSION_GRANTED) {
1983             pw.println("Permission Denial: can't dump UserManager from from pid="
1984                     + Binder.getCallingPid()
1985                     + ", uid=" + Binder.getCallingUid()
1986                     + " without permission "
1987                     + android.Manifest.permission.DUMP);
1988             return;
1989         }
1990 
1991         long now = System.currentTimeMillis();
1992         StringBuilder sb = new StringBuilder();
1993         synchronized (mPackagesLock) {
1994             pw.println("Users:");
1995             for (int i = 0; i < mUsers.size(); i++) {
1996                 UserInfo user = mUsers.valueAt(i);
1997                 if (user == null) continue;
1998                 pw.print("  "); pw.print(user); pw.print(" serialNo="); pw.print(user.serialNumber);
1999                 if (mRemovingUserIds.get(mUsers.keyAt(i))) pw.print(" <removing> ");
2000                 if (user.partial) pw.print(" <partial>");
2001                 pw.println();
2002                 pw.print("    Created: ");
2003                 if (user.creationTime == 0) {
2004                     pw.println("<unknown>");
2005                 } else {
2006                     sb.setLength(0);
2007                     TimeUtils.formatDuration(now - user.creationTime, sb);
2008                     sb.append(" ago");
2009                     pw.println(sb);
2010                 }
2011                 pw.print("    Last logged in: ");
2012                 if (user.lastLoggedInTime == 0) {
2013                     pw.println("<unknown>");
2014                 } else {
2015                     sb.setLength(0);
2016                     TimeUtils.formatDuration(now - user.lastLoggedInTime, sb);
2017                     sb.append(" ago");
2018                     pw.println(sb);
2019                 }
2020             }
2021         }
2022     }
2023 
2024     final class MainHandler extends Handler {
2025 
2026         @Override
handleMessage(Message msg)2027         public void handleMessage(Message msg) {
2028             switch (msg.what) {
2029                 case WRITE_USER_MSG:
2030                     removeMessages(WRITE_USER_MSG, msg.obj);
2031                     synchronized (mPackagesLock) {
2032                         int userId = ((UserInfo) msg.obj).id;
2033                         UserInfo userInfo = mUsers.get(userId);
2034                         if (userInfo != null) {
2035                             writeUserLocked(userInfo);
2036                         }
2037                     }
2038             }
2039         }
2040     }
2041 
2042     /**
2043      * @param userId
2044      * @return whether the user has been initialized yet
2045      */
isInitialized(int userId)2046     boolean isInitialized(int userId) {
2047         return (getUserInfo(userId).flags & UserInfo.FLAG_INITIALIZED) != 0;
2048     }
2049 }
2050