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