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