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