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