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