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