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