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