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