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