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