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