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