UserManagerService.java revision 19c2a57c24fa337030ff31867380b685e9a5b586
1
2/*
3 * Copyright (C) 2011 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *      http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18package com.android.server.pm;
19
20import android.Manifest;
21import android.annotation.NonNull;
22import android.annotation.Nullable;
23import android.annotation.UserIdInt;
24import android.app.Activity;
25import android.app.ActivityManager;
26import android.app.ActivityManagerInternal;
27import android.app.ActivityManagerNative;
28import android.app.IActivityManager;
29import android.app.IStopUserCallback;
30import android.content.BroadcastReceiver;
31import android.content.Context;
32import android.content.Intent;
33import android.content.IntentFilter;
34import android.content.pm.PackageManager;
35import android.content.pm.PackageManager.NameNotFoundException;
36import android.content.pm.UserInfo;
37import android.content.res.Resources;
38import android.graphics.Bitmap;
39import android.os.Binder;
40import android.os.Build;
41import android.os.Bundle;
42import android.os.Debug;
43import android.os.Environment;
44import android.os.FileUtils;
45import android.os.Handler;
46import android.os.IBinder;
47import android.os.IUserManager;
48import android.os.Message;
49import android.os.ParcelFileDescriptor;
50import android.os.Parcelable;
51import android.os.PersistableBundle;
52import android.os.Process;
53import android.os.RemoteException;
54import android.os.ResultReceiver;
55import android.os.SELinux;
56import android.os.ServiceManager;
57import android.os.ShellCommand;
58import android.os.UserHandle;
59import android.os.UserManager;
60import android.os.UserManagerInternal;
61import android.os.UserManagerInternal.UserRestrictionsListener;
62import android.os.storage.StorageManager;
63import android.os.storage.VolumeInfo;
64import android.system.ErrnoException;
65import android.system.Os;
66import android.system.OsConstants;
67import android.util.AtomicFile;
68import android.util.IntArray;
69import android.util.Log;
70import android.util.Slog;
71import android.util.SparseArray;
72import android.util.SparseBooleanArray;
73import android.util.TimeUtils;
74import android.util.Xml;
75
76import com.android.internal.annotations.GuardedBy;
77import com.android.internal.annotations.VisibleForTesting;
78import com.android.internal.app.IAppOpsService;
79import com.android.internal.logging.MetricsLogger;
80import com.android.internal.util.FastXmlSerializer;
81import com.android.internal.util.Preconditions;
82import com.android.internal.util.XmlUtils;
83import com.android.internal.widget.LockPatternUtils;
84import com.android.server.LocalServices;
85
86import libcore.io.IoUtils;
87import libcore.util.Objects;
88
89import org.xmlpull.v1.XmlPullParser;
90import org.xmlpull.v1.XmlPullParserException;
91import org.xmlpull.v1.XmlSerializer;
92
93import java.io.BufferedOutputStream;
94import java.io.File;
95import java.io.FileDescriptor;
96import java.io.FileInputStream;
97import java.io.FileNotFoundException;
98import java.io.FileOutputStream;
99import java.io.IOException;
100import java.io.PrintWriter;
101import java.nio.charset.StandardCharsets;
102import java.util.ArrayList;
103import java.util.List;
104
105/**
106 * Service for {@link UserManager}.
107 *
108 * Method naming convention:
109 * <ul>
110 * <li> Methods suffixed with "LP" should be called within the {@link #mPackagesLock} lock.
111 * <li> Methods suffixed with "LR" should be called within the {@link #mRestrictionsLock} lock.
112 * <li> Methods suffixed with "LU" should be called within the {@link #mUsersLock} lock.
113 * </ul>
114 */
115public class UserManagerService extends IUserManager.Stub {
116    private static final String LOG_TAG = "UserManagerService";
117    static final boolean DBG = false; // DO NOT SUBMIT WITH TRUE
118    private static final boolean DBG_WITH_STACKTRACE = false; // DO NOT SUBMIT WITH TRUE
119
120    private static final String TAG_NAME = "name";
121    private static final String TAG_ACCOUNT = "account";
122    private static final String ATTR_FLAGS = "flags";
123    private static final String ATTR_ICON_PATH = "icon";
124    private static final String ATTR_ID = "id";
125    private static final String ATTR_CREATION_TIME = "created";
126    private static final String ATTR_LAST_LOGGED_IN_TIME = "lastLoggedIn";
127    private static final String ATTR_LAST_LOGGED_IN_FINGERPRINT = "lastLoggedInFingerprint";
128    private static final String ATTR_SERIAL_NO = "serialNumber";
129    private static final String ATTR_NEXT_SERIAL_NO = "nextSerialNumber";
130    private static final String ATTR_PARTIAL = "partial";
131    private static final String ATTR_GUEST_TO_REMOVE = "guestToRemove";
132    private static final String ATTR_USER_VERSION = "version";
133    private static final String ATTR_PROFILE_GROUP_ID = "profileGroupId";
134    private static final String ATTR_RESTRICTED_PROFILE_PARENT_ID = "restrictedProfileParentId";
135    private static final String ATTR_SEED_ACCOUNT_NAME = "seedAccountName";
136    private static final String ATTR_SEED_ACCOUNT_TYPE = "seedAccountType";
137    private static final String TAG_GUEST_RESTRICTIONS = "guestRestrictions";
138    private static final String TAG_USERS = "users";
139    private static final String TAG_USER = "user";
140    private static final String TAG_RESTRICTIONS = "restrictions";
141    private static final String TAG_DEVICE_POLICY_RESTRICTIONS = "device_policy_restrictions";
142    private static final String TAG_ENTRY = "entry";
143    private static final String TAG_VALUE = "value";
144    private static final String TAG_SEED_ACCOUNT_OPTIONS = "seedAccountOptions";
145    private static final String ATTR_KEY = "key";
146    private static final String ATTR_VALUE_TYPE = "type";
147    private static final String ATTR_MULTIPLE = "m";
148
149    private static final String ATTR_TYPE_STRING_ARRAY = "sa";
150    private static final String ATTR_TYPE_STRING = "s";
151    private static final String ATTR_TYPE_BOOLEAN = "b";
152    private static final String ATTR_TYPE_INTEGER = "i";
153    private static final String ATTR_TYPE_BUNDLE = "B";
154    private static final String ATTR_TYPE_BUNDLE_ARRAY = "BA";
155
156    private static final String USER_INFO_DIR = "system" + File.separator + "users";
157    private static final String USER_LIST_FILENAME = "userlist.xml";
158    private static final String USER_PHOTO_FILENAME = "photo.png";
159    private static final String USER_PHOTO_FILENAME_TMP = USER_PHOTO_FILENAME + ".tmp";
160
161    private static final String RESTRICTIONS_FILE_PREFIX = "res_";
162    private static final String XML_SUFFIX = ".xml";
163
164    private static final int MIN_USER_ID = 10;
165    // We need to keep process uid within Integer.MAX_VALUE.
166    private static final int MAX_USER_ID = Integer.MAX_VALUE / UserHandle.PER_USER_RANGE;
167
168    private static final int USER_VERSION = 6;
169
170    private static final long EPOCH_PLUS_30_YEARS = 30L * 365 * 24 * 60 * 60 * 1000L; // ms
171
172    // Maximum number of managed profiles permitted per user is 1. This cannot be increased
173    // without first making sure that the rest of the framework is prepared for it.
174    private static final int MAX_MANAGED_PROFILES = 1;
175
176    static final int WRITE_USER_MSG = 1;
177    static final int WRITE_USER_DELAY = 2*1000;  // 2 seconds
178
179    private static final String XATTR_SERIAL = "user.serial";
180
181    // Tron counters
182    private static final String TRON_GUEST_CREATED = "users_guest_created";
183    private static final String TRON_USER_CREATED = "users_user_created";
184
185    private final Context mContext;
186    private final PackageManagerService mPm;
187    private final Object mPackagesLock;
188    // Short-term lock for internal state, when interaction/sync with PM is not required
189    private final Object mUsersLock = new Object();
190    private final Object mRestrictionsLock = new Object();
191
192    private final Handler mHandler;
193
194    private final File mUsersDir;
195    private final File mUserListFile;
196
197    private static final IBinder mUserRestriconToken = new Binder();
198
199    /**
200     * User-related information that is used for persisting to flash. Only UserInfo is
201     * directly exposed to other system apps.
202     */
203    private static class UserData {
204        // Basic user information and properties
205        UserInfo info;
206        // Account name used when there is a strong association between a user and an account
207        String account;
208        // Account information for seeding into a newly created user. This could also be
209        // used for login validation for an existing user, for updating their credentials.
210        // In the latter case, data may not need to be persisted as it is only valid for the
211        // current login session.
212        String seedAccountName;
213        String seedAccountType;
214        PersistableBundle seedAccountOptions;
215        // Whether to perist the seed account information to be available after a boot
216        boolean persistSeedData;
217
218        void clearSeedAccountData() {
219            seedAccountName = null;
220            seedAccountType = null;
221            seedAccountOptions = null;
222            persistSeedData = false;
223        }
224    }
225
226    @GuardedBy("mUsersLock")
227    private final SparseArray<UserData> mUsers = new SparseArray<>();
228
229    /**
230     * User restrictions set via UserManager.  This doesn't include restrictions set by
231     * device owner / profile owners.
232     *
233     * DO NOT Change existing {@link Bundle} in it.  When changing a restriction for a user,
234     * a new {@link Bundle} should always be created and set.  This is because a {@link Bundle}
235     * maybe shared between {@link #mBaseUserRestrictions} and
236     * {@link #mCachedEffectiveUserRestrictions}, but they should always updated separately.
237     * (Otherwise we won't be able to detect what restrictions have changed in
238     * {@link #updateUserRestrictionsInternalLR}.
239     */
240    @GuardedBy("mRestrictionsLock")
241    private final SparseArray<Bundle> mBaseUserRestrictions = new SparseArray<>();
242
243    /**
244     * Cached user restrictions that are in effect -- i.e. {@link #mBaseUserRestrictions} combined
245     * with device / profile owner restrictions.  We'll initialize it lazily; use
246     * {@link #getEffectiveUserRestrictions} to access it.
247     *
248     * DO NOT Change existing {@link Bundle} in it.  When changing a restriction for a user,
249     * a new {@link Bundle} should always be created and set.  This is because a {@link Bundle}
250     * maybe shared between {@link #mBaseUserRestrictions} and
251     * {@link #mCachedEffectiveUserRestrictions}, but they should always updated separately.
252     * (Otherwise we won't be able to detect what restrictions have changed in
253     * {@link #updateUserRestrictionsInternalLR}.
254     */
255    @GuardedBy("mRestrictionsLock")
256    private final SparseArray<Bundle> mCachedEffectiveUserRestrictions = new SparseArray<>();
257
258    /**
259     * User restrictions that have already been applied in
260     * {@link #updateUserRestrictionsInternalLR(Bundle, int)}.  We use it to detect restrictions
261     * that have changed since the last
262     * {@link #updateUserRestrictionsInternalLR(Bundle, int)} call.
263     */
264    @GuardedBy("mRestrictionsLock")
265    private final SparseArray<Bundle> mAppliedUserRestrictions = new SparseArray<>();
266
267    /**
268     * User restrictions set by {@link com.android.server.devicepolicy.DevicePolicyManagerService}
269     * that should be applied to all users, including guests.
270     */
271    @GuardedBy("mRestrictionsLock")
272    private Bundle mDevicePolicyGlobalUserRestrictions;
273
274    /**
275     * User restrictions set by {@link com.android.server.devicepolicy.DevicePolicyManagerService}
276     * for each user.
277     */
278    @GuardedBy("mRestrictionsLock")
279    private final SparseArray<Bundle> mDevicePolicyLocalUserRestrictions = new SparseArray<>();
280
281    @GuardedBy("mGuestRestrictions")
282    private final Bundle mGuestRestrictions = new Bundle();
283
284    /**
285     * Set of user IDs being actively removed. Removed IDs linger in this set
286     * for several seconds to work around a VFS caching issue.
287     */
288    @GuardedBy("mUsersLock")
289    private final SparseBooleanArray mRemovingUserIds = new SparseBooleanArray();
290
291    @GuardedBy("mUsersLock")
292    private int[] mUserIds;
293    @GuardedBy("mPackagesLock")
294    private int mNextSerialNumber;
295    private int mUserVersion = 0;
296
297    private IAppOpsService mAppOpsService;
298
299    private final LocalService mLocalService;
300
301    @GuardedBy("mUsersLock")
302    private boolean mIsDeviceManaged;
303
304    @GuardedBy("mUsersLock")
305    private final SparseBooleanArray mIsUserManaged = new SparseBooleanArray();
306
307    @GuardedBy("mUserRestrictionsListeners")
308    private final ArrayList<UserRestrictionsListener> mUserRestrictionsListeners =
309            new ArrayList<>();
310
311    private final LockPatternUtils mLockPatternUtils;
312
313    /**
314     * Whether all users should be created ephemeral.
315     */
316    @GuardedBy("mUsersLock")
317    private boolean mForceEphemeralUsers;
318
319    private static UserManagerService sInstance;
320
321    public static UserManagerService getInstance() {
322        synchronized (UserManagerService.class) {
323            return sInstance;
324        }
325    }
326
327    @VisibleForTesting
328    UserManagerService(File dataDir) {
329        this(null, null, new Object(), dataDir);
330    }
331
332    /**
333     * Called by package manager to create the service.  This is closely
334     * associated with the package manager, and the given lock is the
335     * package manager's own lock.
336     */
337    UserManagerService(Context context, PackageManagerService pm, Object packagesLock) {
338        this(context, pm, packagesLock, Environment.getDataDirectory());
339    }
340
341    private UserManagerService(Context context, PackageManagerService pm,
342            Object packagesLock, File dataDir) {
343        mContext = context;
344        mPm = pm;
345        mPackagesLock = packagesLock;
346        mHandler = new MainHandler();
347        synchronized (mPackagesLock) {
348            mUsersDir = new File(dataDir, USER_INFO_DIR);
349            mUsersDir.mkdirs();
350            // Make zeroth user directory, for services to migrate their files to that location
351            File userZeroDir = new File(mUsersDir, String.valueOf(UserHandle.USER_SYSTEM));
352            userZeroDir.mkdirs();
353            FileUtils.setPermissions(mUsersDir.toString(),
354                    FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IROTH | FileUtils.S_IXOTH,
355                    -1, -1);
356            mUserListFile = new File(mUsersDir, USER_LIST_FILENAME);
357            initDefaultGuestRestrictions();
358            readUserListLP();
359            sInstance = this;
360        }
361        mLocalService = new LocalService();
362        LocalServices.addService(UserManagerInternal.class, mLocalService);
363        mLockPatternUtils = new LockPatternUtils(mContext);
364    }
365
366    void systemReady() {
367        // Prune out any partially created, partially removed and ephemeral users.
368        ArrayList<UserInfo> partials = new ArrayList<>();
369        synchronized (mUsersLock) {
370            final int userSize = mUsers.size();
371            for (int i = 0; i < userSize; i++) {
372                UserInfo ui = mUsers.valueAt(i).info;
373                if ((ui.partial || ui.guestToRemove || ui.isEphemeral()) && i != 0) {
374                    partials.add(ui);
375                }
376            }
377        }
378        final int partialsSize = partials.size();
379        for (int i = 0; i < partialsSize; i++) {
380            UserInfo ui = partials.get(i);
381            Slog.w(LOG_TAG, "Removing partially created user " + ui.id
382                    + " (name=" + ui.name + ")");
383            removeUserState(ui.id);
384        }
385
386        mAppOpsService = IAppOpsService.Stub.asInterface(
387                ServiceManager.getService(Context.APP_OPS_SERVICE));
388
389        synchronized (mRestrictionsLock) {
390            applyUserRestrictionsLR(UserHandle.USER_SYSTEM);
391        }
392
393        UserInfo currentGuestUser = findCurrentGuestUser();
394        if (currentGuestUser != null && !hasUserRestriction(
395                UserManager.DISALLOW_CONFIG_WIFI, currentGuestUser.id)) {
396            // If a guest user currently exists, apply the DISALLOW_CONFIG_WIFI option
397            // to it, in case this guest was created in a previous version where this
398            // user restriction was not a default guest restriction.
399            setUserRestriction(UserManager.DISALLOW_CONFIG_WIFI, true, currentGuestUser.id);
400        }
401    }
402
403    @Override
404    public String getUserAccount(int userId) {
405        checkManageUserAndAcrossUsersFullPermission("get user account");
406        synchronized (mUsersLock) {
407            return mUsers.get(userId).account;
408        }
409    }
410
411    @Override
412    public void setUserAccount(int userId, String accountName) {
413        checkManageUserAndAcrossUsersFullPermission("set user account");
414        UserData userToUpdate = null;
415        synchronized (mPackagesLock) {
416            synchronized (mUsersLock) {
417                final UserData userData = mUsers.get(userId);
418                if (userData == null) {
419                    Slog.e(LOG_TAG, "User not found for setting user account: u" + userId);
420                    return;
421                }
422                String currentAccount = userData.account;
423                if (!Objects.equal(currentAccount, accountName)) {
424                    userData.account = accountName;
425                    userToUpdate = userData;
426                }
427            }
428
429            if (userToUpdate != null) {
430                writeUserLP(userToUpdate);
431            }
432        }
433    }
434
435    @Override
436    public UserInfo getPrimaryUser() {
437        checkManageUsersPermission("query users");
438        synchronized (mUsersLock) {
439            final int userSize = mUsers.size();
440            for (int i = 0; i < userSize; i++) {
441                UserInfo ui = mUsers.valueAt(i).info;
442                if (ui.isPrimary() && !mRemovingUserIds.get(ui.id)) {
443                    return ui;
444                }
445            }
446        }
447        return null;
448    }
449
450    @Override
451    public @NonNull List<UserInfo> getUsers(boolean excludeDying) {
452        checkManageUsersPermission("query users");
453        synchronized (mUsersLock) {
454            ArrayList<UserInfo> users = new ArrayList<UserInfo>(mUsers.size());
455            final int userSize = mUsers.size();
456            for (int i = 0; i < userSize; i++) {
457                UserInfo ui = mUsers.valueAt(i).info;
458                if (ui.partial) {
459                    continue;
460                }
461                if (!excludeDying || !mRemovingUserIds.get(ui.id)) {
462                    users.add(userWithName(ui));
463                }
464            }
465            return users;
466        }
467    }
468
469    @Override
470    public List<UserInfo> getProfiles(int userId, boolean enabledOnly) {
471        boolean returnFullInfo = true;
472        if (userId != UserHandle.getCallingUserId()) {
473            checkManageUsersPermission("getting profiles related to user " + userId);
474        } else {
475            returnFullInfo = hasManageUsersPermission();
476        }
477        final long ident = Binder.clearCallingIdentity();
478        try {
479            synchronized (mUsersLock) {
480                return getProfilesLU(userId, enabledOnly, returnFullInfo);
481            }
482        } finally {
483            Binder.restoreCallingIdentity(ident);
484        }
485    }
486
487    @Override
488    public int[] getProfileIds(int userId, boolean enabledOnly) {
489        if (userId != UserHandle.getCallingUserId()) {
490            checkManageUsersPermission("getting profiles related to user " + userId);
491        }
492        final long ident = Binder.clearCallingIdentity();
493        try {
494            synchronized (mUsersLock) {
495                return getProfileIdsLU(userId, enabledOnly).toArray();
496            }
497        } finally {
498            Binder.restoreCallingIdentity(ident);
499        }
500    }
501
502    /** Assume permissions already checked and caller's identity cleared */
503    private List<UserInfo> getProfilesLU(int userId, boolean enabledOnly, boolean fullInfo) {
504        IntArray profileIds = getProfileIdsLU(userId, enabledOnly);
505        ArrayList<UserInfo> users = new ArrayList<>(profileIds.size());
506        for (int i = 0; i < profileIds.size(); i++) {
507            int profileId = profileIds.get(i);
508            UserInfo userInfo = mUsers.get(profileId).info;
509            // If full info is not required - clear PII data to prevent 3P apps from reading it
510            if (!fullInfo) {
511                userInfo = new UserInfo(userInfo);
512                userInfo.name = null;
513                userInfo.iconPath = null;
514            } else {
515                userInfo = userWithName(userInfo);
516            }
517            users.add(userInfo);
518        }
519        return users;
520    }
521
522    /**
523     *  Assume permissions already checked and caller's identity cleared
524     */
525    private IntArray getProfileIdsLU(int userId, boolean enabledOnly) {
526        UserInfo user = getUserInfoLU(userId);
527        IntArray result = new IntArray(mUsers.size());
528        if (user == null) {
529            // Probably a dying user
530            return result;
531        }
532        final int userSize = mUsers.size();
533        for (int i = 0; i < userSize; i++) {
534            UserInfo profile = mUsers.valueAt(i).info;
535            if (!isProfileOf(user, profile)) {
536                continue;
537            }
538            if (enabledOnly && !profile.isEnabled()) {
539                continue;
540            }
541            if (mRemovingUserIds.get(profile.id)) {
542                continue;
543            }
544            if (profile.partial) {
545                continue;
546            }
547            result.add(profile.id);
548        }
549        return result;
550    }
551
552    @Override
553    public int getCredentialOwnerProfile(int userHandle) {
554        checkManageUsersPermission("get the credential owner");
555        if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userHandle)) {
556            synchronized (mUsersLock) {
557                UserInfo profileParent = getProfileParentLU(userHandle);
558                if (profileParent != null) {
559                    return profileParent.id;
560                }
561            }
562        }
563
564        return userHandle;
565    }
566
567    @Override
568    public boolean isSameProfileGroup(int userId, int otherUserId) {
569        if (userId == otherUserId) return true;
570        checkManageUsersPermission("check if in the same profile group");
571        synchronized (mPackagesLock) {
572            return isSameProfileGroupLP(userId, otherUserId);
573        }
574    }
575
576    private boolean isSameProfileGroupLP(int userId, int otherUserId) {
577        synchronized (mUsersLock) {
578            UserInfo userInfo = getUserInfoLU(userId);
579            if (userInfo == null || userInfo.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID) {
580                return false;
581            }
582            UserInfo otherUserInfo = getUserInfoLU(otherUserId);
583            if (otherUserInfo == null
584                    || otherUserInfo.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID) {
585                return false;
586            }
587            return userInfo.profileGroupId == otherUserInfo.profileGroupId;
588        }
589    }
590
591    @Override
592    public UserInfo getProfileParent(int userHandle) {
593        checkManageUsersPermission("get the profile parent");
594        synchronized (mUsersLock) {
595            return getProfileParentLU(userHandle);
596        }
597    }
598
599    private UserInfo getProfileParentLU(int userHandle) {
600        UserInfo profile = getUserInfoLU(userHandle);
601        if (profile == null) {
602            return null;
603        }
604        int parentUserId = profile.profileGroupId;
605        if (parentUserId == UserInfo.NO_PROFILE_GROUP_ID) {
606            return null;
607        } else {
608            return getUserInfoLU(parentUserId);
609        }
610    }
611
612    private static boolean isProfileOf(UserInfo user, UserInfo profile) {
613        return user.id == profile.id ||
614                (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID
615                && user.profileGroupId == profile.profileGroupId);
616    }
617
618    private void broadcastProfileAvailabilityChanges(UserHandle profileHandle,
619            UserHandle parentHandle, boolean inQuietMode) {
620        Intent intent = new Intent();
621        if (inQuietMode) {
622            intent.setAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE);
623        } else {
624            intent.setAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE);
625        }
626        intent.putExtra(Intent.EXTRA_QUIET_MODE, inQuietMode);
627        intent.putExtra(Intent.EXTRA_USER, profileHandle);
628        intent.putExtra(Intent.EXTRA_USER_HANDLE, profileHandle.getIdentifier());
629        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
630        mContext.sendBroadcastAsUser(intent, parentHandle);
631    }
632
633    @Override
634    public void setQuietModeEnabled(int userHandle, boolean enableQuietMode) {
635        checkManageUsersPermission("silence profile");
636        boolean changed = false;
637        UserInfo profile, parent;
638        synchronized (mPackagesLock) {
639            synchronized (mUsersLock) {
640                profile = getUserInfoLU(userHandle);
641                parent = getProfileParentLU(userHandle);
642
643            }
644            if (profile == null || !profile.isManagedProfile()) {
645                throw new IllegalArgumentException("User " + userHandle + " is not a profile");
646            }
647            if (profile.isQuietModeEnabled() != enableQuietMode) {
648                profile.flags ^= UserInfo.FLAG_QUIET_MODE;
649                writeUserLP(getUserDataLU(profile.id));
650                changed = true;
651            }
652        }
653        if (changed) {
654            long identity = Binder.clearCallingIdentity();
655            try {
656                if (enableQuietMode) {
657                    ActivityManagerNative.getDefault().stopUser(userHandle, /* force */true, null);
658                } else {
659                    ActivityManagerNative.getDefault().startUserInBackground(userHandle);
660                }
661            } catch (RemoteException e) {
662                Slog.e(LOG_TAG, "fail to start/stop user for quiet mode", e);
663            } finally {
664                Binder.restoreCallingIdentity(identity);
665            }
666
667            broadcastProfileAvailabilityChanges(profile.getUserHandle(), parent.getUserHandle(),
668                    enableQuietMode);
669        }
670    }
671
672    @Override
673    public boolean isQuietModeEnabled(int userHandle) {
674        synchronized (mPackagesLock) {
675            UserInfo info;
676            synchronized (mUsersLock) {
677                info = getUserInfoLU(userHandle);
678            }
679            if (info == null || !info.isManagedProfile()) {
680                return false;
681            }
682            return info.isQuietModeEnabled();
683        }
684    }
685
686    @Override
687    public void setUserEnabled(int userId) {
688        checkManageUsersPermission("enable user");
689        synchronized (mPackagesLock) {
690            UserInfo info;
691            synchronized (mUsersLock) {
692                info = getUserInfoLU(userId);
693            }
694            if (info != null && !info.isEnabled()) {
695                info.flags ^= UserInfo.FLAG_DISABLED;
696                writeUserLP(getUserDataLU(info.id));
697            }
698        }
699    }
700
701    @Override
702    public UserInfo getUserInfo(int userId) {
703        checkManageUsersPermission("query user");
704        synchronized (mUsersLock) {
705            return userWithName(getUserInfoLU(userId));
706        }
707    }
708
709    /**
710     * Returns a UserInfo object with the name filled in, for Owner, or the original
711     * if the name is already set.
712     */
713    private UserInfo userWithName(UserInfo orig) {
714        if (orig != null && orig.name == null && orig.id == UserHandle.USER_SYSTEM) {
715            UserInfo withName = new UserInfo(orig);
716            withName.name = getOwnerName();
717            return withName;
718        } else {
719            return orig;
720        }
721    }
722
723    @Override
724    public boolean isManagedProfile(int userId) {
725        int callingUserId = UserHandle.getCallingUserId();
726        if (callingUserId != userId && !hasManageUsersPermission()) {
727            synchronized (mPackagesLock) {
728                if (!isSameProfileGroupLP(callingUserId, userId)) {
729                    throw new SecurityException(
730                            "You need MANAGE_USERS permission to: check if specified user a " +
731                            "managed profile outside your profile group");
732                }
733            }
734        }
735        synchronized (mUsersLock) {
736            UserInfo userInfo =  getUserInfoLU(userId);
737            return userInfo != null && userInfo.isManagedProfile();
738        }
739    }
740
741    @Override
742    public boolean isRestricted() {
743        synchronized (mUsersLock) {
744            return getUserInfoLU(UserHandle.getCallingUserId()).isRestricted();
745        }
746    }
747
748    @Override
749    public boolean canHaveRestrictedProfile(int userId) {
750        checkManageUsersPermission("canHaveRestrictedProfile");
751        synchronized (mUsersLock) {
752            final UserInfo userInfo = getUserInfoLU(userId);
753            if (userInfo == null || !userInfo.canHaveProfile()) {
754                return false;
755            }
756            if (!userInfo.isAdmin()) {
757                return false;
758            }
759            // restricted profile can be created if there is no DO set and the admin user has no PO;
760            return !mIsDeviceManaged && !mIsUserManaged.get(userId);
761        }
762    }
763
764    /*
765     * Should be locked on mUsers before calling this.
766     */
767    private UserInfo getUserInfoLU(int userId) {
768        final UserData userData = mUsers.get(userId);
769        // If it is partial and not in the process of being removed, return as unknown user.
770        if (userData != null && userData.info.partial && !mRemovingUserIds.get(userId)) {
771            Slog.w(LOG_TAG, "getUserInfo: unknown user #" + userId);
772            return null;
773        }
774        return userData != null ? userData.info : null;
775    }
776
777    private UserData getUserDataLU(int userId) {
778        final UserData userData = mUsers.get(userId);
779        // If it is partial and not in the process of being removed, return as unknown user.
780        if (userData != null && userData.info.partial && !mRemovingUserIds.get(userId)) {
781            return null;
782        }
783        return userData;
784    }
785
786    /**
787     * Obtains {@link #mUsersLock} and return UserInfo from mUsers.
788     * <p>No permissions checking or any addition checks are made</p>
789     */
790    private UserInfo getUserInfoNoChecks(int userId) {
791        synchronized (mUsersLock) {
792            final UserData userData = mUsers.get(userId);
793            return userData != null ? userData.info : null;
794        }
795    }
796
797    /**
798     * Obtains {@link #mUsersLock} and return UserData from mUsers.
799     * <p>No permissions checking or any addition checks are made</p>
800     */
801    private UserData getUserDataNoChecks(int userId) {
802        synchronized (mUsersLock) {
803            return mUsers.get(userId);
804        }
805    }
806
807    /** Called by PackageManagerService */
808    public boolean exists(int userId) {
809        return getUserInfoNoChecks(userId) != null;
810    }
811
812    @Override
813    public void setUserName(int userId, String name) {
814        checkManageUsersPermission("rename users");
815        boolean changed = false;
816        synchronized (mPackagesLock) {
817            UserData userData = getUserDataNoChecks(userId);
818            if (userData == null || userData.info.partial) {
819                Slog.w(LOG_TAG, "setUserName: unknown user #" + userId);
820                return;
821            }
822            if (name != null && !name.equals(userData.info.name)) {
823                userData.info.name = name;
824                writeUserLP(userData);
825                changed = true;
826            }
827        }
828        if (changed) {
829            sendUserInfoChangedBroadcast(userId);
830        }
831    }
832
833    @Override
834    public void setUserIcon(int userId, Bitmap bitmap) {
835        checkManageUsersPermission("update users");
836        if (hasUserRestriction(UserManager.DISALLOW_SET_USER_ICON, userId)) {
837            Log.w(LOG_TAG, "Cannot set user icon. DISALLOW_SET_USER_ICON is enabled.");
838            return;
839        }
840        mLocalService.setUserIcon(userId, bitmap);
841    }
842
843
844
845    private void sendUserInfoChangedBroadcast(int userId) {
846        Intent changedIntent = new Intent(Intent.ACTION_USER_INFO_CHANGED);
847        changedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
848        changedIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
849        mContext.sendBroadcastAsUser(changedIntent, UserHandle.ALL);
850    }
851
852    @Override
853    public ParcelFileDescriptor getUserIcon(int targetUserId) {
854        String iconPath;
855        synchronized (mPackagesLock) {
856            UserInfo targetUserInfo = getUserInfoNoChecks(targetUserId);
857            if (targetUserInfo == null || targetUserInfo.partial) {
858                Slog.w(LOG_TAG, "getUserIcon: unknown user #" + targetUserId);
859                return null;
860            }
861
862            final int callingUserId = UserHandle.getCallingUserId();
863            final int callingGroupId = getUserInfoNoChecks(callingUserId).profileGroupId;
864            final int targetGroupId = targetUserInfo.profileGroupId;
865            final boolean sameGroup = (callingGroupId != UserInfo.NO_PROFILE_GROUP_ID
866                    && callingGroupId == targetGroupId);
867            if ((callingUserId != targetUserId) && !sameGroup) {
868                checkManageUsersPermission("get the icon of a user who is not related");
869            }
870
871            if (targetUserInfo.iconPath == null) {
872                return null;
873            }
874            iconPath = targetUserInfo.iconPath;
875        }
876
877        try {
878            return ParcelFileDescriptor.open(
879                    new File(iconPath), ParcelFileDescriptor.MODE_READ_ONLY);
880        } catch (FileNotFoundException e) {
881            Log.e(LOG_TAG, "Couldn't find icon file", e);
882        }
883        return null;
884    }
885
886    public void makeInitialized(int userId) {
887        checkManageUsersPermission("makeInitialized");
888        boolean scheduleWriteUser = false;
889        UserData userData;
890        synchronized (mUsersLock) {
891            userData = mUsers.get(userId);
892            if (userData == null || userData.info.partial) {
893                Slog.w(LOG_TAG, "makeInitialized: unknown user #" + userId);
894                return;
895            }
896            if ((userData.info.flags & UserInfo.FLAG_INITIALIZED) == 0) {
897                userData.info.flags |= UserInfo.FLAG_INITIALIZED;
898                scheduleWriteUser = true;
899            }
900        }
901        if (scheduleWriteUser) {
902            scheduleWriteUser(userData);
903        }
904    }
905
906    /**
907     * If default guest restrictions haven't been initialized yet, add the basic
908     * restrictions.
909     */
910    private void initDefaultGuestRestrictions() {
911        synchronized (mGuestRestrictions) {
912            if (mGuestRestrictions.isEmpty()) {
913                mGuestRestrictions.putBoolean(UserManager.DISALLOW_CONFIG_WIFI, true);
914                mGuestRestrictions.putBoolean(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, true);
915                mGuestRestrictions.putBoolean(UserManager.DISALLOW_OUTGOING_CALLS, true);
916                mGuestRestrictions.putBoolean(UserManager.DISALLOW_SMS, true);
917            }
918        }
919    }
920
921    @Override
922    public Bundle getDefaultGuestRestrictions() {
923        checkManageUsersPermission("getDefaultGuestRestrictions");
924        synchronized (mGuestRestrictions) {
925            return new Bundle(mGuestRestrictions);
926        }
927    }
928
929    @Override
930    public void setDefaultGuestRestrictions(Bundle restrictions) {
931        checkManageUsersPermission("setDefaultGuestRestrictions");
932        synchronized (mGuestRestrictions) {
933            mGuestRestrictions.clear();
934            mGuestRestrictions.putAll(restrictions);
935        }
936        synchronized (mPackagesLock) {
937            writeUserListLP();
938        }
939    }
940
941    /**
942     * See {@link UserManagerInternal#setDevicePolicyUserRestrictions(int, Bundle, Bundle)}
943     */
944    void setDevicePolicyUserRestrictionsInner(int userId, @NonNull Bundle local,
945            @Nullable Bundle global) {
946        Preconditions.checkNotNull(local);
947        boolean globalChanged = false;
948        boolean localChanged;
949        synchronized (mRestrictionsLock) {
950            if (global != null) {
951                // Update global.
952                globalChanged = !UserRestrictionsUtils.areEqual(
953                        mDevicePolicyGlobalUserRestrictions, global);
954                if (globalChanged) {
955                    mDevicePolicyGlobalUserRestrictions = global;
956                }
957            }
958            {
959                // Update local.
960                final Bundle prev = mDevicePolicyLocalUserRestrictions.get(userId);
961                localChanged = !UserRestrictionsUtils.areEqual(prev, local);
962                if (localChanged) {
963                    mDevicePolicyLocalUserRestrictions.put(userId, local);
964                }
965            }
966        }
967        if (DBG) {
968            Log.d(LOG_TAG, "setDevicePolicyUserRestrictions: userId=" + userId
969                            + " global=" + global + (globalChanged ? " (changed)" : "")
970                            + " local=" + local + (localChanged ? " (changed)" : "")
971            );
972        }
973        // Don't call them within the mRestrictionsLock.
974        synchronized (mPackagesLock) {
975            if (localChanged) {
976                writeUserLP(getUserDataNoChecks(userId));
977            }
978            if (globalChanged) {
979                writeUserListLP();
980            }
981        }
982
983        synchronized (mRestrictionsLock) {
984            if (globalChanged) {
985                applyUserRestrictionsForAllUsersLR();
986            } else if (localChanged) {
987                applyUserRestrictionsLR(userId);
988            }
989        }
990    }
991
992    @GuardedBy("mRestrictionsLock")
993    private Bundle computeEffectiveUserRestrictionsLR(int userId) {
994        final Bundle baseRestrictions =
995                UserRestrictionsUtils.nonNull(mBaseUserRestrictions.get(userId));
996        final Bundle global = mDevicePolicyGlobalUserRestrictions;
997        final Bundle local = mDevicePolicyLocalUserRestrictions.get(userId);
998
999        if (UserRestrictionsUtils.isEmpty(global) && UserRestrictionsUtils.isEmpty(local)) {
1000            // Common case first.
1001            return baseRestrictions;
1002        }
1003        final Bundle effective = UserRestrictionsUtils.clone(baseRestrictions);
1004        UserRestrictionsUtils.merge(effective, global);
1005        UserRestrictionsUtils.merge(effective, local);
1006
1007        return effective;
1008    }
1009
1010    @GuardedBy("mRestrictionsLock")
1011    private void invalidateEffectiveUserRestrictionsLR(int userId) {
1012        if (DBG) {
1013            Log.d(LOG_TAG, "invalidateEffectiveUserRestrictions userId=" + userId);
1014        }
1015        mCachedEffectiveUserRestrictions.remove(userId);
1016    }
1017
1018    private Bundle getEffectiveUserRestrictions(int userId) {
1019        synchronized (mRestrictionsLock) {
1020            Bundle restrictions = mCachedEffectiveUserRestrictions.get(userId);
1021            if (restrictions == null) {
1022                restrictions = computeEffectiveUserRestrictionsLR(userId);
1023                mCachedEffectiveUserRestrictions.put(userId, restrictions);
1024            }
1025            return restrictions;
1026        }
1027    }
1028
1029    /** @return a specific user restriction that's in effect currently. */
1030    @Override
1031    public boolean hasUserRestriction(String restrictionKey, int userId) {
1032        if (!UserRestrictionsUtils.isValidRestriction(restrictionKey)) {
1033            return false;
1034        }
1035        Bundle restrictions = getEffectiveUserRestrictions(userId);
1036        return restrictions != null && restrictions.getBoolean(restrictionKey);
1037    }
1038
1039    /**
1040     * @return UserRestrictions that are in effect currently.  This always returns a new
1041     * {@link Bundle}.
1042     */
1043    @Override
1044    public Bundle getUserRestrictions(int userId) {
1045        return UserRestrictionsUtils.clone(getEffectiveUserRestrictions(userId));
1046    }
1047
1048    @Override
1049    public boolean hasBaseUserRestriction(String restrictionKey, int userId) {
1050        checkManageUsersPermission("hasBaseUserRestriction");
1051        if (!UserRestrictionsUtils.isValidRestriction(restrictionKey)) {
1052            return false;
1053        }
1054        synchronized (mRestrictionsLock) {
1055            Bundle bundle = mBaseUserRestrictions.get(userId);
1056            return (bundle != null && bundle.getBoolean(restrictionKey, false));
1057        }
1058    }
1059
1060    @Override
1061    public void setUserRestriction(String key, boolean value, int userId) {
1062        checkManageUsersPermission("setUserRestriction");
1063        if (!UserRestrictionsUtils.isValidRestriction(key)) {
1064            return;
1065        }
1066        synchronized (mRestrictionsLock) {
1067            // Note we can't modify Bundles stored in mBaseUserRestrictions directly, so create
1068            // a copy.
1069            final Bundle newRestrictions = UserRestrictionsUtils.clone(
1070                    mBaseUserRestrictions.get(userId));
1071            newRestrictions.putBoolean(key, value);
1072
1073            updateUserRestrictionsInternalLR(newRestrictions, userId);
1074        }
1075    }
1076
1077    /**
1078     * Optionally updating user restrictions, calculate the effective user restrictions and also
1079     * propagate to other services and system settings.
1080     *
1081     * @param newRestrictions User restrictions to set.
1082     *      If null, will not update user restrictions and only does the propagation.
1083     * @param userId target user ID.
1084     */
1085    @GuardedBy("mRestrictionsLock")
1086    private void updateUserRestrictionsInternalLR(
1087            @Nullable Bundle newRestrictions, int userId) {
1088
1089        final Bundle prevAppliedRestrictions = UserRestrictionsUtils.nonNull(
1090                mAppliedUserRestrictions.get(userId));
1091
1092        // Update base restrictions.
1093        if (newRestrictions != null) {
1094            // If newRestrictions == the current one, it's probably a bug.
1095            final Bundle prevBaseRestrictions = mBaseUserRestrictions.get(userId);
1096
1097            Preconditions.checkState(prevBaseRestrictions != newRestrictions);
1098            Preconditions.checkState(mCachedEffectiveUserRestrictions.get(userId)
1099                    != newRestrictions);
1100
1101            if (!UserRestrictionsUtils.areEqual(prevBaseRestrictions, newRestrictions)) {
1102                mBaseUserRestrictions.put(userId, newRestrictions);
1103                scheduleWriteUser(getUserDataNoChecks(userId));
1104            }
1105        }
1106
1107        final Bundle effective = computeEffectiveUserRestrictionsLR(userId);
1108
1109        mCachedEffectiveUserRestrictions.put(userId, effective);
1110
1111        // Apply the new restrictions.
1112        if (DBG) {
1113            debug("Applying user restrictions: userId=" + userId
1114                    + " new=" + effective + " prev=" + prevAppliedRestrictions);
1115        }
1116
1117        if (mAppOpsService != null) { // We skip it until system-ready.
1118            final long token = Binder.clearCallingIdentity();
1119            try {
1120                mAppOpsService.setUserRestrictions(effective, mUserRestriconToken, userId);
1121            } catch (RemoteException e) {
1122                Log.w(LOG_TAG, "Unable to notify AppOpsService of UserRestrictions");
1123            } finally {
1124                Binder.restoreCallingIdentity(token);
1125            }
1126        }
1127
1128        propagateUserRestrictionsLR(userId, effective, prevAppliedRestrictions);
1129
1130        mAppliedUserRestrictions.put(userId, new Bundle(effective));
1131    }
1132
1133    private void propagateUserRestrictionsLR(final int userId,
1134            Bundle newRestrictions, Bundle prevRestrictions) {
1135        // Note this method doesn't touch any state, meaning it doesn't require mRestrictionsLock
1136        // actually, but we still need some kind of synchronization otherwise we might end up
1137        // calling listeners out-of-order, thus "LR".
1138
1139        if (UserRestrictionsUtils.areEqual(newRestrictions, prevRestrictions)) {
1140            return;
1141        }
1142
1143        final Bundle newRestrictionsFinal = new Bundle(newRestrictions);
1144        final Bundle prevRestrictionsFinal = new Bundle(prevRestrictions);
1145
1146        mHandler.post(new Runnable() {
1147            @Override
1148            public void run() {
1149                UserRestrictionsUtils.applyUserRestrictions(
1150                        mContext, userId, newRestrictionsFinal, prevRestrictionsFinal);
1151
1152                final UserRestrictionsListener[] listeners;
1153                synchronized (mUserRestrictionsListeners) {
1154                    listeners = new UserRestrictionsListener[mUserRestrictionsListeners.size()];
1155                    mUserRestrictionsListeners.toArray(listeners);
1156                }
1157                for (int i = 0; i < listeners.length; i++) {
1158                    listeners[i].onUserRestrictionsChanged(userId,
1159                            newRestrictionsFinal, prevRestrictionsFinal);
1160                }
1161            }
1162        });
1163    }
1164
1165    // Package private for the inner class.
1166    void applyUserRestrictionsLR(int userId) {
1167        updateUserRestrictionsInternalLR(null, userId);
1168    }
1169
1170    @GuardedBy("mRestrictionsLock")
1171    // Package private for the inner class.
1172    void applyUserRestrictionsForAllUsersLR() {
1173        if (DBG) {
1174            debug("applyUserRestrictionsForAllUsersLR");
1175        }
1176        // First, invalidate all cached values.
1177        mCachedEffectiveUserRestrictions.clear();
1178
1179        // We don't want to call into ActivityManagerNative while taking a lock, so we'll call
1180        // it on a handler.
1181        final Runnable r = new Runnable() {
1182            @Override
1183            public void run() {
1184                // Then get the list of running users.
1185                final int[] runningUsers;
1186                try {
1187                    runningUsers = ActivityManagerNative.getDefault().getRunningUserIds();
1188                } catch (RemoteException e) {
1189                    Log.w(LOG_TAG, "Unable to access ActivityManagerNative");
1190                    return;
1191                }
1192                // Then re-calculate the effective restrictions and apply, only for running users.
1193                // It's okay if a new user has started after the getRunningUserIds() call,
1194                // because we'll do the same thing (re-calculate the restrictions and apply)
1195                // when we start a user.
1196                synchronized (mRestrictionsLock) {
1197                    for (int i = 0; i < runningUsers.length; i++) {
1198                        applyUserRestrictionsLR(runningUsers[i]);
1199                    }
1200                }
1201            }
1202        };
1203        mHandler.post(r);
1204    }
1205
1206    /**
1207     * Check if we've hit the limit of how many users can be created.
1208     */
1209    private boolean isUserLimitReached() {
1210        int count;
1211        synchronized (mUsersLock) {
1212            count = getAliveUsersExcludingGuestsCountLU();
1213        }
1214        return count >= UserManager.getMaxSupportedUsers();
1215    }
1216
1217    @Override
1218    public boolean canAddMoreManagedProfiles(int userId, boolean allowedToRemoveOne) {
1219        checkManageUsersPermission("check if more managed profiles can be added.");
1220        if (ActivityManager.isLowRamDeviceStatic()) {
1221            return false;
1222        }
1223        if (!mContext.getPackageManager().hasSystemFeature(
1224                PackageManager.FEATURE_MANAGED_USERS)) {
1225            return false;
1226        }
1227        // Limit number of managed profiles that can be created
1228        final int managedProfilesCount = getProfiles(userId, true).size() - 1;
1229        final int profilesRemovedCount = managedProfilesCount > 0 && allowedToRemoveOne ? 1 : 0;
1230        if (managedProfilesCount - profilesRemovedCount >= MAX_MANAGED_PROFILES) {
1231            return false;
1232        }
1233        synchronized(mUsersLock) {
1234            UserInfo userInfo = getUserInfoLU(userId);
1235            if (!userInfo.canHaveProfile()) {
1236                return false;
1237            }
1238            int usersCountAfterRemoving = getAliveUsersExcludingGuestsCountLU()
1239                    - profilesRemovedCount;
1240            // We allow creating a managed profile in the special case where there is only one user.
1241            return usersCountAfterRemoving  == 1
1242                    || usersCountAfterRemoving < UserManager.getMaxSupportedUsers();
1243        }
1244    }
1245
1246    private int getAliveUsersExcludingGuestsCountLU() {
1247        int aliveUserCount = 0;
1248        final int totalUserCount = mUsers.size();
1249        // Skip over users being removed
1250        for (int i = 0; i < totalUserCount; i++) {
1251            UserInfo user = mUsers.valueAt(i).info;
1252            if (!mRemovingUserIds.get(user.id)
1253                    && !user.isGuest() && !user.partial) {
1254                aliveUserCount++;
1255            }
1256        }
1257        return aliveUserCount;
1258    }
1259
1260    /**
1261     * Enforces that only the system UID or root's UID or apps that have the
1262     * {@link android.Manifest.permission#MANAGE_USERS MANAGE_USERS} and
1263     * {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL INTERACT_ACROSS_USERS_FULL}
1264     * permissions can make certain calls to the UserManager.
1265     *
1266     * @param message used as message if SecurityException is thrown
1267     * @throws SecurityException if the caller does not have enough privilege.
1268     */
1269    private static final void checkManageUserAndAcrossUsersFullPermission(String message) {
1270        final int uid = Binder.getCallingUid();
1271        if (uid != Process.SYSTEM_UID && uid != 0
1272                && ActivityManager.checkComponentPermission(
1273                Manifest.permission.MANAGE_USERS,
1274                uid, -1, true) != PackageManager.PERMISSION_GRANTED
1275                && ActivityManager.checkComponentPermission(
1276                Manifest.permission.INTERACT_ACROSS_USERS_FULL,
1277                uid, -1, true) != PackageManager.PERMISSION_GRANTED) {
1278            throw new SecurityException(
1279                    "You need MANAGE_USERS and INTERACT_ACROSS_USERS_FULL permission to: "
1280                            + message);
1281        }
1282    }
1283
1284    /**
1285     * Enforces that only the system UID or root's UID or apps that have the
1286     * {@link android.Manifest.permission#MANAGE_USERS MANAGE_USERS}
1287     * permission can make certain calls to the UserManager.
1288     *
1289     * @param message used as message if SecurityException is thrown
1290     * @throws SecurityException if the caller is not system or root
1291     * @see #hasManageUsersPermission()
1292     */
1293    private static final void checkManageUsersPermission(String message) {
1294        if (!hasManageUsersPermission()) {
1295            throw new SecurityException("You need MANAGE_USERS permission to: " + message);
1296        }
1297    }
1298
1299    /**
1300     * @return whether the calling UID is system UID or root's UID or the calling app has the
1301     * {@link android.Manifest.permission#MANAGE_USERS MANAGE_USERS}.
1302     */
1303    private static final boolean hasManageUsersPermission() {
1304        final int callingUid = Binder.getCallingUid();
1305        return UserHandle.isSameApp(callingUid, Process.SYSTEM_UID)
1306                || callingUid == Process.ROOT_UID
1307                || ActivityManager.checkComponentPermission(
1308                        android.Manifest.permission.MANAGE_USERS,
1309                        callingUid, -1, true) == PackageManager.PERMISSION_GRANTED;
1310    }
1311
1312    /**
1313     * Enforces that only the system UID or root's UID (on any user) can make certain calls to the
1314     * UserManager.
1315     *
1316     * @param message used as message if SecurityException is thrown
1317     * @throws SecurityException if the caller is not system or root
1318     */
1319    private static void checkSystemOrRoot(String message) {
1320        final int uid = Binder.getCallingUid();
1321        if (!UserHandle.isSameApp(uid, Process.SYSTEM_UID) && uid != Process.ROOT_UID) {
1322            throw new SecurityException("Only system may: " + message);
1323        }
1324    }
1325
1326    private void writeBitmapLP(UserInfo info, Bitmap bitmap) {
1327        try {
1328            File dir = new File(mUsersDir, Integer.toString(info.id));
1329            File file = new File(dir, USER_PHOTO_FILENAME);
1330            File tmp = new File(dir, USER_PHOTO_FILENAME_TMP);
1331            if (!dir.exists()) {
1332                dir.mkdir();
1333                FileUtils.setPermissions(
1334                        dir.getPath(),
1335                        FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
1336                        -1, -1);
1337            }
1338            FileOutputStream os;
1339            if (bitmap.compress(Bitmap.CompressFormat.PNG, 100, os = new FileOutputStream(tmp))
1340                    && tmp.renameTo(file) && SELinux.restorecon(file)) {
1341                info.iconPath = file.getAbsolutePath();
1342            }
1343            try {
1344                os.close();
1345            } catch (IOException ioe) {
1346                // What the ... !
1347            }
1348            tmp.delete();
1349        } catch (FileNotFoundException e) {
1350            Slog.w(LOG_TAG, "Error setting photo for user ", e);
1351        }
1352    }
1353
1354    /**
1355     * Returns an array of user ids. This array is cached here for quick access, so do not modify or
1356     * cache it elsewhere.
1357     * @return the array of user ids.
1358     */
1359    public int[] getUserIds() {
1360        synchronized (mUsersLock) {
1361            return mUserIds;
1362        }
1363    }
1364
1365    private void readUserListLP() {
1366        if (!mUserListFile.exists()) {
1367            fallbackToSingleUserLP();
1368            return;
1369        }
1370        FileInputStream fis = null;
1371        AtomicFile userListFile = new AtomicFile(mUserListFile);
1372        try {
1373            fis = userListFile.openRead();
1374            XmlPullParser parser = Xml.newPullParser();
1375            parser.setInput(fis, StandardCharsets.UTF_8.name());
1376            int type;
1377            while ((type = parser.next()) != XmlPullParser.START_TAG
1378                    && type != XmlPullParser.END_DOCUMENT) {
1379                // Skip
1380            }
1381
1382            if (type != XmlPullParser.START_TAG) {
1383                Slog.e(LOG_TAG, "Unable to read user list");
1384                fallbackToSingleUserLP();
1385                return;
1386            }
1387
1388            mNextSerialNumber = -1;
1389            if (parser.getName().equals(TAG_USERS)) {
1390                String lastSerialNumber = parser.getAttributeValue(null, ATTR_NEXT_SERIAL_NO);
1391                if (lastSerialNumber != null) {
1392                    mNextSerialNumber = Integer.parseInt(lastSerialNumber);
1393                }
1394                String versionNumber = parser.getAttributeValue(null, ATTR_USER_VERSION);
1395                if (versionNumber != null) {
1396                    mUserVersion = Integer.parseInt(versionNumber);
1397                }
1398            }
1399
1400            final Bundle newDevicePolicyGlobalUserRestrictions = new Bundle();
1401
1402            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
1403                if (type == XmlPullParser.START_TAG) {
1404                    final String name = parser.getName();
1405                    if (name.equals(TAG_USER)) {
1406                        String id = parser.getAttributeValue(null, ATTR_ID);
1407
1408                        UserData userData = readUserLP(Integer.parseInt(id));
1409
1410                        if (userData != null) {
1411                            synchronized (mUsersLock) {
1412                                mUsers.put(userData.info.id, userData);
1413                                if (mNextSerialNumber < 0
1414                                        || mNextSerialNumber <= userData.info.id) {
1415                                    mNextSerialNumber = userData.info.id + 1;
1416                                }
1417                            }
1418                        }
1419                    } else if (name.equals(TAG_GUEST_RESTRICTIONS)) {
1420                        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1421                                && type != XmlPullParser.END_TAG) {
1422                            if (type == XmlPullParser.START_TAG) {
1423                                if (parser.getName().equals(TAG_RESTRICTIONS)) {
1424                                    synchronized (mGuestRestrictions) {
1425                                        UserRestrictionsUtils
1426                                                .readRestrictions(parser, mGuestRestrictions);
1427                                    }
1428                                } else if (parser.getName().equals(TAG_DEVICE_POLICY_RESTRICTIONS)
1429                                        ) {
1430                                    UserRestrictionsUtils.readRestrictions(parser,
1431                                            newDevicePolicyGlobalUserRestrictions);
1432                                }
1433                                break;
1434                            }
1435                        }
1436                    }
1437                }
1438            }
1439            synchronized (mRestrictionsLock) {
1440                mDevicePolicyGlobalUserRestrictions = newDevicePolicyGlobalUserRestrictions;
1441            }
1442            updateUserIds();
1443            upgradeIfNecessaryLP();
1444        } catch (IOException | XmlPullParserException e) {
1445            fallbackToSingleUserLP();
1446        } finally {
1447            IoUtils.closeQuietly(fis);
1448        }
1449    }
1450
1451    /**
1452     * Upgrade steps between versions, either for fixing bugs or changing the data format.
1453     */
1454    private void upgradeIfNecessaryLP() {
1455        final int originalVersion = mUserVersion;
1456        int userVersion = mUserVersion;
1457        if (userVersion < 1) {
1458            // Assign a proper name for the owner, if not initialized correctly before
1459            UserData userData = getUserDataNoChecks(UserHandle.USER_SYSTEM);
1460            if ("Primary".equals(userData.info.name)) {
1461                userData.info.name =
1462                        mContext.getResources().getString(com.android.internal.R.string.owner_name);
1463                scheduleWriteUser(userData);
1464            }
1465            userVersion = 1;
1466        }
1467
1468        if (userVersion < 2) {
1469            // Owner should be marked as initialized
1470            UserData userData = getUserDataNoChecks(UserHandle.USER_SYSTEM);
1471            if ((userData.info.flags & UserInfo.FLAG_INITIALIZED) == 0) {
1472                userData.info.flags |= UserInfo.FLAG_INITIALIZED;
1473                scheduleWriteUser(userData);
1474            }
1475            userVersion = 2;
1476        }
1477
1478
1479        if (userVersion < 4) {
1480            userVersion = 4;
1481        }
1482
1483        if (userVersion < 5) {
1484            initDefaultGuestRestrictions();
1485            userVersion = 5;
1486        }
1487
1488        if (userVersion < 6) {
1489            final boolean splitSystemUser = UserManager.isSplitSystemUser();
1490            synchronized (mUsersLock) {
1491                for (int i = 0; i < mUsers.size(); i++) {
1492                    UserData userData = mUsers.valueAt(i);
1493                    // In non-split mode, only user 0 can have restricted profiles
1494                    if (!splitSystemUser && userData.info.isRestricted()
1495                            && (userData.info.restrictedProfileParentId
1496                                    == UserInfo.NO_PROFILE_GROUP_ID)) {
1497                        userData.info.restrictedProfileParentId = UserHandle.USER_SYSTEM;
1498                        scheduleWriteUser(userData);
1499                    }
1500                }
1501            }
1502            userVersion = 6;
1503        }
1504
1505        if (userVersion < USER_VERSION) {
1506            Slog.w(LOG_TAG, "User version " + mUserVersion + " didn't upgrade as expected to "
1507                    + USER_VERSION);
1508        } else {
1509            mUserVersion = userVersion;
1510
1511            if (originalVersion < mUserVersion) {
1512                writeUserListLP();
1513            }
1514        }
1515    }
1516
1517    private void fallbackToSingleUserLP() {
1518        int flags = UserInfo.FLAG_INITIALIZED;
1519        // In split system user mode, the admin and primary flags are assigned to the first human
1520        // user.
1521        if (!UserManager.isSplitSystemUser()) {
1522            flags |= UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY;
1523        }
1524        // Create the system user
1525        UserInfo system = new UserInfo(UserHandle.USER_SYSTEM, null, null, flags);
1526        UserData userData = new UserData();
1527        userData.info = system;
1528        synchronized (mUsersLock) {
1529            mUsers.put(system.id, userData);
1530        }
1531        mNextSerialNumber = MIN_USER_ID;
1532        mUserVersion = USER_VERSION;
1533
1534        Bundle restrictions = new Bundle();
1535        synchronized (mRestrictionsLock) {
1536            mBaseUserRestrictions.append(UserHandle.USER_SYSTEM, restrictions);
1537        }
1538
1539        updateUserIds();
1540        initDefaultGuestRestrictions();
1541
1542        writeUserLP(userData);
1543        writeUserListLP();
1544    }
1545
1546    private String getOwnerName() {
1547        return mContext.getResources().getString(com.android.internal.R.string.owner_name);
1548    }
1549
1550    private void scheduleWriteUser(UserData UserData) {
1551        if (DBG) {
1552            debug("scheduleWriteUser");
1553        }
1554        // No need to wrap it within a lock -- worst case, we'll just post the same message
1555        // twice.
1556        if (!mHandler.hasMessages(WRITE_USER_MSG, UserData)) {
1557            Message msg = mHandler.obtainMessage(WRITE_USER_MSG, UserData);
1558            mHandler.sendMessageDelayed(msg, WRITE_USER_DELAY);
1559        }
1560    }
1561
1562    /*
1563     * Writes the user file in this format:
1564     *
1565     * <user flags="20039023" id="0">
1566     *   <name>Primary</name>
1567     * </user>
1568     */
1569    private void writeUserLP(UserData userData) {
1570        if (DBG) {
1571            debug("writeUserLP " + userData);
1572        }
1573        FileOutputStream fos = null;
1574        AtomicFile userFile = new AtomicFile(new File(mUsersDir, userData.info.id + XML_SUFFIX));
1575        try {
1576            fos = userFile.startWrite();
1577            final BufferedOutputStream bos = new BufferedOutputStream(fos);
1578
1579            // XmlSerializer serializer = XmlUtils.serializerInstance();
1580            final XmlSerializer serializer = new FastXmlSerializer();
1581            serializer.setOutput(bos, StandardCharsets.UTF_8.name());
1582            serializer.startDocument(null, true);
1583            serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
1584
1585            final UserInfo userInfo = userData.info;
1586            serializer.startTag(null, TAG_USER);
1587            serializer.attribute(null, ATTR_ID, Integer.toString(userInfo.id));
1588            serializer.attribute(null, ATTR_SERIAL_NO, Integer.toString(userInfo.serialNumber));
1589            serializer.attribute(null, ATTR_FLAGS, Integer.toString(userInfo.flags));
1590            serializer.attribute(null, ATTR_CREATION_TIME, Long.toString(userInfo.creationTime));
1591            serializer.attribute(null, ATTR_LAST_LOGGED_IN_TIME,
1592                    Long.toString(userInfo.lastLoggedInTime));
1593            if (userInfo.lastLoggedInFingerprint != null) {
1594                serializer.attribute(null, ATTR_LAST_LOGGED_IN_FINGERPRINT,
1595                        userInfo.lastLoggedInFingerprint);
1596            }
1597            if (userInfo.iconPath != null) {
1598                serializer.attribute(null,  ATTR_ICON_PATH, userInfo.iconPath);
1599            }
1600            if (userInfo.partial) {
1601                serializer.attribute(null, ATTR_PARTIAL, "true");
1602            }
1603            if (userInfo.guestToRemove) {
1604                serializer.attribute(null, ATTR_GUEST_TO_REMOVE, "true");
1605            }
1606            if (userInfo.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
1607                serializer.attribute(null, ATTR_PROFILE_GROUP_ID,
1608                        Integer.toString(userInfo.profileGroupId));
1609            }
1610            if (userInfo.restrictedProfileParentId != UserInfo.NO_PROFILE_GROUP_ID) {
1611                serializer.attribute(null, ATTR_RESTRICTED_PROFILE_PARENT_ID,
1612                        Integer.toString(userInfo.restrictedProfileParentId));
1613            }
1614            // Write seed data
1615            if (userData.persistSeedData) {
1616                if (userData.seedAccountName != null) {
1617                    serializer.attribute(null, ATTR_SEED_ACCOUNT_NAME, userData.seedAccountName);
1618                }
1619                if (userData.seedAccountType != null) {
1620                    serializer.attribute(null, ATTR_SEED_ACCOUNT_TYPE, userData.seedAccountType);
1621                }
1622            }
1623            if (userInfo.name != null) {
1624                serializer.startTag(null, TAG_NAME);
1625                serializer.text(userInfo.name);
1626                serializer.endTag(null, TAG_NAME);
1627            }
1628            synchronized (mRestrictionsLock) {
1629                UserRestrictionsUtils.writeRestrictions(serializer,
1630                        mBaseUserRestrictions.get(userInfo.id), TAG_RESTRICTIONS);
1631                UserRestrictionsUtils.writeRestrictions(serializer,
1632                        mDevicePolicyLocalUserRestrictions.get(userInfo.id),
1633                        TAG_DEVICE_POLICY_RESTRICTIONS);
1634            }
1635
1636            if (userData.account != null) {
1637                serializer.startTag(null, TAG_ACCOUNT);
1638                serializer.text(userData.account);
1639                serializer.endTag(null, TAG_ACCOUNT);
1640            }
1641
1642            if (userData.persistSeedData && userData.seedAccountOptions != null) {
1643                serializer.startTag(null, TAG_SEED_ACCOUNT_OPTIONS);
1644                userData.seedAccountOptions.saveToXml(serializer);
1645                serializer.endTag(null, TAG_SEED_ACCOUNT_OPTIONS);
1646            }
1647            serializer.endTag(null, TAG_USER);
1648
1649            serializer.endDocument();
1650            userFile.finishWrite(fos);
1651        } catch (Exception ioe) {
1652            Slog.e(LOG_TAG, "Error writing user info " + userData.info.id, ioe);
1653            userFile.failWrite(fos);
1654        }
1655    }
1656
1657    /*
1658     * Writes the user list file in this format:
1659     *
1660     * <users nextSerialNumber="3">
1661     *   <user id="0"></user>
1662     *   <user id="2"></user>
1663     * </users>
1664     */
1665    private void writeUserListLP() {
1666        if (DBG) {
1667            debug("writeUserList");
1668        }
1669        FileOutputStream fos = null;
1670        AtomicFile userListFile = new AtomicFile(mUserListFile);
1671        try {
1672            fos = userListFile.startWrite();
1673            final BufferedOutputStream bos = new BufferedOutputStream(fos);
1674
1675            // XmlSerializer serializer = XmlUtils.serializerInstance();
1676            final XmlSerializer serializer = new FastXmlSerializer();
1677            serializer.setOutput(bos, StandardCharsets.UTF_8.name());
1678            serializer.startDocument(null, true);
1679            serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
1680
1681            serializer.startTag(null, TAG_USERS);
1682            serializer.attribute(null, ATTR_NEXT_SERIAL_NO, Integer.toString(mNextSerialNumber));
1683            serializer.attribute(null, ATTR_USER_VERSION, Integer.toString(mUserVersion));
1684
1685            serializer.startTag(null, TAG_GUEST_RESTRICTIONS);
1686            synchronized (mGuestRestrictions) {
1687                UserRestrictionsUtils
1688                        .writeRestrictions(serializer, mGuestRestrictions, TAG_RESTRICTIONS);
1689            }
1690            serializer.endTag(null, TAG_GUEST_RESTRICTIONS);
1691            synchronized (mRestrictionsLock) {
1692                UserRestrictionsUtils.writeRestrictions(serializer,
1693                        mDevicePolicyGlobalUserRestrictions, TAG_DEVICE_POLICY_RESTRICTIONS);
1694            }
1695            int[] userIdsToWrite;
1696            synchronized (mUsersLock) {
1697                userIdsToWrite = new int[mUsers.size()];
1698                for (int i = 0; i < userIdsToWrite.length; i++) {
1699                    UserInfo user = mUsers.valueAt(i).info;
1700                    userIdsToWrite[i] = user.id;
1701                }
1702            }
1703            for (int id : userIdsToWrite) {
1704                serializer.startTag(null, TAG_USER);
1705                serializer.attribute(null, ATTR_ID, Integer.toString(id));
1706                serializer.endTag(null, TAG_USER);
1707            }
1708
1709            serializer.endTag(null, TAG_USERS);
1710
1711            serializer.endDocument();
1712            userListFile.finishWrite(fos);
1713        } catch (Exception e) {
1714            userListFile.failWrite(fos);
1715            Slog.e(LOG_TAG, "Error writing user list");
1716        }
1717    }
1718
1719    private UserData readUserLP(int id) {
1720        int flags = 0;
1721        int serialNumber = id;
1722        String name = null;
1723        String account = null;
1724        String iconPath = null;
1725        long creationTime = 0L;
1726        long lastLoggedInTime = 0L;
1727        String lastLoggedInFingerprint = null;
1728        int profileGroupId = UserInfo.NO_PROFILE_GROUP_ID;
1729        int restrictedProfileParentId = UserInfo.NO_PROFILE_GROUP_ID;
1730        boolean partial = false;
1731        boolean guestToRemove = false;
1732        boolean persistSeedData = false;
1733        String seedAccountName = null;
1734        String seedAccountType = null;
1735        PersistableBundle seedAccountOptions = null;
1736        Bundle baseRestrictions = new Bundle();
1737        Bundle localRestrictions = new Bundle();
1738
1739        FileInputStream fis = null;
1740        try {
1741            AtomicFile userFile =
1742                    new AtomicFile(new File(mUsersDir, Integer.toString(id) + XML_SUFFIX));
1743            fis = userFile.openRead();
1744            XmlPullParser parser = Xml.newPullParser();
1745            parser.setInput(fis, StandardCharsets.UTF_8.name());
1746            int type;
1747            while ((type = parser.next()) != XmlPullParser.START_TAG
1748                    && type != XmlPullParser.END_DOCUMENT) {
1749                // Skip
1750            }
1751
1752            if (type != XmlPullParser.START_TAG) {
1753                Slog.e(LOG_TAG, "Unable to read user " + id);
1754                return null;
1755            }
1756
1757            if (type == XmlPullParser.START_TAG && parser.getName().equals(TAG_USER)) {
1758                int storedId = readIntAttribute(parser, ATTR_ID, -1);
1759                if (storedId != id) {
1760                    Slog.e(LOG_TAG, "User id does not match the file name");
1761                    return null;
1762                }
1763                serialNumber = readIntAttribute(parser, ATTR_SERIAL_NO, id);
1764                flags = readIntAttribute(parser, ATTR_FLAGS, 0);
1765                iconPath = parser.getAttributeValue(null, ATTR_ICON_PATH);
1766                creationTime = readLongAttribute(parser, ATTR_CREATION_TIME, 0);
1767                lastLoggedInTime = readLongAttribute(parser, ATTR_LAST_LOGGED_IN_TIME, 0);
1768                lastLoggedInFingerprint = parser.getAttributeValue(null,
1769                        ATTR_LAST_LOGGED_IN_FINGERPRINT);
1770                profileGroupId = readIntAttribute(parser, ATTR_PROFILE_GROUP_ID,
1771                        UserInfo.NO_PROFILE_GROUP_ID);
1772                restrictedProfileParentId = readIntAttribute(parser,
1773                        ATTR_RESTRICTED_PROFILE_PARENT_ID, UserInfo.NO_PROFILE_GROUP_ID);
1774                String valueString = parser.getAttributeValue(null, ATTR_PARTIAL);
1775                if ("true".equals(valueString)) {
1776                    partial = true;
1777                }
1778                valueString = parser.getAttributeValue(null, ATTR_GUEST_TO_REMOVE);
1779                if ("true".equals(valueString)) {
1780                    guestToRemove = true;
1781                }
1782
1783                seedAccountName = parser.getAttributeValue(null, ATTR_SEED_ACCOUNT_NAME);
1784                seedAccountType = parser.getAttributeValue(null, ATTR_SEED_ACCOUNT_TYPE);
1785                if (seedAccountName != null || seedAccountType != null) {
1786                    persistSeedData = true;
1787                }
1788
1789                int outerDepth = parser.getDepth();
1790                while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1791                       && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1792                    if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1793                        continue;
1794                    }
1795                    String tag = parser.getName();
1796                    if (TAG_NAME.equals(tag)) {
1797                        type = parser.next();
1798                        if (type == XmlPullParser.TEXT) {
1799                            name = parser.getText();
1800                        }
1801                    } else if (TAG_RESTRICTIONS.equals(tag)) {
1802                        UserRestrictionsUtils.readRestrictions(parser, baseRestrictions);
1803                    } else if (TAG_DEVICE_POLICY_RESTRICTIONS.equals(tag)) {
1804                        UserRestrictionsUtils.readRestrictions(parser, localRestrictions);
1805                    } else if (TAG_ACCOUNT.equals(tag)) {
1806                        type = parser.next();
1807                        if (type == XmlPullParser.TEXT) {
1808                            account = parser.getText();
1809                        }
1810                    } else if (TAG_SEED_ACCOUNT_OPTIONS.equals(tag)) {
1811                        seedAccountOptions = PersistableBundle.restoreFromXml(parser);
1812                        persistSeedData = true;
1813                    }
1814                }
1815            }
1816
1817            // Create the UserInfo object that gets passed around
1818            UserInfo userInfo = new UserInfo(id, name, iconPath, flags);
1819            userInfo.serialNumber = serialNumber;
1820            userInfo.creationTime = creationTime;
1821            userInfo.lastLoggedInTime = lastLoggedInTime;
1822            userInfo.lastLoggedInFingerprint = lastLoggedInFingerprint;
1823            userInfo.partial = partial;
1824            userInfo.guestToRemove = guestToRemove;
1825            userInfo.profileGroupId = profileGroupId;
1826            userInfo.restrictedProfileParentId = restrictedProfileParentId;
1827
1828            // Create the UserData object that's internal to this class
1829            UserData userData = new UserData();
1830            userData.info = userInfo;
1831            userData.account = account;
1832            userData.seedAccountName = seedAccountName;
1833            userData.seedAccountType = seedAccountType;
1834            userData.persistSeedData = persistSeedData;
1835            userData.seedAccountOptions = seedAccountOptions;
1836
1837            synchronized (mRestrictionsLock) {
1838                mBaseUserRestrictions.put(id, baseRestrictions);
1839                mDevicePolicyLocalUserRestrictions.put(id, localRestrictions);
1840            }
1841            return userData;
1842        } catch (IOException ioe) {
1843        } catch (XmlPullParserException pe) {
1844        } finally {
1845            if (fis != null) {
1846                try {
1847                    fis.close();
1848                } catch (IOException e) {
1849                }
1850            }
1851        }
1852        return null;
1853    }
1854
1855    private int readIntAttribute(XmlPullParser parser, String attr, int defaultValue) {
1856        String valueString = parser.getAttributeValue(null, attr);
1857        if (valueString == null) return defaultValue;
1858        try {
1859            return Integer.parseInt(valueString);
1860        } catch (NumberFormatException nfe) {
1861            return defaultValue;
1862        }
1863    }
1864
1865    private long readLongAttribute(XmlPullParser parser, String attr, long defaultValue) {
1866        String valueString = parser.getAttributeValue(null, attr);
1867        if (valueString == null) return defaultValue;
1868        try {
1869            return Long.parseLong(valueString);
1870        } catch (NumberFormatException nfe) {
1871            return defaultValue;
1872        }
1873    }
1874
1875    /**
1876     * Removes the app restrictions file for a specific package and user id, if it exists.
1877     */
1878    private void cleanAppRestrictionsForPackage(String pkg, int userId) {
1879        synchronized (mPackagesLock) {
1880            File dir = Environment.getUserSystemDirectory(userId);
1881            File resFile = new File(dir, packageToRestrictionsFileName(pkg));
1882            if (resFile.exists()) {
1883                resFile.delete();
1884            }
1885        }
1886    }
1887
1888    @Override
1889    public UserInfo createProfileForUser(String name, int flags, int userId) {
1890        checkManageUsersPermission("Only the system can create users");
1891        return createUserInternal(name, flags, userId);
1892    }
1893
1894    @Override
1895    public UserInfo createUser(String name, int flags) {
1896        checkManageUsersPermission("Only the system can create users");
1897        return createUserInternal(name, flags, UserHandle.USER_NULL);
1898    }
1899
1900    private UserInfo createUserInternal(String name, int flags, int parentId) {
1901        if (hasUserRestriction(UserManager.DISALLOW_ADD_USER, UserHandle.getCallingUserId())) {
1902            Log.w(LOG_TAG, "Cannot add user. DISALLOW_ADD_USER is enabled.");
1903            return null;
1904        }
1905        return createUserInternalUnchecked(name, flags, parentId);
1906    }
1907
1908    private UserInfo createUserInternalUnchecked(String name, int flags, int parentId) {
1909        if (ActivityManager.isLowRamDeviceStatic()) {
1910            return null;
1911        }
1912        final boolean isGuest = (flags & UserInfo.FLAG_GUEST) != 0;
1913        final boolean isManagedProfile = (flags & UserInfo.FLAG_MANAGED_PROFILE) != 0;
1914        final boolean isRestricted = (flags & UserInfo.FLAG_RESTRICTED) != 0;
1915        final long ident = Binder.clearCallingIdentity();
1916        UserInfo userInfo;
1917        UserData userData;
1918        final int userId;
1919        try {
1920            synchronized (mPackagesLock) {
1921                UserData parent = null;
1922                if (parentId != UserHandle.USER_NULL) {
1923                    synchronized (mUsersLock) {
1924                        parent = getUserDataLU(parentId);
1925                    }
1926                    if (parent == null) return null;
1927                }
1928                if (isManagedProfile && !canAddMoreManagedProfiles(parentId, false)) {
1929                    Log.e(LOG_TAG, "Cannot add more managed profiles for user " + parentId);
1930                    return null;
1931                }
1932                if (!isGuest && !isManagedProfile && isUserLimitReached()) {
1933                    // If we're not adding a guest user or a managed profile and the limit has
1934                    // been reached, cannot add a user.
1935                    return null;
1936                }
1937                // If we're adding a guest and there already exists one, bail.
1938                if (isGuest && findCurrentGuestUser() != null) {
1939                    return null;
1940                }
1941                // In legacy mode, restricted profile's parent can only be the owner user
1942                if (isRestricted && !UserManager.isSplitSystemUser()
1943                        && (parentId != UserHandle.USER_SYSTEM)) {
1944                    Log.w(LOG_TAG, "Cannot add restricted profile - parent user must be owner");
1945                    return null;
1946                }
1947                if (isRestricted && UserManager.isSplitSystemUser()) {
1948                    if (parent == null) {
1949                        Log.w(LOG_TAG, "Cannot add restricted profile - parent user must be "
1950                                + "specified");
1951                        return null;
1952                    }
1953                    if (!parent.info.canHaveProfile()) {
1954                        Log.w(LOG_TAG, "Cannot add restricted profile - profiles cannot be "
1955                                + "created for the specified parent user id " + parentId);
1956                        return null;
1957                    }
1958                }
1959                if (!UserManager.isSplitSystemUser() && (flags & UserInfo.FLAG_EPHEMERAL) != 0) {
1960                    Log.e(LOG_TAG,
1961                            "Ephemeral users are supported on split-system-user systems only.");
1962                    return null;
1963                }
1964                // In split system user mode, we assign the first human user the primary flag.
1965                // And if there is no device owner, we also assign the admin flag to primary user.
1966                if (UserManager.isSplitSystemUser()
1967                        && !isGuest && !isManagedProfile && getPrimaryUser() == null) {
1968                    flags |= UserInfo.FLAG_PRIMARY;
1969                    synchronized (mUsersLock) {
1970                        if (!mIsDeviceManaged) {
1971                            flags |= UserInfo.FLAG_ADMIN;
1972                        }
1973                    }
1974                }
1975
1976                userId = getNextAvailableId();
1977                Environment.getUserSystemDirectory(userId).mkdirs();
1978                boolean ephemeralGuests = Resources.getSystem()
1979                        .getBoolean(com.android.internal.R.bool.config_guestUserEphemeral);
1980
1981                synchronized (mUsersLock) {
1982                    // Add ephemeral flag to guests/users if required. Also inherit it from parent.
1983                    if ((isGuest && ephemeralGuests) || mForceEphemeralUsers
1984                            || (parent != null && parent.info.isEphemeral())) {
1985                        flags |= UserInfo.FLAG_EPHEMERAL;
1986                    }
1987
1988                    userInfo = new UserInfo(userId, name, null, flags);
1989                    userInfo.serialNumber = mNextSerialNumber++;
1990                    long now = System.currentTimeMillis();
1991                    userInfo.creationTime = (now > EPOCH_PLUS_30_YEARS) ? now : 0;
1992                    userInfo.partial = true;
1993                    userInfo.lastLoggedInFingerprint = Build.FINGERPRINT;
1994                    userData = new UserData();
1995                    userData.info = userInfo;
1996                    mUsers.put(userId, userData);
1997                }
1998                writeUserLP(userData);
1999                writeUserListLP();
2000                if (parent != null) {
2001                    if (isManagedProfile) {
2002                        if (parent.info.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID) {
2003                            parent.info.profileGroupId = parent.info.id;
2004                            writeUserLP(parent);
2005                        }
2006                        userInfo.profileGroupId = parent.info.profileGroupId;
2007                    } else if (isRestricted) {
2008                        if (parent.info.restrictedProfileParentId == UserInfo.NO_PROFILE_GROUP_ID) {
2009                            parent.info.restrictedProfileParentId = parent.info.id;
2010                            writeUserLP(parent);
2011                        }
2012                        userInfo.restrictedProfileParentId = parent.info.restrictedProfileParentId;
2013                    }
2014                }
2015            }
2016            final StorageManager storage = mContext.getSystemService(StorageManager.class);
2017            storage.createUserKey(userId, userInfo.serialNumber, userInfo.isEphemeral());
2018            prepareUserStorage(userId, userInfo.serialNumber,
2019                    StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
2020            mPm.createNewUser(userId);
2021            userInfo.partial = false;
2022            synchronized (mPackagesLock) {
2023                writeUserLP(userData);
2024            }
2025            updateUserIds();
2026            Bundle restrictions = new Bundle();
2027            if (isGuest) {
2028                synchronized (mGuestRestrictions) {
2029                    restrictions.putAll(mGuestRestrictions);
2030                }
2031            }
2032            synchronized (mRestrictionsLock) {
2033                mBaseUserRestrictions.append(userId, restrictions);
2034            }
2035            mPm.newUserCreated(userId);
2036            Intent addedIntent = new Intent(Intent.ACTION_USER_ADDED);
2037            addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
2038            mContext.sendBroadcastAsUser(addedIntent, UserHandle.ALL,
2039                    android.Manifest.permission.MANAGE_USERS);
2040            MetricsLogger.count(mContext, isGuest ? TRON_GUEST_CREATED : TRON_USER_CREATED, 1);
2041        } finally {
2042            Binder.restoreCallingIdentity(ident);
2043        }
2044        return userInfo;
2045    }
2046
2047    /**
2048     * @hide
2049     */
2050    @Override
2051    public UserInfo createRestrictedProfile(String name, int parentUserId) {
2052        checkManageUsersPermission("setupRestrictedProfile");
2053        final UserInfo user = createProfileForUser(name, UserInfo.FLAG_RESTRICTED, parentUserId);
2054        if (user == null) {
2055            return null;
2056        }
2057        long identity = Binder.clearCallingIdentity();
2058        try {
2059            setUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS, true, user.id);
2060            // Change the setting before applying the DISALLOW_SHARE_LOCATION restriction, otherwise
2061            // the putIntForUser() will fail.
2062            android.provider.Settings.Secure.putIntForUser(mContext.getContentResolver(),
2063                    android.provider.Settings.Secure.LOCATION_MODE,
2064                    android.provider.Settings.Secure.LOCATION_MODE_OFF, user.id);
2065            setUserRestriction(UserManager.DISALLOW_SHARE_LOCATION, true, user.id);
2066        } finally {
2067            Binder.restoreCallingIdentity(identity);
2068        }
2069        return user;
2070    }
2071
2072    /**
2073     * Find the current guest user. If the Guest user is partial,
2074     * then do not include it in the results as it is about to die.
2075     */
2076    private UserInfo findCurrentGuestUser() {
2077        synchronized (mUsersLock) {
2078            final int size = mUsers.size();
2079            for (int i = 0; i < size; i++) {
2080                final UserInfo user = mUsers.valueAt(i).info;
2081                if (user.isGuest() && !user.guestToRemove && !mRemovingUserIds.get(user.id)) {
2082                    return user;
2083                }
2084            }
2085        }
2086        return null;
2087    }
2088
2089    /**
2090     * Mark this guest user for deletion to allow us to create another guest
2091     * and switch to that user before actually removing this guest.
2092     * @param userHandle the userid of the current guest
2093     * @return whether the user could be marked for deletion
2094     */
2095    @Override
2096    public boolean markGuestForDeletion(int userHandle) {
2097        checkManageUsersPermission("Only the system can remove users");
2098        if (getUserRestrictions(UserHandle.getCallingUserId()).getBoolean(
2099                UserManager.DISALLOW_REMOVE_USER, false)) {
2100            Log.w(LOG_TAG, "Cannot remove user. DISALLOW_REMOVE_USER is enabled.");
2101            return false;
2102        }
2103
2104        long ident = Binder.clearCallingIdentity();
2105        try {
2106            final UserData userData;
2107            synchronized (mPackagesLock) {
2108                synchronized (mUsersLock) {
2109                    userData = mUsers.get(userHandle);
2110                    if (userHandle == 0 || userData == null || mRemovingUserIds.get(userHandle)) {
2111                        return false;
2112                    }
2113                }
2114                if (!userData.info.isGuest()) {
2115                    return false;
2116                }
2117                // We set this to a guest user that is to be removed. This is a temporary state
2118                // where we are allowed to add new Guest users, even if this one is still not
2119                // removed. This user will still show up in getUserInfo() calls.
2120                // If we don't get around to removing this Guest user, it will be purged on next
2121                // startup.
2122                userData.info.guestToRemove = true;
2123                // Mark it as disabled, so that it isn't returned any more when
2124                // profiles are queried.
2125                userData.info.flags |= UserInfo.FLAG_DISABLED;
2126                writeUserLP(userData);
2127            }
2128        } finally {
2129            Binder.restoreCallingIdentity(ident);
2130        }
2131        return true;
2132    }
2133
2134    /**
2135     * Removes a user and all data directories created for that user. This method should be called
2136     * after the user's processes have been terminated.
2137     * @param userHandle the user's id
2138     */
2139    @Override
2140    public boolean removeUser(int userHandle) {
2141        checkManageUsersPermission("Only the system can remove users");
2142        if (getUserRestrictions(UserHandle.getCallingUserId()).getBoolean(
2143                UserManager.DISALLOW_REMOVE_USER, false)) {
2144            Log.w(LOG_TAG, "Cannot remove user. DISALLOW_REMOVE_USER is enabled.");
2145            return false;
2146        }
2147
2148        long ident = Binder.clearCallingIdentity();
2149        try {
2150            final UserData userData;
2151            int currentUser = ActivityManager.getCurrentUser();
2152            if (currentUser == userHandle) {
2153                Log.w(LOG_TAG, "Current user cannot be removed");
2154                return false;
2155            }
2156            synchronized (mPackagesLock) {
2157                synchronized (mUsersLock) {
2158                    userData = mUsers.get(userHandle);
2159                    if (userHandle == 0 || userData == null || mRemovingUserIds.get(userHandle)) {
2160                        return false;
2161                    }
2162
2163                    // We remember deleted user IDs to prevent them from being
2164                    // reused during the current boot; they can still be reused
2165                    // after a reboot.
2166                    mRemovingUserIds.put(userHandle, true);
2167                }
2168
2169                try {
2170                    mAppOpsService.removeUser(userHandle);
2171                } catch (RemoteException e) {
2172                    Log.w(LOG_TAG, "Unable to notify AppOpsService of removing user", e);
2173                }
2174                // Set this to a partially created user, so that the user will be purged
2175                // on next startup, in case the runtime stops now before stopping and
2176                // removing the user completely.
2177                userData.info.partial = true;
2178                // Mark it as disabled, so that it isn't returned any more when
2179                // profiles are queried.
2180                userData.info.flags |= UserInfo.FLAG_DISABLED;
2181                writeUserLP(userData);
2182            }
2183
2184            if (userData.info.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID
2185                    && userData.info.isManagedProfile()) {
2186                // Send broadcast to notify system that the user removed was a
2187                // managed user.
2188                sendProfileRemovedBroadcast(userData.info.profileGroupId, userData.info.id);
2189            }
2190
2191            if (DBG) Slog.i(LOG_TAG, "Stopping user " + userHandle);
2192            int res;
2193            try {
2194                res = ActivityManagerNative.getDefault().stopUser(userHandle, /* force= */ true,
2195                new IStopUserCallback.Stub() {
2196                            @Override
2197                            public void userStopped(int userId) {
2198                                finishRemoveUser(userId);
2199                            }
2200                            @Override
2201                            public void userStopAborted(int userId) {
2202                            }
2203                        });
2204            } catch (RemoteException e) {
2205                return false;
2206            }
2207            return res == ActivityManager.USER_OP_SUCCESS;
2208        } finally {
2209            Binder.restoreCallingIdentity(ident);
2210        }
2211    }
2212
2213    void finishRemoveUser(final int userHandle) {
2214        if (DBG) Slog.i(LOG_TAG, "finishRemoveUser " + userHandle);
2215        // Let other services shutdown any activity and clean up their state before completely
2216        // wiping the user's system directory and removing from the user list
2217        long ident = Binder.clearCallingIdentity();
2218        try {
2219            Intent addedIntent = new Intent(Intent.ACTION_USER_REMOVED);
2220            addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userHandle);
2221            mContext.sendOrderedBroadcastAsUser(addedIntent, UserHandle.ALL,
2222                    android.Manifest.permission.MANAGE_USERS,
2223
2224                    new BroadcastReceiver() {
2225                        @Override
2226                        public void onReceive(Context context, Intent intent) {
2227                            if (DBG) {
2228                                Slog.i(LOG_TAG,
2229                                        "USER_REMOVED broadcast sent, cleaning up user data "
2230                                        + userHandle);
2231                            }
2232                            new Thread() {
2233                                @Override
2234                                public void run() {
2235                                    // Clean up any ActivityManager state
2236                                    LocalServices.getService(ActivityManagerInternal.class)
2237                                            .onUserRemoved(userHandle);
2238                                    removeUserState(userHandle);
2239                                }
2240                            }.start();
2241                        }
2242                    },
2243
2244                    null, Activity.RESULT_OK, null, null);
2245        } finally {
2246            Binder.restoreCallingIdentity(ident);
2247        }
2248    }
2249
2250    private void removeUserState(final int userHandle) {
2251        try {
2252            mContext.getSystemService(StorageManager.class).destroyUserKey(userHandle);
2253        } catch (IllegalStateException e) {
2254            // This may be simply because the user was partially created.
2255            Slog.i(LOG_TAG,
2256                "Destroying key for user " + userHandle + " failed, continuing anyway", e);
2257        }
2258        // Cleanup package manager settings
2259        mPm.cleanUpUser(this, userHandle);
2260
2261        // Remove this user from the list
2262        synchronized (mUsersLock) {
2263            mUsers.remove(userHandle);
2264            mIsUserManaged.delete(userHandle);
2265        }
2266        synchronized (mRestrictionsLock) {
2267            mBaseUserRestrictions.remove(userHandle);
2268            mAppliedUserRestrictions.remove(userHandle);
2269            mCachedEffectiveUserRestrictions.remove(userHandle);
2270            mDevicePolicyLocalUserRestrictions.remove(userHandle);
2271        }
2272        // Update the user list
2273        synchronized (mPackagesLock) {
2274            writeUserListLP();
2275        }
2276        // Remove user file
2277        AtomicFile userFile = new AtomicFile(new File(mUsersDir, userHandle + XML_SUFFIX));
2278        userFile.delete();
2279        updateUserIds();
2280        File userDir = Environment.getUserSystemDirectory(userHandle);
2281        File renamedUserDir = Environment.getUserSystemDirectory(UserHandle.USER_NULL - userHandle);
2282        if (userDir.renameTo(renamedUserDir)) {
2283            removeDirectoryRecursive(renamedUserDir);
2284        } else {
2285            removeDirectoryRecursive(userDir);
2286        }
2287    }
2288
2289    private void removeDirectoryRecursive(File parent) {
2290        if (parent.isDirectory()) {
2291            String[] files = parent.list();
2292            for (String filename : files) {
2293                File child = new File(parent, filename);
2294                removeDirectoryRecursive(child);
2295            }
2296        }
2297        parent.delete();
2298    }
2299
2300    private void sendProfileRemovedBroadcast(int parentUserId, int removedUserId) {
2301        Intent managedProfileIntent = new Intent(Intent.ACTION_MANAGED_PROFILE_REMOVED);
2302        managedProfileIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY |
2303                Intent.FLAG_RECEIVER_FOREGROUND);
2304        managedProfileIntent.putExtra(Intent.EXTRA_USER, new UserHandle(removedUserId));
2305        managedProfileIntent.putExtra(Intent.EXTRA_USER_HANDLE, removedUserId);
2306        mContext.sendBroadcastAsUser(managedProfileIntent, new UserHandle(parentUserId), null);
2307    }
2308
2309    @Override
2310    public Bundle getApplicationRestrictions(String packageName) {
2311        return getApplicationRestrictionsForUser(packageName, UserHandle.getCallingUserId());
2312    }
2313
2314    @Override
2315    public Bundle getApplicationRestrictionsForUser(String packageName, int userId) {
2316        if (UserHandle.getCallingUserId() != userId
2317                || !UserHandle.isSameApp(Binder.getCallingUid(), getUidForPackage(packageName))) {
2318            checkSystemOrRoot("get application restrictions for other users/apps");
2319        }
2320        synchronized (mPackagesLock) {
2321            // Read the restrictions from XML
2322            return readApplicationRestrictionsLP(packageName, userId);
2323        }
2324    }
2325
2326    @Override
2327    public void setApplicationRestrictions(String packageName, Bundle restrictions,
2328            int userId) {
2329        checkSystemOrRoot("set application restrictions");
2330        synchronized (mPackagesLock) {
2331            if (restrictions == null || restrictions.isEmpty()) {
2332                cleanAppRestrictionsForPackage(packageName, userId);
2333            } else {
2334                restrictions.setDefusable(true);
2335                // Write the restrictions to XML
2336                writeApplicationRestrictionsLP(packageName, restrictions, userId);
2337            }
2338        }
2339
2340        // Notify package of changes via an intent - only sent to explicitly registered receivers.
2341        Intent changeIntent = new Intent(Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED);
2342        changeIntent.setPackage(packageName);
2343        changeIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
2344        mContext.sendBroadcastAsUser(changeIntent, UserHandle.of(userId));
2345    }
2346
2347    private int getUidForPackage(String packageName) {
2348        long ident = Binder.clearCallingIdentity();
2349        try {
2350            return mContext.getPackageManager().getApplicationInfo(packageName,
2351                    PackageManager.MATCH_UNINSTALLED_PACKAGES).uid;
2352        } catch (NameNotFoundException nnfe) {
2353            return -1;
2354        } finally {
2355            Binder.restoreCallingIdentity(ident);
2356        }
2357    }
2358
2359    private Bundle readApplicationRestrictionsLP(String packageName, int userId) {
2360        AtomicFile restrictionsFile =
2361                new AtomicFile(new File(Environment.getUserSystemDirectory(userId),
2362                        packageToRestrictionsFileName(packageName)));
2363        return readApplicationRestrictionsLP(restrictionsFile);
2364    }
2365
2366    @VisibleForTesting
2367    static Bundle readApplicationRestrictionsLP(AtomicFile restrictionsFile) {
2368        final Bundle restrictions = new Bundle();
2369        final ArrayList<String> values = new ArrayList<>();
2370        if (!restrictionsFile.getBaseFile().exists()) {
2371            return restrictions;
2372        }
2373
2374        FileInputStream fis = null;
2375        try {
2376            fis = restrictionsFile.openRead();
2377            XmlPullParser parser = Xml.newPullParser();
2378            parser.setInput(fis, StandardCharsets.UTF_8.name());
2379            XmlUtils.nextElement(parser);
2380            if (parser.getEventType() != XmlPullParser.START_TAG) {
2381                Slog.e(LOG_TAG, "Unable to read restrictions file "
2382                        + restrictionsFile.getBaseFile());
2383                return restrictions;
2384            }
2385            while (parser.next() != XmlPullParser.END_DOCUMENT) {
2386                readEntry(restrictions, values, parser);
2387            }
2388        } catch (IOException|XmlPullParserException e) {
2389            Log.w(LOG_TAG, "Error parsing " + restrictionsFile.getBaseFile(), e);
2390        } finally {
2391            IoUtils.closeQuietly(fis);
2392        }
2393        return restrictions;
2394    }
2395
2396    private static void readEntry(Bundle restrictions, ArrayList<String> values,
2397            XmlPullParser parser) throws XmlPullParserException, IOException {
2398        int type = parser.getEventType();
2399        if (type == XmlPullParser.START_TAG && parser.getName().equals(TAG_ENTRY)) {
2400            String key = parser.getAttributeValue(null, ATTR_KEY);
2401            String valType = parser.getAttributeValue(null, ATTR_VALUE_TYPE);
2402            String multiple = parser.getAttributeValue(null, ATTR_MULTIPLE);
2403            if (multiple != null) {
2404                values.clear();
2405                int count = Integer.parseInt(multiple);
2406                while (count > 0 && (type = parser.next()) != XmlPullParser.END_DOCUMENT) {
2407                    if (type == XmlPullParser.START_TAG
2408                            && parser.getName().equals(TAG_VALUE)) {
2409                        values.add(parser.nextText().trim());
2410                        count--;
2411                    }
2412                }
2413                String [] valueStrings = new String[values.size()];
2414                values.toArray(valueStrings);
2415                restrictions.putStringArray(key, valueStrings);
2416            } else if (ATTR_TYPE_BUNDLE.equals(valType)) {
2417                restrictions.putBundle(key, readBundleEntry(parser, values));
2418            } else if (ATTR_TYPE_BUNDLE_ARRAY.equals(valType)) {
2419                final int outerDepth = parser.getDepth();
2420                ArrayList<Bundle> bundleList = new ArrayList<>();
2421                while (XmlUtils.nextElementWithin(parser, outerDepth)) {
2422                    Bundle childBundle = readBundleEntry(parser, values);
2423                    bundleList.add(childBundle);
2424                }
2425                restrictions.putParcelableArray(key,
2426                        bundleList.toArray(new Bundle[bundleList.size()]));
2427            } else {
2428                String value = parser.nextText().trim();
2429                if (ATTR_TYPE_BOOLEAN.equals(valType)) {
2430                    restrictions.putBoolean(key, Boolean.parseBoolean(value));
2431                } else if (ATTR_TYPE_INTEGER.equals(valType)) {
2432                    restrictions.putInt(key, Integer.parseInt(value));
2433                } else {
2434                    restrictions.putString(key, value);
2435                }
2436            }
2437        }
2438    }
2439
2440    private static Bundle readBundleEntry(XmlPullParser parser, ArrayList<String> values)
2441            throws IOException, XmlPullParserException {
2442        Bundle childBundle = new Bundle();
2443        final int outerDepth = parser.getDepth();
2444        while (XmlUtils.nextElementWithin(parser, outerDepth)) {
2445            readEntry(childBundle, values, parser);
2446        }
2447        return childBundle;
2448    }
2449
2450    private void writeApplicationRestrictionsLP(String packageName,
2451            Bundle restrictions, int userId) {
2452        AtomicFile restrictionsFile = new AtomicFile(
2453                new File(Environment.getUserSystemDirectory(userId),
2454                        packageToRestrictionsFileName(packageName)));
2455        writeApplicationRestrictionsLP(restrictions, restrictionsFile);
2456    }
2457
2458    @VisibleForTesting
2459    static void writeApplicationRestrictionsLP(Bundle restrictions, AtomicFile restrictionsFile) {
2460        FileOutputStream fos = null;
2461        try {
2462            fos = restrictionsFile.startWrite();
2463            final BufferedOutputStream bos = new BufferedOutputStream(fos);
2464
2465            final XmlSerializer serializer = new FastXmlSerializer();
2466            serializer.setOutput(bos, StandardCharsets.UTF_8.name());
2467            serializer.startDocument(null, true);
2468            serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
2469
2470            serializer.startTag(null, TAG_RESTRICTIONS);
2471            writeBundle(restrictions, serializer);
2472            serializer.endTag(null, TAG_RESTRICTIONS);
2473
2474            serializer.endDocument();
2475            restrictionsFile.finishWrite(fos);
2476        } catch (Exception e) {
2477            restrictionsFile.failWrite(fos);
2478            Slog.e(LOG_TAG, "Error writing application restrictions list", e);
2479        }
2480    }
2481
2482    private static void writeBundle(Bundle restrictions, XmlSerializer serializer)
2483            throws IOException {
2484        for (String key : restrictions.keySet()) {
2485            Object value = restrictions.get(key);
2486            serializer.startTag(null, TAG_ENTRY);
2487            serializer.attribute(null, ATTR_KEY, key);
2488
2489            if (value instanceof Boolean) {
2490                serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_BOOLEAN);
2491                serializer.text(value.toString());
2492            } else if (value instanceof Integer) {
2493                serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_INTEGER);
2494                serializer.text(value.toString());
2495            } else if (value == null || value instanceof String) {
2496                serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_STRING);
2497                serializer.text(value != null ? (String) value : "");
2498            } else if (value instanceof Bundle) {
2499                serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_BUNDLE);
2500                writeBundle((Bundle) value, serializer);
2501            } else if (value instanceof Parcelable[]) {
2502                serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_BUNDLE_ARRAY);
2503                Parcelable[] array = (Parcelable[]) value;
2504                for (Parcelable parcelable : array) {
2505                    if (!(parcelable instanceof Bundle)) {
2506                        throw new IllegalArgumentException("bundle-array can only hold Bundles");
2507                    }
2508                    serializer.startTag(null, TAG_ENTRY);
2509                    serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_BUNDLE);
2510                    writeBundle((Bundle) parcelable, serializer);
2511                    serializer.endTag(null, TAG_ENTRY);
2512                }
2513            } else {
2514                serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_STRING_ARRAY);
2515                String[] values = (String[]) value;
2516                serializer.attribute(null, ATTR_MULTIPLE, Integer.toString(values.length));
2517                for (String choice : values) {
2518                    serializer.startTag(null, TAG_VALUE);
2519                    serializer.text(choice != null ? choice : "");
2520                    serializer.endTag(null, TAG_VALUE);
2521                }
2522            }
2523            serializer.endTag(null, TAG_ENTRY);
2524        }
2525    }
2526
2527    @Override
2528    public int getUserSerialNumber(int userHandle) {
2529        synchronized (mUsersLock) {
2530            if (!exists(userHandle)) return -1;
2531            return getUserInfoLU(userHandle).serialNumber;
2532        }
2533    }
2534
2535    @Override
2536    public int getUserHandle(int userSerialNumber) {
2537        synchronized (mUsersLock) {
2538            for (int userId : mUserIds) {
2539                UserInfo info = getUserInfoLU(userId);
2540                if (info != null && info.serialNumber == userSerialNumber) return userId;
2541            }
2542            // Not found
2543            return -1;
2544        }
2545    }
2546
2547    @Override
2548    public long getUserCreationTime(int userHandle) {
2549        int callingUserId = UserHandle.getCallingUserId();
2550        UserInfo userInfo = null;
2551        synchronized (mUsersLock) {
2552            if (callingUserId == userHandle) {
2553                userInfo = getUserInfoLU(userHandle);
2554            } else {
2555                UserInfo parent = getProfileParentLU(userHandle);
2556                if (parent != null && parent.id == callingUserId) {
2557                    userInfo = getUserInfoLU(userHandle);
2558                }
2559            }
2560        }
2561        if (userInfo == null) {
2562            throw new SecurityException("userHandle can only be the calling user or a managed "
2563                    + "profile associated with this user");
2564        }
2565        return userInfo.creationTime;
2566    }
2567
2568    /**
2569     * Caches the list of user ids in an array, adjusting the array size when necessary.
2570     */
2571    private void updateUserIds() {
2572        int num = 0;
2573        synchronized (mUsersLock) {
2574            final int userSize = mUsers.size();
2575            for (int i = 0; i < userSize; i++) {
2576                if (!mUsers.valueAt(i).info.partial) {
2577                    num++;
2578                }
2579            }
2580            final int[] newUsers = new int[num];
2581            int n = 0;
2582            for (int i = 0; i < userSize; i++) {
2583                if (!mUsers.valueAt(i).info.partial) {
2584                    newUsers[n++] = mUsers.keyAt(i);
2585                }
2586            }
2587            mUserIds = newUsers;
2588        }
2589    }
2590
2591    /**
2592     * Prepare storage areas for given user on all mounted devices.
2593     */
2594    private void prepareUserStorage(int userId, int userSerial, int flags) {
2595        final StorageManager storage = mContext.getSystemService(StorageManager.class);
2596        for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
2597            final String volumeUuid = vol.getFsUuid();
2598            storage.prepareUserStorage(volumeUuid, userId, userSerial, flags);
2599        }
2600    }
2601
2602    /**
2603     * Called right before a user is started. This gives us a chance to prepare
2604     * app storage and apply any user restrictions.
2605     */
2606    public void onBeforeStartUser(int userId) {
2607        final int userSerial = getUserSerialNumber(userId);
2608        prepareUserStorage(userId, userSerial, StorageManager.FLAG_STORAGE_DE);
2609        mPm.reconcileAppsData(userId, StorageManager.FLAG_STORAGE_DE);
2610
2611        if (userId != UserHandle.USER_SYSTEM) {
2612            synchronized (mRestrictionsLock) {
2613                applyUserRestrictionsLR(userId);
2614            }
2615        }
2616    }
2617
2618    /**
2619     * Called right before a user is unlocked. This gives us a chance to prepare
2620     * app storage.
2621     */
2622    public void onBeforeUnlockUser(@UserIdInt int userId) {
2623        final int userSerial = getUserSerialNumber(userId);
2624        prepareUserStorage(userId, userSerial, StorageManager.FLAG_STORAGE_CE);
2625        mPm.reconcileAppsData(userId, StorageManager.FLAG_STORAGE_CE);
2626    }
2627
2628    /**
2629     * Make a note of the last started time of a user and do some cleanup.
2630     * @param userId the user that was just foregrounded
2631     */
2632    public void onUserLoggedIn(@UserIdInt int userId) {
2633        UserData userData = getUserDataNoChecks(userId);
2634        if (userData == null || userData.info.partial) {
2635            Slog.w(LOG_TAG, "userForeground: unknown user #" + userId);
2636            return;
2637        }
2638
2639        final long now = System.currentTimeMillis();
2640        if (now > EPOCH_PLUS_30_YEARS) {
2641            userData.info.lastLoggedInTime = now;
2642        }
2643        userData.info.lastLoggedInFingerprint = Build.FINGERPRINT;
2644        scheduleWriteUser(userData);
2645    }
2646
2647    /**
2648     * Returns the next available user id, filling in any holes in the ids.
2649     * TODO: May not be a good idea to recycle ids, in case it results in confusion
2650     * for data and battery stats collection, or unexpected cross-talk.
2651     */
2652    private int getNextAvailableId() {
2653        synchronized (mUsersLock) {
2654            int i = MIN_USER_ID;
2655            while (i < MAX_USER_ID) {
2656                if (mUsers.indexOfKey(i) < 0 && !mRemovingUserIds.get(i)) {
2657                    return i;
2658                }
2659                i++;
2660            }
2661        }
2662        throw new IllegalStateException("No user id available!");
2663    }
2664
2665    private String packageToRestrictionsFileName(String packageName) {
2666        return RESTRICTIONS_FILE_PREFIX + packageName + XML_SUFFIX;
2667    }
2668
2669    /**
2670     * Enforce that serial number stored in user directory inode matches the
2671     * given expected value. Gracefully sets the serial number if currently
2672     * undefined.
2673     *
2674     * @throws IOException when problem extracting serial number, or serial
2675     *             number is mismatched.
2676     */
2677    public static void enforceSerialNumber(File file, int serialNumber) throws IOException {
2678        final int foundSerial = getSerialNumber(file);
2679        Slog.v(LOG_TAG, "Found " + file + " with serial number " + foundSerial);
2680
2681        if (foundSerial == -1) {
2682            Slog.d(LOG_TAG, "Serial number missing on " + file + "; assuming current is valid");
2683            try {
2684                setSerialNumber(file, serialNumber);
2685            } catch (IOException e) {
2686                Slog.w(LOG_TAG, "Failed to set serial number on " + file, e);
2687            }
2688
2689        } else if (foundSerial != serialNumber) {
2690            throw new IOException("Found serial number " + foundSerial
2691                    + " doesn't match expected " + serialNumber);
2692        }
2693    }
2694
2695    /**
2696     * Set serial number stored in user directory inode.
2697     *
2698     * @throws IOException if serial number was already set
2699     */
2700    private static void setSerialNumber(File file, int serialNumber)
2701            throws IOException {
2702        try {
2703            final byte[] buf = Integer.toString(serialNumber).getBytes(StandardCharsets.UTF_8);
2704            Os.setxattr(file.getAbsolutePath(), XATTR_SERIAL, buf, OsConstants.XATTR_CREATE);
2705        } catch (ErrnoException e) {
2706            throw e.rethrowAsIOException();
2707        }
2708    }
2709
2710    /**
2711     * Return serial number stored in user directory inode.
2712     *
2713     * @return parsed serial number, or -1 if not set
2714     */
2715    private static int getSerialNumber(File file) throws IOException {
2716        try {
2717            final byte[] buf = new byte[256];
2718            final int len = Os.getxattr(file.getAbsolutePath(), XATTR_SERIAL, buf);
2719            final String serial = new String(buf, 0, len);
2720            try {
2721                return Integer.parseInt(serial);
2722            } catch (NumberFormatException e) {
2723                throw new IOException("Bad serial number: " + serial);
2724            }
2725        } catch (ErrnoException e) {
2726            if (e.errno == OsConstants.ENODATA) {
2727                return -1;
2728            } else {
2729                throw e.rethrowAsIOException();
2730            }
2731        }
2732    }
2733
2734    @Override
2735    public void setSeedAccountData(int userId, String accountName, String accountType,
2736            PersistableBundle accountOptions, boolean persist) {
2737        checkManageUsersPermission("Require MANAGE_USERS permission to set user seed data");
2738        synchronized (mPackagesLock) {
2739            final UserData userData;
2740            synchronized (mUsersLock) {
2741                userData = getUserDataLU(userId);
2742                if (userData == null) {
2743                    Slog.e(LOG_TAG, "No such user for settings seed data u=" + userId);
2744                    return;
2745                }
2746                userData.seedAccountName = accountName;
2747                userData.seedAccountType = accountType;
2748                userData.seedAccountOptions = accountOptions;
2749                userData.persistSeedData = persist;
2750            }
2751            if (persist) {
2752                writeUserLP(userData);
2753            }
2754        }
2755    }
2756
2757    @Override
2758    public String getSeedAccountName() throws RemoteException {
2759        checkManageUsersPermission("Cannot get seed account information");
2760        synchronized (mUsersLock) {
2761            UserData userData = getUserDataLU(UserHandle.getCallingUserId());
2762            return userData.seedAccountName;
2763        }
2764    }
2765
2766    @Override
2767    public String getSeedAccountType() throws RemoteException {
2768        checkManageUsersPermission("Cannot get seed account information");
2769        synchronized (mUsersLock) {
2770            UserData userData = getUserDataLU(UserHandle.getCallingUserId());
2771            return userData.seedAccountType;
2772        }
2773    }
2774
2775    @Override
2776    public PersistableBundle getSeedAccountOptions() throws RemoteException {
2777        checkManageUsersPermission("Cannot get seed account information");
2778        synchronized (mUsersLock) {
2779            UserData userData = getUserDataLU(UserHandle.getCallingUserId());
2780            return userData.seedAccountOptions;
2781        }
2782    }
2783
2784    @Override
2785    public void clearSeedAccountData() throws RemoteException {
2786        checkManageUsersPermission("Cannot clear seed account information");
2787        synchronized (mPackagesLock) {
2788            UserData userData;
2789            synchronized (mUsersLock) {
2790                userData = getUserDataLU(UserHandle.getCallingUserId());
2791                if (userData == null) return;
2792                userData.clearSeedAccountData();
2793            }
2794            writeUserLP(userData);
2795        }
2796    }
2797
2798    @Override
2799    public boolean someUserHasSeedAccount(String accountName, String accountType)
2800            throws RemoteException {
2801        checkManageUsersPermission("Cannot check seed account information");
2802        synchronized (mUsersLock) {
2803            final int userSize = mUsers.size();
2804            for (int i = 0; i < userSize; i++) {
2805                final UserData data = mUsers.valueAt(i);
2806                if (data.info.isInitialized()) continue;
2807                if (data.seedAccountName == null || !data.seedAccountName.equals(accountName)) {
2808                    continue;
2809                }
2810                if (data.seedAccountType == null || !data.seedAccountType.equals(accountType)) {
2811                    continue;
2812                }
2813                return true;
2814            }
2815        }
2816        return false;
2817    }
2818
2819    @Override
2820    public void onShellCommand(FileDescriptor in, FileDescriptor out,
2821            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
2822        (new Shell()).exec(this, in, out, err, args, resultReceiver);
2823    }
2824
2825    int onShellCommand(Shell shell, String cmd) {
2826        if (cmd == null) {
2827            return shell.handleDefaultCommands(cmd);
2828        }
2829
2830        final PrintWriter pw = shell.getOutPrintWriter();
2831        try {
2832            switch(cmd) {
2833                case "list":
2834                    return runList(pw);
2835            }
2836        } catch (RemoteException e) {
2837            pw.println("Remote exception: " + e);
2838        }
2839        return -1;
2840    }
2841
2842    private int runList(PrintWriter pw) throws RemoteException {
2843        final IActivityManager am = ActivityManagerNative.getDefault();
2844        final List<UserInfo> users = getUsers(false);
2845        if (users == null) {
2846            pw.println("Error: couldn't get users");
2847            return 1;
2848        } else {
2849            pw.println("Users:");
2850            for (int i = 0; i < users.size(); i++) {
2851                String running = am.isUserRunning(users.get(i).id, 0) ? " running" : "";
2852                pw.println("\t" + users.get(i).toString() + running);
2853            }
2854            return 0;
2855        }
2856    }
2857
2858    @Override
2859    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2860        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
2861                != PackageManager.PERMISSION_GRANTED) {
2862            pw.println("Permission Denial: can't dump UserManager from from pid="
2863                    + Binder.getCallingPid()
2864                    + ", uid=" + Binder.getCallingUid()
2865                    + " without permission "
2866                    + android.Manifest.permission.DUMP);
2867            return;
2868        }
2869
2870        long now = System.currentTimeMillis();
2871        StringBuilder sb = new StringBuilder();
2872        synchronized (mPackagesLock) {
2873            synchronized (mUsersLock) {
2874                pw.println("Users:");
2875                for (int i = 0; i < mUsers.size(); i++) {
2876                    UserData userData = mUsers.valueAt(i);
2877                    if (userData == null) {
2878                        continue;
2879                    }
2880                    UserInfo userInfo = userData.info;
2881                    final int userId = userInfo.id;
2882                    pw.print("  "); pw.print(userInfo);
2883                    pw.print(" serialNo="); pw.print(userInfo.serialNumber);
2884                    if (mRemovingUserIds.get(userId)) {
2885                        pw.print(" <removing> ");
2886                    }
2887                    if (userInfo.partial) {
2888                        pw.print(" <partial>");
2889                    }
2890                    pw.println();
2891                    pw.print("    Created: ");
2892                    if (userInfo.creationTime == 0) {
2893                        pw.println("<unknown>");
2894                    } else {
2895                        sb.setLength(0);
2896                        TimeUtils.formatDuration(now - userInfo.creationTime, sb);
2897                        sb.append(" ago");
2898                        pw.println(sb);
2899                    }
2900                    pw.print("    Last logged in: ");
2901                    if (userInfo.lastLoggedInTime == 0) {
2902                        pw.println("<unknown>");
2903                    } else {
2904                        sb.setLength(0);
2905                        TimeUtils.formatDuration(now - userInfo.lastLoggedInTime, sb);
2906                        sb.append(" ago");
2907                        pw.println(sb);
2908                    }
2909                    pw.print("    Last logged in fingerprint: ");
2910                    pw.println(userInfo.lastLoggedInFingerprint);
2911                    pw.print("    Has profile owner: ");
2912                    pw.println(mIsUserManaged.get(userId));
2913                    pw.println("    Restrictions:");
2914                    synchronized (mRestrictionsLock) {
2915                        UserRestrictionsUtils.dumpRestrictions(
2916                                pw, "      ", mBaseUserRestrictions.get(userInfo.id));
2917                        pw.println("    Device policy local restrictions:");
2918                        UserRestrictionsUtils.dumpRestrictions(
2919                                pw, "      ", mDevicePolicyLocalUserRestrictions.get(userInfo.id));
2920                        pw.println("    Effective restrictions:");
2921                        UserRestrictionsUtils.dumpRestrictions(
2922                                pw, "      ", mCachedEffectiveUserRestrictions.get(userInfo.id));
2923                    }
2924
2925                    if (userData.account != null) {
2926                        pw.print("    Account name: " + userData.account);
2927                        pw.println();
2928                    }
2929
2930                    if (userData.seedAccountName != null) {
2931                        pw.print("    Seed account name: " + userData.seedAccountName);
2932                        pw.println();
2933                        if (userData.seedAccountType != null) {
2934                            pw.print("         account type: " + userData.seedAccountType);
2935                            pw.println();
2936                        }
2937                        if (userData.seedAccountOptions != null) {
2938                            pw.print("         account options exist");
2939                            pw.println();
2940                        }
2941                    }
2942                }
2943            }
2944            pw.println();
2945            pw.println("  Device policy global restrictions:");
2946            synchronized (mRestrictionsLock) {
2947                UserRestrictionsUtils
2948                        .dumpRestrictions(pw, "    ", mDevicePolicyGlobalUserRestrictions);
2949            }
2950            pw.println();
2951            pw.println("  Guest restrictions:");
2952            synchronized (mGuestRestrictions) {
2953                UserRestrictionsUtils.dumpRestrictions(pw, "    ", mGuestRestrictions);
2954            }
2955            synchronized (mUsersLock) {
2956                pw.println();
2957                pw.println("  Device managed: " + mIsDeviceManaged);
2958            }
2959            // Dump some capabilities
2960            pw.println();
2961            pw.println("  Max users: " + UserManager.getMaxSupportedUsers());
2962            pw.println("  Supports switchable users: " + UserManager.supportsMultipleUsers());
2963            pw.println("  All guests ephemeral: " + Resources.getSystem().getBoolean(
2964                    com.android.internal.R.bool.config_guestUserEphemeral));
2965        }
2966    }
2967
2968    final class MainHandler extends Handler {
2969
2970        @Override
2971        public void handleMessage(Message msg) {
2972            switch (msg.what) {
2973                case WRITE_USER_MSG:
2974                    removeMessages(WRITE_USER_MSG, msg.obj);
2975                    synchronized (mPackagesLock) {
2976                        int userId = ((UserData) msg.obj).info.id;
2977                        UserData userData = getUserDataNoChecks(userId);
2978                        if (userData != null) {
2979                            writeUserLP(userData);
2980                        }
2981                    }
2982            }
2983        }
2984    }
2985
2986    /**
2987     * @param userId
2988     * @return whether the user has been initialized yet
2989     */
2990    boolean isInitialized(int userId) {
2991        return (getUserInfo(userId).flags & UserInfo.FLAG_INITIALIZED) != 0;
2992    }
2993
2994    private class LocalService extends UserManagerInternal {
2995        @Override
2996        public void setDevicePolicyUserRestrictions(int userId, @NonNull Bundle localRestrictions,
2997                @Nullable Bundle globalRestrictions) {
2998            UserManagerService.this.setDevicePolicyUserRestrictionsInner(userId, localRestrictions,
2999                    globalRestrictions);
3000        }
3001
3002        @Override
3003        public Bundle getBaseUserRestrictions(int userId) {
3004            synchronized (mRestrictionsLock) {
3005                return mBaseUserRestrictions.get(userId);
3006            }
3007        }
3008
3009        @Override
3010        public void setBaseUserRestrictionsByDpmsForMigration(
3011                int userId, Bundle baseRestrictions) {
3012            synchronized (mRestrictionsLock) {
3013                mBaseUserRestrictions.put(userId, new Bundle(baseRestrictions));
3014                invalidateEffectiveUserRestrictionsLR(userId);
3015            }
3016
3017            final UserData userData = getUserDataNoChecks(userId);
3018            synchronized (mPackagesLock) {
3019                if (userData != null) {
3020                    writeUserLP(userData);
3021                } else {
3022                    Slog.w(LOG_TAG, "UserInfo not found for " + userId);
3023                }
3024            }
3025        }
3026
3027        @Override
3028        public boolean getUserRestriction(int userId, String key) {
3029            return getUserRestrictions(userId).getBoolean(key);
3030        }
3031
3032        @Override
3033        public void addUserRestrictionsListener(UserRestrictionsListener listener) {
3034            synchronized (mUserRestrictionsListeners) {
3035                mUserRestrictionsListeners.add(listener);
3036            }
3037        }
3038
3039        @Override
3040        public void removeUserRestrictionsListener(UserRestrictionsListener listener) {
3041            synchronized (mUserRestrictionsListeners) {
3042                mUserRestrictionsListeners.remove(listener);
3043            }
3044        }
3045
3046        @Override
3047        public void setDeviceManaged(boolean isManaged) {
3048            synchronized (mUsersLock) {
3049                mIsDeviceManaged = isManaged;
3050            }
3051        }
3052
3053        @Override
3054        public void setUserManaged(int userId, boolean isManaged) {
3055            synchronized (mUsersLock) {
3056                mIsUserManaged.put(userId, isManaged);
3057            }
3058        }
3059
3060        @Override
3061        public void setUserIcon(int userId, Bitmap bitmap) {
3062            long ident = Binder.clearCallingIdentity();
3063            try {
3064                synchronized (mPackagesLock) {
3065                    UserData userData = getUserDataNoChecks(userId);
3066                    if (userData == null || userData.info.partial) {
3067                        Slog.w(LOG_TAG, "setUserIcon: unknown user #" + userId);
3068                        return;
3069                    }
3070                    writeBitmapLP(userData.info, bitmap);
3071                    writeUserLP(userData);
3072                }
3073                sendUserInfoChangedBroadcast(userId);
3074            } finally {
3075                Binder.restoreCallingIdentity(ident);
3076            }
3077        }
3078
3079        @Override
3080        public void setForceEphemeralUsers(boolean forceEphemeralUsers) {
3081            synchronized (mUsersLock) {
3082                mForceEphemeralUsers = forceEphemeralUsers;
3083            }
3084        }
3085
3086        @Override
3087        public void removeAllUsers() {
3088            if (UserHandle.USER_SYSTEM == ActivityManager.getCurrentUser()) {
3089                // Remove the non-system users straight away.
3090                removeNonSystemUsers();
3091            } else {
3092                // Switch to the system user first and then remove the other users.
3093                BroadcastReceiver userSwitchedReceiver = new BroadcastReceiver() {
3094                    @Override
3095                    public void onReceive(Context context, Intent intent) {
3096                        int userId =
3097                                intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
3098                        if (userId != UserHandle.USER_SYSTEM) {
3099                            return;
3100                        }
3101                        mContext.unregisterReceiver(this);
3102                        removeNonSystemUsers();
3103                    }
3104                };
3105                IntentFilter userSwitchedFilter = new IntentFilter();
3106                userSwitchedFilter.addAction(Intent.ACTION_USER_SWITCHED);
3107                mContext.registerReceiver(
3108                        userSwitchedReceiver, userSwitchedFilter, null, mHandler);
3109
3110                // Switch to the system user.
3111                ActivityManager am =
3112                        (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
3113                am.switchUser(UserHandle.USER_SYSTEM);
3114            }
3115        }
3116
3117        @Override
3118        public void onEphemeralUserStop(int userId) {
3119            synchronized (mUsersLock) {
3120               UserInfo userInfo = getUserInfoLU(userId);
3121               if (userInfo != null && userInfo.isEphemeral()) {
3122                    // Do not allow switching back to the ephemeral user again as the user is going
3123                    // to be deleted.
3124                    userInfo.flags |= UserInfo.FLAG_DISABLED;
3125                    if (userInfo.isGuest()) {
3126                        // Indicate that the guest will be deleted after it stops.
3127                        userInfo.guestToRemove = true;
3128                    }
3129               }
3130            }
3131        }
3132
3133        @Override
3134        public UserInfo createUserEvenWhenDisallowed(String name, int flags) {
3135            UserInfo user = createUserInternalUnchecked(name, flags, UserHandle.USER_NULL);
3136            // Keep this in sync with UserManager.createUser
3137            if (user != null && !user.isAdmin()) {
3138                setUserRestriction(UserManager.DISALLOW_SMS, true, user.id);
3139                setUserRestriction(UserManager.DISALLOW_OUTGOING_CALLS, true, user.id);
3140            }
3141            return user;
3142        }
3143    }
3144
3145    /* Remove all the users except of the system one. */
3146    private void removeNonSystemUsers() {
3147        ArrayList<UserInfo> usersToRemove = new ArrayList<>();
3148        synchronized (mUsersLock) {
3149            final int userSize = mUsers.size();
3150            for (int i = 0; i < userSize; i++) {
3151                UserInfo ui = mUsers.valueAt(i).info;
3152                if (ui.id != UserHandle.USER_SYSTEM) {
3153                    usersToRemove.add(ui);
3154                }
3155            }
3156        }
3157        for (UserInfo ui: usersToRemove) {
3158            removeUser(ui.id);
3159        }
3160    }
3161
3162    private class Shell extends ShellCommand {
3163        @Override
3164        public int onCommand(String cmd) {
3165            return onShellCommand(this, cmd);
3166        }
3167
3168        @Override
3169        public void onHelp() {
3170            final PrintWriter pw = getOutPrintWriter();
3171            pw.println("User manager (user) commands:");
3172            pw.println("  help");
3173            pw.println("    Print this help text.");
3174            pw.println("");
3175            pw.println("  list");
3176            pw.println("    Prints all users on the system.");
3177        }
3178    }
3179
3180    private static void debug(String message) {
3181        Log.d(LOG_TAG, message +
3182                (DBG_WITH_STACKTRACE ? " called at\n" + Debug.getCallers(10, "  ") : ""));
3183    }
3184}
3185