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