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