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