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