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