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