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