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