UserManagerService.java revision 2e7e09685a69cc6b9e3418065507c6c7f843b446
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        if (hasUserRestriction(UserManager.DISALLOW_ADD_USER, UserHandle.getCallingUserId())) {
2273            Log.w(LOG_TAG, "Cannot add user. DISALLOW_ADD_USER is enabled.");
2274            return null;
2275        }
2276        return createUserInternalUnchecked(name, flags, parentId, disallowedPackages);
2277    }
2278
2279    private UserInfo createUserInternalUnchecked(String name, int flags, int parentId,
2280            String[] disallowedPackages) {
2281        DeviceStorageMonitorInternal dsm = LocalServices
2282                .getService(DeviceStorageMonitorInternal.class);
2283        if (dsm.isMemoryLow()) {
2284            Log.w(LOG_TAG, "Cannot add user. Not enough space on disk.");
2285            return null;
2286        }
2287        if (ActivityManager.isLowRamDeviceStatic()) {
2288            return null;
2289        }
2290        final boolean isGuest = (flags & UserInfo.FLAG_GUEST) != 0;
2291        final boolean isManagedProfile = (flags & UserInfo.FLAG_MANAGED_PROFILE) != 0;
2292        final boolean isRestricted = (flags & UserInfo.FLAG_RESTRICTED) != 0;
2293        final boolean isDemo = (flags & UserInfo.FLAG_DEMO) != 0;
2294        final long ident = Binder.clearCallingIdentity();
2295        UserInfo userInfo;
2296        UserData userData;
2297        final int userId;
2298        try {
2299            synchronized (mPackagesLock) {
2300                UserData parent = null;
2301                if (parentId != UserHandle.USER_NULL) {
2302                    synchronized (mUsersLock) {
2303                        parent = getUserDataLU(parentId);
2304                    }
2305                    if (parent == null) return null;
2306                }
2307                if (isManagedProfile && !canAddMoreManagedProfiles(parentId, false)) {
2308                    Log.e(LOG_TAG, "Cannot add more managed profiles for user " + parentId);
2309                    return null;
2310                }
2311                if (!isGuest && !isManagedProfile && !isDemo && isUserLimitReached()) {
2312                    // If we're not adding a guest/demo user or a managed profile and the limit has
2313                    // been reached, cannot add a user.
2314                    return null;
2315                }
2316                // If we're adding a guest and there already exists one, bail.
2317                if (isGuest && findCurrentGuestUser() != null) {
2318                    return null;
2319                }
2320                // In legacy mode, restricted profile's parent can only be the owner user
2321                if (isRestricted && !UserManager.isSplitSystemUser()
2322                        && (parentId != UserHandle.USER_SYSTEM)) {
2323                    Log.w(LOG_TAG, "Cannot add restricted profile - parent user must be owner");
2324                    return null;
2325                }
2326                if (isRestricted && UserManager.isSplitSystemUser()) {
2327                    if (parent == null) {
2328                        Log.w(LOG_TAG, "Cannot add restricted profile - parent user must be "
2329                                + "specified");
2330                        return null;
2331                    }
2332                    if (!parent.info.canHaveProfile()) {
2333                        Log.w(LOG_TAG, "Cannot add restricted profile - profiles cannot be "
2334                                + "created for the specified parent user id " + parentId);
2335                        return null;
2336                    }
2337                }
2338                if (!UserManager.isSplitSystemUser() && (flags & UserInfo.FLAG_EPHEMERAL) != 0
2339                        && (flags & UserInfo.FLAG_DEMO) == 0) {
2340                    Log.e(LOG_TAG,
2341                            "Ephemeral users are supported on split-system-user systems only.");
2342                    return null;
2343                }
2344                // In split system user mode, we assign the first human user the primary flag.
2345                // And if there is no device owner, we also assign the admin flag to primary user.
2346                if (UserManager.isSplitSystemUser()
2347                        && !isGuest && !isManagedProfile && getPrimaryUser() == null) {
2348                    flags |= UserInfo.FLAG_PRIMARY;
2349                    synchronized (mUsersLock) {
2350                        if (!mIsDeviceManaged) {
2351                            flags |= UserInfo.FLAG_ADMIN;
2352                        }
2353                    }
2354                }
2355
2356                userId = getNextAvailableId();
2357                Environment.getUserSystemDirectory(userId).mkdirs();
2358                boolean ephemeralGuests = Resources.getSystem()
2359                        .getBoolean(com.android.internal.R.bool.config_guestUserEphemeral);
2360
2361                synchronized (mUsersLock) {
2362                    // Add ephemeral flag to guests/users if required. Also inherit it from parent.
2363                    if ((isGuest && ephemeralGuests) || mForceEphemeralUsers
2364                            || (parent != null && parent.info.isEphemeral())) {
2365                        flags |= UserInfo.FLAG_EPHEMERAL;
2366                    }
2367
2368                    userInfo = new UserInfo(userId, name, null, flags);
2369                    userInfo.serialNumber = mNextSerialNumber++;
2370                    long now = System.currentTimeMillis();
2371                    userInfo.creationTime = (now > EPOCH_PLUS_30_YEARS) ? now : 0;
2372                    userInfo.partial = true;
2373                    userInfo.lastLoggedInFingerprint = Build.FINGERPRINT;
2374                    if (isManagedProfile && parentId != UserHandle.USER_NULL) {
2375                        userInfo.profileBadge = getFreeProfileBadgeLU(parentId);
2376                    }
2377                    userData = new UserData();
2378                    userData.info = userInfo;
2379                    mUsers.put(userId, userData);
2380                }
2381                writeUserLP(userData);
2382                writeUserListLP();
2383                if (parent != null) {
2384                    if (isManagedProfile) {
2385                        if (parent.info.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID) {
2386                            parent.info.profileGroupId = parent.info.id;
2387                            writeUserLP(parent);
2388                        }
2389                        userInfo.profileGroupId = parent.info.profileGroupId;
2390                    } else if (isRestricted) {
2391                        if (parent.info.restrictedProfileParentId == UserInfo.NO_PROFILE_GROUP_ID) {
2392                            parent.info.restrictedProfileParentId = parent.info.id;
2393                            writeUserLP(parent);
2394                        }
2395                        userInfo.restrictedProfileParentId = parent.info.restrictedProfileParentId;
2396                    }
2397                }
2398            }
2399            final StorageManager storage = mContext.getSystemService(StorageManager.class);
2400            storage.createUserKey(userId, userInfo.serialNumber, userInfo.isEphemeral());
2401            mPm.prepareUserData(userId, userInfo.serialNumber,
2402                    StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
2403            mPm.createNewUser(userId, disallowedPackages);
2404            userInfo.partial = false;
2405            synchronized (mPackagesLock) {
2406                writeUserLP(userData);
2407            }
2408            updateUserIds();
2409            Bundle restrictions = new Bundle();
2410            if (isGuest) {
2411                synchronized (mGuestRestrictions) {
2412                    restrictions.putAll(mGuestRestrictions);
2413                }
2414            }
2415            synchronized (mRestrictionsLock) {
2416                mBaseUserRestrictions.append(userId, restrictions);
2417            }
2418            mPm.onNewUserCreated(userId);
2419            Intent addedIntent = new Intent(Intent.ACTION_USER_ADDED);
2420            addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
2421            mContext.sendBroadcastAsUser(addedIntent, UserHandle.ALL,
2422                    android.Manifest.permission.MANAGE_USERS);
2423            MetricsLogger.count(mContext, isGuest ? TRON_GUEST_CREATED : TRON_USER_CREATED, 1);
2424        } finally {
2425            Binder.restoreCallingIdentity(ident);
2426        }
2427        return userInfo;
2428    }
2429
2430    @VisibleForTesting
2431    UserData putUserInfo(UserInfo userInfo) {
2432        final UserData userData = new UserData();
2433        userData.info = userInfo;
2434        synchronized (mUsers) {
2435            mUsers.put(userInfo.id, userData);
2436        }
2437        return userData;
2438    }
2439
2440    @VisibleForTesting
2441    void removeUserInfo(int userId) {
2442        synchronized (mUsers) {
2443            mUsers.remove(userId);
2444        }
2445    }
2446
2447    /**
2448     * @hide
2449     */
2450    @Override
2451    public UserInfo createRestrictedProfile(String name, int parentUserId) {
2452        checkManageOrCreateUsersPermission("setupRestrictedProfile");
2453        final UserInfo user = createProfileForUser(
2454                name, UserInfo.FLAG_RESTRICTED, parentUserId, null);
2455        if (user == null) {
2456            return null;
2457        }
2458        long identity = Binder.clearCallingIdentity();
2459        try {
2460            setUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS, true, user.id);
2461            // Change the setting before applying the DISALLOW_SHARE_LOCATION restriction, otherwise
2462            // the putIntForUser() will fail.
2463            android.provider.Settings.Secure.putIntForUser(mContext.getContentResolver(),
2464                    android.provider.Settings.Secure.LOCATION_MODE,
2465                    android.provider.Settings.Secure.LOCATION_MODE_OFF, user.id);
2466            setUserRestriction(UserManager.DISALLOW_SHARE_LOCATION, true, user.id);
2467        } finally {
2468            Binder.restoreCallingIdentity(identity);
2469        }
2470        return user;
2471    }
2472
2473    /**
2474     * Find the current guest user. If the Guest user is partial,
2475     * then do not include it in the results as it is about to die.
2476     */
2477    private UserInfo findCurrentGuestUser() {
2478        synchronized (mUsersLock) {
2479            final int size = mUsers.size();
2480            for (int i = 0; i < size; i++) {
2481                final UserInfo user = mUsers.valueAt(i).info;
2482                if (user.isGuest() && !user.guestToRemove && !mRemovingUserIds.get(user.id)) {
2483                    return user;
2484                }
2485            }
2486        }
2487        return null;
2488    }
2489
2490    /**
2491     * Mark this guest user for deletion to allow us to create another guest
2492     * and switch to that user before actually removing this guest.
2493     * @param userHandle the userid of the current guest
2494     * @return whether the user could be marked for deletion
2495     */
2496    @Override
2497    public boolean markGuestForDeletion(int userHandle) {
2498        checkManageUsersPermission("Only the system can remove users");
2499        if (getUserRestrictions(UserHandle.getCallingUserId()).getBoolean(
2500                UserManager.DISALLOW_REMOVE_USER, false)) {
2501            Log.w(LOG_TAG, "Cannot remove user. DISALLOW_REMOVE_USER is enabled.");
2502            return false;
2503        }
2504
2505        long ident = Binder.clearCallingIdentity();
2506        try {
2507            final UserData userData;
2508            synchronized (mPackagesLock) {
2509                synchronized (mUsersLock) {
2510                    userData = mUsers.get(userHandle);
2511                    if (userHandle == 0 || userData == null || mRemovingUserIds.get(userHandle)) {
2512                        return false;
2513                    }
2514                }
2515                if (!userData.info.isGuest()) {
2516                    return false;
2517                }
2518                // We set this to a guest user that is to be removed. This is a temporary state
2519                // where we are allowed to add new Guest users, even if this one is still not
2520                // removed. This user will still show up in getUserInfo() calls.
2521                // If we don't get around to removing this Guest user, it will be purged on next
2522                // startup.
2523                userData.info.guestToRemove = true;
2524                // Mark it as disabled, so that it isn't returned any more when
2525                // profiles are queried.
2526                userData.info.flags |= UserInfo.FLAG_DISABLED;
2527                writeUserLP(userData);
2528            }
2529        } finally {
2530            Binder.restoreCallingIdentity(ident);
2531        }
2532        return true;
2533    }
2534
2535    /**
2536     * Removes a user and all data directories created for that user. This method should be called
2537     * after the user's processes have been terminated.
2538     * @param userHandle the user's id
2539     */
2540    @Override
2541    public boolean removeUser(int userHandle) {
2542        Slog.i(LOG_TAG, "removeUser u" + userHandle);
2543        checkManageOrCreateUsersPermission("Only the system can remove users");
2544        if (getUserRestrictions(UserHandle.getCallingUserId()).getBoolean(
2545                UserManager.DISALLOW_REMOVE_USER, false)) {
2546            Log.w(LOG_TAG, "Cannot remove user. DISALLOW_REMOVE_USER is enabled.");
2547            return false;
2548        }
2549        return removeUserUnchecked(userHandle);
2550    }
2551
2552    private boolean removeUserUnchecked(int userHandle) {
2553        long ident = Binder.clearCallingIdentity();
2554        try {
2555            final UserData userData;
2556            int currentUser = ActivityManager.getCurrentUser();
2557            if (currentUser == userHandle) {
2558                Log.w(LOG_TAG, "Current user cannot be removed");
2559                return false;
2560            }
2561            synchronized (mPackagesLock) {
2562                synchronized (mUsersLock) {
2563                    userData = mUsers.get(userHandle);
2564                    if (userHandle == 0 || userData == null || mRemovingUserIds.get(userHandle)) {
2565                        return false;
2566                    }
2567
2568                    addRemovingUserIdLocked(userHandle);
2569                }
2570
2571                try {
2572                    mAppOpsService.removeUser(userHandle);
2573                } catch (RemoteException e) {
2574                    Log.w(LOG_TAG, "Unable to notify AppOpsService of removing user", e);
2575                }
2576                // Set this to a partially created user, so that the user will be purged
2577                // on next startup, in case the runtime stops now before stopping and
2578                // removing the user completely.
2579                userData.info.partial = true;
2580                // Mark it as disabled, so that it isn't returned any more when
2581                // profiles are queried.
2582                userData.info.flags |= UserInfo.FLAG_DISABLED;
2583                writeUserLP(userData);
2584            }
2585
2586            if (userData.info.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID
2587                    && userData.info.isManagedProfile()) {
2588                // Send broadcast to notify system that the user removed was a
2589                // managed user.
2590                sendProfileRemovedBroadcast(userData.info.profileGroupId, userData.info.id);
2591            }
2592
2593            if (DBG) Slog.i(LOG_TAG, "Stopping user " + userHandle);
2594            int res;
2595            try {
2596                res = ActivityManager.getService().stopUser(userHandle, /* force= */ true,
2597                new IStopUserCallback.Stub() {
2598                            @Override
2599                            public void userStopped(int userId) {
2600                                finishRemoveUser(userId);
2601                            }
2602                            @Override
2603                            public void userStopAborted(int userId) {
2604                            }
2605                        });
2606            } catch (RemoteException e) {
2607                return false;
2608            }
2609            return res == ActivityManager.USER_OP_SUCCESS;
2610        } finally {
2611            Binder.restoreCallingIdentity(ident);
2612        }
2613    }
2614
2615    @VisibleForTesting
2616    void addRemovingUserIdLocked(int userId) {
2617        // We remember deleted user IDs to prevent them from being
2618        // reused during the current boot; they can still be reused
2619        // after a reboot or recycling of userIds.
2620        mRemovingUserIds.put(userId, true);
2621        mRecentlyRemovedIds.add(userId);
2622        // Keep LRU queue of recently removed IDs for recycling
2623        if (mRecentlyRemovedIds.size() > MAX_RECENTLY_REMOVED_IDS_SIZE) {
2624            mRecentlyRemovedIds.removeFirst();
2625        }
2626    }
2627
2628    void finishRemoveUser(final int userHandle) {
2629        if (DBG) Slog.i(LOG_TAG, "finishRemoveUser " + userHandle);
2630        // Let other services shutdown any activity and clean up their state before completely
2631        // wiping the user's system directory and removing from the user list
2632        long ident = Binder.clearCallingIdentity();
2633        try {
2634            Intent addedIntent = new Intent(Intent.ACTION_USER_REMOVED);
2635            addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userHandle);
2636            mContext.sendOrderedBroadcastAsUser(addedIntent, UserHandle.ALL,
2637                    android.Manifest.permission.MANAGE_USERS,
2638
2639                    new BroadcastReceiver() {
2640                        @Override
2641                        public void onReceive(Context context, Intent intent) {
2642                            if (DBG) {
2643                                Slog.i(LOG_TAG,
2644                                        "USER_REMOVED broadcast sent, cleaning up user data "
2645                                        + userHandle);
2646                            }
2647                            new Thread() {
2648                                @Override
2649                                public void run() {
2650                                    // Clean up any ActivityManager state
2651                                    LocalServices.getService(ActivityManagerInternal.class)
2652                                            .onUserRemoved(userHandle);
2653                                    removeUserState(userHandle);
2654                                }
2655                            }.start();
2656                        }
2657                    },
2658
2659                    null, Activity.RESULT_OK, null, null);
2660        } finally {
2661            Binder.restoreCallingIdentity(ident);
2662        }
2663    }
2664
2665    private void removeUserState(final int userHandle) {
2666        try {
2667            mContext.getSystemService(StorageManager.class).destroyUserKey(userHandle);
2668        } catch (IllegalStateException e) {
2669            // This may be simply because the user was partially created.
2670            Slog.i(LOG_TAG,
2671                "Destroying key for user " + userHandle + " failed, continuing anyway", e);
2672        }
2673
2674        // Cleanup gatekeeper secure user id
2675        try {
2676            final IGateKeeperService gk = GateKeeper.getService();
2677            if (gk != null) {
2678                gk.clearSecureUserId(userHandle);
2679            }
2680        } catch (Exception ex) {
2681            Slog.w(LOG_TAG, "unable to clear GK secure user id");
2682        }
2683
2684        // Cleanup package manager settings
2685        mPm.cleanUpUser(this, userHandle);
2686
2687        // Clean up all data before removing metadata
2688        mPm.destroyUserData(userHandle,
2689                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
2690
2691        // Remove this user from the list
2692        synchronized (mUsersLock) {
2693            mUsers.remove(userHandle);
2694            mIsUserManaged.delete(userHandle);
2695        }
2696        synchronized (mUserStates) {
2697            mUserStates.delete(userHandle);
2698        }
2699        synchronized (mRestrictionsLock) {
2700            mBaseUserRestrictions.remove(userHandle);
2701            mAppliedUserRestrictions.remove(userHandle);
2702            mCachedEffectiveUserRestrictions.remove(userHandle);
2703            mDevicePolicyLocalUserRestrictions.remove(userHandle);
2704        }
2705        // Update the user list
2706        synchronized (mPackagesLock) {
2707            writeUserListLP();
2708        }
2709        // Remove user file
2710        AtomicFile userFile = new AtomicFile(new File(mUsersDir, userHandle + XML_SUFFIX));
2711        userFile.delete();
2712        updateUserIds();
2713        if (RELEASE_DELETED_USER_ID) {
2714            synchronized (mUsers) {
2715                mRemovingUserIds.delete(userHandle);
2716            }
2717        }
2718    }
2719
2720    private void sendProfileRemovedBroadcast(int parentUserId, int removedUserId) {
2721        Intent managedProfileIntent = new Intent(Intent.ACTION_MANAGED_PROFILE_REMOVED);
2722        managedProfileIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY |
2723                Intent.FLAG_RECEIVER_FOREGROUND);
2724        managedProfileIntent.putExtra(Intent.EXTRA_USER, new UserHandle(removedUserId));
2725        managedProfileIntent.putExtra(Intent.EXTRA_USER_HANDLE, removedUserId);
2726        mContext.sendBroadcastAsUser(managedProfileIntent, new UserHandle(parentUserId), null);
2727    }
2728
2729    @Override
2730    public Bundle getApplicationRestrictions(String packageName) {
2731        return getApplicationRestrictionsForUser(packageName, UserHandle.getCallingUserId());
2732    }
2733
2734    @Override
2735    public Bundle getApplicationRestrictionsForUser(String packageName, int userId) {
2736        if (UserHandle.getCallingUserId() != userId
2737                || !UserHandle.isSameApp(Binder.getCallingUid(), getUidForPackage(packageName))) {
2738            checkSystemOrRoot("get application restrictions for other users/apps");
2739        }
2740        synchronized (mPackagesLock) {
2741            // Read the restrictions from XML
2742            return readApplicationRestrictionsLP(packageName, userId);
2743        }
2744    }
2745
2746    @Override
2747    public void setApplicationRestrictions(String packageName, Bundle restrictions,
2748            int userId) {
2749        checkSystemOrRoot("set application restrictions");
2750        if (restrictions != null) {
2751            restrictions.setDefusable(true);
2752        }
2753        synchronized (mPackagesLock) {
2754            if (restrictions == null || restrictions.isEmpty()) {
2755                cleanAppRestrictionsForPackage(packageName, userId);
2756            } else {
2757                // Write the restrictions to XML
2758                writeApplicationRestrictionsLP(packageName, restrictions, userId);
2759            }
2760        }
2761
2762        // Notify package of changes via an intent - only sent to explicitly registered receivers.
2763        Intent changeIntent = new Intent(Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED);
2764        changeIntent.setPackage(packageName);
2765        changeIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
2766        mContext.sendBroadcastAsUser(changeIntent, UserHandle.of(userId));
2767    }
2768
2769    private int getUidForPackage(String packageName) {
2770        long ident = Binder.clearCallingIdentity();
2771        try {
2772            return mContext.getPackageManager().getApplicationInfo(packageName,
2773                    PackageManager.MATCH_UNINSTALLED_PACKAGES).uid;
2774        } catch (NameNotFoundException nnfe) {
2775            return -1;
2776        } finally {
2777            Binder.restoreCallingIdentity(ident);
2778        }
2779    }
2780
2781    private Bundle readApplicationRestrictionsLP(String packageName, int userId) {
2782        AtomicFile restrictionsFile =
2783                new AtomicFile(new File(Environment.getUserSystemDirectory(userId),
2784                        packageToRestrictionsFileName(packageName)));
2785        return readApplicationRestrictionsLP(restrictionsFile);
2786    }
2787
2788    @VisibleForTesting
2789    static Bundle readApplicationRestrictionsLP(AtomicFile restrictionsFile) {
2790        final Bundle restrictions = new Bundle();
2791        final ArrayList<String> values = new ArrayList<>();
2792        if (!restrictionsFile.getBaseFile().exists()) {
2793            return restrictions;
2794        }
2795
2796        FileInputStream fis = null;
2797        try {
2798            fis = restrictionsFile.openRead();
2799            XmlPullParser parser = Xml.newPullParser();
2800            parser.setInput(fis, StandardCharsets.UTF_8.name());
2801            XmlUtils.nextElement(parser);
2802            if (parser.getEventType() != XmlPullParser.START_TAG) {
2803                Slog.e(LOG_TAG, "Unable to read restrictions file "
2804                        + restrictionsFile.getBaseFile());
2805                return restrictions;
2806            }
2807            while (parser.next() != XmlPullParser.END_DOCUMENT) {
2808                readEntry(restrictions, values, parser);
2809            }
2810        } catch (IOException|XmlPullParserException e) {
2811            Log.w(LOG_TAG, "Error parsing " + restrictionsFile.getBaseFile(), e);
2812        } finally {
2813            IoUtils.closeQuietly(fis);
2814        }
2815        return restrictions;
2816    }
2817
2818    private static void readEntry(Bundle restrictions, ArrayList<String> values,
2819            XmlPullParser parser) throws XmlPullParserException, IOException {
2820        int type = parser.getEventType();
2821        if (type == XmlPullParser.START_TAG && parser.getName().equals(TAG_ENTRY)) {
2822            String key = parser.getAttributeValue(null, ATTR_KEY);
2823            String valType = parser.getAttributeValue(null, ATTR_VALUE_TYPE);
2824            String multiple = parser.getAttributeValue(null, ATTR_MULTIPLE);
2825            if (multiple != null) {
2826                values.clear();
2827                int count = Integer.parseInt(multiple);
2828                while (count > 0 && (type = parser.next()) != XmlPullParser.END_DOCUMENT) {
2829                    if (type == XmlPullParser.START_TAG
2830                            && parser.getName().equals(TAG_VALUE)) {
2831                        values.add(parser.nextText().trim());
2832                        count--;
2833                    }
2834                }
2835                String [] valueStrings = new String[values.size()];
2836                values.toArray(valueStrings);
2837                restrictions.putStringArray(key, valueStrings);
2838            } else if (ATTR_TYPE_BUNDLE.equals(valType)) {
2839                restrictions.putBundle(key, readBundleEntry(parser, values));
2840            } else if (ATTR_TYPE_BUNDLE_ARRAY.equals(valType)) {
2841                final int outerDepth = parser.getDepth();
2842                ArrayList<Bundle> bundleList = new ArrayList<>();
2843                while (XmlUtils.nextElementWithin(parser, outerDepth)) {
2844                    Bundle childBundle = readBundleEntry(parser, values);
2845                    bundleList.add(childBundle);
2846                }
2847                restrictions.putParcelableArray(key,
2848                        bundleList.toArray(new Bundle[bundleList.size()]));
2849            } else {
2850                String value = parser.nextText().trim();
2851                if (ATTR_TYPE_BOOLEAN.equals(valType)) {
2852                    restrictions.putBoolean(key, Boolean.parseBoolean(value));
2853                } else if (ATTR_TYPE_INTEGER.equals(valType)) {
2854                    restrictions.putInt(key, Integer.parseInt(value));
2855                } else {
2856                    restrictions.putString(key, value);
2857                }
2858            }
2859        }
2860    }
2861
2862    private static Bundle readBundleEntry(XmlPullParser parser, ArrayList<String> values)
2863            throws IOException, XmlPullParserException {
2864        Bundle childBundle = new Bundle();
2865        final int outerDepth = parser.getDepth();
2866        while (XmlUtils.nextElementWithin(parser, outerDepth)) {
2867            readEntry(childBundle, values, parser);
2868        }
2869        return childBundle;
2870    }
2871
2872    private void writeApplicationRestrictionsLP(String packageName,
2873            Bundle restrictions, int userId) {
2874        AtomicFile restrictionsFile = new AtomicFile(
2875                new File(Environment.getUserSystemDirectory(userId),
2876                        packageToRestrictionsFileName(packageName)));
2877        writeApplicationRestrictionsLP(restrictions, restrictionsFile);
2878    }
2879
2880    @VisibleForTesting
2881    static void writeApplicationRestrictionsLP(Bundle restrictions, AtomicFile restrictionsFile) {
2882        FileOutputStream fos = null;
2883        try {
2884            fos = restrictionsFile.startWrite();
2885            final BufferedOutputStream bos = new BufferedOutputStream(fos);
2886
2887            final XmlSerializer serializer = new FastXmlSerializer();
2888            serializer.setOutput(bos, StandardCharsets.UTF_8.name());
2889            serializer.startDocument(null, true);
2890            serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
2891
2892            serializer.startTag(null, TAG_RESTRICTIONS);
2893            writeBundle(restrictions, serializer);
2894            serializer.endTag(null, TAG_RESTRICTIONS);
2895
2896            serializer.endDocument();
2897            restrictionsFile.finishWrite(fos);
2898        } catch (Exception e) {
2899            restrictionsFile.failWrite(fos);
2900            Slog.e(LOG_TAG, "Error writing application restrictions list", e);
2901        }
2902    }
2903
2904    private static void writeBundle(Bundle restrictions, XmlSerializer serializer)
2905            throws IOException {
2906        for (String key : restrictions.keySet()) {
2907            Object value = restrictions.get(key);
2908            serializer.startTag(null, TAG_ENTRY);
2909            serializer.attribute(null, ATTR_KEY, key);
2910
2911            if (value instanceof Boolean) {
2912                serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_BOOLEAN);
2913                serializer.text(value.toString());
2914            } else if (value instanceof Integer) {
2915                serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_INTEGER);
2916                serializer.text(value.toString());
2917            } else if (value == null || value instanceof String) {
2918                serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_STRING);
2919                serializer.text(value != null ? (String) value : "");
2920            } else if (value instanceof Bundle) {
2921                serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_BUNDLE);
2922                writeBundle((Bundle) value, serializer);
2923            } else if (value instanceof Parcelable[]) {
2924                serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_BUNDLE_ARRAY);
2925                Parcelable[] array = (Parcelable[]) value;
2926                for (Parcelable parcelable : array) {
2927                    if (!(parcelable instanceof Bundle)) {
2928                        throw new IllegalArgumentException("bundle-array can only hold Bundles");
2929                    }
2930                    serializer.startTag(null, TAG_ENTRY);
2931                    serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_BUNDLE);
2932                    writeBundle((Bundle) parcelable, serializer);
2933                    serializer.endTag(null, TAG_ENTRY);
2934                }
2935            } else {
2936                serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_STRING_ARRAY);
2937                String[] values = (String[]) value;
2938                serializer.attribute(null, ATTR_MULTIPLE, Integer.toString(values.length));
2939                for (String choice : values) {
2940                    serializer.startTag(null, TAG_VALUE);
2941                    serializer.text(choice != null ? choice : "");
2942                    serializer.endTag(null, TAG_VALUE);
2943                }
2944            }
2945            serializer.endTag(null, TAG_ENTRY);
2946        }
2947    }
2948
2949    @Override
2950    public int getUserSerialNumber(int userHandle) {
2951        synchronized (mUsersLock) {
2952            if (!exists(userHandle)) return -1;
2953            return getUserInfoLU(userHandle).serialNumber;
2954        }
2955    }
2956
2957    @Override
2958    public int getUserHandle(int userSerialNumber) {
2959        synchronized (mUsersLock) {
2960            for (int userId : mUserIds) {
2961                UserInfo info = getUserInfoLU(userId);
2962                if (info != null && info.serialNumber == userSerialNumber) return userId;
2963            }
2964            // Not found
2965            return -1;
2966        }
2967    }
2968
2969    @Override
2970    public long getUserCreationTime(int userHandle) {
2971        int callingUserId = UserHandle.getCallingUserId();
2972        UserInfo userInfo = null;
2973        synchronized (mUsersLock) {
2974            if (callingUserId == userHandle) {
2975                userInfo = getUserInfoLU(userHandle);
2976            } else {
2977                UserInfo parent = getProfileParentLU(userHandle);
2978                if (parent != null && parent.id == callingUserId) {
2979                    userInfo = getUserInfoLU(userHandle);
2980                }
2981            }
2982        }
2983        if (userInfo == null) {
2984            throw new SecurityException("userHandle can only be the calling user or a managed "
2985                    + "profile associated with this user");
2986        }
2987        return userInfo.creationTime;
2988    }
2989
2990    /**
2991     * Caches the list of user ids in an array, adjusting the array size when necessary.
2992     */
2993    private void updateUserIds() {
2994        int num = 0;
2995        synchronized (mUsersLock) {
2996            final int userSize = mUsers.size();
2997            for (int i = 0; i < userSize; i++) {
2998                if (!mUsers.valueAt(i).info.partial) {
2999                    num++;
3000                }
3001            }
3002            final int[] newUsers = new int[num];
3003            int n = 0;
3004            for (int i = 0; i < userSize; i++) {
3005                if (!mUsers.valueAt(i).info.partial) {
3006                    newUsers[n++] = mUsers.keyAt(i);
3007                }
3008            }
3009            mUserIds = newUsers;
3010        }
3011    }
3012
3013    /**
3014     * Called right before a user is started. This gives us a chance to prepare
3015     * app storage and apply any user restrictions.
3016     */
3017    public void onBeforeStartUser(int userId) {
3018        UserInfo userInfo = getUserInfo(userId);
3019        if (userInfo == null) {
3020            return;
3021        }
3022        final int userSerial = userInfo.serialNumber;
3023        // Migrate only if build fingerprints mismatch
3024        boolean migrateAppsData = !Build.FINGERPRINT.equals(userInfo.lastLoggedInFingerprint);
3025        mPm.prepareUserData(userId, userSerial, StorageManager.FLAG_STORAGE_DE);
3026        mPm.reconcileAppsData(userId, StorageManager.FLAG_STORAGE_DE, migrateAppsData);
3027
3028        if (userId != UserHandle.USER_SYSTEM) {
3029            synchronized (mRestrictionsLock) {
3030                applyUserRestrictionsLR(userId);
3031            }
3032        }
3033
3034        maybeInitializeDemoMode(userId);
3035    }
3036
3037    /**
3038     * Called right before a user is unlocked. This gives us a chance to prepare
3039     * app storage.
3040     */
3041    public void onBeforeUnlockUser(@UserIdInt int userId) {
3042        UserInfo userInfo = getUserInfo(userId);
3043        if (userInfo == null) {
3044            return;
3045        }
3046        final int userSerial = userInfo.serialNumber;
3047        // Migrate only if build fingerprints mismatch
3048        boolean migrateAppsData = !Build.FINGERPRINT.equals(userInfo.lastLoggedInFingerprint);
3049        mPm.prepareUserData(userId, userSerial, StorageManager.FLAG_STORAGE_CE);
3050        mPm.reconcileAppsData(userId, StorageManager.FLAG_STORAGE_CE, migrateAppsData);
3051    }
3052
3053    /**
3054     * Make a note of the last started time of a user and do some cleanup.
3055     * This is called with ActivityManagerService lock held.
3056     * @param userId the user that was just foregrounded
3057     */
3058    public void onUserLoggedIn(@UserIdInt int userId) {
3059        UserData userData = getUserDataNoChecks(userId);
3060        if (userData == null || userData.info.partial) {
3061            Slog.w(LOG_TAG, "userForeground: unknown user #" + userId);
3062            return;
3063        }
3064
3065        final long now = System.currentTimeMillis();
3066        if (now > EPOCH_PLUS_30_YEARS) {
3067            userData.info.lastLoggedInTime = now;
3068        }
3069        userData.info.lastLoggedInFingerprint = Build.FINGERPRINT;
3070        scheduleWriteUser(userData);
3071    }
3072
3073    private void maybeInitializeDemoMode(int userId) {
3074        if (UserManager.isDeviceInDemoMode(mContext) && userId != UserHandle.USER_SYSTEM) {
3075            String demoLauncher =
3076                    mContext.getResources().getString(
3077                            com.android.internal.R.string.config_demoModeLauncherComponent);
3078            if (!TextUtils.isEmpty(demoLauncher)) {
3079                ComponentName componentToEnable = ComponentName.unflattenFromString(demoLauncher);
3080                String demoLauncherPkg = componentToEnable.getPackageName();
3081                try {
3082                    final IPackageManager iPm = AppGlobals.getPackageManager();
3083                    iPm.setComponentEnabledSetting(componentToEnable,
3084                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, /* flags= */ 0,
3085                            /* userId= */ userId);
3086                    iPm.setApplicationEnabledSetting(demoLauncherPkg,
3087                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, /* flags= */ 0,
3088                            /* userId= */ userId, null);
3089                } catch (RemoteException re) {
3090                    // Internal, shouldn't happen
3091                }
3092            }
3093        }
3094    }
3095
3096    /**
3097     * Returns the next available user id, filling in any holes in the ids.
3098     */
3099    @VisibleForTesting
3100    int getNextAvailableId() {
3101        int nextId;
3102        synchronized (mUsersLock) {
3103            nextId = scanNextAvailableIdLocked();
3104            if (nextId >= 0) {
3105                return nextId;
3106            }
3107            // All ids up to MAX_USER_ID were used. Remove all mRemovingUserIds,
3108            // except most recently removed
3109            if (mRemovingUserIds.size() > 0) {
3110                Slog.i(LOG_TAG, "All available IDs are used. Recycling LRU ids.");
3111                mRemovingUserIds.clear();
3112                for (Integer recentlyRemovedId : mRecentlyRemovedIds) {
3113                    mRemovingUserIds.put(recentlyRemovedId, true);
3114                }
3115                nextId = scanNextAvailableIdLocked();
3116            }
3117        }
3118        if (nextId < 0) {
3119            throw new IllegalStateException("No user id available!");
3120        }
3121        return nextId;
3122    }
3123
3124    private int scanNextAvailableIdLocked() {
3125        for (int i = MIN_USER_ID; i < MAX_USER_ID; i++) {
3126            if (mUsers.indexOfKey(i) < 0 && !mRemovingUserIds.get(i)) {
3127                return i;
3128            }
3129        }
3130        return -1;
3131    }
3132
3133    private String packageToRestrictionsFileName(String packageName) {
3134        return RESTRICTIONS_FILE_PREFIX + packageName + XML_SUFFIX;
3135    }
3136
3137    /**
3138     * Enforce that serial number stored in user directory inode matches the
3139     * given expected value. Gracefully sets the serial number if currently
3140     * undefined.
3141     *
3142     * @throws IOException when problem extracting serial number, or serial
3143     *             number is mismatched.
3144     */
3145    public static void enforceSerialNumber(File file, int serialNumber) throws IOException {
3146        if (StorageManager.isFileEncryptedEmulatedOnly()) {
3147            // When we're emulating FBE, the directory may have been chmod
3148            // 000'ed, meaning we can't read the serial number to enforce it;
3149            // instead of destroying the user, just log a warning.
3150            Slog.w(LOG_TAG, "Device is emulating FBE; assuming current serial number is valid");
3151            return;
3152        }
3153
3154        final int foundSerial = getSerialNumber(file);
3155        Slog.v(LOG_TAG, "Found " + file + " with serial number " + foundSerial);
3156
3157        if (foundSerial == -1) {
3158            Slog.d(LOG_TAG, "Serial number missing on " + file + "; assuming current is valid");
3159            try {
3160                setSerialNumber(file, serialNumber);
3161            } catch (IOException e) {
3162                Slog.w(LOG_TAG, "Failed to set serial number on " + file, e);
3163            }
3164
3165        } else if (foundSerial != serialNumber) {
3166            throw new IOException("Found serial number " + foundSerial
3167                    + " doesn't match expected " + serialNumber);
3168        }
3169    }
3170
3171    /**
3172     * Set serial number stored in user directory inode.
3173     *
3174     * @throws IOException if serial number was already set
3175     */
3176    private static void setSerialNumber(File file, int serialNumber)
3177            throws IOException {
3178        try {
3179            final byte[] buf = Integer.toString(serialNumber).getBytes(StandardCharsets.UTF_8);
3180            Os.setxattr(file.getAbsolutePath(), XATTR_SERIAL, buf, OsConstants.XATTR_CREATE);
3181        } catch (ErrnoException e) {
3182            throw e.rethrowAsIOException();
3183        }
3184    }
3185
3186    /**
3187     * Return serial number stored in user directory inode.
3188     *
3189     * @return parsed serial number, or -1 if not set
3190     */
3191    private static int getSerialNumber(File file) throws IOException {
3192        try {
3193            final byte[] buf = Os.getxattr(file.getAbsolutePath(), XATTR_SERIAL);
3194            final String serial = new String(buf);
3195            try {
3196                return Integer.parseInt(serial);
3197            } catch (NumberFormatException e) {
3198                throw new IOException("Bad serial number: " + serial);
3199            }
3200        } catch (ErrnoException e) {
3201            if (e.errno == OsConstants.ENODATA) {
3202                return -1;
3203            } else {
3204                throw e.rethrowAsIOException();
3205            }
3206        }
3207    }
3208
3209    @Override
3210    public void setSeedAccountData(int userId, String accountName, String accountType,
3211            PersistableBundle accountOptions, boolean persist) {
3212        checkManageUsersPermission("Require MANAGE_USERS permission to set user seed data");
3213        synchronized (mPackagesLock) {
3214            final UserData userData;
3215            synchronized (mUsersLock) {
3216                userData = getUserDataLU(userId);
3217                if (userData == null) {
3218                    Slog.e(LOG_TAG, "No such user for settings seed data u=" + userId);
3219                    return;
3220                }
3221                userData.seedAccountName = accountName;
3222                userData.seedAccountType = accountType;
3223                userData.seedAccountOptions = accountOptions;
3224                userData.persistSeedData = persist;
3225            }
3226            if (persist) {
3227                writeUserLP(userData);
3228            }
3229        }
3230    }
3231
3232    @Override
3233    public String getSeedAccountName() throws RemoteException {
3234        checkManageUsersPermission("Cannot get seed account information");
3235        synchronized (mUsersLock) {
3236            UserData userData = getUserDataLU(UserHandle.getCallingUserId());
3237            return userData.seedAccountName;
3238        }
3239    }
3240
3241    @Override
3242    public String getSeedAccountType() throws RemoteException {
3243        checkManageUsersPermission("Cannot get seed account information");
3244        synchronized (mUsersLock) {
3245            UserData userData = getUserDataLU(UserHandle.getCallingUserId());
3246            return userData.seedAccountType;
3247        }
3248    }
3249
3250    @Override
3251    public PersistableBundle getSeedAccountOptions() throws RemoteException {
3252        checkManageUsersPermission("Cannot get seed account information");
3253        synchronized (mUsersLock) {
3254            UserData userData = getUserDataLU(UserHandle.getCallingUserId());
3255            return userData.seedAccountOptions;
3256        }
3257    }
3258
3259    @Override
3260    public void clearSeedAccountData() throws RemoteException {
3261        checkManageUsersPermission("Cannot clear seed account information");
3262        synchronized (mPackagesLock) {
3263            UserData userData;
3264            synchronized (mUsersLock) {
3265                userData = getUserDataLU(UserHandle.getCallingUserId());
3266                if (userData == null) return;
3267                userData.clearSeedAccountData();
3268            }
3269            writeUserLP(userData);
3270        }
3271    }
3272
3273    @Override
3274    public boolean someUserHasSeedAccount(String accountName, String accountType)
3275            throws RemoteException {
3276        checkManageUsersPermission("Cannot check seed account information");
3277        synchronized (mUsersLock) {
3278            final int userSize = mUsers.size();
3279            for (int i = 0; i < userSize; i++) {
3280                final UserData data = mUsers.valueAt(i);
3281                if (data.info.isInitialized()) continue;
3282                if (data.seedAccountName == null || !data.seedAccountName.equals(accountName)) {
3283                    continue;
3284                }
3285                if (data.seedAccountType == null || !data.seedAccountType.equals(accountType)) {
3286                    continue;
3287                }
3288                return true;
3289            }
3290        }
3291        return false;
3292    }
3293
3294    @Override
3295    public void onShellCommand(FileDescriptor in, FileDescriptor out,
3296            FileDescriptor err, String[] args, ShellCallback callback,
3297            ResultReceiver resultReceiver) {
3298        (new Shell()).exec(this, in, out, err, args, callback, resultReceiver);
3299    }
3300
3301    int onShellCommand(Shell shell, String cmd) {
3302        if (cmd == null) {
3303            return shell.handleDefaultCommands(cmd);
3304        }
3305
3306        final PrintWriter pw = shell.getOutPrintWriter();
3307        try {
3308            switch(cmd) {
3309                case "list":
3310                    return runList(pw);
3311            }
3312        } catch (RemoteException e) {
3313            pw.println("Remote exception: " + e);
3314        }
3315        return -1;
3316    }
3317
3318    private int runList(PrintWriter pw) throws RemoteException {
3319        final IActivityManager am = ActivityManager.getService();
3320        final List<UserInfo> users = getUsers(false);
3321        if (users == null) {
3322            pw.println("Error: couldn't get users");
3323            return 1;
3324        } else {
3325            pw.println("Users:");
3326            for (int i = 0; i < users.size(); i++) {
3327                String running = am.isUserRunning(users.get(i).id, 0) ? " running" : "";
3328                pw.println("\t" + users.get(i).toString() + running);
3329            }
3330            return 0;
3331        }
3332    }
3333
3334    @Override
3335    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
3336        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
3337                != PackageManager.PERMISSION_GRANTED) {
3338            pw.println("Permission Denial: can't dump UserManager from from pid="
3339                    + Binder.getCallingPid()
3340                    + ", uid=" + Binder.getCallingUid()
3341                    + " without permission "
3342                    + android.Manifest.permission.DUMP);
3343            return;
3344        }
3345
3346        long now = System.currentTimeMillis();
3347        StringBuilder sb = new StringBuilder();
3348        synchronized (mPackagesLock) {
3349            synchronized (mUsersLock) {
3350                pw.println("Users:");
3351                for (int i = 0; i < mUsers.size(); i++) {
3352                    UserData userData = mUsers.valueAt(i);
3353                    if (userData == null) {
3354                        continue;
3355                    }
3356                    UserInfo userInfo = userData.info;
3357                    final int userId = userInfo.id;
3358                    pw.print("  "); pw.print(userInfo);
3359                    pw.print(" serialNo="); pw.print(userInfo.serialNumber);
3360                    if (mRemovingUserIds.get(userId)) {
3361                        pw.print(" <removing> ");
3362                    }
3363                    if (userInfo.partial) {
3364                        pw.print(" <partial>");
3365                    }
3366                    pw.println();
3367                    pw.print("    Created: ");
3368                    if (userInfo.creationTime == 0) {
3369                        pw.println("<unknown>");
3370                    } else {
3371                        sb.setLength(0);
3372                        TimeUtils.formatDuration(now - userInfo.creationTime, sb);
3373                        sb.append(" ago");
3374                        pw.println(sb);
3375                    }
3376                    pw.print("    Last logged in: ");
3377                    if (userInfo.lastLoggedInTime == 0) {
3378                        pw.println("<unknown>");
3379                    } else {
3380                        sb.setLength(0);
3381                        TimeUtils.formatDuration(now - userInfo.lastLoggedInTime, sb);
3382                        sb.append(" ago");
3383                        pw.println(sb);
3384                    }
3385                    pw.print("    Last logged in fingerprint: ");
3386                    pw.println(userInfo.lastLoggedInFingerprint);
3387                    pw.print("    Has profile owner: ");
3388                    pw.println(mIsUserManaged.get(userId));
3389                    pw.println("    Restrictions:");
3390                    synchronized (mRestrictionsLock) {
3391                        UserRestrictionsUtils.dumpRestrictions(
3392                                pw, "      ", mBaseUserRestrictions.get(userInfo.id));
3393                        pw.println("    Device policy local restrictions:");
3394                        UserRestrictionsUtils.dumpRestrictions(
3395                                pw, "      ", mDevicePolicyLocalUserRestrictions.get(userInfo.id));
3396                        pw.println("    Effective restrictions:");
3397                        UserRestrictionsUtils.dumpRestrictions(
3398                                pw, "      ", mCachedEffectiveUserRestrictions.get(userInfo.id));
3399                    }
3400
3401                    if (userData.account != null) {
3402                        pw.print("    Account name: " + userData.account);
3403                        pw.println();
3404                    }
3405
3406                    if (userData.seedAccountName != null) {
3407                        pw.print("    Seed account name: " + userData.seedAccountName);
3408                        pw.println();
3409                        if (userData.seedAccountType != null) {
3410                            pw.print("         account type: " + userData.seedAccountType);
3411                            pw.println();
3412                        }
3413                        if (userData.seedAccountOptions != null) {
3414                            pw.print("         account options exist");
3415                            pw.println();
3416                        }
3417                    }
3418                }
3419            }
3420            pw.println();
3421            pw.println("  Device policy global restrictions:");
3422            synchronized (mRestrictionsLock) {
3423                UserRestrictionsUtils
3424                        .dumpRestrictions(pw, "    ", mDevicePolicyGlobalUserRestrictions);
3425            }
3426            pw.println();
3427            pw.println("  Global restrictions owner id:" + mGlobalRestrictionOwnerUserId);
3428            pw.println();
3429            pw.println("  Guest restrictions:");
3430            synchronized (mGuestRestrictions) {
3431                UserRestrictionsUtils.dumpRestrictions(pw, "    ", mGuestRestrictions);
3432            }
3433            synchronized (mUsersLock) {
3434                pw.println();
3435                pw.println("  Device managed: " + mIsDeviceManaged);
3436                if (mRemovingUserIds.size() > 0) {
3437                    pw.println();
3438                    pw.println("  Recently removed userIds: " + mRecentlyRemovedIds);
3439                }
3440            }
3441            synchronized (mUserStates) {
3442                pw.println("  Started users state: " + mUserStates);
3443            }
3444            // Dump some capabilities
3445            pw.println();
3446            pw.println("  Max users: " + UserManager.getMaxSupportedUsers());
3447            pw.println("  Supports switchable users: " + UserManager.supportsMultipleUsers());
3448            pw.println("  All guests ephemeral: " + Resources.getSystem().getBoolean(
3449                    com.android.internal.R.bool.config_guestUserEphemeral));
3450        }
3451    }
3452
3453    final class MainHandler extends Handler {
3454
3455        @Override
3456        public void handleMessage(Message msg) {
3457            switch (msg.what) {
3458                case WRITE_USER_MSG:
3459                    removeMessages(WRITE_USER_MSG, msg.obj);
3460                    synchronized (mPackagesLock) {
3461                        int userId = ((UserData) msg.obj).info.id;
3462                        UserData userData = getUserDataNoChecks(userId);
3463                        if (userData != null) {
3464                            writeUserLP(userData);
3465                        }
3466                    }
3467            }
3468        }
3469    }
3470
3471    /**
3472     * @param userId
3473     * @return whether the user has been initialized yet
3474     */
3475    boolean isInitialized(int userId) {
3476        return (getUserInfo(userId).flags & UserInfo.FLAG_INITIALIZED) != 0;
3477    }
3478
3479    private class LocalService extends UserManagerInternal {
3480        @Override
3481        public void setDevicePolicyUserRestrictions(int userId, @NonNull Bundle localRestrictions,
3482                @Nullable Bundle globalRestrictions) {
3483            UserManagerService.this.setDevicePolicyUserRestrictionsInner(userId, localRestrictions,
3484                    globalRestrictions);
3485        }
3486
3487        @Override
3488        public Bundle getBaseUserRestrictions(int userId) {
3489            synchronized (mRestrictionsLock) {
3490                return mBaseUserRestrictions.get(userId);
3491            }
3492        }
3493
3494        @Override
3495        public void setBaseUserRestrictionsByDpmsForMigration(
3496                int userId, Bundle baseRestrictions) {
3497            synchronized (mRestrictionsLock) {
3498                mBaseUserRestrictions.put(userId, new Bundle(baseRestrictions));
3499                invalidateEffectiveUserRestrictionsLR(userId);
3500            }
3501
3502            final UserData userData = getUserDataNoChecks(userId);
3503            synchronized (mPackagesLock) {
3504                if (userData != null) {
3505                    writeUserLP(userData);
3506                } else {
3507                    Slog.w(LOG_TAG, "UserInfo not found for " + userId);
3508                }
3509            }
3510        }
3511
3512        @Override
3513        public boolean getUserRestriction(int userId, String key) {
3514            return getUserRestrictions(userId).getBoolean(key);
3515        }
3516
3517        @Override
3518        public void addUserRestrictionsListener(UserRestrictionsListener listener) {
3519            synchronized (mUserRestrictionsListeners) {
3520                mUserRestrictionsListeners.add(listener);
3521            }
3522        }
3523
3524        @Override
3525        public void removeUserRestrictionsListener(UserRestrictionsListener listener) {
3526            synchronized (mUserRestrictionsListeners) {
3527                mUserRestrictionsListeners.remove(listener);
3528            }
3529        }
3530
3531        @Override
3532        public void setDeviceManaged(boolean isManaged) {
3533            synchronized (mUsersLock) {
3534                mIsDeviceManaged = isManaged;
3535            }
3536        }
3537
3538        @Override
3539        public void setUserManaged(int userId, boolean isManaged) {
3540            synchronized (mUsersLock) {
3541                mIsUserManaged.put(userId, isManaged);
3542            }
3543        }
3544
3545        @Override
3546        public void setUserIcon(int userId, Bitmap bitmap) {
3547            long ident = Binder.clearCallingIdentity();
3548            try {
3549                synchronized (mPackagesLock) {
3550                    UserData userData = getUserDataNoChecks(userId);
3551                    if (userData == null || userData.info.partial) {
3552                        Slog.w(LOG_TAG, "setUserIcon: unknown user #" + userId);
3553                        return;
3554                    }
3555                    writeBitmapLP(userData.info, bitmap);
3556                    writeUserLP(userData);
3557                }
3558                sendUserInfoChangedBroadcast(userId);
3559            } finally {
3560                Binder.restoreCallingIdentity(ident);
3561            }
3562        }
3563
3564        @Override
3565        public void setForceEphemeralUsers(boolean forceEphemeralUsers) {
3566            synchronized (mUsersLock) {
3567                mForceEphemeralUsers = forceEphemeralUsers;
3568            }
3569        }
3570
3571        @Override
3572        public void removeAllUsers() {
3573            if (UserHandle.USER_SYSTEM == ActivityManager.getCurrentUser()) {
3574                // Remove the non-system users straight away.
3575                removeNonSystemUsers();
3576            } else {
3577                // Switch to the system user first and then remove the other users.
3578                BroadcastReceiver userSwitchedReceiver = new BroadcastReceiver() {
3579                    @Override
3580                    public void onReceive(Context context, Intent intent) {
3581                        int userId =
3582                                intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
3583                        if (userId != UserHandle.USER_SYSTEM) {
3584                            return;
3585                        }
3586                        mContext.unregisterReceiver(this);
3587                        removeNonSystemUsers();
3588                    }
3589                };
3590                IntentFilter userSwitchedFilter = new IntentFilter();
3591                userSwitchedFilter.addAction(Intent.ACTION_USER_SWITCHED);
3592                mContext.registerReceiver(
3593                        userSwitchedReceiver, userSwitchedFilter, null, mHandler);
3594
3595                // Switch to the system user.
3596                ActivityManager am =
3597                        (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
3598                am.switchUser(UserHandle.USER_SYSTEM);
3599            }
3600        }
3601
3602        @Override
3603        public void onEphemeralUserStop(int userId) {
3604            synchronized (mUsersLock) {
3605               UserInfo userInfo = getUserInfoLU(userId);
3606               if (userInfo != null && userInfo.isEphemeral()) {
3607                    // Do not allow switching back to the ephemeral user again as the user is going
3608                    // to be deleted.
3609                    userInfo.flags |= UserInfo.FLAG_DISABLED;
3610                    if (userInfo.isGuest()) {
3611                        // Indicate that the guest will be deleted after it stops.
3612                        userInfo.guestToRemove = true;
3613                    }
3614               }
3615            }
3616        }
3617
3618        @Override
3619        public UserInfo createUserEvenWhenDisallowed(String name, int flags) {
3620            UserInfo user = createUserInternalUnchecked(name, flags, UserHandle.USER_NULL, null);
3621            // Keep this in sync with UserManager.createUser
3622            if (user != null && !user.isAdmin()) {
3623                setUserRestriction(UserManager.DISALLOW_SMS, true, user.id);
3624                setUserRestriction(UserManager.DISALLOW_OUTGOING_CALLS, true, user.id);
3625            }
3626            return user;
3627        }
3628
3629        @Override
3630        public boolean removeUserEvenWhenDisallowed(int userId) {
3631            return removeUserUnchecked(userId);
3632        }
3633
3634        @Override
3635        public boolean isUserRunning(int userId) {
3636            synchronized (mUserStates) {
3637                return mUserStates.get(userId, -1) >= 0;
3638            }
3639        }
3640
3641        @Override
3642        public void setUserState(int userId, int userState) {
3643            synchronized (mUserStates) {
3644                mUserStates.put(userId, userState);
3645            }
3646        }
3647
3648        @Override
3649        public void removeUserState(int userId) {
3650            synchronized (mUserStates) {
3651                mUserStates.delete(userId);
3652            }
3653        }
3654
3655        @Override
3656        public boolean isUserUnlockingOrUnlocked(int userId) {
3657            synchronized (mUserStates) {
3658                int state = mUserStates.get(userId, -1);
3659                return (state == UserState.STATE_RUNNING_UNLOCKING)
3660                        || (state == UserState.STATE_RUNNING_UNLOCKED);
3661            }
3662        }
3663
3664        @Override
3665        public boolean isUserUnlocked(int userId) {
3666            synchronized (mUserStates) {
3667                int state = mUserStates.get(userId, -1);
3668                return state == UserState.STATE_RUNNING_UNLOCKED;
3669            }
3670        }
3671    }
3672
3673    /* Remove all the users except of the system one. */
3674    private void removeNonSystemUsers() {
3675        ArrayList<UserInfo> usersToRemove = new ArrayList<>();
3676        synchronized (mUsersLock) {
3677            final int userSize = mUsers.size();
3678            for (int i = 0; i < userSize; i++) {
3679                UserInfo ui = mUsers.valueAt(i).info;
3680                if (ui.id != UserHandle.USER_SYSTEM) {
3681                    usersToRemove.add(ui);
3682                }
3683            }
3684        }
3685        for (UserInfo ui: usersToRemove) {
3686            removeUser(ui.id);
3687        }
3688    }
3689
3690    private class Shell extends ShellCommand {
3691        @Override
3692        public int onCommand(String cmd) {
3693            return onShellCommand(this, cmd);
3694        }
3695
3696        @Override
3697        public void onHelp() {
3698            final PrintWriter pw = getOutPrintWriter();
3699            pw.println("User manager (user) commands:");
3700            pw.println("  help");
3701            pw.println("    Print this help text.");
3702            pw.println("");
3703            pw.println("  list");
3704            pw.println("    Prints all users on the system.");
3705        }
3706    }
3707
3708    private static void debug(String message) {
3709        Log.d(LOG_TAG, message +
3710                (DBG_WITH_STACKTRACE ? " called at\n" + Debug.getCallers(10, "  ") : ""));
3711    }
3712
3713    @VisibleForTesting
3714    static int getMaxManagedProfiles() {
3715        // Allow overriding max managed profiles on debuggable builds for testing
3716        // of multiple profiles.
3717        if (!Build.IS_DEBUGGABLE) {
3718            return MAX_MANAGED_PROFILES;
3719        } else {
3720            return SystemProperties.getInt("persist.sys.max_profiles",
3721                    MAX_MANAGED_PROFILES);
3722        }
3723    }
3724
3725    @VisibleForTesting
3726    int getFreeProfileBadgeLU(int parentUserId) {
3727        int maxManagedProfiles = getMaxManagedProfiles();
3728        boolean[] usedBadges = new boolean[maxManagedProfiles];
3729        final int userSize = mUsers.size();
3730        for (int i = 0; i < userSize; i++) {
3731            UserInfo ui = mUsers.valueAt(i).info;
3732            // Check which badge indexes are already used by this profile group.
3733            if (ui.isManagedProfile()
3734                    && ui.profileGroupId == parentUserId
3735                    && !mRemovingUserIds.get(ui.id)
3736                    && ui.profileBadge < maxManagedProfiles) {
3737                usedBadges[ui.profileBadge] = true;
3738            }
3739        }
3740        for (int i = 0; i < maxManagedProfiles; i++) {
3741            if (!usedBadges[i]) {
3742                return i;
3743            }
3744        }
3745        return 0;
3746    }
3747}
3748