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