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