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.ColorRes;
24 import android.annotation.DrawableRes;
25 import android.annotation.NonNull;
26 import android.annotation.Nullable;
27 import android.annotation.StringRes;
28 import android.annotation.UserIdInt;
29 import android.app.Activity;
30 import android.app.ActivityManager;
31 import android.app.ActivityManagerInternal;
32 import android.app.ActivityManagerNative;
33 import android.app.IActivityManager;
34 import android.app.IStopUserCallback;
35 import android.app.KeyguardManager;
36 import android.app.PendingIntent;
37 import android.app.admin.DevicePolicyEventLogger;
38 import android.app.admin.DevicePolicyManagerInternal;
39 import android.content.BroadcastReceiver;
40 import android.content.Context;
41 import android.content.Intent;
42 import android.content.IntentFilter;
43 import android.content.IntentSender;
44 import android.content.pm.PackageManager;
45 import android.content.pm.PackageManager.NameNotFoundException;
46 import android.content.pm.PackageManagerInternal;
47 import android.content.pm.ShortcutServiceInternal;
48 import android.content.pm.UserInfo;
49 import android.content.pm.UserInfo.UserInfoFlag;
50 import android.content.res.Configuration;
51 import android.content.res.Resources;
52 import android.graphics.Bitmap;
53 import android.os.Binder;
54 import android.os.Build;
55 import android.os.Bundle;
56 import android.os.Debug;
57 import android.os.Environment;
58 import android.os.FileUtils;
59 import android.os.Handler;
60 import android.os.IBinder;
61 import android.os.IProgressListener;
62 import android.os.IUserManager;
63 import android.os.IUserRestrictionsListener;
64 import android.os.Message;
65 import android.os.ParcelFileDescriptor;
66 import android.os.Parcelable;
67 import android.os.PersistableBundle;
68 import android.os.Process;
69 import android.os.RemoteException;
70 import android.os.ResultReceiver;
71 import android.os.SELinux;
72 import android.os.ServiceManager;
73 import android.os.ServiceSpecificException;
74 import android.os.ShellCallback;
75 import android.os.ShellCommand;
76 import android.os.SystemClock;
77 import android.os.SystemProperties;
78 import android.os.UserHandle;
79 import android.os.UserManager;
80 import android.os.UserManager.EnforcingUser;
81 import android.os.UserManager.QuietModeFlag;
82 import android.os.storage.StorageManager;
83 import android.os.storage.StorageManagerInternal;
84 import android.provider.Settings;
85 import android.security.GateKeeper;
86 import android.service.gatekeeper.IGateKeeperService;
87 import android.stats.devicepolicy.DevicePolicyEnums;
88 import android.util.ArrayMap;
89 import android.util.ArraySet;
90 import android.util.AtomicFile;
91 import android.util.IndentingPrintWriter;
92 import android.util.IntArray;
93 import android.util.Slog;
94 import android.util.SparseArray;
95 import android.util.SparseBooleanArray;
96 import android.util.SparseIntArray;
97 import android.util.TimeUtils;
98 import android.util.TypedValue;
99 import android.util.TypedXmlPullParser;
100 import android.util.TypedXmlSerializer;
101 import android.util.Xml;
102 
103 import com.android.internal.annotations.GuardedBy;
104 import com.android.internal.annotations.VisibleForTesting;
105 import com.android.internal.app.IAppOpsService;
106 import com.android.internal.logging.MetricsLogger;
107 import com.android.internal.os.BackgroundThread;
108 import com.android.internal.util.DumpUtils;
109 import com.android.internal.util.FrameworkStatsLog;
110 import com.android.internal.util.Preconditions;
111 import com.android.internal.util.XmlUtils;
112 import com.android.internal.widget.LockPatternUtils;
113 import com.android.server.BundleUtils;
114 import com.android.server.LocalServices;
115 import com.android.server.LockGuard;
116 import com.android.server.SystemService;
117 import com.android.server.am.UserState;
118 import com.android.server.pm.UserManagerInternal.UserLifecycleListener;
119 import com.android.server.pm.UserManagerInternal.UserRestrictionsListener;
120 import com.android.server.storage.DeviceStorageMonitorInternal;
121 import com.android.server.utils.TimingsTraceAndSlog;
122 import com.android.server.wm.ActivityTaskManagerInternal;
123 
124 import libcore.io.IoUtils;
125 
126 import org.xmlpull.v1.XmlPullParser;
127 import org.xmlpull.v1.XmlPullParserException;
128 
129 import java.io.File;
130 import java.io.FileDescriptor;
131 import java.io.FileInputStream;
132 import java.io.FileNotFoundException;
133 import java.io.FileOutputStream;
134 import java.io.IOException;
135 import java.io.InputStream;
136 import java.io.OutputStream;
137 import java.io.PrintWriter;
138 import java.util.ArrayList;
139 import java.util.Arrays;
140 import java.util.Collections;
141 import java.util.LinkedList;
142 import java.util.List;
143 import java.util.Objects;
144 import java.util.Set;
145 import java.util.concurrent.ThreadLocalRandom;
146 import java.util.concurrent.atomic.AtomicInteger;
147 import java.util.concurrent.atomic.AtomicReference;
148 
149 /**
150  * Service for {@link UserManager}.
151  *
152  * Method naming convention:
153  * <ul>
154  * <li> Methods suffixed with "LAr" should be called within the {@link #mAppRestrictionsLock} lock.
155  * <li> Methods suffixed with "LP" should be called within the {@link #mPackagesLock} lock.
156  * <li> Methods suffixed with "LR" should be called within the {@link #mRestrictionsLock} lock.
157  * <li> Methods suffixed with "LU" should be called within the {@link #mUsersLock} lock.
158  * </ul>
159  */
160 public class UserManagerService extends IUserManager.Stub {
161 
162     private static final String LOG_TAG = "UserManagerService";
163     static final boolean DBG = false; // DO NOT SUBMIT WITH TRUE
164     private static final boolean DBG_WITH_STACKTRACE = false; // DO NOT SUBMIT WITH TRUE
165     // Can be used for manual testing of id recycling
166     private static final boolean RELEASE_DELETED_USER_ID = false; // DO NOT SUBMIT WITH TRUE
167 
168     private static final String TAG_NAME = "name";
169     private static final String TAG_ACCOUNT = "account";
170     private static final String ATTR_FLAGS = "flags";
171     private static final String ATTR_TYPE = "type";
172     private static final String ATTR_ICON_PATH = "icon";
173     private static final String ATTR_ID = "id";
174     private static final String ATTR_CREATION_TIME = "created";
175     private static final String ATTR_LAST_LOGGED_IN_TIME = "lastLoggedIn";
176     private static final String ATTR_LAST_LOGGED_IN_FINGERPRINT = "lastLoggedInFingerprint";
177     private static final String ATTR_SERIAL_NO = "serialNumber";
178     private static final String ATTR_NEXT_SERIAL_NO = "nextSerialNumber";
179     private static final String ATTR_PARTIAL = "partial";
180     private static final String ATTR_PRE_CREATED = "preCreated";
181     private static final String ATTR_CONVERTED_FROM_PRE_CREATED = "convertedFromPreCreated";
182     private static final String ATTR_GUEST_TO_REMOVE = "guestToRemove";
183     private static final String ATTR_USER_VERSION = "version";
184     private static final String ATTR_USER_TYPE_VERSION = "userTypeConfigVersion";
185     private static final String ATTR_PROFILE_GROUP_ID = "profileGroupId";
186     private static final String ATTR_PROFILE_BADGE = "profileBadge";
187     private static final String ATTR_RESTRICTED_PROFILE_PARENT_ID = "restrictedProfileParentId";
188     private static final String ATTR_SEED_ACCOUNT_NAME = "seedAccountName";
189     private static final String ATTR_SEED_ACCOUNT_TYPE = "seedAccountType";
190     private static final String TAG_GUEST_RESTRICTIONS = "guestRestrictions";
191     private static final String TAG_USERS = "users";
192     private static final String TAG_USER = "user";
193     private static final String TAG_RESTRICTIONS = "restrictions";
194     private static final String TAG_DEVICE_POLICY_RESTRICTIONS = "device_policy_restrictions";
195     private static final String TAG_DEVICE_POLICY_LOCAL_RESTRICTIONS =
196             "device_policy_local_restrictions";
197     private static final String TAG_DEVICE_POLICY_GLOBAL_RESTRICTIONS =
198             "device_policy_global_restrictions";
199     /** Legacy name for device owner id tag. */
200     private static final String TAG_GLOBAL_RESTRICTION_OWNER_ID = "globalRestrictionOwnerUserId";
201     private static final String TAG_DEVICE_OWNER_USER_ID = "deviceOwnerUserId";
202     private static final String TAG_ENTRY = "entry";
203     private static final String TAG_VALUE = "value";
204     private static final String TAG_SEED_ACCOUNT_OPTIONS = "seedAccountOptions";
205     private static final String TAG_LAST_REQUEST_QUIET_MODE_ENABLED_CALL =
206             "lastRequestQuietModeEnabledCall";
207     private static final String ATTR_KEY = "key";
208     private static final String ATTR_VALUE_TYPE = "type";
209     private static final String ATTR_MULTIPLE = "m";
210 
211     private static final String ATTR_TYPE_STRING_ARRAY = "sa";
212     private static final String ATTR_TYPE_STRING = "s";
213     private static final String ATTR_TYPE_BOOLEAN = "b";
214     private static final String ATTR_TYPE_INTEGER = "i";
215     private static final String ATTR_TYPE_BUNDLE = "B";
216     private static final String ATTR_TYPE_BUNDLE_ARRAY = "BA";
217 
218     private static final String USER_INFO_DIR = "system" + File.separator + "users";
219     private static final String USER_LIST_FILENAME = "userlist.xml";
220     private static final String USER_PHOTO_FILENAME = "photo.png";
221     private static final String USER_PHOTO_FILENAME_TMP = USER_PHOTO_FILENAME + ".tmp";
222 
223     private static final String RESTRICTIONS_FILE_PREFIX = "res_";
224     private static final String XML_SUFFIX = ".xml";
225 
226     private static final int ALLOWED_FLAGS_FOR_CREATE_USERS_PERMISSION =
227             UserInfo.FLAG_MANAGED_PROFILE
228             | UserInfo.FLAG_PROFILE
229             | UserInfo.FLAG_EPHEMERAL
230             | UserInfo.FLAG_RESTRICTED
231             | UserInfo.FLAG_GUEST
232             | UserInfo.FLAG_DEMO
233             | UserInfo.FLAG_FULL;
234 
235     @VisibleForTesting
236     static final int MIN_USER_ID = UserHandle.MIN_SECONDARY_USER_ID;
237 
238     // We need to keep process uid within Integer.MAX_VALUE.
239     @VisibleForTesting
240     static final int MAX_USER_ID = Integer.MAX_VALUE / UserHandle.PER_USER_RANGE;
241 
242     // Max size of the queue of recently removed users
243     @VisibleForTesting
244     static final int MAX_RECENTLY_REMOVED_IDS_SIZE = 100;
245 
246     private static final int USER_VERSION = 9;
247 
248     private static final long EPOCH_PLUS_30_YEARS = 30L * 365 * 24 * 60 * 60 * 1000L; // ms
249 
250     static final int WRITE_USER_MSG = 1;
251     static final int WRITE_USER_DELAY = 2*1000;  // 2 seconds
252 
253     // Tron counters
254     private static final String TRON_GUEST_CREATED = "users_guest_created";
255     private static final String TRON_USER_CREATED = "users_user_created";
256     private static final String TRON_DEMO_CREATED = "users_demo_created";
257 
258     private final Context mContext;
259     private final PackageManagerService mPm;
260 
261     /**
262      * Lock for packages. If using with {@link #mUsersLock}, {@link #mPackagesLock} should be
263      * acquired first.
264      */
265     private final Object mPackagesLock;
266     private final UserDataPreparer mUserDataPreparer;
267     /**
268      * Short-term lock for internal state, when interaction/sync with PM is not required. If using
269      * with {@link #mPackagesLock}, {@link #mPackagesLock} should be acquired first.
270      */
271     private final Object mUsersLock = LockGuard.installNewLock(LockGuard.INDEX_USER);
272     private final Object mRestrictionsLock = new Object();
273     // Used for serializing access to app restriction files
274     private final Object mAppRestrictionsLock = new Object();
275 
276     private final Handler mHandler;
277 
278     private final File mUsersDir;
279     private final File mUserListFile;
280 
281     private static final IBinder mUserRestriconToken = new Binder();
282 
283     /** Installs system packages based on user-type. */
284     private final UserSystemPackageInstaller mSystemPackageInstaller;
285 
286     private PackageManagerInternal mPmInternal;
287     private DevicePolicyManagerInternal mDevicePolicyManagerInternal;
288 
289     /**
290      * Internal non-parcelable wrapper for UserInfo that is not exposed to other system apps.
291      */
292     @VisibleForTesting
293     static class UserData {
294         // Basic user information and properties
295         UserInfo info;
296         // Account name used when there is a strong association between a user and an account
297         String account;
298         // Account information for seeding into a newly created user. This could also be
299         // used for login validation for an existing user, for updating their credentials.
300         // In the latter case, data may not need to be persisted as it is only valid for the
301         // current login session.
302         String seedAccountName;
303         String seedAccountType;
304         PersistableBundle seedAccountOptions;
305         // Whether to perist the seed account information to be available after a boot
306         boolean persistSeedData;
307 
308         /** Elapsed realtime since boot when the user started. */
309         long startRealtime;
310 
311         /** Elapsed realtime since boot when the user was unlocked. */
312         long unlockRealtime;
313 
314         private long mLastRequestQuietModeEnabledMillis;
315 
setLastRequestQuietModeEnabledMillis(long millis)316         void setLastRequestQuietModeEnabledMillis(long millis) {
317             mLastRequestQuietModeEnabledMillis = millis;
318         }
319 
getLastRequestQuietModeEnabledMillis()320         long getLastRequestQuietModeEnabledMillis() {
321             return mLastRequestQuietModeEnabledMillis;
322         }
323 
clearSeedAccountData()324         void clearSeedAccountData() {
325             seedAccountName = null;
326             seedAccountType = null;
327             seedAccountOptions = null;
328             persistSeedData = false;
329         }
330     }
331 
332     @GuardedBy("mUsersLock")
333     private final SparseArray<UserData> mUsers = new SparseArray<>();
334 
335     /**
336      * Map of user type names to their corresponding {@link UserTypeDetails}.
337      * Should not be modified after UserManagerService constructor finishes.
338      */
339     private final ArrayMap<String, UserTypeDetails> mUserTypes;
340 
341     /**
342      * User restrictions set via UserManager.  This doesn't include restrictions set by
343      * device owner / profile owners. Only non-empty restriction bundles are stored.
344      *
345      * DO NOT Change existing {@link Bundle} in it.  When changing a restriction for a user,
346      * a new {@link Bundle} should always be created and set.  This is because a {@link Bundle}
347      * maybe shared between {@link #mBaseUserRestrictions} and
348      * {@link #mCachedEffectiveUserRestrictions}, but they should always updated separately.
349      * (Otherwise we won't be able to detect what restrictions have changed in
350      * {@link #updateUserRestrictionsInternalLR}.
351      */
352     @GuardedBy("mRestrictionsLock")
353     private final RestrictionsSet mBaseUserRestrictions = new RestrictionsSet();
354 
355     /**
356      * Cached user restrictions that are in effect -- i.e. {@link #mBaseUserRestrictions} combined
357      * with device / profile owner restrictions.  We'll initialize it lazily; use
358      * {@link #getEffectiveUserRestrictions} to access it.
359      *
360      * DO NOT Change existing {@link Bundle} in it.  When changing a restriction for a user,
361      * a new {@link Bundle} should always be created and set.  This is because a {@link Bundle}
362      * maybe shared between {@link #mBaseUserRestrictions} and
363      * {@link #mCachedEffectiveUserRestrictions}, but they should always updated separately.
364      * (Otherwise we won't be able to detect what restrictions have changed in
365      * {@link #updateUserRestrictionsInternalLR}.
366      */
367     @GuardedBy("mRestrictionsLock")
368     private final RestrictionsSet mCachedEffectiveUserRestrictions = new RestrictionsSet();
369 
370     /**
371      * User restrictions that have already been applied in
372      * {@link #updateUserRestrictionsInternalLR(Bundle, int)}.  We use it to detect restrictions
373      * that have changed since the last
374      * {@link #updateUserRestrictionsInternalLR(Bundle, int)} call.
375      */
376     @GuardedBy("mRestrictionsLock")
377     private final RestrictionsSet mAppliedUserRestrictions = new RestrictionsSet();
378 
379     /**
380      * User restrictions set by {@link com.android.server.devicepolicy.DevicePolicyManagerService}
381      * that should be applied to all users, including guests. Only non-empty restriction bundles are
382      * stored.
383      * The key is the user id of the user whom the restriction originated from.
384      */
385     @GuardedBy("mRestrictionsLock")
386     private final RestrictionsSet mDevicePolicyGlobalUserRestrictions = new RestrictionsSet();
387 
388     /**
389      * Id of the user that set global restrictions.
390      */
391     @GuardedBy("mRestrictionsLock")
392     private int mDeviceOwnerUserId = UserHandle.USER_NULL;
393 
394     /**
395      * User restrictions set by {@link com.android.server.devicepolicy.DevicePolicyManagerService}
396      * for each user.
397      * The key is the user id of the user whom the restrictions are targeting.
398      * The key inside the restrictionsSet is the user id of the user whom the restriction
399      * originated from.
400      * targetUserId -> originatingUserId -> restrictionBundle
401      */
402     @GuardedBy("mRestrictionsLock")
403     private final SparseArray<RestrictionsSet> mDevicePolicyLocalUserRestrictions =
404             new SparseArray<>();
405 
406     @GuardedBy("mGuestRestrictions")
407     private final Bundle mGuestRestrictions = new Bundle();
408 
409     /**
410      * Set of user IDs being actively removed. Removed IDs linger in this set
411      * for several seconds to work around a VFS caching issue.
412      * Use {@link #addRemovingUserIdLocked(int)} to add elements to this array
413      */
414     @GuardedBy("mUsersLock")
415     private final SparseBooleanArray mRemovingUserIds = new SparseBooleanArray();
416 
417     /**
418      * Queue of recently removed userIds. Used for recycling of userIds
419      */
420     @GuardedBy("mUsersLock")
421     private final LinkedList<Integer> mRecentlyRemovedIds = new LinkedList<>();
422 
423     @GuardedBy("mUsersLock")
424     private int[] mUserIds;
425 
426     @GuardedBy("mUsersLock")
427     private int[] mUserIdsIncludingPreCreated;
428 
429     @GuardedBy("mPackagesLock")
430     private int mNextSerialNumber;
431     private int mUserVersion = 0;
432     private int mUserTypeVersion = 0;
433 
434     private IAppOpsService mAppOpsService;
435 
436     private final LocalService mLocalService;
437 
438     @GuardedBy("mUsersLock")
439     private boolean mIsDeviceManaged;
440 
441     @GuardedBy("mUsersLock")
442     private final SparseBooleanArray mIsUserManaged = new SparseBooleanArray();
443 
444     @GuardedBy("mUserRestrictionsListeners")
445     private final ArrayList<UserRestrictionsListener> mUserRestrictionsListeners =
446             new ArrayList<>();
447 
448     @GuardedBy("mUserRemovedListeners")
449     private final ArrayList<UserLifecycleListener> mUserLifecycleListeners = new ArrayList<>();
450 
451     private final LockPatternUtils mLockPatternUtils;
452 
453     private final String ACTION_DISABLE_QUIET_MODE_AFTER_UNLOCK =
454             "com.android.server.pm.DISABLE_QUIET_MODE_AFTER_UNLOCK";
455 
456     private final BroadcastReceiver mDisableQuietModeCallback = new BroadcastReceiver() {
457         @Override
458         public void onReceive(Context context, Intent intent) {
459             if (!ACTION_DISABLE_QUIET_MODE_AFTER_UNLOCK.equals(intent.getAction())) {
460                 return;
461             }
462             final IntentSender target = intent.getParcelableExtra(Intent.EXTRA_INTENT);
463             final int userId = intent.getIntExtra(Intent.EXTRA_USER_ID, UserHandle.USER_NULL);
464             // Call setQuietModeEnabled on bg thread to avoid ANR
465             BackgroundThread.getHandler().post(() ->
466                     setQuietModeEnabled(userId, false, target, /* callingPackage */ null));
467         }
468     };
469 
470     /**
471      * Cache the owner name string, since it could be read repeatedly on a critical code path
472      * but hit by slow IO. This could be eliminated once we have the cached UserInfo in place.
473      */
474     private final AtomicReference<String> mOwnerName = new AtomicReference<>();
475 
476     private final TypedValue mOwnerNameTypedValue = new TypedValue();
477 
478     private final Configuration mLastConfiguration = new Configuration();
479 
480     private final BroadcastReceiver mConfigurationChangeReceiver = new BroadcastReceiver() {
481         @Override
482         public void onReceive(Context context, Intent intent) {
483             if (!Intent.ACTION_CONFIGURATION_CHANGED.equals(intent.getAction())) {
484                 return;
485             }
486             invalidateOwnerNameIfNecessary(context.getResources(), false /* forceUpdate */);
487         }
488     };
489 
490     // TODO(b/161915546): remove once userWithName() is fixed / removed
491     // Use to debug / dump when user 0 is allocated at userWithName()
492     public static final boolean DBG_ALLOCATION = false; // DO NOT SUBMIT WITH TRUE
493     public final AtomicInteger mUser0Allocations;
494 
495     /**
496      * Start an {@link IntentSender} when user is unlocked after disabling quiet mode.
497      *
498      * @see #requestQuietModeEnabled(String, boolean, int, IntentSender, int)
499      */
500     private class DisableQuietModeUserUnlockedCallback extends IProgressListener.Stub {
501         private final IntentSender mTarget;
502 
DisableQuietModeUserUnlockedCallback(IntentSender target)503         public DisableQuietModeUserUnlockedCallback(IntentSender target) {
504             Objects.requireNonNull(target);
505             mTarget = target;
506         }
507 
508         @Override
onStarted(int id, Bundle extras)509         public void onStarted(int id, Bundle extras) {}
510 
511         @Override
onProgress(int id, int progress, Bundle extras)512         public void onProgress(int id, int progress, Bundle extras) {}
513 
514         @Override
onFinished(int id, Bundle extras)515         public void onFinished(int id, Bundle extras) {
516             mHandler.post(() -> {
517                 try {
518                     mContext.startIntentSender(mTarget, null, 0, 0, 0);
519                 } catch (IntentSender.SendIntentException e) {
520                     Slog.e(LOG_TAG, "Failed to start the target in the callback", e);
521                 }
522             });
523         }
524     }
525 
526     /**
527      * Whether all users should be created ephemeral.
528      */
529     @GuardedBy("mUsersLock")
530     private boolean mForceEphemeralUsers;
531 
532     /**
533      * The member mUserStates affects the return value of isUserUnlocked.
534      * If any value in mUserStates changes, then the binder cache for
535      * isUserUnlocked must be invalidated.  When adding mutating methods to
536      * WatchedUserStates, be sure to invalidate the cache in the new
537      * methods.
538      */
539     private class WatchedUserStates {
540         final SparseIntArray states;
WatchedUserStates()541         public WatchedUserStates() {
542             states = new SparseIntArray();
543             invalidateIsUserUnlockedCache();
544         }
get(@serIdInt int userId)545         public int get(@UserIdInt int userId) {
546             return states.get(userId);
547         }
get(@serIdInt int userId, int fallback)548         public int get(@UserIdInt int userId, int fallback) {
549             return states.indexOfKey(userId) >= 0 ? states.get(userId) : fallback;
550         }
put(@serIdInt int userId, int state)551         public void put(@UserIdInt int userId, int state) {
552             states.put(userId, state);
553             invalidateIsUserUnlockedCache();
554         }
delete(@serIdInt int userId)555         public void delete(@UserIdInt int userId) {
556             states.delete(userId);
557             invalidateIsUserUnlockedCache();
558         }
has(@serIdInt int userId)559         public boolean has(@UserIdInt int userId) {
560             return states.get(userId, UserHandle.USER_NULL) != UserHandle.USER_NULL;
561         }
562         @Override
toString()563         public String toString() {
564             return states.toString();
565         }
invalidateIsUserUnlockedCache()566         private void invalidateIsUserUnlockedCache() {
567             UserManager.invalidateIsUserUnlockedCache();
568         }
569     }
570     @GuardedBy("mUserStates")
571     private final WatchedUserStates mUserStates = new WatchedUserStates();
572 
573     private static UserManagerService sInstance;
574 
getInstance()575     public static UserManagerService getInstance() {
576         synchronized (UserManagerService.class) {
577             return sInstance;
578         }
579     }
580 
581     public static class LifeCycle extends SystemService {
582 
583         private UserManagerService mUms;
584 
585         /**
586          * @param context
587          */
LifeCycle(Context context)588         public LifeCycle(Context context) {
589             super(context);
590         }
591 
592         @Override
onStart()593         public void onStart() {
594             mUms = UserManagerService.getInstance();
595             publishBinderService(Context.USER_SERVICE, mUms);
596         }
597 
598         @Override
onBootPhase(int phase)599         public void onBootPhase(int phase) {
600             if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
601                 mUms.cleanupPartialUsers();
602 
603                 if (mUms.mPm.isDeviceUpgrading()) {
604                     mUms.cleanupPreCreatedUsers();
605                 }
606             }
607         }
608 
609         @Override
onUserStarting(@onNull TargetUser targetUser)610         public void onUserStarting(@NonNull TargetUser targetUser) {
611             synchronized (mUms.mUsersLock) {
612                 final UserData user = mUms.getUserDataLU(targetUser.getUserIdentifier());
613                 if (user != null) {
614                     user.startRealtime = SystemClock.elapsedRealtime();
615                 }
616             }
617         }
618 
619         @Override
onUserUnlocking(@onNull TargetUser targetUser)620         public void onUserUnlocking(@NonNull TargetUser targetUser) {
621             synchronized (mUms.mUsersLock) {
622                 final UserData user = mUms.getUserDataLU(targetUser.getUserIdentifier());
623                 if (user != null) {
624                     user.unlockRealtime = SystemClock.elapsedRealtime();
625                 }
626             }
627         }
628 
629         @Override
onUserStopping(@onNull TargetUser targetUser)630         public void onUserStopping(@NonNull TargetUser targetUser) {
631             synchronized (mUms.mUsersLock) {
632                 final UserData user = mUms.getUserDataLU(targetUser.getUserIdentifier());
633                 if (user != null) {
634                     user.startRealtime = 0;
635                     user.unlockRealtime = 0;
636                 }
637             }
638         }
639     }
640 
641     // TODO b/28848102 Add support for test dependencies injection
642     @VisibleForTesting
UserManagerService(Context context)643     UserManagerService(Context context) {
644         this(context, null, null, new Object(), context.getCacheDir());
645     }
646 
647     /**
648      * Called by package manager to create the service.  This is closely
649      * associated with the package manager, and the given lock is the
650      * package manager's own lock.
651      */
UserManagerService(Context context, PackageManagerService pm, UserDataPreparer userDataPreparer, Object packagesLock)652     UserManagerService(Context context, PackageManagerService pm, UserDataPreparer userDataPreparer,
653             Object packagesLock) {
654         this(context, pm, userDataPreparer, packagesLock, Environment.getDataDirectory());
655     }
656 
UserManagerService(Context context, PackageManagerService pm, UserDataPreparer userDataPreparer, Object packagesLock, File dataDir)657     private UserManagerService(Context context, PackageManagerService pm,
658             UserDataPreparer userDataPreparer, Object packagesLock, File dataDir) {
659         mContext = context;
660         mPm = pm;
661         mPackagesLock = packagesLock;
662         mHandler = new MainHandler();
663         mUserDataPreparer = userDataPreparer;
664         mUserTypes = UserTypeFactory.getUserTypes();
665         invalidateOwnerNameIfNecessary(context.getResources(), true /* forceUpdate */);
666         synchronized (mPackagesLock) {
667             mUsersDir = new File(dataDir, USER_INFO_DIR);
668             mUsersDir.mkdirs();
669             // Make zeroth user directory, for services to migrate their files to that location
670             File userZeroDir = new File(mUsersDir, String.valueOf(UserHandle.USER_SYSTEM));
671             userZeroDir.mkdirs();
672             FileUtils.setPermissions(mUsersDir.toString(),
673                     FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IROTH | FileUtils.S_IXOTH,
674                     -1, -1);
675             mUserListFile = new File(mUsersDir, USER_LIST_FILENAME);
676             initDefaultGuestRestrictions();
677             readUserListLP();
678             sInstance = this;
679         }
680         mSystemPackageInstaller = new UserSystemPackageInstaller(this, mUserTypes);
681         mLocalService = new LocalService();
682         LocalServices.addService(UserManagerInternal.class, mLocalService);
683         mLockPatternUtils = new LockPatternUtils(mContext);
684         mUserStates.put(UserHandle.USER_SYSTEM, UserState.STATE_BOOTING);
685         mUser0Allocations = DBG_ALLOCATION ? new AtomicInteger() : null;
686     }
687 
systemReady()688     void systemReady() {
689         mAppOpsService = IAppOpsService.Stub.asInterface(
690                 ServiceManager.getService(Context.APP_OPS_SERVICE));
691 
692         synchronized (mRestrictionsLock) {
693             applyUserRestrictionsLR(UserHandle.USER_SYSTEM);
694         }
695 
696         mContext.registerReceiver(mDisableQuietModeCallback,
697                 new IntentFilter(ACTION_DISABLE_QUIET_MODE_AFTER_UNLOCK),
698                 null, mHandler);
699 
700         mContext.registerReceiver(mConfigurationChangeReceiver,
701                 new IntentFilter(Intent.ACTION_CONFIGURATION_CHANGED),
702                 null, mHandler);
703 
704         markEphemeralUsersForRemoval();
705     }
706 
707     /**
708      * This method retrieves the  {@link UserManagerInternal} only for the purpose of
709      * PackageManagerService construction.
710      */
getInternalForInjectorOnly()711     UserManagerInternal getInternalForInjectorOnly() {
712         return mLocalService;
713     }
714 
715     /** Marks all ephemeral users as slated for deletion. **/
markEphemeralUsersForRemoval()716     private void markEphemeralUsersForRemoval() {
717         synchronized (mUsersLock) {
718             final int userSize = mUsers.size();
719             for (int i = 0; i < userSize; i++) {
720                 final UserInfo ui = mUsers.valueAt(i).info;
721                 if (ui.isEphemeral() && !ui.preCreated && ui.id != UserHandle.USER_SYSTEM) {
722                     addRemovingUserIdLocked(ui.id);
723                     ui.partial = true;
724                     ui.flags |= UserInfo.FLAG_DISABLED;
725                 }
726             }
727         }
728     }
729 
730     /* Prunes out any partially created or partially removed users. */
cleanupPartialUsers()731     void cleanupPartialUsers() {
732         ArrayList<UserInfo> partials = new ArrayList<>();
733         synchronized (mUsersLock) {
734             final int userSize = mUsers.size();
735             for (int i = 0; i < userSize; i++) {
736                 UserInfo ui = mUsers.valueAt(i).info;
737                 if ((ui.partial || ui.guestToRemove) && ui.id != UserHandle.USER_SYSTEM) {
738                     partials.add(ui);
739                     if (!mRemovingUserIds.get(ui.id)) {
740                         addRemovingUserIdLocked(ui.id);
741                     }
742                     ui.partial = true;
743                 }
744             }
745         }
746         final int partialsSize = partials.size();
747         for (int i = 0; i < partialsSize; i++) {
748             UserInfo ui = partials.get(i);
749             Slog.w(LOG_TAG, "Removing partially created user " + ui.id
750                     + " (name=" + ui.name + ")");
751             removeUserState(ui.id);
752         }
753     }
754 
755     /**
756      * Removes any pre-created users from the system. Should be invoked after OTAs, to ensure
757      * pre-created users are not stale. New pre-created pool can be re-created after the update.
758      */
cleanupPreCreatedUsers()759     void cleanupPreCreatedUsers() {
760         final ArrayList<UserInfo> preCreatedUsers;
761         synchronized (mUsersLock) {
762             final int userSize = mUsers.size();
763             preCreatedUsers = new ArrayList<>(userSize);
764             for (int i = 0; i < userSize; i++) {
765                 UserInfo ui = mUsers.valueAt(i).info;
766                 if (ui.preCreated) {
767                     preCreatedUsers.add(ui);
768                     addRemovingUserIdLocked(ui.id);
769                     ui.flags |= UserInfo.FLAG_DISABLED;
770                     ui.partial = true;
771                 }
772             }
773         }
774         final int preCreatedSize = preCreatedUsers.size();
775         for (int i = 0; i < preCreatedSize; i++) {
776             UserInfo ui = preCreatedUsers.get(i);
777             Slog.i(LOG_TAG, "Removing pre-created user " + ui.id);
778             removeUserState(ui.id);
779         }
780     }
781 
782     @Override
getUserAccount(@serIdInt int userId)783     public String getUserAccount(@UserIdInt int userId) {
784         checkManageUserAndAcrossUsersFullPermission("get user account");
785         synchronized (mUsersLock) {
786             return mUsers.get(userId).account;
787         }
788     }
789 
790     @Override
setUserAccount(@serIdInt int userId, String accountName)791     public void setUserAccount(@UserIdInt int userId, String accountName) {
792         checkManageUserAndAcrossUsersFullPermission("set user account");
793         UserData userToUpdate = null;
794         synchronized (mPackagesLock) {
795             synchronized (mUsersLock) {
796                 final UserData userData = mUsers.get(userId);
797                 if (userData == null) {
798                     Slog.e(LOG_TAG, "User not found for setting user account: u" + userId);
799                     return;
800                 }
801                 String currentAccount = userData.account;
802                 if (!Objects.equals(currentAccount, accountName)) {
803                     userData.account = accountName;
804                     userToUpdate = userData;
805                 }
806             }
807 
808             if (userToUpdate != null) {
809                 writeUserLP(userToUpdate);
810             }
811         }
812     }
813 
814     @Override
getPrimaryUser()815     public UserInfo getPrimaryUser() {
816         checkManageUsersPermission("query users");
817         synchronized (mUsersLock) {
818             final int userSize = mUsers.size();
819             for (int i = 0; i < userSize; i++) {
820                 UserInfo ui = mUsers.valueAt(i).info;
821                 if (ui.isPrimary() && !mRemovingUserIds.get(ui.id)) {
822                     return ui;
823                 }
824             }
825         }
826         return null;
827     }
828 
getUsers(boolean excludeDying)829     public @NonNull List<UserInfo> getUsers(boolean excludeDying) {
830         return getUsers(/*excludePartial= */ true, excludeDying, /* excludePreCreated= */
831                 true);
832     }
833 
834     @Override
getUsers(boolean excludePartial, boolean excludeDying, boolean excludePreCreated)835     public @NonNull List<UserInfo> getUsers(boolean excludePartial, boolean excludeDying,
836             boolean excludePreCreated) {
837         checkManageOrCreateUsersPermission("query users");
838         return getUsersInternal(excludePartial, excludeDying, excludePreCreated);
839     }
840 
getUsersInternal(boolean excludePartial, boolean excludeDying, boolean excludePreCreated)841     private @NonNull List<UserInfo> getUsersInternal(boolean excludePartial, boolean excludeDying,
842             boolean excludePreCreated) {
843         synchronized (mUsersLock) {
844             ArrayList<UserInfo> users = new ArrayList<UserInfo>(mUsers.size());
845             final int userSize = mUsers.size();
846             for (int i = 0; i < userSize; i++) {
847                 UserInfo ui = mUsers.valueAt(i).info;
848                 if ((excludePartial && ui.partial)
849                         || (excludeDying && mRemovingUserIds.get(ui.id))
850                         || (excludePreCreated && ui.preCreated)) {
851                     continue;
852                 }
853                 users.add(userWithName(ui));
854             }
855             return users;
856         }
857     }
858 
859     @Override
getProfiles(@serIdInt int userId, boolean enabledOnly)860     public List<UserInfo> getProfiles(@UserIdInt int userId, boolean enabledOnly) {
861         boolean returnFullInfo = true;
862         if (userId != UserHandle.getCallingUserId()) {
863             checkManageOrCreateUsersPermission("getting profiles related to user " + userId);
864         } else {
865             returnFullInfo = hasManageUsersPermission();
866         }
867         final long ident = Binder.clearCallingIdentity();
868         try {
869             synchronized (mUsersLock) {
870                 return getProfilesLU(userId, /* userType */ null, enabledOnly, returnFullInfo);
871             }
872         } finally {
873             Binder.restoreCallingIdentity(ident);
874         }
875     }
876 
877     // TODO(b/142482943): Will probably need a getProfiles(userType). But permissions may vary.
878 
879     @Override
getProfileIds(@serIdInt int userId, boolean enabledOnly)880     public int[] getProfileIds(@UserIdInt int userId, boolean enabledOnly) {
881         return getProfileIds(userId, null, enabledOnly);
882     }
883 
884     // TODO(b/142482943): Probably @Override and make this accessible in UserManager.
885     /**
886      * Returns all the users of type userType that are in the same profile group as userId
887      * (including userId itself, if it is of the appropriate user type).
888      *
889      * <p>If userType is non-{@code null}, only returns users that are of type userType.
890      * If enabledOnly, only returns users that are not {@link UserInfo#FLAG_DISABLED}.
891      */
getProfileIds(@serIdInt int userId, @Nullable String userType, boolean enabledOnly)892     public int[] getProfileIds(@UserIdInt int userId, @Nullable String userType,
893             boolean enabledOnly) {
894         if (userId != UserHandle.getCallingUserId()) {
895             checkManageOrCreateUsersPermission("getting profiles related to user " + userId);
896         }
897         final long ident = Binder.clearCallingIdentity();
898         try {
899             synchronized (mUsersLock) {
900                 return getProfileIdsLU(userId, userType, enabledOnly).toArray();
901             }
902         } finally {
903             Binder.restoreCallingIdentity(ident);
904         }
905     }
906 
907     /** Assume permissions already checked and caller's identity cleared */
908     @GuardedBy("mUsersLock")
getProfilesLU(@serIdInt int userId, @Nullable String userType, boolean enabledOnly, boolean fullInfo)909     private List<UserInfo> getProfilesLU(@UserIdInt int userId, @Nullable String userType,
910             boolean enabledOnly, boolean fullInfo) {
911         IntArray profileIds = getProfileIdsLU(userId, userType, enabledOnly);
912         ArrayList<UserInfo> users = new ArrayList<>(profileIds.size());
913         for (int i = 0; i < profileIds.size(); i++) {
914             int profileId = profileIds.get(i);
915             UserInfo userInfo = mUsers.get(profileId).info;
916             // If full info is not required - clear PII data to prevent 3P apps from reading it
917             if (!fullInfo) {
918                 userInfo = new UserInfo(userInfo);
919                 userInfo.name = null;
920                 userInfo.iconPath = null;
921             } else {
922                 userInfo = userWithName(userInfo);
923             }
924             users.add(userInfo);
925         }
926         return users;
927     }
928 
929     /**
930      *  Assume permissions already checked and caller's identity cleared
931      *  <p>If userType is {@code null}, returns all profiles for user; else, only returns
932      *  profiles of that type.
933      */
934     @GuardedBy("mUsersLock")
getProfileIdsLU(@serIdInt int userId, @Nullable String userType, boolean enabledOnly)935     private IntArray getProfileIdsLU(@UserIdInt int userId, @Nullable String userType,
936             boolean enabledOnly) {
937         UserInfo user = getUserInfoLU(userId);
938         IntArray result = new IntArray(mUsers.size());
939         if (user == null) {
940             // Probably a dying user
941             return result;
942         }
943         final int userSize = mUsers.size();
944         for (int i = 0; i < userSize; i++) {
945             UserInfo profile = mUsers.valueAt(i).info;
946             if (!isProfileOf(user, profile)) {
947                 continue;
948             }
949             if (enabledOnly && !profile.isEnabled()) {
950                 continue;
951             }
952             if (mRemovingUserIds.get(profile.id)) {
953                 continue;
954             }
955             if (profile.partial) {
956                 continue;
957             }
958             if (userType != null && !userType.equals(profile.userType)) {
959                 continue;
960             }
961             result.add(profile.id);
962         }
963         return result;
964     }
965 
966     @Override
getCredentialOwnerProfile(@serIdInt int userId)967     public int getCredentialOwnerProfile(@UserIdInt int userId) {
968         checkManageUsersPermission("get the credential owner");
969         if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
970             synchronized (mUsersLock) {
971                 UserInfo profileParent = getProfileParentLU(userId);
972                 if (profileParent != null) {
973                     return profileParent.id;
974                 }
975             }
976         }
977 
978         return userId;
979     }
980 
981     @Override
isSameProfileGroup(@serIdInt int userId, int otherUserId)982     public boolean isSameProfileGroup(@UserIdInt int userId, int otherUserId) {
983         if (userId == otherUserId) return true;
984         checkManageUsersPermission("check if in the same profile group");
985         return isSameProfileGroupNoChecks(userId, otherUserId);
986     }
987 
isSameProfileGroupNoChecks(@serIdInt int userId, int otherUserId)988     private boolean isSameProfileGroupNoChecks(@UserIdInt int userId, int otherUserId) {
989         synchronized (mUsersLock) {
990             UserInfo userInfo = getUserInfoLU(userId);
991             if (userInfo == null || userInfo.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID) {
992                 return false;
993             }
994             UserInfo otherUserInfo = getUserInfoLU(otherUserId);
995             if (otherUserInfo == null
996                     || otherUserInfo.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID) {
997                 return false;
998             }
999             return userInfo.profileGroupId == otherUserInfo.profileGroupId;
1000         }
1001     }
1002 
1003     @Override
getProfileParent(@serIdInt int userId)1004     public UserInfo getProfileParent(@UserIdInt int userId) {
1005         if (!hasManageUsersOrPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)) {
1006             throw new SecurityException(
1007                     "You need MANAGE_USERS or INTERACT_ACROSS_USERS permission to get the "
1008                             + "profile parent");
1009         }
1010         synchronized (mUsersLock) {
1011             return getProfileParentLU(userId);
1012         }
1013     }
1014 
1015     @Override
getProfileParentId(@serIdInt int userId)1016     public int getProfileParentId(@UserIdInt int userId) {
1017         checkManageUsersPermission("get the profile parent");
1018         return mLocalService.getProfileParentId(userId);
1019     }
1020 
1021     @GuardedBy("mUsersLock")
getProfileParentLU(@serIdInt int userId)1022     private UserInfo getProfileParentLU(@UserIdInt int userId) {
1023         UserInfo profile = getUserInfoLU(userId);
1024         if (profile == null) {
1025             return null;
1026         }
1027         int parentUserId = profile.profileGroupId;
1028         if (parentUserId == userId || parentUserId == UserInfo.NO_PROFILE_GROUP_ID) {
1029             return null;
1030         } else {
1031             return getUserInfoLU(parentUserId);
1032         }
1033     }
1034 
isProfileOf(UserInfo user, UserInfo profile)1035     private static boolean isProfileOf(UserInfo user, UserInfo profile) {
1036         return user.id == profile.id ||
1037                 (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID
1038                 && user.profileGroupId == profile.profileGroupId);
1039     }
1040 
broadcastProfileAvailabilityChanges(UserHandle profileHandle, UserHandle parentHandle, boolean inQuietMode)1041     private void broadcastProfileAvailabilityChanges(UserHandle profileHandle,
1042             UserHandle parentHandle, boolean inQuietMode) {
1043         Intent intent = new Intent();
1044         if (inQuietMode) {
1045             intent.setAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE);
1046         } else {
1047             intent.setAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE);
1048         }
1049         intent.putExtra(Intent.EXTRA_QUIET_MODE, inQuietMode);
1050         intent.putExtra(Intent.EXTRA_USER, profileHandle);
1051         intent.putExtra(Intent.EXTRA_USER_HANDLE, profileHandle.getIdentifier());
1052         getDevicePolicyManagerInternal().broadcastIntentToCrossProfileManifestReceiversAsUser(
1053                 intent, parentHandle, /* requiresPermission= */ true);
1054         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
1055         mContext.sendBroadcastAsUser(intent, parentHandle);
1056     }
1057 
1058     @Override
requestQuietModeEnabled(@onNull String callingPackage, boolean enableQuietMode, @UserIdInt int userId, @Nullable IntentSender target, @QuietModeFlag int flags)1059     public boolean requestQuietModeEnabled(@NonNull String callingPackage, boolean enableQuietMode,
1060             @UserIdInt int userId, @Nullable IntentSender target, @QuietModeFlag int flags) {
1061         Objects.requireNonNull(callingPackage);
1062 
1063         if (enableQuietMode && target != null) {
1064             throw new IllegalArgumentException(
1065                     "target should only be specified when we are disabling quiet mode.");
1066         }
1067 
1068         final boolean dontAskCredential =
1069                 (flags & UserManager.QUIET_MODE_DISABLE_DONT_ASK_CREDENTIAL) != 0;
1070         final boolean onlyIfCredentialNotRequired =
1071                 (flags & UserManager.QUIET_MODE_DISABLE_ONLY_IF_CREDENTIAL_NOT_REQUIRED) != 0;
1072         if (dontAskCredential && onlyIfCredentialNotRequired) {
1073             throw new IllegalArgumentException("invalid flags: " + flags);
1074         }
1075 
1076         ensureCanModifyQuietMode(
1077                 callingPackage, Binder.getCallingUid(), userId, target != null, dontAskCredential);
1078 
1079         if (onlyIfCredentialNotRequired && callingPackage.equals(
1080                 getPackageManagerInternal().getSystemUiServiceComponent().getPackageName())) {
1081             // This is to prevent SysUI from accidentally allowing the profile to turned on
1082             // without password when keyguard is still locked.
1083             throw new SecurityException("SystemUI is not allowed to set "
1084                     + "QUIET_MODE_DISABLE_ONLY_IF_CREDENTIAL_NOT_REQUIRED");
1085         }
1086 
1087         final long identity = Binder.clearCallingIdentity();
1088         try {
1089             if (enableQuietMode) {
1090                 setQuietModeEnabled(
1091                         userId, true /* enableQuietMode */, target, callingPackage);
1092                 return true;
1093             }
1094             if (mLockPatternUtils.isManagedProfileWithUnifiedChallenge(userId)) {
1095                 KeyguardManager km = mContext.getSystemService(KeyguardManager.class);
1096                 // Normally only attempt to auto-unlock unified challenge if keyguard is not showing
1097                 // (to stop turning profile on automatically via the QS tile), except when we
1098                 // are called with QUIET_MODE_DISABLE_ONLY_IF_CREDENTIAL_NOT_REQUIRED, in which
1099                 // case always attempt to auto-unlock.
1100                 if (!km.isDeviceLocked(mLocalService.getProfileParentId(userId))
1101                         || onlyIfCredentialNotRequired) {
1102                     mLockPatternUtils.tryUnlockWithCachedUnifiedChallenge(userId);
1103                 }
1104             }
1105             final boolean needToShowConfirmCredential = !dontAskCredential
1106                     && mLockPatternUtils.isSecure(userId)
1107                     && !StorageManager.isUserKeyUnlocked(userId);
1108             if (needToShowConfirmCredential) {
1109                 if (onlyIfCredentialNotRequired) {
1110                     return false;
1111                 }
1112                 showConfirmCredentialToDisableQuietMode(userId, target);
1113                 return false;
1114             }
1115             setQuietModeEnabled(userId, false /* enableQuietMode */, target, callingPackage);
1116             return true;
1117         } finally {
1118             Binder.restoreCallingIdentity(identity);
1119         }
1120     }
1121 
1122     /**
1123      * The caller can modify quiet mode if it meets one of these conditions:
1124      * <ul>
1125      *     <li>Has system UID or root UID</li>
1126      *     <li>Has {@link Manifest.permission#MODIFY_QUIET_MODE}</li>
1127      *     <li>Has {@link Manifest.permission#MANAGE_USERS}</li>
1128      *     <li>Is the foreground default launcher app</li>
1129      * </ul>
1130      * <p>
1131      * If caller wants to start an intent after disabling the quiet mode, or if it is targeting a
1132      * user in a different profile group from the caller, it must have
1133      * {@link Manifest.permission#MANAGE_USERS}.
1134      */
ensureCanModifyQuietMode(String callingPackage, int callingUid, @UserIdInt int targetUserId, boolean startIntent, boolean dontAskCredential)1135     private void ensureCanModifyQuietMode(String callingPackage, int callingUid,
1136             @UserIdInt int targetUserId, boolean startIntent, boolean dontAskCredential) {
1137         verifyCallingPackage(callingPackage, callingUid);
1138 
1139         if (hasManageUsersPermission()) {
1140             return;
1141         }
1142         if (startIntent) {
1143             throw new SecurityException("MANAGE_USERS permission is required to start intent "
1144                     + "after disabling quiet mode.");
1145         }
1146         if (dontAskCredential) {
1147             throw new SecurityException("MANAGE_USERS permission is required to disable quiet "
1148                     + "mode without credentials.");
1149         }
1150         if (!isSameProfileGroupNoChecks(UserHandle.getUserId(callingUid), targetUserId)) {
1151             throw new SecurityException("MANAGE_USERS permission is required to modify quiet mode "
1152                     + "for a different profile group.");
1153         }
1154         final boolean hasModifyQuietModePermission = hasPermissionGranted(
1155                 Manifest.permission.MODIFY_QUIET_MODE, callingUid);
1156         if (hasModifyQuietModePermission) {
1157             return;
1158         }
1159 
1160         final ShortcutServiceInternal shortcutInternal =
1161                 LocalServices.getService(ShortcutServiceInternal.class);
1162         if (shortcutInternal != null) {
1163             boolean isForegroundLauncher =
1164                     shortcutInternal.isForegroundDefaultLauncher(callingPackage, callingUid);
1165             if (isForegroundLauncher) {
1166                 return;
1167             }
1168         }
1169         throw new SecurityException("Can't modify quiet mode, caller is neither foreground "
1170                 + "default launcher nor has MANAGE_USERS/MODIFY_QUIET_MODE permission");
1171     }
1172 
setQuietModeEnabled(@serIdInt int userId, boolean enableQuietMode, IntentSender target, @Nullable String callingPackage)1173     private void setQuietModeEnabled(@UserIdInt int userId, boolean enableQuietMode,
1174             IntentSender target, @Nullable String callingPackage) {
1175         final UserInfo profile, parent;
1176         final UserData profileUserData;
1177         synchronized (mUsersLock) {
1178             profile = getUserInfoLU(userId);
1179             parent = getProfileParentLU(userId);
1180 
1181             if (profile == null || !profile.isManagedProfile()) {
1182                 throw new IllegalArgumentException("User " + userId + " is not a profile");
1183             }
1184             if (profile.isQuietModeEnabled() == enableQuietMode) {
1185                 Slog.i(LOG_TAG, "Quiet mode is already " + enableQuietMode);
1186                 return;
1187             }
1188             profile.flags ^= UserInfo.FLAG_QUIET_MODE;
1189             profileUserData = getUserDataLU(profile.id);
1190         }
1191         synchronized (mPackagesLock) {
1192             writeUserLP(profileUserData);
1193         }
1194         try {
1195             if (enableQuietMode) {
1196                 ActivityManager.getService().stopUser(userId, /* force */true, null);
1197                 LocalServices.getService(ActivityManagerInternal.class)
1198                         .killForegroundAppsForUser(userId);
1199             } else {
1200                 IProgressListener callback = target != null
1201                         ? new DisableQuietModeUserUnlockedCallback(target)
1202                         : null;
1203                 ActivityManager.getService().startUserInBackgroundWithListener(
1204                         userId, callback);
1205             }
1206             logQuietModeEnabled(userId, enableQuietMode, callingPackage);
1207         } catch (RemoteException e) {
1208             // Should not happen, same process.
1209             e.rethrowAsRuntimeException();
1210         }
1211         broadcastProfileAvailabilityChanges(profile.getUserHandle(), parent.getUserHandle(),
1212                 enableQuietMode);
1213     }
1214 
logQuietModeEnabled(@serIdInt int userId, boolean enableQuietMode, @Nullable String callingPackage)1215     private void logQuietModeEnabled(@UserIdInt int userId, boolean enableQuietMode,
1216             @Nullable String callingPackage) {
1217         UserData userData;
1218         synchronized (mUsersLock) {
1219             userData = getUserDataLU(userId);
1220         }
1221         if (userData == null) {
1222             return;
1223         }
1224         final long now = System.currentTimeMillis();
1225         final long period = (userData.getLastRequestQuietModeEnabledMillis() != 0L
1226                 ? now - userData.getLastRequestQuietModeEnabledMillis()
1227                 : now - userData.info.creationTime);
1228         DevicePolicyEventLogger
1229                 .createEvent(DevicePolicyEnums.REQUEST_QUIET_MODE_ENABLED)
1230                 .setStrings(callingPackage)
1231                 .setBoolean(enableQuietMode)
1232                 .setTimePeriod(period)
1233                 .write();
1234         userData.setLastRequestQuietModeEnabledMillis(now);
1235     }
1236 
1237     @Override
isQuietModeEnabled(@serIdInt int userId)1238     public boolean isQuietModeEnabled(@UserIdInt int userId) {
1239         synchronized (mPackagesLock) {
1240             UserInfo info;
1241             synchronized (mUsersLock) {
1242                 info = getUserInfoLU(userId);
1243             }
1244             if (info == null || !info.isManagedProfile()) {
1245                 return false;
1246             }
1247             return info.isQuietModeEnabled();
1248         }
1249     }
1250 
1251     /**
1252      * Show confirm credential screen to unlock user in order to turn off quiet mode.
1253      */
showConfirmCredentialToDisableQuietMode( @serIdInt int userId, @Nullable IntentSender target)1254     private void showConfirmCredentialToDisableQuietMode(
1255             @UserIdInt int userId, @Nullable IntentSender target) {
1256         // otherwise, we show a profile challenge to trigger decryption of the user
1257         final KeyguardManager km = (KeyguardManager) mContext.getSystemService(
1258                 Context.KEYGUARD_SERVICE);
1259         // We should use userId not credentialOwnerUserId here, as even if it is unified
1260         // lock, confirm screenlock page will know and show personal challenge, and unlock
1261         // work profile when personal challenge is correct
1262         final Intent unlockIntent = km.createConfirmDeviceCredentialIntent(null, null, userId);
1263         if (unlockIntent == null) {
1264             return;
1265         }
1266         final Intent callBackIntent = new Intent(
1267                 ACTION_DISABLE_QUIET_MODE_AFTER_UNLOCK);
1268         if (target != null) {
1269             callBackIntent.putExtra(Intent.EXTRA_INTENT, target);
1270         }
1271         callBackIntent.putExtra(Intent.EXTRA_USER_ID, userId);
1272         callBackIntent.setPackage(mContext.getPackageName());
1273         callBackIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
1274         final PendingIntent pendingIntent = PendingIntent.getBroadcast(
1275                 mContext,
1276                 0,
1277                 callBackIntent,
1278                 PendingIntent.FLAG_CANCEL_CURRENT |
1279                         PendingIntent.FLAG_ONE_SHOT |
1280                         PendingIntent.FLAG_IMMUTABLE);
1281         // After unlocking the challenge, it will disable quiet mode and run the original
1282         // intentSender
1283         unlockIntent.putExtra(Intent.EXTRA_INTENT, pendingIntent.getIntentSender());
1284         unlockIntent.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
1285         mContext.startActivity(unlockIntent);
1286     }
1287 
1288     @Override
setUserEnabled(@serIdInt int userId)1289     public void setUserEnabled(@UserIdInt int userId) {
1290         checkManageUsersPermission("enable user");
1291         synchronized (mPackagesLock) {
1292             UserInfo info;
1293             synchronized (mUsersLock) {
1294                 info = getUserInfoLU(userId);
1295             }
1296             if (info != null && !info.isEnabled()) {
1297                 info.flags ^= UserInfo.FLAG_DISABLED;
1298                 writeUserLP(getUserDataLU(info.id));
1299             }
1300         }
1301     }
1302 
1303     @Override
setUserAdmin(@serIdInt int userId)1304     public void setUserAdmin(@UserIdInt int userId) {
1305         checkManageUserAndAcrossUsersFullPermission("set user admin");
1306 
1307         synchronized (mPackagesLock) {
1308             UserInfo info;
1309             synchronized (mUsersLock) {
1310                 info = getUserInfoLU(userId);
1311             }
1312             if (info == null || info.isAdmin()) {
1313                 // Exit if no user found with that id, or the user is already an Admin.
1314                 return;
1315             }
1316 
1317             info.flags ^= UserInfo.FLAG_ADMIN;
1318             writeUserLP(getUserDataLU(info.id));
1319         }
1320     }
1321 
1322     /**
1323      * Evicts a user's CE key by stopping and restarting the user.
1324      *
1325      * The key is evicted automatically by the user controller when the user has stopped.
1326      */
1327     @Override
evictCredentialEncryptionKey(@serIdInt int userId)1328     public void evictCredentialEncryptionKey(@UserIdInt int userId) {
1329         checkManageUsersPermission("evict CE key");
1330         final IActivityManager am = ActivityManagerNative.getDefault();
1331         final long identity = Binder.clearCallingIdentity();
1332         try {
1333             am.restartUserInBackground(userId);
1334         } catch (RemoteException re) {
1335             throw re.rethrowAsRuntimeException();
1336         } finally {
1337             Binder.restoreCallingIdentity(identity);
1338         }
1339     }
1340 
1341     /**
1342      * Returns whether the given user (specified by userId) is of the given user type, such as
1343      * {@link UserManager#USER_TYPE_FULL_GUEST}.
1344      */
1345     @Override
isUserOfType(@serIdInt int userId, String userType)1346     public boolean isUserOfType(@UserIdInt int userId, String userType) {
1347         checkManageUsersPermission("check user type");
1348         return userType != null && userType.equals(getUserTypeNoChecks(userId));
1349     }
1350 
1351     /**
1352      * Returns the user type of the given userId, or null if the user doesn't exist.
1353      * <p>No permissions checks are made (but userId checks may be made).
1354      */
getUserTypeNoChecks(@serIdInt int userId)1355     private @Nullable String getUserTypeNoChecks(@UserIdInt int userId) {
1356         synchronized (mUsersLock) {
1357             final UserInfo userInfo = getUserInfoLU(userId);
1358             return userInfo != null ? userInfo.userType : null;
1359         }
1360     }
1361 
1362     /**
1363      * Returns the UserTypeDetails of the given userId's user type, or null if the no such user.
1364      * <p>No permissions checks are made (but userId checks may be made).
1365      */
getUserTypeDetailsNoChecks(@serIdInt int userId)1366     private @Nullable UserTypeDetails getUserTypeDetailsNoChecks(@UserIdInt int userId) {
1367         final String typeStr = getUserTypeNoChecks(userId);
1368         return typeStr != null ? mUserTypes.get(typeStr) : null;
1369     }
1370 
1371     /**
1372      * Returns the UserTypeDetails of the given userInfo's user type (or null for a null userInfo).
1373      */
getUserTypeDetails(@ullable UserInfo userInfo)1374     private @Nullable UserTypeDetails getUserTypeDetails(@Nullable UserInfo userInfo) {
1375         final String typeStr = userInfo != null ? userInfo.userType : null;
1376         return typeStr != null ? mUserTypes.get(typeStr) : null;
1377     }
1378 
1379     @Override
getUserInfo(@serIdInt int userId)1380     public UserInfo getUserInfo(@UserIdInt int userId) {
1381         checkManageOrCreateUsersPermission("query user");
1382         synchronized (mUsersLock) {
1383             return userWithName(getUserInfoLU(userId));
1384         }
1385     }
1386 
1387     /**
1388      * Returns a UserInfo object with the name filled in, for Owner, or the original
1389      * if the name is already set.
1390      */
userWithName(UserInfo orig)1391     private UserInfo userWithName(UserInfo orig) {
1392         if (orig != null && orig.name == null && orig.id == UserHandle.USER_SYSTEM) {
1393             if (DBG_ALLOCATION) {
1394                 final int number = mUser0Allocations.incrementAndGet();
1395                 Slog.w(LOG_TAG, "System user instantiated at least " + number + " times");
1396             }
1397             UserInfo withName = new UserInfo(orig);
1398             withName.name = getOwnerName();
1399             return withName;
1400         } else {
1401             return orig;
1402         }
1403     }
1404 
1405     /** Returns whether the given user type is one of the FULL user types. */
isUserTypeSubtypeOfFull(String userType)1406     boolean isUserTypeSubtypeOfFull(String userType) {
1407         UserTypeDetails userTypeDetails = mUserTypes.get(userType);
1408         return userTypeDetails != null && userTypeDetails.isFull();
1409     }
1410 
1411     /** Returns whether the given user type is one of the PROFILE user types. */
isUserTypeSubtypeOfProfile(String userType)1412     boolean isUserTypeSubtypeOfProfile(String userType) {
1413         UserTypeDetails userTypeDetails = mUserTypes.get(userType);
1414         return userTypeDetails != null && userTypeDetails.isProfile();
1415     }
1416 
1417     /** Returns whether the given user type is one of the SYSTEM user types. */
isUserTypeSubtypeOfSystem(String userType)1418     boolean isUserTypeSubtypeOfSystem(String userType) {
1419         UserTypeDetails userTypeDetails = mUserTypes.get(userType);
1420         return userTypeDetails != null && userTypeDetails.isSystem();
1421     }
1422 
1423     @Override
hasBadge(@serIdInt int userId)1424     public boolean hasBadge(@UserIdInt int userId) {
1425         checkManageOrInteractPermissionIfCallerInOtherProfileGroup(userId, "hasBadge");
1426         final UserTypeDetails userTypeDetails = getUserTypeDetailsNoChecks(userId);
1427         return userTypeDetails != null && userTypeDetails.hasBadge();
1428     }
1429 
1430     @Override
getUserBadgeLabelResId(@serIdInt int userId)1431     public @StringRes int getUserBadgeLabelResId(@UserIdInt int userId) {
1432         checkManageOrInteractPermissionIfCallerInOtherProfileGroup(userId,
1433                 "getUserBadgeLabelResId");
1434         final UserInfo userInfo = getUserInfoNoChecks(userId);
1435         final UserTypeDetails userTypeDetails = getUserTypeDetails(userInfo);
1436         if (userInfo == null || userTypeDetails == null || !userTypeDetails.hasBadge()) {
1437             Slog.e(LOG_TAG, "Requested badge label for non-badged user " + userId);
1438             return Resources.ID_NULL;
1439         }
1440         final int badgeIndex = userInfo.profileBadge;
1441         return userTypeDetails.getBadgeLabel(badgeIndex);
1442     }
1443 
1444     /**
1445      * @return the color (not the resource ID) to be used for the user's badge in light theme
1446      */
1447     @Override
getUserBadgeColorResId(@serIdInt int userId)1448     public @ColorRes int getUserBadgeColorResId(@UserIdInt int userId) {
1449         checkManageOrInteractPermissionIfCallerInOtherProfileGroup(userId,
1450                 "getUserBadgeColorResId");
1451         final UserInfo userInfo = getUserInfoNoChecks(userId);
1452         final UserTypeDetails userTypeDetails = getUserTypeDetails(userInfo);
1453         if (userInfo == null || userTypeDetails == null || !userTypeDetails.hasBadge()) {
1454             Slog.e(LOG_TAG, "Requested badge dark color for non-badged user " + userId);
1455             return Resources.ID_NULL;
1456         }
1457         return userTypeDetails.getBadgeColor(userInfo.profileBadge);
1458     }
1459 
1460     /**
1461      * @return the color (not the resource ID) to be used for the user's badge in dark theme
1462      */
1463     @Override
getUserBadgeDarkColorResId(@serIdInt int userId)1464     public @ColorRes int getUserBadgeDarkColorResId(@UserIdInt int userId) {
1465         checkManageOrInteractPermissionIfCallerInOtherProfileGroup(userId,
1466                 "getUserBadgeDarkColorResId");
1467         final UserInfo userInfo = getUserInfoNoChecks(userId);
1468         final UserTypeDetails userTypeDetails = getUserTypeDetails(userInfo);
1469         if (userInfo == null || userTypeDetails == null || !userTypeDetails.hasBadge()) {
1470             Slog.e(LOG_TAG, "Requested badge color for non-badged user " + userId);
1471             return Resources.ID_NULL;
1472         }
1473         return userTypeDetails.getDarkThemeBadgeColor(userInfo.profileBadge);
1474     }
1475 
1476     @Override
getUserIconBadgeResId(@serIdInt int userId)1477     public @DrawableRes int getUserIconBadgeResId(@UserIdInt int userId) {
1478         checkManageOrInteractPermissionIfCallerInOtherProfileGroup(userId, "getUserIconBadgeResId");
1479         final UserTypeDetails userTypeDetails = getUserTypeDetailsNoChecks(userId);
1480         if (userTypeDetails == null || !userTypeDetails.hasBadge()) {
1481             Slog.e(LOG_TAG, "Requested icon badge for non-badged user " + userId);
1482             return Resources.ID_NULL;
1483         }
1484         return userTypeDetails.getIconBadge();
1485     }
1486 
1487     @Override
getUserBadgeResId(@serIdInt int userId)1488     public @DrawableRes int getUserBadgeResId(@UserIdInt int userId) {
1489         checkManageOrInteractPermissionIfCallerInOtherProfileGroup(userId, "getUserBadgeResId");
1490         final UserTypeDetails userTypeDetails = getUserTypeDetailsNoChecks(userId);
1491         if (userTypeDetails == null || !userTypeDetails.hasBadge()) {
1492             Slog.e(LOG_TAG, "Requested badge for non-badged user " + userId);
1493             return Resources.ID_NULL;
1494         }
1495         return userTypeDetails.getBadgePlain();
1496     }
1497 
1498     @Override
getUserBadgeNoBackgroundResId(@serIdInt int userId)1499     public @DrawableRes int getUserBadgeNoBackgroundResId(@UserIdInt int userId) {
1500         checkManageOrInteractPermissionIfCallerInOtherProfileGroup(userId,
1501                 "getUserBadgeNoBackgroundResId");
1502         final UserTypeDetails userTypeDetails = getUserTypeDetailsNoChecks(userId);
1503         if (userTypeDetails == null || !userTypeDetails.hasBadge()) {
1504             Slog.e(LOG_TAG, "Requested badge (no background) for non-badged user " + userId);
1505             return Resources.ID_NULL;
1506         }
1507         return userTypeDetails.getBadgeNoBackground();
1508     }
1509 
1510     @Override
isProfile(@serIdInt int userId)1511     public boolean isProfile(@UserIdInt int userId) {
1512         checkManageOrInteractPermissionIfCallerInOtherProfileGroup(userId, "isProfile");
1513         synchronized (mUsersLock) {
1514             UserInfo userInfo = getUserInfoLU(userId);
1515             return userInfo != null && userInfo.isProfile();
1516         }
1517     }
1518 
1519     @Override
isManagedProfile(@serIdInt int userId)1520     public boolean isManagedProfile(@UserIdInt int userId) {
1521         checkManageOrInteractPermissionIfCallerInOtherProfileGroup(userId, "isManagedProfile");
1522         synchronized (mUsersLock) {
1523             UserInfo userInfo = getUserInfoLU(userId);
1524             return userInfo != null && userInfo.isManagedProfile();
1525         }
1526     }
1527 
1528     @Override
isCloneProfile(@serIdInt int userId)1529     public boolean isCloneProfile(@UserIdInt int userId) {
1530         checkManageOrInteractPermissionIfCallerInOtherProfileGroup(userId, "isCloneProfile");
1531         synchronized (mUsersLock) {
1532             UserInfo userInfo = getUserInfoLU(userId);
1533             return userInfo != null && userInfo.isCloneProfile();
1534         }
1535     }
1536 
1537     @Override
isMediaSharedWithParent(@serIdInt int userId)1538     public boolean isMediaSharedWithParent(@UserIdInt int userId) {
1539         checkManageOrInteractPermissionIfCallerInOtherProfileGroup(userId,
1540                 "isMediaSharedWithParent");
1541         synchronized (mUsersLock) {
1542             UserTypeDetails userTypeDetails = getUserTypeDetailsNoChecks(userId);
1543             return userTypeDetails != null ? userTypeDetails.isProfile()
1544                     && userTypeDetails.isMediaSharedWithParent() : false;
1545         }
1546     }
1547 
1548     @Override
isUserUnlockingOrUnlocked(@serIdInt int userId)1549     public boolean isUserUnlockingOrUnlocked(@UserIdInt int userId) {
1550         checkManageOrInteractPermissionIfCallerInOtherProfileGroup(userId,
1551                 "isUserUnlockingOrUnlocked");
1552         return mLocalService.isUserUnlockingOrUnlocked(userId);
1553     }
1554 
1555     @Override
isUserUnlocked(@serIdInt int userId)1556     public boolean isUserUnlocked(@UserIdInt int userId) {
1557         checkManageOrInteractPermissionIfCallerInOtherProfileGroup(userId, "isUserUnlocked");
1558         return mLocalService.isUserUnlocked(userId);
1559     }
1560 
1561     @Override
isUserRunning(@serIdInt int userId)1562     public boolean isUserRunning(@UserIdInt int userId) {
1563         checkManageOrInteractPermissionIfCallerInOtherProfileGroup(userId, "isUserRunning");
1564         return mLocalService.isUserRunning(userId);
1565     }
1566 
1567     @Override
isUserForeground(@serIdInt int userId)1568     public boolean isUserForeground(@UserIdInt int userId) {
1569         final int callingUserId = UserHandle.getCallingUserId();
1570         if (callingUserId != userId
1571                 && !hasManageUsersOrPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)) {
1572             throw new SecurityException("Caller from user " + callingUserId + " needs MANAGE_USERS "
1573                     + "or INTERACT_ACROSS_USERS permission to check if another user (" + userId
1574                     + ") is running in the foreground");
1575         }
1576 
1577         int currentUser = Binder.withCleanCallingIdentity(() -> ActivityManager.getCurrentUser());
1578         // TODO(b/179163496): should return true for profile users of the current user as well
1579         return currentUser == userId;
1580     }
1581 
1582     @Override
getUserName()1583     public String getUserName() {
1584         final int callingUid = Binder.getCallingUid();
1585         if (!hasManageOrCreateUsersPermission()
1586                 && !hasPermissionGranted(
1587                         android.Manifest.permission.GET_ACCOUNTS_PRIVILEGED, callingUid)) {
1588             throw new SecurityException("You need MANAGE_USERS or CREATE_USERS or "
1589                     + "GET_ACCOUNTS_PRIVILEGED permissions to: get user name");
1590         }
1591         final int userId = UserHandle.getUserId(callingUid);
1592         synchronized (mUsersLock) {
1593             UserInfo userInfo = userWithName(getUserInfoLU(userId));
1594             return userInfo == null ? "" : userInfo.name;
1595         }
1596     }
1597 
1598     @Override
getUserStartRealtime()1599     public long getUserStartRealtime() {
1600         final int userId = UserHandle.getUserId(Binder.getCallingUid());
1601         synchronized (mUsersLock) {
1602             final UserData user = getUserDataLU(userId);
1603             if (user != null) {
1604                 return user.startRealtime;
1605             }
1606             return 0;
1607         }
1608     }
1609 
1610     @Override
getUserUnlockRealtime()1611     public long getUserUnlockRealtime() {
1612         synchronized (mUsersLock) {
1613             final UserData user = getUserDataLU(UserHandle.getUserId(Binder.getCallingUid()));
1614             if (user != null) {
1615                 return user.unlockRealtime;
1616             }
1617             return 0;
1618         }
1619     }
1620 
checkManageOrInteractPermissionIfCallerInOtherProfileGroup(@serIdInt int userId, String name)1621     private void checkManageOrInteractPermissionIfCallerInOtherProfileGroup(@UserIdInt int userId,
1622             String name) {
1623         final int callingUserId = UserHandle.getCallingUserId();
1624         if (callingUserId == userId || isSameProfileGroupNoChecks(callingUserId, userId) ||
1625                 hasManageUsersPermission()) {
1626             return;
1627         }
1628         if (!hasPermissionGranted(Manifest.permission.INTERACT_ACROSS_USERS,
1629                 Binder.getCallingUid())) {
1630             throw new SecurityException("You need INTERACT_ACROSS_USERS or MANAGE_USERS permission "
1631                     + "to: check " + name);
1632         }
1633     }
1634 
1635     @Override
isDemoUser(@serIdInt int userId)1636     public boolean isDemoUser(@UserIdInt int userId) {
1637         final int callingUserId = UserHandle.getCallingUserId();
1638         if (callingUserId != userId && !hasManageUsersPermission()) {
1639             throw new SecurityException("You need MANAGE_USERS permission to query if u=" + userId
1640                     + " is a demo user");
1641         }
1642         synchronized (mUsersLock) {
1643             UserInfo userInfo = getUserInfoLU(userId);
1644             return userInfo != null && userInfo.isDemo();
1645         }
1646     }
1647 
1648     @Override
isPreCreated(@serIdInt int userId)1649     public boolean isPreCreated(@UserIdInt int userId) {
1650         checkManageOrInteractPermissionIfCallerInOtherProfileGroup(userId, "isPreCreated");
1651         synchronized (mUsersLock) {
1652             UserInfo userInfo = getUserInfoLU(userId);
1653             return userInfo != null && userInfo.preCreated;
1654         }
1655     }
1656 
1657     @Override
isRestricted()1658     public boolean isRestricted() {
1659         synchronized (mUsersLock) {
1660             return getUserInfoLU(UserHandle.getCallingUserId()).isRestricted();
1661         }
1662     }
1663 
1664     @Override
canHaveRestrictedProfile(@serIdInt int userId)1665     public boolean canHaveRestrictedProfile(@UserIdInt int userId) {
1666         checkManageUsersPermission("canHaveRestrictedProfile");
1667         synchronized (mUsersLock) {
1668             final UserInfo userInfo = getUserInfoLU(userId);
1669             if (userInfo == null || !userInfo.canHaveProfile()) {
1670                 return false;
1671             }
1672             if (!userInfo.isAdmin()) {
1673                 return false;
1674             }
1675             // restricted profile can be created if there is no DO set and the admin user has no PO;
1676             return !mIsDeviceManaged && !mIsUserManaged.get(userId);
1677         }
1678     }
1679 
1680     @Override
hasRestrictedProfiles()1681     public boolean hasRestrictedProfiles() {
1682         checkManageUsersPermission("hasRestrictedProfiles");
1683         final int callingUserId = UserHandle.getCallingUserId();
1684         synchronized (mUsersLock) {
1685             final int userSize = mUsers.size();
1686             for (int i = 0; i < userSize; i++) {
1687                 UserInfo profile = mUsers.valueAt(i).info;
1688                 if (callingUserId != profile.id
1689                         && profile.restrictedProfileParentId == callingUserId) {
1690                     return true;
1691                 }
1692             }
1693             return false;
1694         }
1695     }
1696 
1697     /*
1698      * Should be locked on mUsers before calling this.
1699      */
1700     @GuardedBy("mUsersLock")
getUserInfoLU(@serIdInt int userId)1701     private UserInfo getUserInfoLU(@UserIdInt int userId) {
1702         final UserData userData = mUsers.get(userId);
1703         // If it is partial and not in the process of being removed, return as unknown user.
1704         if (userData != null && userData.info.partial && !mRemovingUserIds.get(userId)) {
1705             Slog.w(LOG_TAG, "getUserInfo: unknown user #" + userId);
1706             return null;
1707         }
1708         return userData != null ? userData.info : null;
1709     }
1710 
1711     @GuardedBy("mUsersLock")
getUserDataLU(@serIdInt int userId)1712     private UserData getUserDataLU(@UserIdInt int userId) {
1713         final UserData userData = mUsers.get(userId);
1714         // If it is partial and not in the process of being removed, return as unknown user.
1715         if (userData != null && userData.info.partial && !mRemovingUserIds.get(userId)) {
1716             return null;
1717         }
1718         return userData;
1719     }
1720 
1721     /**
1722      * Obtains {@link #mUsersLock} and return UserInfo from mUsers.
1723      * <p>No permissions checking or any addition checks are made</p>
1724      */
getUserInfoNoChecks(@serIdInt int userId)1725     private UserInfo getUserInfoNoChecks(@UserIdInt int userId) {
1726         synchronized (mUsersLock) {
1727             final UserData userData = mUsers.get(userId);
1728             return userData != null ? userData.info : null;
1729         }
1730     }
1731 
1732     /**
1733      * Obtains {@link #mUsersLock} and return UserData from mUsers.
1734      * <p>No permissions checking or any addition checks are made</p>
1735      */
getUserDataNoChecks(@serIdInt int userId)1736     private UserData getUserDataNoChecks(@UserIdInt int userId) {
1737         synchronized (mUsersLock) {
1738             return mUsers.get(userId);
1739         }
1740     }
1741 
1742     /** Called by PackageManagerService */
exists(@serIdInt int userId)1743     public boolean exists(@UserIdInt int userId) {
1744         return mLocalService.exists(userId);
1745     }
1746 
1747     @Override
setUserName(@serIdInt int userId, String name)1748     public void setUserName(@UserIdInt int userId, String name) {
1749         checkManageUsersPermission("rename users");
1750         boolean changed = false;
1751         synchronized (mPackagesLock) {
1752             UserData userData = getUserDataNoChecks(userId);
1753             if (userData == null || userData.info.partial) {
1754                 Slog.w(LOG_TAG, "setUserName: unknown user #" + userId);
1755                 return;
1756             }
1757             if (name != null && !name.equals(userData.info.name)) {
1758                 userData.info.name = name;
1759                 writeUserLP(userData);
1760                 changed = true;
1761             }
1762         }
1763         if (changed) {
1764             final long ident = Binder.clearCallingIdentity();
1765             try {
1766                 sendUserInfoChangedBroadcast(userId);
1767             } finally {
1768                 Binder.restoreCallingIdentity(ident);
1769             }
1770         }
1771     }
1772 
1773     @Override
setUserIcon(@serIdInt int userId, Bitmap bitmap)1774     public void setUserIcon(@UserIdInt int userId, Bitmap bitmap) {
1775         try {
1776             checkManageUsersPermission("update users");
1777             enforceUserRestriction(UserManager.DISALLOW_SET_USER_ICON, userId,
1778                     "Cannot set user icon");
1779             mLocalService.setUserIcon(userId, bitmap);
1780         } catch (UserManager.CheckedUserOperationException e) {
1781             throw e.toServiceSpecificException();
1782         }
1783     }
1784 
1785 
1786 
sendUserInfoChangedBroadcast(@serIdInt int userId)1787     private void sendUserInfoChangedBroadcast(@UserIdInt int userId) {
1788         Intent changedIntent = new Intent(Intent.ACTION_USER_INFO_CHANGED);
1789         changedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
1790         changedIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
1791         mContext.sendBroadcastAsUser(changedIntent, UserHandle.ALL);
1792     }
1793 
1794     @Override
getUserIcon(int targetUserId)1795     public ParcelFileDescriptor getUserIcon(int targetUserId) {
1796         if (!hasManageUsersOrPermission(android.Manifest.permission.GET_ACCOUNTS_PRIVILEGED)) {
1797             throw new SecurityException("You need MANAGE_USERS or GET_ACCOUNTS_PRIVILEGED "
1798                     + "permissions to: get user icon");
1799         }
1800         String iconPath;
1801         synchronized (mPackagesLock) {
1802             UserInfo targetUserInfo = getUserInfoNoChecks(targetUserId);
1803             if (targetUserInfo == null || targetUserInfo.partial) {
1804                 Slog.w(LOG_TAG, "getUserIcon: unknown user #" + targetUserId);
1805                 return null;
1806             }
1807 
1808             final int callingUserId = UserHandle.getCallingUserId();
1809             final int callingGroupId = getUserInfoNoChecks(callingUserId).profileGroupId;
1810             final int targetGroupId = targetUserInfo.profileGroupId;
1811             final boolean sameGroup = (callingGroupId != UserInfo.NO_PROFILE_GROUP_ID
1812                     && callingGroupId == targetGroupId);
1813             if ((callingUserId != targetUserId) && !sameGroup) {
1814                 checkManageUsersPermission("get the icon of a user who is not related");
1815             }
1816 
1817             if (targetUserInfo.iconPath == null) {
1818                 return null;
1819             }
1820             iconPath = targetUserInfo.iconPath;
1821         }
1822 
1823         try {
1824             return ParcelFileDescriptor.open(
1825                     new File(iconPath), ParcelFileDescriptor.MODE_READ_ONLY);
1826         } catch (FileNotFoundException e) {
1827             Slog.e(LOG_TAG, "Couldn't find icon file", e);
1828         }
1829         return null;
1830     }
1831 
makeInitialized(@serIdInt int userId)1832     public void makeInitialized(@UserIdInt int userId) {
1833         if (DBG) Slog.d(LOG_TAG, "makeInitialized(" + userId + ")");
1834         checkManageUsersPermission("makeInitialized");
1835         boolean scheduleWriteUser = false;
1836         UserData userData;
1837         synchronized (mUsersLock) {
1838             userData = mUsers.get(userId);
1839             if (userData == null || userData.info.partial) {
1840                 Slog.w(LOG_TAG, "makeInitialized: unknown user #" + userId);
1841                 return;
1842             }
1843             if ((userData.info.flags & UserInfo.FLAG_INITIALIZED) == 0) {
1844                 userData.info.flags |= UserInfo.FLAG_INITIALIZED;
1845                 scheduleWriteUser = true;
1846             }
1847         }
1848         if (scheduleWriteUser) {
1849             scheduleWriteUser(userData);
1850         }
1851     }
1852 
1853     /**
1854      * If default guest restrictions haven't been initialized yet, add the basic
1855      * restrictions.
1856      */
initDefaultGuestRestrictions()1857     private void initDefaultGuestRestrictions() {
1858         synchronized (mGuestRestrictions) {
1859             if (mGuestRestrictions.isEmpty()) {
1860                 UserTypeDetails guestType = mUserTypes.get(UserManager.USER_TYPE_FULL_GUEST);
1861                 if (guestType == null) {
1862                     Slog.wtf(LOG_TAG, "Can't set default guest restrictions: type doesn't exist.");
1863                     return;
1864                 }
1865                 guestType.addDefaultRestrictionsTo(mGuestRestrictions);
1866             }
1867         }
1868     }
1869 
1870     @Override
getDefaultGuestRestrictions()1871     public Bundle getDefaultGuestRestrictions() {
1872         checkManageUsersPermission("getDefaultGuestRestrictions");
1873         synchronized (mGuestRestrictions) {
1874             return new Bundle(mGuestRestrictions);
1875         }
1876     }
1877 
1878     @Override
setDefaultGuestRestrictions(Bundle restrictions)1879     public void setDefaultGuestRestrictions(Bundle restrictions) {
1880         checkManageUsersPermission("setDefaultGuestRestrictions");
1881         synchronized (mGuestRestrictions) {
1882             mGuestRestrictions.clear();
1883             mGuestRestrictions.putAll(restrictions);
1884         }
1885         synchronized (mPackagesLock) {
1886             writeUserListLP();
1887         }
1888     }
1889 
1890     /**
1891      * See {@link UserManagerInternal#setDevicePolicyUserRestrictions}
1892      */
setDevicePolicyUserRestrictionsInner(@serIdInt int originatingUserId, @NonNull Bundle global, @NonNull RestrictionsSet local, boolean isDeviceOwner)1893     private void setDevicePolicyUserRestrictionsInner(@UserIdInt int originatingUserId,
1894             @NonNull Bundle global, @NonNull RestrictionsSet local,
1895             boolean isDeviceOwner) {
1896         boolean globalChanged, localChanged;
1897         List<Integer> updatedLocalTargetUserIds;
1898         synchronized (mRestrictionsLock) {
1899             // Update global and local restrictions if they were changed.
1900             globalChanged = mDevicePolicyGlobalUserRestrictions
1901                     .updateRestrictions(originatingUserId, global);
1902             updatedLocalTargetUserIds = getUpdatedTargetUserIdsFromLocalRestrictions(
1903                     originatingUserId, local);
1904             localChanged = updateLocalRestrictionsForTargetUsersLR(originatingUserId, local,
1905                     updatedLocalTargetUserIds);
1906 
1907             if (isDeviceOwner) {
1908                 // Remember the global restriction owner userId to be able to make a distinction
1909                 // in getUserRestrictionSource on who set local policies.
1910                 mDeviceOwnerUserId = originatingUserId;
1911             } else {
1912                 if (mDeviceOwnerUserId == originatingUserId) {
1913                     // When profile owner sets restrictions it passes null global bundle and we
1914                     // reset global restriction owner userId.
1915                     // This means this user used to have DO, but now the DO is gone and the user
1916                     // instead has PO.
1917                     mDeviceOwnerUserId = UserHandle.USER_NULL;
1918                 }
1919             }
1920         }
1921         if (DBG) {
1922             Slog.d(LOG_TAG, "setDevicePolicyUserRestrictions: "
1923                     + " originatingUserId=" + originatingUserId
1924                     + " global=" + global + (globalChanged ? " (changed)" : "")
1925                     + " local=" + local + (localChanged ? " (changed)" : "")
1926             );
1927         }
1928         // Don't call them within the mRestrictionsLock.
1929         synchronized (mPackagesLock) {
1930             if (globalChanged || localChanged) {
1931                 if (updatedLocalTargetUserIds.size() == 1
1932                         && updatedLocalTargetUserIds.contains(originatingUserId)) {
1933                     writeUserLP(getUserDataNoChecks(originatingUserId));
1934                 } else {
1935                     if (globalChanged) {
1936                         writeUserLP(getUserDataNoChecks(originatingUserId));
1937                     }
1938                     if (localChanged) {
1939                         for (int targetUserId : updatedLocalTargetUserIds) {
1940                             writeAllTargetUsersLP(targetUserId);
1941                         }
1942                     }
1943                 }
1944             }
1945         }
1946 
1947         synchronized (mRestrictionsLock) {
1948             if (globalChanged) {
1949                 applyUserRestrictionsForAllUsersLR();
1950             } else if (localChanged) {
1951                 for (int targetUserId : updatedLocalTargetUserIds) {
1952                     applyUserRestrictionsLR(targetUserId);
1953                 }
1954             }
1955         }
1956     }
1957 
1958     /**
1959      * @return the list of updated target user ids in device policy local restrictions for a
1960      * given originating user id.
1961      */
getUpdatedTargetUserIdsFromLocalRestrictions(int originatingUserId, @NonNull RestrictionsSet local)1962     private List<Integer> getUpdatedTargetUserIdsFromLocalRestrictions(int originatingUserId,
1963             @NonNull RestrictionsSet local) {
1964         List<Integer> targetUserIds = new ArrayList<>();
1965         // Update all the target user ids from the local restrictions set
1966         for (int i = 0; i < local.size(); i++) {
1967             targetUserIds.add(local.keyAt(i));
1968         }
1969         // Update the target user id from device policy local restrictions if the local
1970         // restrictions set does not contain the target user id.
1971         for (int i = 0; i < mDevicePolicyLocalUserRestrictions.size(); i++) {
1972             int targetUserId = mDevicePolicyLocalUserRestrictions.keyAt(i);
1973             RestrictionsSet restrictionsSet = mDevicePolicyLocalUserRestrictions.valueAt(i);
1974             if (!local.containsKey(targetUserId)
1975                     && restrictionsSet.containsKey(originatingUserId)) {
1976                 targetUserIds.add(targetUserId);
1977             }
1978         }
1979         return targetUserIds;
1980     }
1981 
1982     /**
1983      * Update restrictions for all target users in the restriction set. If a target user does not
1984      * exist in device policy local restrictions, remove the restrictions bundle for that target
1985      * user originating from the specified originating user.
1986      */
updateLocalRestrictionsForTargetUsersLR(int originatingUserId, RestrictionsSet local, List<Integer> updatedTargetUserIds)1987     private boolean updateLocalRestrictionsForTargetUsersLR(int originatingUserId,
1988             RestrictionsSet local, List<Integer> updatedTargetUserIds) {
1989         boolean changed = false;
1990         for (int targetUserId : updatedTargetUserIds) {
1991             Bundle restrictions = local.getRestrictions(targetUserId);
1992             if (restrictions == null) {
1993                 restrictions = new Bundle();
1994             }
1995             if (getDevicePolicyLocalRestrictionsForTargetUserLR(targetUserId)
1996                     .updateRestrictions(originatingUserId, restrictions)) {
1997                 changed = true;
1998             }
1999         }
2000         return changed;
2001     }
2002 
2003     /**
2004      * A new restriction set is created if a restriction set does not already exist for a given
2005      * target user.
2006      *
2007      * @return restrictions set for a given target user.
2008      */
getDevicePolicyLocalRestrictionsForTargetUserLR( int targetUserId)2009     private @NonNull RestrictionsSet getDevicePolicyLocalRestrictionsForTargetUserLR(
2010             int targetUserId) {
2011         RestrictionsSet result = mDevicePolicyLocalUserRestrictions.get(targetUserId);
2012         if (result == null) {
2013             result = new RestrictionsSet();
2014             mDevicePolicyLocalUserRestrictions.put(targetUserId, result);
2015         }
2016         return result;
2017     }
2018 
2019     @GuardedBy("mRestrictionsLock")
computeEffectiveUserRestrictionsLR(@serIdInt int userId)2020     private Bundle computeEffectiveUserRestrictionsLR(@UserIdInt int userId) {
2021         final Bundle baseRestrictions =
2022                 UserRestrictionsUtils.nonNull(mBaseUserRestrictions.getRestrictions(userId));
2023         final Bundle global = mDevicePolicyGlobalUserRestrictions.mergeAll();
2024         final RestrictionsSet local = getDevicePolicyLocalRestrictionsForTargetUserLR(userId);
2025 
2026         if (BundleUtils.isEmpty(global) && local.isEmpty()) {
2027             // Common case first.
2028             return baseRestrictions;
2029         }
2030         final Bundle effective = BundleUtils.clone(baseRestrictions);
2031         UserRestrictionsUtils.merge(effective, global);
2032         UserRestrictionsUtils.merge(effective, local.mergeAll());
2033 
2034         return effective;
2035     }
2036 
2037     @GuardedBy("mRestrictionsLock")
invalidateEffectiveUserRestrictionsLR(@serIdInt int userId)2038     private void invalidateEffectiveUserRestrictionsLR(@UserIdInt int userId) {
2039         if (DBG) {
2040             Slog.d(LOG_TAG, "invalidateEffectiveUserRestrictions userId=" + userId);
2041         }
2042         mCachedEffectiveUserRestrictions.remove(userId);
2043     }
2044 
getEffectiveUserRestrictions(@serIdInt int userId)2045     private Bundle getEffectiveUserRestrictions(@UserIdInt int userId) {
2046         synchronized (mRestrictionsLock) {
2047             Bundle restrictions = mCachedEffectiveUserRestrictions.getRestrictions(userId);
2048             if (restrictions == null) {
2049                 restrictions = computeEffectiveUserRestrictionsLR(userId);
2050                 mCachedEffectiveUserRestrictions.updateRestrictions(userId, restrictions);
2051             }
2052             return restrictions;
2053         }
2054     }
2055 
2056     /** @return a specific user restriction that's in effect currently. */
2057     @Override
hasUserRestriction(String restrictionKey, @UserIdInt int userId)2058     public boolean hasUserRestriction(String restrictionKey, @UserIdInt int userId) {
2059         checkManageOrInteractPermissionIfCallerInOtherProfileGroup(userId, "hasUserRestriction");
2060         return mLocalService.hasUserRestriction(restrictionKey, userId);
2061     }
2062 
2063     /** @return if any user has the given restriction. */
2064     @Override
hasUserRestrictionOnAnyUser(String restrictionKey)2065     public boolean hasUserRestrictionOnAnyUser(String restrictionKey) {
2066         if (!UserRestrictionsUtils.isValidRestriction(restrictionKey)) {
2067             return false;
2068         }
2069         final List<UserInfo> users = getUsers(/* excludeDying= */ true);
2070         for (int i = 0; i < users.size(); i++) {
2071             final int userId = users.get(i).id;
2072             Bundle restrictions = getEffectiveUserRestrictions(userId);
2073             if (restrictions != null && restrictions.getBoolean(restrictionKey)) {
2074                 return true;
2075             }
2076         }
2077         return false;
2078     }
2079 
2080     @Override
isSettingRestrictedForUser(String setting, @UserIdInt int userId, String value, int callingUid)2081     public boolean isSettingRestrictedForUser(String setting, @UserIdInt int userId,
2082             String value, int callingUid) {
2083         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
2084             throw new SecurityException("Non-system caller");
2085         }
2086         return UserRestrictionsUtils.isSettingRestrictedForUser(mContext, setting, userId,
2087                 value, callingUid);
2088     }
2089 
2090     @Override
addUserRestrictionsListener(final IUserRestrictionsListener listener)2091     public void addUserRestrictionsListener(final IUserRestrictionsListener listener) {
2092         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
2093             throw new SecurityException("Non-system caller");
2094         }
2095 
2096         // NOTE: unregistering not supported; only client is the settings provider,
2097         // which installs a single static permanent listener.  If that listener goes
2098         // bad it implies the whole system process is going to crash.
2099         mLocalService.addUserRestrictionsListener(
2100                 (int userId, Bundle newRestrict, Bundle prevRestrict) -> {
2101                     try {
2102                         listener.onUserRestrictionsChanged(userId, newRestrict, prevRestrict);
2103                     } catch (RemoteException re) {
2104                         Slog.e("IUserRestrictionsListener",
2105                                 "Unable to invoke listener: " + re.getMessage());
2106                     }
2107                 });
2108     }
2109 
2110     /**
2111      * @hide
2112      *
2113      * Returns who set a user restriction on a user.
2114      * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
2115      * @param restrictionKey the string key representing the restriction
2116      * @param userId the id of the user for whom to retrieve the restrictions.
2117      * @return The source of user restriction. Any combination of
2118      *         {@link UserManager#RESTRICTION_NOT_SET},
2119      *         {@link UserManager#RESTRICTION_SOURCE_SYSTEM},
2120      *         {@link UserManager#RESTRICTION_SOURCE_DEVICE_OWNER}
2121      *         and {@link UserManager#RESTRICTION_SOURCE_PROFILE_OWNER}
2122      */
2123     @Override
getUserRestrictionSource(String restrictionKey, @UserIdInt int userId)2124     public int getUserRestrictionSource(String restrictionKey, @UserIdInt int userId) {
2125         List<EnforcingUser> enforcingUsers = getUserRestrictionSources(restrictionKey,  userId);
2126         // Get "bitwise or" of restriction sources for all enforcing users.
2127         int result = UserManager.RESTRICTION_NOT_SET;
2128         for (int i = enforcingUsers.size() - 1; i >= 0; i--) {
2129             result |= enforcingUsers.get(i).getUserRestrictionSource();
2130         }
2131         return result;
2132     }
2133 
2134     @Override
getUserRestrictionSources( String restrictionKey, @UserIdInt int userId)2135     public List<EnforcingUser> getUserRestrictionSources(
2136             String restrictionKey, @UserIdInt int userId) {
2137         checkManageUsersPermission("getUserRestrictionSource");
2138 
2139         // Shortcut for the most common case
2140         if (!hasUserRestriction(restrictionKey, userId)) {
2141             return Collections.emptyList();
2142         }
2143 
2144         final List<EnforcingUser> result = new ArrayList<>();
2145 
2146         // Check if it is base restriction.
2147         if (hasBaseUserRestriction(restrictionKey, userId)) {
2148             result.add(new EnforcingUser(
2149                     UserHandle.USER_NULL, UserManager.RESTRICTION_SOURCE_SYSTEM));
2150         }
2151 
2152         synchronized (mRestrictionsLock) {
2153             // Check if it is set as a local restriction.
2154             result.addAll(getDevicePolicyLocalRestrictionsForTargetUserLR(userId).getEnforcingUsers(
2155                     restrictionKey, mDeviceOwnerUserId));
2156 
2157             // Check if it is set as a global restriction.
2158             result.addAll(mDevicePolicyGlobalUserRestrictions.getEnforcingUsers(restrictionKey,
2159                     mDeviceOwnerUserId));
2160         }
2161         return result;
2162     }
2163 
2164     /**
2165      * @return UserRestrictions that are in effect currently.  This always returns a new
2166      * {@link Bundle}.
2167      */
2168     @Override
getUserRestrictions(@serIdInt int userId)2169     public Bundle getUserRestrictions(@UserIdInt int userId) {
2170         checkManageOrInteractPermissionIfCallerInOtherProfileGroup(userId, "getUserRestrictions");
2171         return BundleUtils.clone(getEffectiveUserRestrictions(userId));
2172     }
2173 
2174     @Override
hasBaseUserRestriction(String restrictionKey, @UserIdInt int userId)2175     public boolean hasBaseUserRestriction(String restrictionKey, @UserIdInt int userId) {
2176         checkManageOrCreateUsersPermission("hasBaseUserRestriction");
2177         if (!UserRestrictionsUtils.isValidRestriction(restrictionKey)) {
2178             return false;
2179         }
2180         synchronized (mRestrictionsLock) {
2181             Bundle bundle = mBaseUserRestrictions.getRestrictions(userId);
2182             return (bundle != null && bundle.getBoolean(restrictionKey, false));
2183         }
2184     }
2185 
2186     @Override
setUserRestriction(String key, boolean value, @UserIdInt int userId)2187     public void setUserRestriction(String key, boolean value, @UserIdInt int userId) {
2188         checkManageUsersPermission("setUserRestriction");
2189         if (!UserRestrictionsUtils.isValidRestriction(key)) {
2190             return;
2191         }
2192         synchronized (mRestrictionsLock) {
2193             // Note we can't modify Bundles stored in mBaseUserRestrictions directly, so create
2194             // a copy.
2195             final Bundle newRestrictions = BundleUtils.clone(
2196                     mBaseUserRestrictions.getRestrictions(userId));
2197             newRestrictions.putBoolean(key, value);
2198 
2199             updateUserRestrictionsInternalLR(newRestrictions, userId);
2200         }
2201     }
2202 
2203     /**
2204      * Optionally updating user restrictions, calculate the effective user restrictions and also
2205      * propagate to other services and system settings.
2206      *
2207      * @param newBaseRestrictions User restrictions to set.
2208      *      If null, will not update user restrictions and only does the propagation.
2209      * @param userId target user ID.
2210      */
2211     @GuardedBy("mRestrictionsLock")
updateUserRestrictionsInternalLR( @ullable Bundle newBaseRestrictions, @UserIdInt int userId)2212     private void updateUserRestrictionsInternalLR(
2213             @Nullable Bundle newBaseRestrictions, @UserIdInt int userId) {
2214         final Bundle prevAppliedRestrictions = UserRestrictionsUtils.nonNull(
2215                 mAppliedUserRestrictions.getRestrictions(userId));
2216 
2217         // Update base restrictions.
2218         if (newBaseRestrictions != null) {
2219             // If newBaseRestrictions == the current one, it's probably a bug.
2220             final Bundle prevBaseRestrictions = mBaseUserRestrictions.getRestrictions(userId);
2221 
2222             Preconditions.checkState(prevBaseRestrictions != newBaseRestrictions);
2223             Preconditions.checkState(mCachedEffectiveUserRestrictions.getRestrictions(userId)
2224                     != newBaseRestrictions);
2225 
2226             if (mBaseUserRestrictions.updateRestrictions(userId, newBaseRestrictions)) {
2227                 scheduleWriteUser(getUserDataNoChecks(userId));
2228             }
2229         }
2230 
2231         final Bundle effective = computeEffectiveUserRestrictionsLR(userId);
2232 
2233         mCachedEffectiveUserRestrictions.updateRestrictions(userId, effective);
2234 
2235         // Apply the new restrictions.
2236         if (DBG) {
2237             debug("Applying user restrictions: userId=" + userId
2238                     + " new=" + effective + " prev=" + prevAppliedRestrictions);
2239         }
2240 
2241         if (mAppOpsService != null) { // We skip it until system-ready.
2242             mHandler.post(new Runnable() {
2243                 @Override
2244                 public void run() {
2245                     try {
2246                         mAppOpsService.setUserRestrictions(effective, mUserRestriconToken, userId);
2247                     } catch (RemoteException e) {
2248                         Slog.w(LOG_TAG, "Unable to notify AppOpsService of UserRestrictions");
2249                     }
2250                 }
2251             });
2252         }
2253 
2254         propagateUserRestrictionsLR(userId, effective, prevAppliedRestrictions);
2255 
2256         mAppliedUserRestrictions.updateRestrictions(userId, new Bundle(effective));
2257     }
2258 
propagateUserRestrictionsLR(final int userId, Bundle newRestrictions, Bundle prevRestrictions)2259     private void propagateUserRestrictionsLR(final int userId,
2260             Bundle newRestrictions, Bundle prevRestrictions) {
2261         // Note this method doesn't touch any state, meaning it doesn't require mRestrictionsLock
2262         // actually, but we still need some kind of synchronization otherwise we might end up
2263         // calling listeners out-of-order, thus "LR".
2264 
2265         if (UserRestrictionsUtils.areEqual(newRestrictions, prevRestrictions)) {
2266             return;
2267         }
2268 
2269         final Bundle newRestrictionsFinal = new Bundle(newRestrictions);
2270         final Bundle prevRestrictionsFinal = new Bundle(prevRestrictions);
2271 
2272         mHandler.post(new Runnable() {
2273             @Override
2274             public void run() {
2275                 UserRestrictionsUtils.applyUserRestrictions(
2276                         mContext, userId, newRestrictionsFinal, prevRestrictionsFinal);
2277 
2278                 final UserRestrictionsListener[] listeners;
2279                 synchronized (mUserRestrictionsListeners) {
2280                     listeners = new UserRestrictionsListener[mUserRestrictionsListeners.size()];
2281                     mUserRestrictionsListeners.toArray(listeners);
2282                 }
2283                 for (int i = 0; i < listeners.length; i++) {
2284                     listeners[i].onUserRestrictionsChanged(userId,
2285                             newRestrictionsFinal, prevRestrictionsFinal);
2286                 }
2287 
2288                 final Intent broadcast = new Intent(UserManager.ACTION_USER_RESTRICTIONS_CHANGED)
2289                         .setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
2290                 mContext.sendBroadcastAsUser(broadcast, UserHandle.of(userId));
2291             }
2292         });
2293     }
2294 
2295     // Package private for the inner class.
2296     @GuardedBy("mRestrictionsLock")
applyUserRestrictionsLR(@serIdInt int userId)2297     void applyUserRestrictionsLR(@UserIdInt int userId) {
2298         updateUserRestrictionsInternalLR(null, userId);
2299     }
2300 
2301     @GuardedBy("mRestrictionsLock")
2302     // Package private for the inner class.
applyUserRestrictionsForAllUsersLR()2303     void applyUserRestrictionsForAllUsersLR() {
2304         if (DBG) {
2305             debug("applyUserRestrictionsForAllUsersLR");
2306         }
2307         // First, invalidate all cached values.
2308         mCachedEffectiveUserRestrictions.removeAllRestrictions();
2309 
2310         // We don't want to call into ActivityManagerService while taking a lock, so we'll call
2311         // it on a handler.
2312         final Runnable r = new Runnable() {
2313             @Override
2314             public void run() {
2315                 // Then get the list of running users.
2316                 final int[] runningUsers;
2317                 try {
2318                     runningUsers = ActivityManager.getService().getRunningUserIds();
2319                 } catch (RemoteException e) {
2320                     Slog.w(LOG_TAG, "Unable to access ActivityManagerService");
2321                     return;
2322                 }
2323                 // Then re-calculate the effective restrictions and apply, only for running users.
2324                 // It's okay if a new user has started after the getRunningUserIds() call,
2325                 // because we'll do the same thing (re-calculate the restrictions and apply)
2326                 // when we start a user.
2327                 synchronized (mRestrictionsLock) {
2328                     for (int i = 0; i < runningUsers.length; i++) {
2329                         applyUserRestrictionsLR(runningUsers[i]);
2330                     }
2331                 }
2332             }
2333         };
2334         mHandler.post(r);
2335     }
2336 
2337     /**
2338      * Check if we've hit the limit of how many users can be created.
2339      */
isUserLimitReached()2340     private boolean isUserLimitReached() {
2341         int count;
2342         synchronized (mUsersLock) {
2343             count = getAliveUsersExcludingGuestsCountLU();
2344         }
2345         return count >= UserManager.getMaxSupportedUsers();
2346     }
2347 
2348     /**
2349      * Returns whether more users of the given type can be added (based on how many users of that
2350      * type already exist).
2351      *
2352      * <p>For checking whether more profiles can be added to a particular parent use
2353      * {@link #canAddMoreProfilesToUser}.
2354      */
canAddMoreUsersOfType(UserTypeDetails userTypeDetails)2355     private boolean canAddMoreUsersOfType(UserTypeDetails userTypeDetails) {
2356         final int max = userTypeDetails.getMaxAllowed();
2357         if (max == UserTypeDetails.UNLIMITED_NUMBER_OF_USERS) {
2358             return true; // Indicates that there is no max.
2359         }
2360         return getNumberOfUsersOfType(userTypeDetails.getName()) < max;
2361     }
2362 
2363     /**
2364      * Gets the number of users of the given user type.
2365      * Does not include users that are about to die.
2366      */
getNumberOfUsersOfType(String userType)2367     private int getNumberOfUsersOfType(String userType) {
2368         int count = 0;
2369         synchronized (mUsersLock) {
2370             final int size = mUsers.size();
2371             for (int i = 0; i < size; i++) {
2372                 final UserInfo user = mUsers.valueAt(i).info;
2373                 if (user.userType.equals(userType)
2374                         && !user.guestToRemove
2375                         && !mRemovingUserIds.get(user.id)
2376                         && !user.preCreated) {
2377                     count++;
2378                 }
2379             }
2380         }
2381         return count;
2382     }
2383 
2384     @Override
canAddMoreManagedProfiles(@serIdInt int userId, boolean allowedToRemoveOne)2385     public boolean canAddMoreManagedProfiles(@UserIdInt int userId, boolean allowedToRemoveOne) {
2386         return canAddMoreProfilesToUser(UserManager.USER_TYPE_PROFILE_MANAGED, userId,
2387                 allowedToRemoveOne);
2388     }
2389 
2390     /** Returns whether more profiles of the given type can be added to the given parent userId. */
2391     @Override
canAddMoreProfilesToUser(String userType, @UserIdInt int userId, boolean allowedToRemoveOne)2392     public boolean canAddMoreProfilesToUser(String userType, @UserIdInt int userId,
2393             boolean allowedToRemoveOne) {
2394         checkManageUsersPermission("check if more profiles can be added.");
2395         final UserTypeDetails type = mUserTypes.get(userType);
2396         if (type == null) {
2397             return false;
2398         }
2399         // Managed profiles have their own specific rules.
2400         final boolean isManagedProfile = type.isManagedProfile();
2401         if (isManagedProfile) {
2402             if (!mContext.getPackageManager().hasSystemFeature(
2403                     PackageManager.FEATURE_MANAGED_USERS)) {
2404                 return false;
2405             }
2406         }
2407         synchronized (mUsersLock) {
2408             // Check if the parent exists and its type is even allowed to have a profile.
2409             UserInfo userInfo = getUserInfoLU(userId);
2410             if (userInfo == null || !userInfo.canHaveProfile()) {
2411                 return false;
2412             }
2413 
2414             // Limit the number of profiles that can be created
2415             final int maxUsersOfType = getMaxUsersOfTypePerParent(type);
2416             if (maxUsersOfType != UserTypeDetails.UNLIMITED_NUMBER_OF_USERS) {
2417                 final int userTypeCount = getProfileIds(userId, userType, false).length;
2418                 final int profilesRemovedCount = userTypeCount > 0 && allowedToRemoveOne ? 1 : 0;
2419                 if (userTypeCount - profilesRemovedCount >= maxUsersOfType) {
2420                     return false;
2421                 }
2422                 // Allow creating a managed profile in the special case where there is only one user
2423                 if (isManagedProfile) {
2424                     int usersCountAfterRemoving = getAliveUsersExcludingGuestsCountLU()
2425                             - profilesRemovedCount;
2426                     return usersCountAfterRemoving == 1
2427                             || usersCountAfterRemoving < UserManager.getMaxSupportedUsers();
2428                 }
2429             }
2430         }
2431         return true;
2432     }
2433 
2434     @GuardedBy("mUsersLock")
getAliveUsersExcludingGuestsCountLU()2435     private int getAliveUsersExcludingGuestsCountLU() {
2436         int aliveUserCount = 0;
2437         final int totalUserCount = mUsers.size();
2438         // Skip over users being removed
2439         for (int i = 0; i < totalUserCount; i++) {
2440             UserInfo user = mUsers.valueAt(i).info;
2441             if (!mRemovingUserIds.get(user.id) && !user.isGuest() && !user.preCreated) {
2442                 aliveUserCount++;
2443             }
2444         }
2445         return aliveUserCount;
2446     }
2447 
2448     /**
2449      * Enforces that only the system UID or root's UID or apps that have the
2450      * {@link android.Manifest.permission#MANAGE_USERS MANAGE_USERS} and
2451      * {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL INTERACT_ACROSS_USERS_FULL}
2452      * permissions can make certain calls to the UserManager.
2453      *
2454      * @param message used as message if SecurityException is thrown
2455      * @throws SecurityException if the caller does not have enough privilege.
2456      */
checkManageUserAndAcrossUsersFullPermission(String message)2457     private static final void checkManageUserAndAcrossUsersFullPermission(String message) {
2458         final int uid = Binder.getCallingUid();
2459 
2460         if (uid == Process.SYSTEM_UID || uid == 0) {
2461             // System UID or root's UID are granted privilege.
2462             return;
2463         }
2464 
2465         if (hasPermissionGranted(Manifest.permission.MANAGE_USERS, uid)
2466                 && hasPermissionGranted(Manifest.permission.INTERACT_ACROSS_USERS_FULL, uid)) {
2467             // Apps with both permissions are granted privilege.
2468             return;
2469         }
2470 
2471         throw new SecurityException(
2472                 "You need MANAGE_USERS and INTERACT_ACROSS_USERS_FULL permission to: " + message);
2473     }
2474 
hasPermissionGranted(String permission, int uid)2475     private static boolean hasPermissionGranted(String permission, int uid) {
2476         return ActivityManager.checkComponentPermission(
2477                 permission, uid, /* owningUid = */-1, /* exported = */ true) ==
2478                 PackageManager.PERMISSION_GRANTED;
2479     }
2480 
2481     /**
2482      * Enforces that only the system UID or root's UID or apps that have the
2483      * {@link android.Manifest.permission#MANAGE_USERS MANAGE_USERS}
2484      * permission can make certain calls to the UserManager.
2485      *
2486      * @param message used as message if SecurityException is thrown
2487      * @throws SecurityException if the caller is not system or root
2488      * @see #hasManageUsersPermission()
2489      */
checkManageUsersPermission(String message)2490     private static final void checkManageUsersPermission(String message) {
2491         if (!hasManageUsersPermission()) {
2492             throw new SecurityException("You need MANAGE_USERS permission to: " + message);
2493         }
2494     }
2495 
2496     /**
2497      * Enforces that only the system UID or root's UID or apps that have the
2498      * {@link android.Manifest.permission#MANAGE_USERS MANAGE_USERS} or
2499      * {@link android.Manifest.permission#CREATE_USERS CREATE_USERS}
2500      * can make certain calls to the UserManager.
2501      *
2502      * @param message used as message if SecurityException is thrown
2503      * @throws SecurityException if the caller is not system or root
2504      * @see #hasManageOrCreateUsersPermission()
2505      */
checkManageOrCreateUsersPermission(String message)2506     private static final void checkManageOrCreateUsersPermission(String message) {
2507         if (!hasManageOrCreateUsersPermission()) {
2508             throw new SecurityException(
2509                     "You either need MANAGE_USERS or CREATE_USERS permission to: " + message);
2510         }
2511     }
2512 
2513     /**
2514      * Similar to {@link #checkManageOrCreateUsersPermission(String)} but when the caller is tries
2515      * to create user/profiles other than what is allowed for
2516      * {@link android.Manifest.permission#CREATE_USERS CREATE_USERS} permission, then it will only
2517      * allow callers with {@link android.Manifest.permission#MANAGE_USERS MANAGE_USERS} permission.
2518      */
checkManageOrCreateUsersPermission(int creationFlags)2519     private static final void checkManageOrCreateUsersPermission(int creationFlags) {
2520         if ((creationFlags & ~ALLOWED_FLAGS_FOR_CREATE_USERS_PERMISSION) == 0) {
2521             if (!hasManageOrCreateUsersPermission()) {
2522                 throw new SecurityException("You either need MANAGE_USERS or CREATE_USERS "
2523                         + "permission to create an user with flags: " + creationFlags);
2524             }
2525         } else if (!hasManageUsersPermission()) {
2526             throw new SecurityException("You need MANAGE_USERS permission to create an user "
2527                     + " with flags: " + creationFlags);
2528         }
2529     }
2530 
2531     /**
2532      * @return whether the calling UID is system UID or root's UID or the calling app has the
2533      * {@link android.Manifest.permission#MANAGE_USERS MANAGE_USERS}.
2534      */
hasManageUsersPermission()2535     private static final boolean hasManageUsersPermission() {
2536         final int callingUid = Binder.getCallingUid();
2537         return UserHandle.isSameApp(callingUid, Process.SYSTEM_UID)
2538                 || callingUid == Process.ROOT_UID
2539                 || hasPermissionGranted(android.Manifest.permission.MANAGE_USERS, callingUid);
2540     }
2541 
2542     /**
2543      * @return whether the calling UID is system UID or root's UID or the calling app has the
2544      * {@link android.Manifest.permission#MANAGE_USERS MANAGE_USERS} or the provided permission.
2545      */
hasManageUsersOrPermission(String alternativePermission)2546     private static final boolean hasManageUsersOrPermission(String alternativePermission) {
2547         final int callingUid = Binder.getCallingUid();
2548         return UserHandle.isSameApp(callingUid, Process.SYSTEM_UID)
2549                 || callingUid == Process.ROOT_UID
2550                 || hasPermissionGranted(android.Manifest.permission.MANAGE_USERS, callingUid)
2551                 || hasPermissionGranted(alternativePermission, callingUid);
2552     }
2553 
2554     /**
2555      * @return whether the calling UID is system UID or root's UID or the calling app has the
2556      * {@link android.Manifest.permission#MANAGE_USERS MANAGE_USERS} or
2557      * {@link android.Manifest.permission#CREATE_USERS CREATE_USERS}.
2558      */
hasManageOrCreateUsersPermission()2559     private static final boolean hasManageOrCreateUsersPermission() {
2560         return hasManageUsersOrPermission(android.Manifest.permission.CREATE_USERS);
2561     }
2562 
2563     /**
2564      * Enforces that only the system UID or root's UID (on any user) can make certain calls to the
2565      * UserManager.
2566      *
2567      * @param message used as message if SecurityException is thrown
2568      * @throws SecurityException if the caller is not system or root
2569      */
checkSystemOrRoot(String message)2570     private static void checkSystemOrRoot(String message) {
2571         final int uid = Binder.getCallingUid();
2572         if (!UserHandle.isSameApp(uid, Process.SYSTEM_UID) && uid != Process.ROOT_UID) {
2573             throw new SecurityException("Only system may: " + message);
2574         }
2575     }
2576 
writeBitmapLP(UserInfo info, Bitmap bitmap)2577     private void writeBitmapLP(UserInfo info, Bitmap bitmap) {
2578         try {
2579             File dir = new File(mUsersDir, Integer.toString(info.id));
2580             File file = new File(dir, USER_PHOTO_FILENAME);
2581             File tmp = new File(dir, USER_PHOTO_FILENAME_TMP);
2582             if (!dir.exists()) {
2583                 dir.mkdir();
2584                 FileUtils.setPermissions(
2585                         dir.getPath(),
2586                         FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
2587                         -1, -1);
2588             }
2589             FileOutputStream os;
2590             if (bitmap.compress(Bitmap.CompressFormat.PNG, 100, os = new FileOutputStream(tmp))
2591                     && tmp.renameTo(file) && SELinux.restorecon(file)) {
2592                 info.iconPath = file.getAbsolutePath();
2593             }
2594             try {
2595                 os.close();
2596             } catch (IOException ioe) {
2597                 // What the ... !
2598             }
2599             tmp.delete();
2600         } catch (FileNotFoundException e) {
2601             Slog.w(LOG_TAG, "Error setting photo for user ", e);
2602         }
2603     }
2604 
2605     /**
2606      * Returns an array of user ids.
2607      *
2608      * <p>This array is cached here for quick access, so do not modify or cache it elsewhere.
2609      *
2610      * @return the array of user ids.
2611      */
getUserIds()2612     public @NonNull int[] getUserIds() {
2613         synchronized (mUsersLock) {
2614             return mUserIds;
2615         }
2616     }
2617 
2618     /**
2619      * Returns an array of user ids, including pre-created users.
2620      *
2621      * <p>This method should only used for the specific cases that need to handle pre-created users;
2622      * most callers should call {@link #getUserIds()} instead.
2623      *
2624      * <p>This array is cached here for quick access, so do not modify or
2625      * cache it elsewhere.
2626      *
2627      * @return the array of user ids.
2628      */
getUserIdsIncludingPreCreated()2629     public @NonNull int[] getUserIdsIncludingPreCreated() {
2630         synchronized (mUsersLock) {
2631             return mUserIdsIncludingPreCreated;
2632         }
2633     }
2634 
2635     @GuardedBy({"mRestrictionsLock", "mPackagesLock"})
readUserListLP()2636     private void readUserListLP() {
2637         if (!mUserListFile.exists()) {
2638             fallbackToSingleUserLP();
2639             return;
2640         }
2641         FileInputStream fis = null;
2642         AtomicFile userListFile = new AtomicFile(mUserListFile);
2643         try {
2644             fis = userListFile.openRead();
2645             final TypedXmlPullParser parser = Xml.resolvePullParser(fis);
2646             int type;
2647             while ((type = parser.next()) != XmlPullParser.START_TAG
2648                     && type != XmlPullParser.END_DOCUMENT) {
2649                 // Skip
2650             }
2651 
2652             if (type != XmlPullParser.START_TAG) {
2653                 Slog.e(LOG_TAG, "Unable to read user list");
2654                 fallbackToSingleUserLP();
2655                 return;
2656             }
2657 
2658             mNextSerialNumber = -1;
2659             if (parser.getName().equals(TAG_USERS)) {
2660                 mNextSerialNumber =
2661                         parser.getAttributeInt(null, ATTR_NEXT_SERIAL_NO, mNextSerialNumber);
2662                 mUserVersion =
2663                         parser.getAttributeInt(null, ATTR_USER_VERSION, mUserVersion);
2664                 mUserTypeVersion =
2665                         parser.getAttributeInt(null, ATTR_USER_TYPE_VERSION, mUserTypeVersion);
2666             }
2667 
2668             // Pre-O global user restriction were stored as a single bundle (as opposed to per-user
2669             // currently), take care of it in case of upgrade.
2670             Bundle oldDevicePolicyGlobalUserRestrictions = null;
2671 
2672             while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
2673                 if (type == XmlPullParser.START_TAG) {
2674                     final String name = parser.getName();
2675                     if (name.equals(TAG_USER)) {
2676                         UserData userData = readUserLP(parser.getAttributeInt(null, ATTR_ID));
2677 
2678                         if (userData != null) {
2679                             synchronized (mUsersLock) {
2680                                 mUsers.put(userData.info.id, userData);
2681                                 if (mNextSerialNumber < 0
2682                                         || mNextSerialNumber <= userData.info.id) {
2683                                     mNextSerialNumber = userData.info.id + 1;
2684                                 }
2685                             }
2686                         }
2687                     } else if (name.equals(TAG_GUEST_RESTRICTIONS)) {
2688                         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
2689                                 && type != XmlPullParser.END_TAG) {
2690                             if (type == XmlPullParser.START_TAG) {
2691                                 if (parser.getName().equals(TAG_RESTRICTIONS)) {
2692                                     synchronized (mGuestRestrictions) {
2693                                         UserRestrictionsUtils
2694                                                 .readRestrictions(parser, mGuestRestrictions);
2695                                     }
2696                                 }
2697                                 break;
2698                             }
2699                         }
2700                     } else if (name.equals(TAG_DEVICE_OWNER_USER_ID)
2701                             // Legacy name, should only be encountered when upgrading from pre-O.
2702                             || name.equals(TAG_GLOBAL_RESTRICTION_OWNER_ID)) {
2703                         mDeviceOwnerUserId =
2704                                 parser.getAttributeInt(null, ATTR_ID, mDeviceOwnerUserId);
2705                     } else if (name.equals(TAG_DEVICE_POLICY_RESTRICTIONS)) {
2706                         // Should only happen when upgrading from pre-O (version < 7).
2707                         oldDevicePolicyGlobalUserRestrictions =
2708                                 UserRestrictionsUtils.readRestrictions(parser);
2709                     }
2710                 }
2711             }
2712 
2713             updateUserIds();
2714             upgradeIfNecessaryLP(oldDevicePolicyGlobalUserRestrictions);
2715         } catch (IOException | XmlPullParserException e) {
2716             fallbackToSingleUserLP();
2717         } finally {
2718             IoUtils.closeQuietly(fis);
2719         }
2720     }
2721 
2722     /**
2723      * Upgrade steps between versions, either for fixing bugs or changing the data format.
2724      * @param oldGlobalUserRestrictions Pre-O global device policy restrictions.
2725      */
2726     @GuardedBy({"mRestrictionsLock", "mPackagesLock"})
upgradeIfNecessaryLP(Bundle oldGlobalUserRestrictions)2727     private void upgradeIfNecessaryLP(Bundle oldGlobalUserRestrictions) {
2728         upgradeIfNecessaryLP(oldGlobalUserRestrictions, mUserVersion, mUserTypeVersion);
2729     }
2730 
2731     /**
2732      * Version of {@link #upgradeIfNecessaryLP(Bundle)} that takes in the userVersion for testing
2733      * purposes. For non-tests, use {@link #upgradeIfNecessaryLP(Bundle)}.
2734      */
2735     @GuardedBy({"mRestrictionsLock", "mPackagesLock"})
2736     @VisibleForTesting
upgradeIfNecessaryLP(Bundle oldGlobalUserRestrictions, int userVersion, int userTypeVersion)2737     void upgradeIfNecessaryLP(Bundle oldGlobalUserRestrictions, int userVersion,
2738             int userTypeVersion) {
2739         Set<Integer> userIdsToWrite = new ArraySet<>();
2740         final int originalVersion = mUserVersion;
2741         final int originalUserTypeVersion = mUserTypeVersion;
2742         if (userVersion < 1) {
2743             // Assign a proper name for the owner, if not initialized correctly before
2744             UserData userData = getUserDataNoChecks(UserHandle.USER_SYSTEM);
2745             if ("Primary".equals(userData.info.name)) {
2746                 userData.info.name =
2747                         mContext.getResources().getString(com.android.internal.R.string.owner_name);
2748                 userIdsToWrite.add(userData.info.id);
2749             }
2750             userVersion = 1;
2751         }
2752 
2753         if (userVersion < 2) {
2754             // Owner should be marked as initialized
2755             UserData userData = getUserDataNoChecks(UserHandle.USER_SYSTEM);
2756             if ((userData.info.flags & UserInfo.FLAG_INITIALIZED) == 0) {
2757                 userData.info.flags |= UserInfo.FLAG_INITIALIZED;
2758                 userIdsToWrite.add(userData.info.id);
2759             }
2760             userVersion = 2;
2761         }
2762 
2763 
2764         if (userVersion < 4) {
2765             userVersion = 4;
2766         }
2767 
2768         if (userVersion < 5) {
2769             initDefaultGuestRestrictions();
2770             userVersion = 5;
2771         }
2772 
2773         if (userVersion < 6) {
2774             final boolean splitSystemUser = UserManager.isSplitSystemUser();
2775             synchronized (mUsersLock) {
2776                 for (int i = 0; i < mUsers.size(); i++) {
2777                     UserData userData = mUsers.valueAt(i);
2778                     // In non-split mode, only user 0 can have restricted profiles
2779                     if (!splitSystemUser && userData.info.isRestricted()
2780                             && (userData.info.restrictedProfileParentId
2781                                     == UserInfo.NO_PROFILE_GROUP_ID)) {
2782                         userData.info.restrictedProfileParentId = UserHandle.USER_SYSTEM;
2783                         userIdsToWrite.add(userData.info.id);
2784                     }
2785                 }
2786             }
2787             userVersion = 6;
2788         }
2789 
2790         if (userVersion < 7) {
2791             // Previously only one user could enforce global restrictions, now it is per-user.
2792             synchronized (mRestrictionsLock) {
2793                 if (!BundleUtils.isEmpty(oldGlobalUserRestrictions)
2794                         && mDeviceOwnerUserId != UserHandle.USER_NULL) {
2795                     mDevicePolicyGlobalUserRestrictions.updateRestrictions(
2796                             mDeviceOwnerUserId, oldGlobalUserRestrictions);
2797                 }
2798                 // ENSURE_VERIFY_APPS is now enforced globally even if put by profile owner, so move
2799                 // it from local to global bundle for all users who set it.
2800                 UserRestrictionsUtils.moveRestriction(UserManager.ENSURE_VERIFY_APPS,
2801                         mDevicePolicyLocalUserRestrictions, mDevicePolicyGlobalUserRestrictions
2802                 );
2803             }
2804             // DISALLOW_CONFIG_WIFI was made a default guest restriction some time during version 6.
2805             final UserInfo currentGuestUser = findCurrentGuestUser();
2806             if (currentGuestUser != null && !hasUserRestriction(
2807                     UserManager.DISALLOW_CONFIG_WIFI, currentGuestUser.id)) {
2808                 setUserRestriction(UserManager.DISALLOW_CONFIG_WIFI, true, currentGuestUser.id);
2809             }
2810             userVersion = 7;
2811         }
2812 
2813         if (userVersion < 8) {
2814             // Added FLAG_FULL and FLAG_SYSTEM flags.
2815             synchronized (mUsersLock) {
2816                 UserData userData = mUsers.get(UserHandle.USER_SYSTEM);
2817                 userData.info.flags |= UserInfo.FLAG_SYSTEM;
2818                 if (!UserManager.isHeadlessSystemUserMode()) {
2819                     userData.info.flags |= UserInfo.FLAG_FULL;
2820                 }
2821                 userIdsToWrite.add(userData.info.id);
2822 
2823                 // Mark FULL all non-profile users except USER_SYSTEM.
2824                 // Start index at 1 since USER_SYSTEM is the smallest userId and we're skipping it.
2825                 for (int i = 1; i < mUsers.size(); i++) {
2826                     userData = mUsers.valueAt(i);
2827                     if ((userData.info.flags & UserInfo.FLAG_MANAGED_PROFILE) == 0) {
2828                         userData.info.flags |= UserInfo.FLAG_FULL;
2829                         userIdsToWrite.add(userData.info.id);
2830                     }
2831                 }
2832             }
2833             userVersion = 8;
2834         }
2835 
2836         if (userVersion < 9) {
2837             // Convert from UserInfo flags to UserTypes. Apply FLAG_PROFILE to FLAG_MANAGED_PROFILE.
2838             synchronized (mUsersLock) {
2839                 for (int i = 0; i < mUsers.size(); i++) {
2840                     UserData userData = mUsers.valueAt(i);
2841                     final int flags = userData.info.flags;
2842                     if ((flags & UserInfo.FLAG_SYSTEM) != 0) {
2843                         if ((flags & UserInfo.FLAG_FULL) != 0) {
2844                             userData.info.userType = UserManager.USER_TYPE_FULL_SYSTEM;
2845                         } else {
2846                             userData.info.userType = UserManager.USER_TYPE_SYSTEM_HEADLESS;
2847                         }
2848                     } else {
2849                         try {
2850                             userData.info.userType = UserInfo.getDefaultUserType(flags);
2851                         } catch (IllegalArgumentException e) {
2852                             // TODO(b/142482943): What should we do here? Delete user? Crashloop?
2853                             throw new IllegalStateException("Cannot upgrade user with flags "
2854                                     + Integer.toHexString(flags) + " because it doesn't correspond "
2855                                     + "to a valid user type.", e);
2856                         }
2857                     }
2858                     // OEMs are responsible for their own custom upgrade logic here.
2859 
2860                     final UserTypeDetails userTypeDetails = mUserTypes.get(userData.info.userType);
2861                     if (userTypeDetails == null) {
2862                         throw new IllegalStateException(
2863                                 "Cannot upgrade user with flags " + Integer.toHexString(flags)
2864                                         + " because " + userData.info.userType + " isn't defined"
2865                                         + " on this device!");
2866                     }
2867                     userData.info.flags |= userTypeDetails.getDefaultUserInfoFlags();
2868                     userIdsToWrite.add(userData.info.id);
2869                 }
2870             }
2871             userVersion = 9;
2872         }
2873 
2874         // Done with userVersion changes, moving on to deal with userTypeVersion upgrades
2875         // Upgrade from previous user type to a new user type
2876         final int newUserTypeVersion = UserTypeFactory.getUserTypeVersion();
2877         if (newUserTypeVersion > userTypeVersion) {
2878             synchronized (mUsersLock) {
2879                 upgradeUserTypesLU(UserTypeFactory.getUserTypeUpgrades(), mUserTypes,
2880                         userTypeVersion, userIdsToWrite);
2881             }
2882         }
2883 
2884         if (userVersion < USER_VERSION) {
2885             Slog.w(LOG_TAG, "User version " + mUserVersion + " didn't upgrade as expected to "
2886                     + USER_VERSION);
2887         } else {
2888             mUserVersion = userVersion;
2889             mUserTypeVersion = newUserTypeVersion;
2890 
2891             if (originalVersion < mUserVersion || originalUserTypeVersion < mUserTypeVersion) {
2892                 for (int userId : userIdsToWrite) {
2893                     UserData userData = getUserDataNoChecks(userId);
2894                     if (userData != null) {
2895                         writeUserLP(userData);
2896                     }
2897                 }
2898                 writeUserListLP();
2899             }
2900         }
2901     }
2902 
2903     @GuardedBy("mUsersLock")
2904     @VisibleForTesting
upgradeUserTypesLU(@onNull List<UserTypeFactory.UserTypeUpgrade> upgradeOps, @NonNull ArrayMap<String, UserTypeDetails> userTypes, final int formerUserTypeVersion, @NonNull Set<Integer> userIdsToWrite)2905     void upgradeUserTypesLU(@NonNull List<UserTypeFactory.UserTypeUpgrade> upgradeOps,
2906             @NonNull ArrayMap<String, UserTypeDetails> userTypes,
2907             final int formerUserTypeVersion,
2908             @NonNull Set<Integer> userIdsToWrite) {
2909         for (UserTypeFactory.UserTypeUpgrade userTypeUpgrade : upgradeOps) {
2910             if (DBG) {
2911                 Slog.i(LOG_TAG, "Upgrade: " + userTypeUpgrade.getFromType() + " to: "
2912                         + userTypeUpgrade.getToType() + " maxVersion: "
2913                         + userTypeUpgrade.getUpToVersion());
2914             }
2915 
2916             // upgrade user type if version up to getUpToVersion()
2917             if (formerUserTypeVersion <= userTypeUpgrade.getUpToVersion()) {
2918                 for (int i = 0; i < mUsers.size(); i++) {
2919                     UserData userData = mUsers.valueAt(i);
2920                     if (userTypeUpgrade.getFromType().equals(userData.info.userType)) {
2921                         final UserTypeDetails newUserType = userTypes.get(
2922                                 userTypeUpgrade.getToType());
2923 
2924                         if (newUserType == null) {
2925                             throw new IllegalStateException(
2926                                     "Upgrade destination user type not defined: "
2927                                             + userTypeUpgrade.getToType());
2928                         }
2929 
2930                         upgradeProfileToTypeLU(userData.info, newUserType);
2931                         userIdsToWrite.add(userData.info.id);
2932                     }
2933                 }
2934             }
2935         }
2936     }
2937 
2938     /**
2939      * Changes the user type of a profile to a new user type.
2940      * @param userInfo    The user to be updated.
2941      * @param newUserType The new user type.
2942      */
2943     @GuardedBy("mUsersLock")
2944     @VisibleForTesting
upgradeProfileToTypeLU(@onNull UserInfo userInfo, @NonNull UserTypeDetails newUserType)2945     void upgradeProfileToTypeLU(@NonNull UserInfo userInfo, @NonNull UserTypeDetails newUserType) {
2946         Slog.i(LOG_TAG, "Upgrading user " + userInfo.id
2947                 + " from " + userInfo.userType
2948                 + " to " + newUserType.getName());
2949 
2950         if (!userInfo.isProfile()) {
2951             throw new IllegalStateException(
2952                     "Can only upgrade profile types. " + userInfo.userType
2953                             + " is not a profile type.");
2954         }
2955 
2956         // Exceeded maximum profiles for parent user: log error, but allow upgrade
2957         if (!canAddMoreProfilesToUser(newUserType.getName(), userInfo.profileGroupId, false)) {
2958             Slog.w(LOG_TAG,
2959                     "Exceeded maximum profiles of type " + newUserType.getName() + " for user "
2960                             + userInfo.id + ". Maximum allowed= "
2961                             + newUserType.getMaxAllowedPerParent());
2962         }
2963 
2964         final UserTypeDetails oldUserType = mUserTypes.get(userInfo.userType);
2965         final int oldFlags;
2966         if (oldUserType != null) {
2967             oldFlags = oldUserType.getDefaultUserInfoFlags();
2968         } else {
2969             // if oldUserType is missing from config_user_types.xml -> can only assume FLAG_PROFILE
2970             oldFlags = UserInfo.FLAG_PROFILE;
2971         }
2972 
2973         //convert userData to newUserType
2974         userInfo.userType = newUserType.getName();
2975         // remove old default flags and add newUserType's default flags
2976         userInfo.flags = newUserType.getDefaultUserInfoFlags() | (userInfo.flags ^ oldFlags);
2977 
2978         // merge existing base restrictions with the new type's default restrictions
2979         synchronized (mRestrictionsLock) {
2980             if (!BundleUtils.isEmpty(newUserType.getDefaultRestrictions())) {
2981                 final Bundle newRestrictions = BundleUtils.clone(
2982                         mBaseUserRestrictions.getRestrictions(userInfo.id));
2983                 UserRestrictionsUtils.merge(newRestrictions,
2984                         newUserType.getDefaultRestrictions());
2985                 updateUserRestrictionsInternalLR(newRestrictions, userInfo.id);
2986                 if (DBG) {
2987                     Slog.i(LOG_TAG, "Updated user " + userInfo.id
2988                             + " restrictions to " + newRestrictions);
2989                 }
2990             }
2991         }
2992 
2993         // re-compute badge index
2994         userInfo.profileBadge = getFreeProfileBadgeLU(userInfo.profileGroupId, userInfo.userType);
2995     }
2996 
2997     @GuardedBy({"mPackagesLock", "mRestrictionsLock"})
fallbackToSingleUserLP()2998     private void fallbackToSingleUserLP() {
2999         int flags = UserInfo.FLAG_SYSTEM | UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_ADMIN
3000                 | UserInfo.FLAG_PRIMARY;
3001         // Create the system user
3002         String systemUserType = UserManager.isHeadlessSystemUserMode() ?
3003                 UserManager.USER_TYPE_SYSTEM_HEADLESS : UserManager.USER_TYPE_FULL_SYSTEM;
3004         flags |= mUserTypes.get(systemUserType).getDefaultUserInfoFlags();
3005         UserInfo system = new UserInfo(UserHandle.USER_SYSTEM, null, null, flags, systemUserType);
3006         UserData userData = putUserInfo(system);
3007         mNextSerialNumber = MIN_USER_ID;
3008         mUserVersion = USER_VERSION;
3009         mUserTypeVersion = UserTypeFactory.getUserTypeVersion();
3010 
3011         Bundle restrictions = new Bundle();
3012         try {
3013             final String[] defaultFirstUserRestrictions = mContext.getResources().getStringArray(
3014                     com.android.internal.R.array.config_defaultFirstUserRestrictions);
3015             for (String userRestriction : defaultFirstUserRestrictions) {
3016                 if (UserRestrictionsUtils.isValidRestriction(userRestriction)) {
3017                     restrictions.putBoolean(userRestriction, true);
3018                 }
3019             }
3020         } catch (Resources.NotFoundException e) {
3021             Slog.e(LOG_TAG, "Couldn't find resource: config_defaultFirstUserRestrictions", e);
3022         }
3023 
3024         if (!restrictions.isEmpty()) {
3025             synchronized (mRestrictionsLock) {
3026                 mBaseUserRestrictions.updateRestrictions(UserHandle.USER_SYSTEM,
3027                         restrictions);
3028             }
3029         }
3030 
3031         updateUserIds();
3032         initDefaultGuestRestrictions();
3033 
3034         writeUserLP(userData);
3035         writeUserListLP();
3036     }
3037 
getOwnerName()3038     private String getOwnerName() {
3039         return mOwnerName.get();
3040     }
3041 
invalidateOwnerNameIfNecessary(@onNull Resources res, boolean forceUpdate)3042     private void invalidateOwnerNameIfNecessary(@NonNull Resources res, boolean forceUpdate) {
3043         final int configChanges = mLastConfiguration.updateFrom(res.getConfiguration());
3044         if (forceUpdate || (configChanges & mOwnerNameTypedValue.changingConfigurations) != 0) {
3045             res.getValue(com.android.internal.R.string.owner_name, mOwnerNameTypedValue, true);
3046             final CharSequence ownerName = mOwnerNameTypedValue.coerceToString();
3047             mOwnerName.set(ownerName != null ? ownerName.toString() : null);
3048         }
3049     }
3050 
scheduleWriteUser(UserData userData)3051     private void scheduleWriteUser(UserData userData) {
3052         if (DBG) {
3053             debug("scheduleWriteUser");
3054         }
3055         // No need to wrap it within a lock -- worst case, we'll just post the same message
3056         // twice.
3057         if (!mHandler.hasMessages(WRITE_USER_MSG, userData)) {
3058             Message msg = mHandler.obtainMessage(WRITE_USER_MSG, userData);
3059             mHandler.sendMessageDelayed(msg, WRITE_USER_DELAY);
3060         }
3061     }
3062 
writeAllTargetUsersLP(int originatingUserId)3063     private void writeAllTargetUsersLP(int originatingUserId) {
3064         for (int i = 0; i < mDevicePolicyLocalUserRestrictions.size(); i++) {
3065             int targetUserId = mDevicePolicyLocalUserRestrictions.keyAt(i);
3066             RestrictionsSet restrictionsSet = mDevicePolicyLocalUserRestrictions.valueAt(i);
3067             if (restrictionsSet.containsKey(originatingUserId)) {
3068                 writeUserLP(getUserDataNoChecks(targetUserId));
3069             }
3070         }
3071     }
3072 
writeUserLP(UserData userData)3073     private void writeUserLP(UserData userData) {
3074         if (DBG) {
3075             debug("writeUserLP " + userData);
3076         }
3077         FileOutputStream fos = null;
3078         AtomicFile userFile = new AtomicFile(new File(mUsersDir, userData.info.id + XML_SUFFIX));
3079         try {
3080             fos = userFile.startWrite();
3081             writeUserLP(userData, fos);
3082             userFile.finishWrite(fos);
3083         } catch (Exception ioe) {
3084             Slog.e(LOG_TAG, "Error writing user info " + userData.info.id, ioe);
3085             userFile.failWrite(fos);
3086         }
3087     }
3088 
3089     /*
3090      * Writes the user file in this format:
3091      *
3092      * <user flags="20039023" id="0">
3093      *   <name>Primary</name>
3094      * </user>
3095      */
3096     @VisibleForTesting
writeUserLP(UserData userData, OutputStream os)3097     void writeUserLP(UserData userData, OutputStream os)
3098             throws IOException, XmlPullParserException {
3099         final TypedXmlSerializer serializer = Xml.resolveSerializer(os);
3100         serializer.startDocument(null, true);
3101         serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
3102 
3103         final UserInfo userInfo = userData.info;
3104         serializer.startTag(null, TAG_USER);
3105         serializer.attributeInt(null, ATTR_ID, userInfo.id);
3106         serializer.attributeInt(null, ATTR_SERIAL_NO, userInfo.serialNumber);
3107         serializer.attributeInt(null, ATTR_FLAGS, userInfo.flags);
3108         serializer.attribute(null, ATTR_TYPE, userInfo.userType);
3109         serializer.attributeLong(null, ATTR_CREATION_TIME, userInfo.creationTime);
3110         serializer.attributeLong(null, ATTR_LAST_LOGGED_IN_TIME, userInfo.lastLoggedInTime);
3111         if (userInfo.lastLoggedInFingerprint != null) {
3112             serializer.attribute(null, ATTR_LAST_LOGGED_IN_FINGERPRINT,
3113                     userInfo.lastLoggedInFingerprint);
3114         }
3115         if (userInfo.iconPath != null) {
3116             serializer.attribute(null,  ATTR_ICON_PATH, userInfo.iconPath);
3117         }
3118         if (userInfo.partial) {
3119             serializer.attributeBoolean(null, ATTR_PARTIAL, true);
3120         }
3121         if (userInfo.preCreated) {
3122             serializer.attributeBoolean(null, ATTR_PRE_CREATED, true);
3123         }
3124         if (userInfo.convertedFromPreCreated) {
3125             serializer.attributeBoolean(null, ATTR_CONVERTED_FROM_PRE_CREATED, true);
3126         }
3127         if (userInfo.guestToRemove) {
3128             serializer.attributeBoolean(null, ATTR_GUEST_TO_REMOVE, true);
3129         }
3130         if (userInfo.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
3131             serializer.attributeInt(null, ATTR_PROFILE_GROUP_ID, userInfo.profileGroupId);
3132         }
3133         serializer.attributeInt(null, ATTR_PROFILE_BADGE, userInfo.profileBadge);
3134         if (userInfo.restrictedProfileParentId != UserInfo.NO_PROFILE_GROUP_ID) {
3135             serializer.attributeInt(null, ATTR_RESTRICTED_PROFILE_PARENT_ID,
3136                     userInfo.restrictedProfileParentId);
3137         }
3138         // Write seed data
3139         if (userData.persistSeedData) {
3140             if (userData.seedAccountName != null) {
3141                 serializer.attribute(null, ATTR_SEED_ACCOUNT_NAME, userData.seedAccountName);
3142             }
3143             if (userData.seedAccountType != null) {
3144                 serializer.attribute(null, ATTR_SEED_ACCOUNT_TYPE, userData.seedAccountType);
3145             }
3146         }
3147         if (userInfo.name != null) {
3148             serializer.startTag(null, TAG_NAME);
3149             serializer.text(userInfo.name);
3150             serializer.endTag(null, TAG_NAME);
3151         }
3152         synchronized (mRestrictionsLock) {
3153             UserRestrictionsUtils.writeRestrictions(serializer,
3154                     mBaseUserRestrictions.getRestrictions(userInfo.id), TAG_RESTRICTIONS);
3155             getDevicePolicyLocalRestrictionsForTargetUserLR(userInfo.id).writeRestrictions(
3156                     serializer, TAG_DEVICE_POLICY_LOCAL_RESTRICTIONS);
3157             UserRestrictionsUtils.writeRestrictions(serializer,
3158                     mDevicePolicyGlobalUserRestrictions.getRestrictions(userInfo.id),
3159                     TAG_DEVICE_POLICY_GLOBAL_RESTRICTIONS);
3160         }
3161 
3162         if (userData.account != null) {
3163             serializer.startTag(null, TAG_ACCOUNT);
3164             serializer.text(userData.account);
3165             serializer.endTag(null, TAG_ACCOUNT);
3166         }
3167 
3168         if (userData.persistSeedData && userData.seedAccountOptions != null) {
3169             serializer.startTag(null, TAG_SEED_ACCOUNT_OPTIONS);
3170             userData.seedAccountOptions.saveToXml(serializer);
3171             serializer.endTag(null, TAG_SEED_ACCOUNT_OPTIONS);
3172         }
3173 
3174         if (userData.getLastRequestQuietModeEnabledMillis() != 0L) {
3175             serializer.startTag(/* namespace */ null, TAG_LAST_REQUEST_QUIET_MODE_ENABLED_CALL);
3176             serializer.text(String.valueOf(userData.getLastRequestQuietModeEnabledMillis()));
3177             serializer.endTag(/* namespace */ null, TAG_LAST_REQUEST_QUIET_MODE_ENABLED_CALL);
3178         }
3179 
3180         serializer.endTag(null, TAG_USER);
3181 
3182         serializer.endDocument();
3183     }
3184 
3185     /*
3186      * Writes the user list file in this format:
3187      *
3188      * <users nextSerialNumber="3">
3189      *   <user id="0"></user>
3190      *   <user id="2"></user>
3191      * </users>
3192      */
3193     @GuardedBy({"mRestrictionsLock", "mPackagesLock"})
writeUserListLP()3194     private void writeUserListLP() {
3195         if (DBG) {
3196             debug("writeUserList");
3197         }
3198         FileOutputStream fos = null;
3199         AtomicFile userListFile = new AtomicFile(mUserListFile);
3200         try {
3201             fos = userListFile.startWrite();
3202             final TypedXmlSerializer serializer = Xml.resolveSerializer(fos);
3203             serializer.startDocument(null, true);
3204             serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
3205 
3206             serializer.startTag(null, TAG_USERS);
3207             serializer.attributeInt(null, ATTR_NEXT_SERIAL_NO, mNextSerialNumber);
3208             serializer.attributeInt(null, ATTR_USER_VERSION, mUserVersion);
3209             serializer.attributeInt(null, ATTR_USER_TYPE_VERSION, mUserTypeVersion);
3210 
3211             serializer.startTag(null, TAG_GUEST_RESTRICTIONS);
3212             synchronized (mGuestRestrictions) {
3213                 UserRestrictionsUtils
3214                         .writeRestrictions(serializer, mGuestRestrictions, TAG_RESTRICTIONS);
3215             }
3216             serializer.endTag(null, TAG_GUEST_RESTRICTIONS);
3217             serializer.startTag(null, TAG_DEVICE_OWNER_USER_ID);
3218             serializer.attributeInt(null, ATTR_ID, mDeviceOwnerUserId);
3219             serializer.endTag(null, TAG_DEVICE_OWNER_USER_ID);
3220             int[] userIdsToWrite;
3221             synchronized (mUsersLock) {
3222                 userIdsToWrite = new int[mUsers.size()];
3223                 for (int i = 0; i < userIdsToWrite.length; i++) {
3224                     UserInfo user = mUsers.valueAt(i).info;
3225                     userIdsToWrite[i] = user.id;
3226                 }
3227             }
3228             for (int id : userIdsToWrite) {
3229                 serializer.startTag(null, TAG_USER);
3230                 serializer.attributeInt(null, ATTR_ID, id);
3231                 serializer.endTag(null, TAG_USER);
3232             }
3233 
3234             serializer.endTag(null, TAG_USERS);
3235 
3236             serializer.endDocument();
3237             userListFile.finishWrite(fos);
3238         } catch (Exception e) {
3239             userListFile.failWrite(fos);
3240             Slog.e(LOG_TAG, "Error writing user list");
3241         }
3242     }
3243 
readUserLP(int id)3244     private UserData readUserLP(int id) {
3245         FileInputStream fis = null;
3246         try {
3247             AtomicFile userFile =
3248                     new AtomicFile(new File(mUsersDir, Integer.toString(id) + XML_SUFFIX));
3249             fis = userFile.openRead();
3250             return readUserLP(id, fis);
3251         } catch (IOException ioe) {
3252             Slog.e(LOG_TAG, "Error reading user list");
3253         } catch (XmlPullParserException pe) {
3254             Slog.e(LOG_TAG, "Error reading user list");
3255         } finally {
3256             IoUtils.closeQuietly(fis);
3257         }
3258         return null;
3259     }
3260 
3261     @VisibleForTesting
readUserLP(int id, InputStream is)3262     UserData readUserLP(int id, InputStream is) throws IOException,
3263             XmlPullParserException {
3264         int flags = 0;
3265         String userType = null;
3266         int serialNumber = id;
3267         String name = null;
3268         String account = null;
3269         String iconPath = null;
3270         long creationTime = 0L;
3271         long lastLoggedInTime = 0L;
3272         long lastRequestQuietModeEnabledTimestamp = 0L;
3273         String lastLoggedInFingerprint = null;
3274         int profileGroupId = UserInfo.NO_PROFILE_GROUP_ID;
3275         int profileBadge = 0;
3276         int restrictedProfileParentId = UserInfo.NO_PROFILE_GROUP_ID;
3277         boolean partial = false;
3278         boolean preCreated = false;
3279         boolean converted = false;
3280         boolean guestToRemove = false;
3281         boolean persistSeedData = false;
3282         String seedAccountName = null;
3283         String seedAccountType = null;
3284         PersistableBundle seedAccountOptions = null;
3285         Bundle baseRestrictions = null;
3286         Bundle legacyLocalRestrictions = null;
3287         RestrictionsSet localRestrictions = null;
3288         Bundle globalRestrictions = null;
3289 
3290         final TypedXmlPullParser parser = Xml.resolvePullParser(is);
3291         int type;
3292         while ((type = parser.next()) != XmlPullParser.START_TAG
3293                 && type != XmlPullParser.END_DOCUMENT) {
3294             // Skip
3295         }
3296 
3297         if (type != XmlPullParser.START_TAG) {
3298             Slog.e(LOG_TAG, "Unable to read user " + id);
3299             return null;
3300         }
3301 
3302         if (type == XmlPullParser.START_TAG && parser.getName().equals(TAG_USER)) {
3303             int storedId = parser.getAttributeInt(null, ATTR_ID, -1);
3304             if (storedId != id) {
3305                 Slog.e(LOG_TAG, "User id does not match the file name");
3306                 return null;
3307             }
3308             serialNumber = parser.getAttributeInt(null, ATTR_SERIAL_NO, id);
3309             flags = parser.getAttributeInt(null, ATTR_FLAGS, 0);
3310             userType = parser.getAttributeValue(null, ATTR_TYPE);
3311             userType = userType != null ? userType.intern() : null;
3312             iconPath = parser.getAttributeValue(null, ATTR_ICON_PATH);
3313             creationTime = parser.getAttributeLong(null, ATTR_CREATION_TIME, 0);
3314             lastLoggedInTime = parser.getAttributeLong(null, ATTR_LAST_LOGGED_IN_TIME, 0);
3315             lastLoggedInFingerprint = parser.getAttributeValue(null,
3316                     ATTR_LAST_LOGGED_IN_FINGERPRINT);
3317             profileGroupId = parser.getAttributeInt(null, ATTR_PROFILE_GROUP_ID,
3318                     UserInfo.NO_PROFILE_GROUP_ID);
3319             profileBadge = parser.getAttributeInt(null, ATTR_PROFILE_BADGE, 0);
3320             restrictedProfileParentId = parser.getAttributeInt(null,
3321                     ATTR_RESTRICTED_PROFILE_PARENT_ID, UserInfo.NO_PROFILE_GROUP_ID);
3322             partial = parser.getAttributeBoolean(null, ATTR_PARTIAL, false);
3323             preCreated = parser.getAttributeBoolean(null, ATTR_PRE_CREATED, false);
3324             converted = parser.getAttributeBoolean(null, ATTR_CONVERTED_FROM_PRE_CREATED, false);
3325             guestToRemove = parser.getAttributeBoolean(null, ATTR_GUEST_TO_REMOVE, false);
3326 
3327             seedAccountName = parser.getAttributeValue(null, ATTR_SEED_ACCOUNT_NAME);
3328             seedAccountType = parser.getAttributeValue(null, ATTR_SEED_ACCOUNT_TYPE);
3329             if (seedAccountName != null || seedAccountType != null) {
3330                 persistSeedData = true;
3331             }
3332 
3333             int outerDepth = parser.getDepth();
3334             while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
3335                     && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
3336                 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
3337                     continue;
3338                 }
3339                 String tag = parser.getName();
3340                 if (TAG_NAME.equals(tag)) {
3341                     type = parser.next();
3342                     if (type == XmlPullParser.TEXT) {
3343                         name = parser.getText();
3344                     }
3345                 } else if (TAG_RESTRICTIONS.equals(tag)) {
3346                     baseRestrictions = UserRestrictionsUtils.readRestrictions(parser);
3347                 } else if (TAG_DEVICE_POLICY_RESTRICTIONS.equals(tag)) {
3348                     legacyLocalRestrictions = UserRestrictionsUtils.readRestrictions(parser);
3349                 } else if (TAG_DEVICE_POLICY_LOCAL_RESTRICTIONS.equals(tag)) {
3350                     localRestrictions = RestrictionsSet.readRestrictions(parser,
3351                             TAG_DEVICE_POLICY_LOCAL_RESTRICTIONS);
3352                 } else if (TAG_DEVICE_POLICY_GLOBAL_RESTRICTIONS.equals(tag)) {
3353                     globalRestrictions = UserRestrictionsUtils.readRestrictions(parser);
3354                 } else if (TAG_ACCOUNT.equals(tag)) {
3355                     type = parser.next();
3356                     if (type == XmlPullParser.TEXT) {
3357                         account = parser.getText();
3358                     }
3359                 } else if (TAG_SEED_ACCOUNT_OPTIONS.equals(tag)) {
3360                     seedAccountOptions = PersistableBundle.restoreFromXml(parser);
3361                     persistSeedData = true;
3362                 } else if (TAG_LAST_REQUEST_QUIET_MODE_ENABLED_CALL.equals(tag)) {
3363                     type = parser.next();
3364                     if (type == XmlPullParser.TEXT) {
3365                         lastRequestQuietModeEnabledTimestamp = Long.parseLong(parser.getText());
3366                     }
3367                 }
3368             }
3369         }
3370 
3371         // Create the UserInfo object that gets passed around
3372         UserInfo userInfo = new UserInfo(id, name, iconPath, flags, userType);
3373         userInfo.serialNumber = serialNumber;
3374         userInfo.creationTime = creationTime;
3375         userInfo.lastLoggedInTime = lastLoggedInTime;
3376         userInfo.lastLoggedInFingerprint = lastLoggedInFingerprint;
3377         userInfo.partial = partial;
3378         userInfo.preCreated = preCreated;
3379         userInfo.convertedFromPreCreated = converted;
3380         userInfo.guestToRemove = guestToRemove;
3381         userInfo.profileGroupId = profileGroupId;
3382         userInfo.profileBadge = profileBadge;
3383         userInfo.restrictedProfileParentId = restrictedProfileParentId;
3384 
3385         // Create the UserData object that's internal to this class
3386         UserData userData = new UserData();
3387         userData.info = userInfo;
3388         userData.account = account;
3389         userData.seedAccountName = seedAccountName;
3390         userData.seedAccountType = seedAccountType;
3391         userData.persistSeedData = persistSeedData;
3392         userData.seedAccountOptions = seedAccountOptions;
3393         userData.setLastRequestQuietModeEnabledMillis(lastRequestQuietModeEnabledTimestamp);
3394 
3395         synchronized (mRestrictionsLock) {
3396             if (baseRestrictions != null) {
3397                 mBaseUserRestrictions.updateRestrictions(id, baseRestrictions);
3398             }
3399             if (localRestrictions != null) {
3400                 mDevicePolicyLocalUserRestrictions.put(id, localRestrictions);
3401                 if (legacyLocalRestrictions != null) {
3402                     Slog.wtf(LOG_TAG, "Seeing both legacy and current local restrictions in xml");
3403                 }
3404             } else if (legacyLocalRestrictions != null) {
3405                 mDevicePolicyLocalUserRestrictions.put(id,
3406                         new RestrictionsSet(id, legacyLocalRestrictions));
3407             }
3408             if (globalRestrictions != null) {
3409                 mDevicePolicyGlobalUserRestrictions.updateRestrictions(id,
3410                         globalRestrictions);
3411             }
3412         }
3413         return userData;
3414     }
3415 
3416     /**
3417      * Removes the app restrictions file for a specific package and user id, if it exists.
3418      *
3419      * @return whether there were any restrictions.
3420      */
cleanAppRestrictionsForPackageLAr(String pkg, @UserIdInt int userId)3421     private static boolean cleanAppRestrictionsForPackageLAr(String pkg, @UserIdInt int userId) {
3422         final File dir = Environment.getUserSystemDirectory(userId);
3423         final File resFile = new File(dir, packageToRestrictionsFileName(pkg));
3424         if (resFile.exists()) {
3425             resFile.delete();
3426             return true;
3427         }
3428         return false;
3429     }
3430 
3431     /**
3432      * Creates a profile user. Used for actual profiles, like
3433      * {@link UserManager#USER_TYPE_PROFILE_MANAGED},
3434      * as well as for {@link UserManager#USER_TYPE_FULL_RESTRICTED}.
3435      */
3436     @Override
createProfileForUserWithThrow(@ullable String name, @NonNull String userType, @UserInfoFlag int flags, @UserIdInt int userId, @Nullable String[] disallowedPackages)3437     public UserInfo createProfileForUserWithThrow(@Nullable String name, @NonNull String userType,
3438             @UserInfoFlag int flags, @UserIdInt int userId, @Nullable String[] disallowedPackages)
3439             throws ServiceSpecificException {
3440         checkManageOrCreateUsersPermission(flags);
3441         try {
3442             return createUserInternal(name, userType, flags, userId, disallowedPackages);
3443         } catch (UserManager.CheckedUserOperationException e) {
3444             throw e.toServiceSpecificException();
3445         }
3446     }
3447 
3448     /**
3449      * @see #createProfileForUser
3450      */
3451     @Override
createProfileForUserEvenWhenDisallowedWithThrow(String name, @NonNull String userType, @UserInfoFlag int flags, @UserIdInt int userId, @Nullable String[] disallowedPackages)3452     public UserInfo createProfileForUserEvenWhenDisallowedWithThrow(String name,
3453             @NonNull String userType,
3454             @UserInfoFlag int flags, @UserIdInt int userId, @Nullable String[] disallowedPackages)
3455             throws ServiceSpecificException {
3456         checkManageOrCreateUsersPermission(flags);
3457         try {
3458             return createUserInternalUnchecked(name, userType, flags, userId,
3459                     /* preCreate= */ false, disallowedPackages, /* token= */ null);
3460         } catch (UserManager.CheckedUserOperationException e) {
3461             throw e.toServiceSpecificException();
3462         }
3463     }
3464 
3465     @Override
createUserWithThrow(String name, @NonNull String userType, @UserInfoFlag int flags)3466     public UserInfo createUserWithThrow(String name, @NonNull String userType,
3467             @UserInfoFlag int flags)
3468             throws ServiceSpecificException {
3469         checkManageOrCreateUsersPermission(flags);
3470         try {
3471             return createUserInternal(name, userType, flags, UserHandle.USER_NULL,
3472                     /* disallowedPackages= */ null);
3473         } catch (UserManager.CheckedUserOperationException e) {
3474             throw e.toServiceSpecificException();
3475         }
3476     }
3477 
3478     @Override
preCreateUserWithThrow(String userType)3479     public UserInfo preCreateUserWithThrow(String userType) throws ServiceSpecificException {
3480         final UserTypeDetails userTypeDetails = mUserTypes.get(userType);
3481         final int flags = userTypeDetails != null ? userTypeDetails.getDefaultUserInfoFlags() : 0;
3482 
3483         checkManageOrCreateUsersPermission(flags);
3484 
3485         Preconditions.checkArgument(isUserTypeEligibleForPreCreation(userTypeDetails),
3486                 "cannot pre-create user of type " + userType);
3487         Slog.i(LOG_TAG, "Pre-creating user of type " + userType);
3488 
3489         try {
3490             return createUserInternalUnchecked(/* name= */ null, userType, flags,
3491                     /* parentId= */ UserHandle.USER_NULL, /* preCreate= */ true,
3492                     /* disallowedPackages= */ null, /* token= */ null);
3493         } catch (UserManager.CheckedUserOperationException e) {
3494             throw e.toServiceSpecificException();
3495         }
3496     }
3497 
createUserInternal(@ullable String name, @NonNull String userType, @UserInfoFlag int flags, @UserIdInt int parentId, @Nullable String[] disallowedPackages)3498     private UserInfo createUserInternal(@Nullable String name, @NonNull String userType,
3499             @UserInfoFlag int flags, @UserIdInt int parentId,
3500             @Nullable String[] disallowedPackages)
3501             throws UserManager.CheckedUserOperationException {
3502         String restriction = (UserManager.isUserTypeManagedProfile(userType))
3503                 ? UserManager.DISALLOW_ADD_MANAGED_PROFILE
3504                 : UserManager.DISALLOW_ADD_USER;
3505         enforceUserRestriction(restriction, UserHandle.getCallingUserId(),
3506                 "Cannot add user");
3507         return createUserInternalUnchecked(name, userType, flags, parentId,
3508                 /* preCreate= */ false, disallowedPackages, /* token= */ null);
3509     }
3510 
createUserInternalUnchecked(@ullable String name, @NonNull String userType, @UserInfoFlag int flags, @UserIdInt int parentId, boolean preCreate, @Nullable String[] disallowedPackages, @Nullable Object token)3511     private UserInfo createUserInternalUnchecked(@Nullable String name,
3512             @NonNull String userType, @UserInfoFlag int flags, @UserIdInt int parentId,
3513             boolean preCreate, @Nullable String[] disallowedPackages,
3514             @Nullable Object token)
3515             throws UserManager.CheckedUserOperationException {
3516         final int nextProbableUserId = getNextAvailableId();
3517         final TimingsTraceAndSlog t = new TimingsTraceAndSlog();
3518         t.traceBegin("createUser-" + flags);
3519         final long sessionId = logUserCreateJourneyBegin(nextProbableUserId, userType, flags);
3520         UserInfo newUser = null;
3521         try {
3522             newUser = createUserInternalUncheckedNoTracing(name, userType, flags, parentId,
3523                         preCreate, disallowedPackages, t, token);
3524             return newUser;
3525         } finally {
3526             logUserCreateJourneyFinish(sessionId, nextProbableUserId, newUser != null);
3527             t.traceEnd();
3528         }
3529     }
3530 
createUserInternalUncheckedNoTracing(@ullable String name, @NonNull String userType, @UserInfoFlag int flags, @UserIdInt int parentId, boolean preCreate, @Nullable String[] disallowedPackages, @NonNull TimingsTraceAndSlog t, @Nullable Object token)3531     private UserInfo createUserInternalUncheckedNoTracing(@Nullable String name,
3532             @NonNull String userType, @UserInfoFlag int flags, @UserIdInt int parentId,
3533             boolean preCreate, @Nullable String[] disallowedPackages,
3534             @NonNull TimingsTraceAndSlog t, @Nullable Object token)
3535                     throws UserManager.CheckedUserOperationException {
3536         final UserTypeDetails userTypeDetails = mUserTypes.get(userType);
3537         if (userTypeDetails == null) {
3538             Slog.e(LOG_TAG, "Cannot create user of invalid user type: " + userType);
3539             return null;
3540         }
3541         userType = userType.intern(); // Now that we know it's valid, we can intern it.
3542         flags |= userTypeDetails.getDefaultUserInfoFlags();
3543         if (!checkUserTypeConsistency(flags)) {
3544             Slog.e(LOG_TAG, "Cannot add user. Flags (" + Integer.toHexString(flags)
3545                     + ") and userTypeDetails (" + userType +  ") are inconsistent.");
3546             return null;
3547         }
3548         if ((flags & UserInfo.FLAG_SYSTEM) != 0) {
3549             Slog.e(LOG_TAG, "Cannot add user. Flags (" + Integer.toHexString(flags)
3550                     + ") indicated SYSTEM user, which cannot be created.");
3551             return null;
3552         }
3553         synchronized (mUsersLock) {
3554             if (mForceEphemeralUsers) {
3555                 flags |= UserInfo.FLAG_EPHEMERAL;
3556             }
3557         }
3558 
3559         // Try to use a pre-created user (if available).
3560         if (!preCreate && parentId < 0 && isUserTypeEligibleForPreCreation(userTypeDetails)) {
3561             final UserInfo preCreatedUser = convertPreCreatedUserIfPossible(userType, flags, name,
3562                     token);
3563             if (preCreatedUser != null) {
3564                 return preCreatedUser;
3565             }
3566         }
3567 
3568         DeviceStorageMonitorInternal dsm = LocalServices
3569                 .getService(DeviceStorageMonitorInternal.class);
3570         if (dsm.isMemoryLow()) {
3571             throwCheckedUserOperationException("Cannot add user. Not enough space on disk.",
3572                     UserManager.USER_OPERATION_ERROR_LOW_STORAGE);
3573         }
3574 
3575         final boolean isProfile = userTypeDetails.isProfile();
3576         final boolean isGuest = UserManager.isUserTypeGuest(userType);
3577         final boolean isRestricted = UserManager.isUserTypeRestricted(userType);
3578         final boolean isDemo = UserManager.isUserTypeDemo(userType);
3579 
3580         final long ident = Binder.clearCallingIdentity();
3581         UserInfo userInfo;
3582         UserData userData;
3583         final int userId;
3584         try {
3585             synchronized (mPackagesLock) {
3586                 UserData parent = null;
3587                 if (parentId != UserHandle.USER_NULL) {
3588                     synchronized (mUsersLock) {
3589                         parent = getUserDataLU(parentId);
3590                     }
3591                     if (parent == null) {
3592                         throwCheckedUserOperationException(
3593                                 "Cannot find user data for parent user " + parentId,
3594                                 UserManager.USER_OPERATION_ERROR_UNKNOWN);
3595                     }
3596                 }
3597                 if (!preCreate && !canAddMoreUsersOfType(userTypeDetails)) {
3598                     throwCheckedUserOperationException("Cannot add more users of type " + userType
3599                                     + ". Maximum number of that type already exists.",
3600                             UserManager.USER_OPERATION_ERROR_MAX_USERS);
3601                 }
3602                 // TODO(b/142482943): Perhaps let the following code apply to restricted users too.
3603                 if (isProfile && !canAddMoreProfilesToUser(userType, parentId, false)) {
3604                     throwCheckedUserOperationException(
3605                             "Cannot add more profiles of type " + userType
3606                                     + " for user " + parentId,
3607                             UserManager.USER_OPERATION_ERROR_MAX_USERS);
3608                 }
3609                 if (!isGuest && !isProfile && !isDemo && isUserLimitReached()) {
3610                     // If we're not adding a guest/demo user or a profile and the 'user limit' has
3611                     // been reached, cannot add a user.
3612                     throwCheckedUserOperationException(
3613                             "Cannot add user. Maximum user limit is reached.",
3614                             UserManager.USER_OPERATION_ERROR_MAX_USERS);
3615                 }
3616                 // In legacy mode, restricted profile's parent can only be the owner user
3617                 if (isRestricted && !UserManager.isSplitSystemUser()
3618                         && (parentId != UserHandle.USER_SYSTEM)) {
3619                     throwCheckedUserOperationException(
3620                             "Cannot add restricted profile - parent user must be owner",
3621                             UserManager.USER_OPERATION_ERROR_UNKNOWN);
3622                 }
3623                 if (isRestricted && UserManager.isSplitSystemUser()) {
3624                     if (parent == null) {
3625                         throwCheckedUserOperationException(
3626                                 "Cannot add restricted profile - parent user must be specified",
3627                                 UserManager.USER_OPERATION_ERROR_UNKNOWN);
3628                     }
3629                     if (!parent.info.canHaveProfile()) {
3630                         throwCheckedUserOperationException(
3631                                 "Cannot add restricted profile - profiles cannot be created for "
3632                                         + "the specified parent user id "
3633                                         + parentId,
3634                                 UserManager.USER_OPERATION_ERROR_UNKNOWN);
3635                     }
3636                 }
3637 
3638                 userId = getNextAvailableId();
3639                 Slog.i(LOG_TAG, "Creating user " + userId + " of type " + userType);
3640                 Environment.getUserSystemDirectory(userId).mkdirs();
3641 
3642                 synchronized (mUsersLock) {
3643                     // Inherit ephemeral flag from parent.
3644                     if (parent != null && parent.info.isEphemeral()) {
3645                         flags |= UserInfo.FLAG_EPHEMERAL;
3646                     }
3647 
3648                     // Always clear EPHEMERAL for pre-created users, otherwise the storage key
3649                     // won't be persisted. The flag will be re-added (if needed) when the
3650                     // pre-created user is "converted" to a normal user.
3651                     if (preCreate) {
3652                         flags &= ~UserInfo.FLAG_EPHEMERAL;
3653                     }
3654 
3655                     userInfo = new UserInfo(userId, name, null, flags, userType);
3656                     userInfo.serialNumber = mNextSerialNumber++;
3657                     userInfo.creationTime = getCreationTime();
3658                     userInfo.partial = true;
3659                     userInfo.preCreated = preCreate;
3660                     userInfo.lastLoggedInFingerprint = Build.FINGERPRINT;
3661                     if (userTypeDetails.hasBadge() && parentId != UserHandle.USER_NULL) {
3662                         userInfo.profileBadge = getFreeProfileBadgeLU(parentId, userType);
3663                     }
3664                     userData = new UserData();
3665                     userData.info = userInfo;
3666                     mUsers.put(userId, userData);
3667                 }
3668                 writeUserLP(userData);
3669                 writeUserListLP();
3670                 if (parent != null) {
3671                     if (isProfile) {
3672                         if (parent.info.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID) {
3673                             parent.info.profileGroupId = parent.info.id;
3674                             writeUserLP(parent);
3675                         }
3676                         userInfo.profileGroupId = parent.info.profileGroupId;
3677                     } else if (isRestricted) {
3678                         if (parent.info.restrictedProfileParentId == UserInfo.NO_PROFILE_GROUP_ID) {
3679                             parent.info.restrictedProfileParentId = parent.info.id;
3680                             writeUserLP(parent);
3681                         }
3682                         userInfo.restrictedProfileParentId = parent.info.restrictedProfileParentId;
3683                     }
3684                 }
3685             }
3686 
3687             t.traceBegin("createUserKey");
3688             final StorageManager storage = mContext.getSystemService(StorageManager.class);
3689             storage.createUserKey(userId, userInfo.serialNumber, userInfo.isEphemeral());
3690             t.traceEnd();
3691 
3692             t.traceBegin("prepareUserData");
3693             mUserDataPreparer.prepareUserData(userId, userInfo.serialNumber,
3694                     StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
3695             t.traceEnd();
3696 
3697             final Set<String> userTypeInstallablePackages =
3698                     mSystemPackageInstaller.getInstallablePackagesForUserType(userType);
3699             t.traceBegin("PM.createNewUser");
3700             mPm.createNewUser(userId, userTypeInstallablePackages, disallowedPackages);
3701             t.traceEnd();
3702 
3703             userInfo.partial = false;
3704             synchronized (mPackagesLock) {
3705                 writeUserLP(userData);
3706             }
3707             updateUserIds();
3708 
3709             Bundle restrictions = new Bundle();
3710             if (isGuest) {
3711                 // Guest default restrictions can be modified via setDefaultGuestRestrictions.
3712                 synchronized (mGuestRestrictions) {
3713                     restrictions.putAll(mGuestRestrictions);
3714                 }
3715             } else {
3716                 userTypeDetails.addDefaultRestrictionsTo(restrictions);
3717             }
3718             synchronized (mRestrictionsLock) {
3719                 mBaseUserRestrictions.updateRestrictions(userId, restrictions);
3720             }
3721 
3722             t.traceBegin("PM.onNewUserCreated-" + userId);
3723             mPm.onNewUserCreated(userId, /* convertedFromPreCreated= */ false);
3724             t.traceEnd();
3725             applyDefaultUserSettings(userTypeDetails, userId);
3726             setDefaultCrossProfileIntentFilters(userId, userTypeDetails, restrictions, parentId);
3727 
3728             if (preCreate) {
3729                 // Must start user (which will be stopped right away, through
3730                 // UserController.finishUserUnlockedCompleted) so services can properly
3731                 // intialize it.
3732                 // NOTE: user will be stopped on UserController.finishUserUnlockedCompleted().
3733                 Slog.i(LOG_TAG, "starting pre-created user " + userInfo.toFullString());
3734                 final IActivityManager am = ActivityManager.getService();
3735                 try {
3736                     am.startUserInBackground(userId);
3737                 } catch (RemoteException e) {
3738                     Slog.w(LOG_TAG, "could not start pre-created user " + userId, e);
3739                 }
3740             } else {
3741                 dispatchUserAdded(userInfo, token);
3742             }
3743 
3744         } finally {
3745             Binder.restoreCallingIdentity(ident);
3746         }
3747 
3748         // TODO(b/143092698): it's possible to reach "max users overflow" when the user is created
3749         // "from scratch" (i.e., not from a pre-created user) and reaches the maximum number of
3750         // users without counting the pre-created one. Then when the pre-created is converted, the
3751         // "effective" number of max users is exceeds. Example:
3752         // Max: 3 Current: 2 full (u0 and u10) + 1 pre-created (u11)
3753         // Step 1: create(/* flags doesn't match u11 */): u12 is created, "effective max" is now 3
3754         //         (u0, u10, u12) but "real" max is 4 (u0, u10, u11, u12)
3755         // Step 2: create(/* flags match u11 */): u11 is converted, now "effective max" is also 4
3756         //         (u0, u10, u11, u12)
3757         // One way to avoid this issue is by removing a pre-created user from the pool when the
3758         // "real" max exceeds the max here.
3759 
3760         return userInfo;
3761     }
3762 
applyDefaultUserSettings(UserTypeDetails userTypeDetails, @UserIdInt int userId)3763     private void applyDefaultUserSettings(UserTypeDetails userTypeDetails, @UserIdInt int userId) {
3764         final Bundle systemSettings = userTypeDetails.getDefaultSystemSettings();
3765         final Bundle secureSettings = userTypeDetails.getDefaultSecureSettings();
3766         if (systemSettings.isEmpty() && secureSettings.isEmpty()) {
3767             return;
3768         }
3769 
3770         final int systemSettingsSize = systemSettings.size();
3771         final String[] systemSettingsArray = systemSettings.keySet().toArray(
3772                 new String[systemSettingsSize]);
3773         for (int i = 0; i < systemSettingsSize; i++) {
3774             final String setting = systemSettingsArray[i];
3775             if (!Settings.System.putStringForUser(
3776                     mContext.getContentResolver(), setting, systemSettings.getString(setting),
3777                     userId)) {
3778                 Slog.e(LOG_TAG, "Failed to insert default system setting: " + setting);
3779             }
3780         }
3781 
3782         final int secureSettingsSize = secureSettings.size();
3783         final String[] secureSettingsArray = secureSettings.keySet().toArray(
3784                 new String[secureSettingsSize]);
3785         for (int i = 0; i < secureSettingsSize; i++) {
3786             final String setting = secureSettingsArray[i];
3787             if (!Settings.Secure.putStringForUser(
3788                     mContext.getContentResolver(), setting, secureSettings.getString(setting),
3789                     userId)) {
3790                 Slog.e(LOG_TAG, "Failed to insert default secure setting: " + setting);
3791             }
3792         }
3793     }
3794 
3795     /**
3796      * Sets all default cross profile intent filters between {@code parentUserId} and
3797      * {@code profileUserId}, does nothing if {@code userType} is not a profile.
3798      */
setDefaultCrossProfileIntentFilters( @serIdInt int profileUserId, UserTypeDetails profileDetails, Bundle profileRestrictions, @UserIdInt int parentUserId)3799     private void setDefaultCrossProfileIntentFilters(
3800             @UserIdInt int profileUserId, UserTypeDetails profileDetails,
3801             Bundle profileRestrictions, @UserIdInt int parentUserId) {
3802         if (profileDetails == null || !profileDetails.isProfile()) {
3803             return;
3804         }
3805         final List<DefaultCrossProfileIntentFilter> filters =
3806                 profileDetails.getDefaultCrossProfileIntentFilters();
3807         if (filters.isEmpty()) {
3808             return;
3809         }
3810 
3811         // Skip filters that allow data to be shared into the profile, if admin has disabled it.
3812         final boolean disallowSharingIntoProfile =
3813                 profileRestrictions.getBoolean(
3814                         UserManager.DISALLOW_SHARE_INTO_MANAGED_PROFILE,
3815                         /* defaultValue = */ false);
3816         final int size = profileDetails.getDefaultCrossProfileIntentFilters().size();
3817         for (int i = 0; i < size; i++) {
3818             final DefaultCrossProfileIntentFilter filter =
3819                     profileDetails.getDefaultCrossProfileIntentFilters().get(i);
3820             if (disallowSharingIntoProfile && filter.letsPersonalDataIntoProfile) {
3821                 continue;
3822             }
3823             if (filter.direction == DefaultCrossProfileIntentFilter.Direction.TO_PARENT) {
3824                 mPm.addCrossProfileIntentFilter(
3825                         filter.filter, mContext.getOpPackageName(), profileUserId, parentUserId,
3826                         filter.flags);
3827             } else {
3828                 mPm.addCrossProfileIntentFilter(
3829                         filter.filter, mContext.getOpPackageName(), parentUserId, profileUserId,
3830                         filter.flags);
3831             }
3832         }
3833     }
3834 
3835     /**
3836      * Finds and converts a previously pre-created user into a regular user, if possible.
3837      *
3838      * @return the converted user, or {@code null} if no pre-created user could be converted.
3839      */
convertPreCreatedUserIfPossible(String userType, @UserInfoFlag int flags, String name, @Nullable Object token)3840     private @Nullable UserInfo convertPreCreatedUserIfPossible(String userType,
3841             @UserInfoFlag int flags, String name, @Nullable Object token) {
3842         final UserData preCreatedUserData;
3843         synchronized (mUsersLock) {
3844             preCreatedUserData = getPreCreatedUserLU(userType);
3845         }
3846         if (preCreatedUserData == null) {
3847             return null;
3848         }
3849         synchronized (mUserStates) {
3850             if (mUserStates.has(preCreatedUserData.info.id)) {
3851                 Slog.w(LOG_TAG, "Cannot reuse pre-created user "
3852                         + preCreatedUserData.info.id + " because it didn't stop yet");
3853                 return null;
3854             }
3855         }
3856         final UserInfo preCreatedUser = preCreatedUserData.info;
3857         final int newFlags = preCreatedUser.flags | flags;
3858         if (!checkUserTypeConsistency(newFlags)) {
3859             Slog.wtf(LOG_TAG, "Cannot reuse pre-created user " + preCreatedUser.id
3860                     + " of type " + userType + " because flags are inconsistent. "
3861                     + "Flags (" + Integer.toHexString(flags) + "); preCreatedUserFlags ( "
3862                     + Integer.toHexString(preCreatedUser.flags) + ").");
3863             return null;
3864         }
3865         Slog.i(LOG_TAG, "Reusing pre-created user " + preCreatedUser.id + " of type "
3866                 + userType + " and bestowing on it flags " + UserInfo.flagsToString(flags));
3867         preCreatedUser.name = name;
3868         preCreatedUser.flags = newFlags;
3869         preCreatedUser.preCreated = false;
3870         preCreatedUser.convertedFromPreCreated = true;
3871         preCreatedUser.creationTime = getCreationTime();
3872 
3873         synchronized (mPackagesLock) {
3874             writeUserLP(preCreatedUserData);
3875             writeUserListLP();
3876         }
3877         updateUserIds();
3878         mPm.onNewUserCreated(preCreatedUser.id, /* convertedFromPreCreated= */ true);
3879         dispatchUserAdded(preCreatedUser, token);
3880         return preCreatedUser;
3881     }
3882 
3883     /** Checks that the flags do not contain mutually exclusive types/properties. */
checkUserTypeConsistency(@serInfoFlag int flags)3884     static boolean checkUserTypeConsistency(@UserInfoFlag int flags) {
3885         // Mask to check that flags don't refer to multiple user types.
3886         final int userTypeFlagMask = UserInfo.FLAG_GUEST | UserInfo.FLAG_DEMO
3887                 | UserInfo.FLAG_RESTRICTED | UserInfo.FLAG_PROFILE;
3888         return isAtMostOneFlag(flags & userTypeFlagMask)
3889                 && isAtMostOneFlag(flags & (UserInfo.FLAG_PROFILE | UserInfo.FLAG_FULL))
3890                 && isAtMostOneFlag(flags & (UserInfo.FLAG_PROFILE | UserInfo.FLAG_SYSTEM));
3891     }
3892 
3893     /** Returns whether the given flags contains at most one 1. */
isAtMostOneFlag(int flags)3894     private static boolean isAtMostOneFlag(int flags) {
3895         return (flags & (flags - 1)) == 0;
3896         // If !=0, this means that flags is not a power of 2, and therefore is multiple types.
3897     }
3898 
3899     /** Install/uninstall system packages for all users based on their user-type, as applicable. */
installWhitelistedSystemPackages(boolean isFirstBoot, boolean isUpgrade, @Nullable ArraySet<String> existingPackages)3900     boolean installWhitelistedSystemPackages(boolean isFirstBoot, boolean isUpgrade,
3901             @Nullable ArraySet<String> existingPackages) {
3902         return mSystemPackageInstaller.installWhitelistedSystemPackages(
3903                 isFirstBoot, isUpgrade, existingPackages);
3904     }
3905 
3906     @Override
getPreInstallableSystemPackages(@onNull String userType)3907     public String[] getPreInstallableSystemPackages(@NonNull String userType) {
3908         checkManageOrCreateUsersPermission("getPreInstallableSystemPackages");
3909         final Set<String> installableSystemPackages =
3910                 mSystemPackageInstaller.getInstallablePackagesForUserType(userType);
3911         if (installableSystemPackages == null) {
3912             return null;
3913         }
3914         return installableSystemPackages.toArray(new String[installableSystemPackages.size()]);
3915     }
3916 
getCreationTime()3917     private long getCreationTime() {
3918         final long now = System.currentTimeMillis();
3919         return (now > EPOCH_PLUS_30_YEARS) ? now : 0;
3920     }
3921 
dispatchUserAdded(@onNull UserInfo userInfo, @Nullable Object token)3922     private void dispatchUserAdded(@NonNull UserInfo userInfo, @Nullable Object token) {
3923         // Notify internal listeners first...
3924         synchronized (mUserLifecycleListeners) {
3925             for (int i = 0; i < mUserLifecycleListeners.size(); i++) {
3926                 mUserLifecycleListeners.get(i).onUserCreated(userInfo, token);
3927             }
3928         }
3929 
3930         //...then external ones
3931         Intent addedIntent = new Intent(Intent.ACTION_USER_ADDED);
3932         addedIntent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
3933         addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userInfo.id);
3934         // Also, add the UserHandle for mainline modules which can't use the @hide
3935         // EXTRA_USER_HANDLE.
3936         addedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(userInfo.id));
3937         mContext.sendBroadcastAsUser(addedIntent, UserHandle.ALL,
3938                 android.Manifest.permission.MANAGE_USERS);
3939         MetricsLogger.count(mContext, userInfo.isGuest() ? TRON_GUEST_CREATED
3940                 : (userInfo.isDemo() ? TRON_DEMO_CREATED : TRON_USER_CREATED), 1);
3941 
3942         if (!userInfo.isProfile()) {
3943             // If the user switch hasn't been explicitly toggled on or off by the user, turn it on.
3944             if (android.provider.Settings.Global.getString(mContext.getContentResolver(),
3945                     android.provider.Settings.Global.USER_SWITCHER_ENABLED) == null) {
3946                 android.provider.Settings.Global.putInt(mContext.getContentResolver(),
3947                         android.provider.Settings.Global.USER_SWITCHER_ENABLED, 1);
3948             }
3949         }
3950     }
3951 
3952     /**
3953      * Gets a pre-created user for the given user type.
3954      *
3955      * <p>Should be used only during user creation, so the pre-created user can be used (instead of
3956      * creating and initializing a new user from scratch).
3957      */
3958     // TODO(b/143092698): add unit test
3959     @GuardedBy("mUsersLock")
getPreCreatedUserLU(String userType)3960     private @Nullable UserData getPreCreatedUserLU(String userType) {
3961         if (DBG) Slog.d(LOG_TAG, "getPreCreatedUser(): userType= " + userType);
3962         final int userSize = mUsers.size();
3963         for (int i = 0; i < userSize; i++) {
3964             final UserData user = mUsers.valueAt(i);
3965             if (DBG) Slog.d(LOG_TAG, i + ":" + user.info.toFullString());
3966             if (user.info.preCreated && user.info.userType.equals(userType)) {
3967                 if (!user.info.isInitialized()) {
3968                     Slog.w(LOG_TAG, "found pre-created user of type " + userType
3969                             + ", but it's not initialized yet: " + user.info.toFullString());
3970                     continue;
3971                 }
3972                 return user;
3973             }
3974         }
3975         return null;
3976     }
3977 
3978     /**
3979      * Returns whether a user with the given userTypeDetails is eligible to be
3980      * {@link UserInfo#preCreated}.
3981      */
isUserTypeEligibleForPreCreation(UserTypeDetails userTypeDetails)3982     private static boolean isUserTypeEligibleForPreCreation(UserTypeDetails userTypeDetails) {
3983         if (userTypeDetails == null) {
3984             return false;
3985         }
3986         return !userTypeDetails.isProfile()
3987                 && !userTypeDetails.getName().equals(UserManager.USER_TYPE_FULL_RESTRICTED);
3988     }
3989 
logUserCreateJourneyBegin(@serIdInt int userId, String userType, @UserInfoFlag int flags)3990     private long logUserCreateJourneyBegin(@UserIdInt int userId, String userType,
3991             @UserInfoFlag int flags) {
3992         final long sessionId = ThreadLocalRandom.current().nextLong(1, Long.MAX_VALUE);
3993         // log the journey atom with the user metadata
3994         FrameworkStatsLog.write(FrameworkStatsLog.USER_LIFECYCLE_JOURNEY_REPORTED, sessionId,
3995                 FrameworkStatsLog.USER_LIFECYCLE_JOURNEY_REPORTED__JOURNEY__USER_CREATE,
3996                 /* origin_user= */ -1, userId, UserManager.getUserTypeForStatsd(userType), flags);
3997         // log the event atom to indicate the event start
3998         FrameworkStatsLog.write(FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED, sessionId, userId,
3999                 FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED__EVENT__CREATE_USER,
4000                 FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED__STATE__BEGIN);
4001         return sessionId;
4002     }
4003 
logUserCreateJourneyFinish(long sessionId, @UserIdInt int userId, boolean finish)4004     private void logUserCreateJourneyFinish(long sessionId, @UserIdInt int userId, boolean finish) {
4005         FrameworkStatsLog.write(FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED, sessionId, userId,
4006                 FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED__EVENT__CREATE_USER,
4007                 finish ? FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED__STATE__FINISH
4008                         : FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED__STATE__NONE);
4009     }
4010 
4011     @VisibleForTesting
putUserInfo(UserInfo userInfo)4012     UserData putUserInfo(UserInfo userInfo) {
4013         final UserData userData = new UserData();
4014         userData.info = userInfo;
4015         synchronized (mUsersLock) {
4016             mUsers.put(userInfo.id, userData);
4017         }
4018         return userData;
4019     }
4020 
4021     @VisibleForTesting
removeUserInfo(@serIdInt int userId)4022     void removeUserInfo(@UserIdInt int userId) {
4023         synchronized (mUsersLock) {
4024             mUsers.remove(userId);
4025         }
4026     }
4027 
4028     /**
4029      * @hide
4030      */
4031     @Override
createRestrictedProfileWithThrow(@ullable String name, int parentUserId)4032     public UserInfo createRestrictedProfileWithThrow(@Nullable String name, int parentUserId) {
4033         checkManageOrCreateUsersPermission("setupRestrictedProfile");
4034         final UserInfo user = createProfileForUserWithThrow(
4035                 name, UserManager.USER_TYPE_FULL_RESTRICTED, 0, parentUserId, null);
4036         if (user == null) {
4037             return null;
4038         }
4039         final long identity = Binder.clearCallingIdentity();
4040         try {
4041             setUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS, true, user.id);
4042             // Change the setting before applying the DISALLOW_SHARE_LOCATION restriction, otherwise
4043             // the putIntForUser() will fail.
4044             android.provider.Settings.Secure.putIntForUser(mContext.getContentResolver(),
4045                     android.provider.Settings.Secure.LOCATION_MODE,
4046                     android.provider.Settings.Secure.LOCATION_MODE_OFF, user.id);
4047             setUserRestriction(UserManager.DISALLOW_SHARE_LOCATION, true, user.id);
4048         } finally {
4049             Binder.restoreCallingIdentity(identity);
4050         }
4051         return user;
4052     }
4053 
4054     /**
4055      * Find the current guest user. If the Guest user is partial,
4056      * then do not include it in the results as it is about to die.
4057      *
4058      * @return The current guest user.  Null if it doesn't exist.
4059      * @hide
4060      */
4061     @Override
findCurrentGuestUser()4062     public UserInfo findCurrentGuestUser() {
4063         checkManageUsersPermission("findCurrentGuestUser");
4064         synchronized (mUsersLock) {
4065             final int size = mUsers.size();
4066             for (int i = 0; i < size; i++) {
4067                 final UserInfo user = mUsers.valueAt(i).info;
4068                 if (user.isGuest() && !user.guestToRemove && !user.preCreated
4069                         && !mRemovingUserIds.get(user.id)) {
4070                     return user;
4071                 }
4072             }
4073         }
4074         return null;
4075     }
4076 
4077     /**
4078      * Mark this guest user for deletion to allow us to create another guest
4079      * and switch to that user before actually removing this guest.
4080      * @param userId the userid of the current guest
4081      * @return whether the user could be marked for deletion
4082      */
4083     @Override
markGuestForDeletion(@serIdInt int userId)4084     public boolean markGuestForDeletion(@UserIdInt int userId) {
4085         checkManageUsersPermission("Only the system can remove users");
4086         if (getUserRestrictions(UserHandle.getCallingUserId()).getBoolean(
4087                 UserManager.DISALLOW_REMOVE_USER, false)) {
4088             Slog.w(LOG_TAG, "Cannot remove user. DISALLOW_REMOVE_USER is enabled.");
4089             return false;
4090         }
4091 
4092         final long ident = Binder.clearCallingIdentity();
4093         try {
4094             final UserData userData;
4095             synchronized (mPackagesLock) {
4096                 synchronized (mUsersLock) {
4097                     userData = mUsers.get(userId);
4098                     if (userId == 0 || userData == null || mRemovingUserIds.get(userId)) {
4099                         return false;
4100                     }
4101                 }
4102                 if (!userData.info.isGuest()) {
4103                     return false;
4104                 }
4105                 // We set this to a guest user that is to be removed. This is a temporary state
4106                 // where we are allowed to add new Guest users, even if this one is still not
4107                 // removed. This user will still show up in getUserInfo() calls.
4108                 // If we don't get around to removing this Guest user, it will be purged on next
4109                 // startup.
4110                 userData.info.guestToRemove = true;
4111                 // Mark it as disabled, so that it isn't returned any more when
4112                 // profiles are queried.
4113                 userData.info.flags |= UserInfo.FLAG_DISABLED;
4114                 writeUserLP(userData);
4115             }
4116         } finally {
4117             Binder.restoreCallingIdentity(ident);
4118         }
4119         return true;
4120     }
4121 
4122     /**
4123      * Removes a user and all data directories created for that user. This method should be called
4124      * after the user's processes have been terminated.
4125      * @param userId the user's id
4126      */
4127     @Override
removeUser(@serIdInt int userId)4128     public boolean removeUser(@UserIdInt int userId) {
4129         Slog.i(LOG_TAG, "removeUser u" + userId);
4130         checkManageOrCreateUsersPermission("Only the system can remove users");
4131 
4132         final String restriction = getUserRemovalRestriction(userId);
4133         if (getUserRestrictions(UserHandle.getCallingUserId()).getBoolean(restriction, false)) {
4134             Slog.w(LOG_TAG, "Cannot remove user. " + restriction + " is enabled.");
4135             return false;
4136         }
4137         return removeUserUnchecked(userId);
4138     }
4139 
4140     @Override
removeUserEvenWhenDisallowed(@serIdInt int userId)4141     public boolean removeUserEvenWhenDisallowed(@UserIdInt int userId) {
4142         checkManageOrCreateUsersPermission("Only the system can remove users");
4143         return removeUserUnchecked(userId);
4144     }
4145 
4146     /**
4147      * Returns the string name of the restriction to check for user removal. The restriction name
4148      * varies depending on whether the user is a managed profile.
4149      */
getUserRemovalRestriction(@serIdInt int userId)4150     private String getUserRemovalRestriction(@UserIdInt int userId) {
4151         final boolean isManagedProfile;
4152         final UserInfo userInfo;
4153         synchronized (mUsersLock) {
4154             userInfo = getUserInfoLU(userId);
4155         }
4156         isManagedProfile = userInfo != null && userInfo.isManagedProfile();
4157         return isManagedProfile
4158                 ? UserManager.DISALLOW_REMOVE_MANAGED_PROFILE : UserManager.DISALLOW_REMOVE_USER;
4159     }
4160 
removeUserUnchecked(@serIdInt int userId)4161     private boolean removeUserUnchecked(@UserIdInt int userId) {
4162         final long ident = Binder.clearCallingIdentity();
4163         try {
4164             final UserData userData;
4165             int currentUser = ActivityManager.getCurrentUser();
4166             if (currentUser == userId) {
4167                 Slog.w(LOG_TAG, "Current user cannot be removed.");
4168                 return false;
4169             }
4170             synchronized (mPackagesLock) {
4171                 synchronized (mUsersLock) {
4172                     userData = mUsers.get(userId);
4173                     if (userId == UserHandle.USER_SYSTEM) {
4174                         Slog.e(LOG_TAG, "System user cannot be removed.");
4175                         return false;
4176                     }
4177 
4178                     if (userData == null) {
4179                         Slog.e(LOG_TAG, String.format(
4180                                 "Cannot remove user %d, invalid user id provided.", userId));
4181                         return false;
4182                     }
4183 
4184                     if (mRemovingUserIds.get(userId)) {
4185                         Slog.e(LOG_TAG, String.format(
4186                                 "User %d is already scheduled for removal.", userId));
4187                         return false;
4188                     }
4189 
4190                     addRemovingUserIdLocked(userId);
4191                 }
4192 
4193                 // Set this to a partially created user, so that the user will be purged
4194                 // on next startup, in case the runtime stops now before stopping and
4195                 // removing the user completely.
4196                 userData.info.partial = true;
4197                 // Mark it as disabled, so that it isn't returned any more when
4198                 // profiles are queried.
4199                 userData.info.flags |= UserInfo.FLAG_DISABLED;
4200                 writeUserLP(userData);
4201             }
4202             try {
4203                 mAppOpsService.removeUser(userId);
4204             } catch (RemoteException e) {
4205                 Slog.w(LOG_TAG, "Unable to notify AppOpsService of removing user.", e);
4206             }
4207 
4208             // TODO(b/142482943): Send some sort of broadcast for profiles even if non-managed?
4209             if (userData.info.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID
4210                     && userData.info.isManagedProfile()) {
4211                 // Send broadcast to notify system that the user removed was a
4212                 // managed user.
4213                 sendProfileRemovedBroadcast(userData.info.profileGroupId, userData.info.id);
4214             }
4215 
4216             if (DBG) Slog.i(LOG_TAG, "Stopping user " + userId);
4217             int res;
4218             try {
4219                 res = ActivityManager.getService().stopUser(userId, /* force= */ true,
4220                 new IStopUserCallback.Stub() {
4221                             @Override
4222                             public void userStopped(int userIdParam) {
4223                                 finishRemoveUser(userIdParam);
4224                             }
4225                             @Override
4226                             public void userStopAborted(int userIdParam) {
4227                             }
4228                         });
4229             } catch (RemoteException e) {
4230                 Slog.w(LOG_TAG, "Failed to stop user during removal.", e);
4231                 return false;
4232             }
4233             return res == ActivityManager.USER_OP_SUCCESS;
4234         } finally {
4235             Binder.restoreCallingIdentity(ident);
4236         }
4237     }
4238 
4239     @GuardedBy("mUsersLock")
4240     @VisibleForTesting
addRemovingUserIdLocked(@serIdInt int userId)4241     void addRemovingUserIdLocked(@UserIdInt int userId) {
4242         // We remember deleted user IDs to prevent them from being
4243         // reused during the current boot; they can still be reused
4244         // after a reboot or recycling of userIds.
4245         mRemovingUserIds.put(userId, true);
4246         mRecentlyRemovedIds.add(userId);
4247         // Keep LRU queue of recently removed IDs for recycling
4248         if (mRecentlyRemovedIds.size() > MAX_RECENTLY_REMOVED_IDS_SIZE) {
4249             mRecentlyRemovedIds.removeFirst();
4250         }
4251     }
4252 
4253     @Override
removeUserOrSetEphemeral(@serIdInt int userId, boolean evenWhenDisallowed)4254     public @UserManager.RemoveResult int removeUserOrSetEphemeral(@UserIdInt int userId,
4255             boolean evenWhenDisallowed) {
4256         checkManageOrCreateUsersPermission("Only the system can remove users");
4257 
4258         if (!evenWhenDisallowed) {
4259             final String restriction = getUserRemovalRestriction(userId);
4260             if (getUserRestrictions(UserHandle.getCallingUserId()).getBoolean(restriction, false)) {
4261                 Slog.w(LOG_TAG, "Cannot remove user. " + restriction + " is enabled.");
4262                 return UserManager.REMOVE_RESULT_ERROR;
4263             }
4264         }
4265         if (userId == UserHandle.USER_SYSTEM) {
4266             Slog.e(LOG_TAG, "System user cannot be removed.");
4267             return UserManager.REMOVE_RESULT_ERROR;
4268         }
4269 
4270         final long ident = Binder.clearCallingIdentity();
4271         try {
4272             final UserData userData;
4273             synchronized (mPackagesLock) {
4274                 synchronized (mUsersLock) {
4275                     userData = mUsers.get(userId);
4276                     if (userData == null) {
4277                         Slog.e(LOG_TAG,
4278                                 "Cannot remove user " + userId + ", invalid user id provided.");
4279                         return UserManager.REMOVE_RESULT_ERROR;
4280                     }
4281 
4282                     if (mRemovingUserIds.get(userId)) {
4283                         Slog.e(LOG_TAG, "User " + userId + " is already scheduled for removal.");
4284                         return UserManager.REMOVE_RESULT_ALREADY_BEING_REMOVED;
4285                     }
4286                 }
4287 
4288                 // Attempt to immediately remove a non-current user
4289                 final int currentUser = ActivityManager.getCurrentUser();
4290                 if (currentUser != userId) {
4291                     // Attempt to remove the user. This will fail if the user is the current user
4292                     if (removeUserUnchecked(userId)) {
4293                         return UserManager.REMOVE_RESULT_REMOVED;
4294                     }
4295                 }
4296                 // If the user was not immediately removed, make sure it is marked as ephemeral.
4297                 // Don't mark as disabled since, per UserInfo.FLAG_DISABLED documentation, an
4298                 // ephemeral user should only be marked as disabled when its removal is in progress.
4299                 Slog.i(LOG_TAG, "Unable to immediately remove user " + userId + " (current user is "
4300                         + currentUser + "). User is set as ephemeral and will be removed on user "
4301                         + "switch or reboot.");
4302                 userData.info.flags |= UserInfo.FLAG_EPHEMERAL;
4303                 writeUserLP(userData);
4304 
4305                 return UserManager.REMOVE_RESULT_SET_EPHEMERAL;
4306             }
4307         } finally {
4308             Binder.restoreCallingIdentity(ident);
4309         }
4310     }
4311 
finishRemoveUser(final @UserIdInt int userId)4312     void finishRemoveUser(final @UserIdInt int userId) {
4313         if (DBG) Slog.i(LOG_TAG, "finishRemoveUser " + userId);
4314 
4315         UserInfo user;
4316         synchronized (mUsersLock) {
4317             user = getUserInfoLU(userId);
4318         }
4319         if (user != null && user.preCreated) {
4320             Slog.i(LOG_TAG, "Removing a pre-created user with user id: " + userId);
4321             // Don't want to fire ACTION_USER_REMOVED, so cleanup the state and exit early.
4322             LocalServices.getService(ActivityTaskManagerInternal.class).onUserStopped(userId);
4323             removeUserState(userId);
4324             return;
4325         }
4326 
4327         synchronized (mUserLifecycleListeners) {
4328             for (int i = 0; i < mUserLifecycleListeners.size(); i++) {
4329                 mUserLifecycleListeners.get(i).onUserRemoved(user);
4330             }
4331         }
4332 
4333         // Let other services shutdown any activity and clean up their state before completely
4334         // wiping the user's system directory and removing from the user list
4335         final long ident = Binder.clearCallingIdentity();
4336         try {
4337             Intent removedIntent = new Intent(Intent.ACTION_USER_REMOVED);
4338             removedIntent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
4339             removedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4340             // Also, add the UserHandle for mainline modules which can't use the @hide
4341             // EXTRA_USER_HANDLE.
4342             removedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(userId));
4343             mContext.sendOrderedBroadcastAsUser(removedIntent, UserHandle.ALL,
4344                     android.Manifest.permission.MANAGE_USERS,
4345 
4346                     new BroadcastReceiver() {
4347                         @Override
4348                         public void onReceive(Context context, Intent intent) {
4349                             if (DBG) {
4350                                 Slog.i(LOG_TAG,
4351                                         "USER_REMOVED broadcast sent, cleaning up user data "
4352                                         + userId);
4353                             }
4354                             new Thread() {
4355                                 @Override
4356                                 public void run() {
4357                                     LocalServices.getService(ActivityManagerInternal.class)
4358                                             .onUserRemoved(userId);
4359                                     removeUserState(userId);
4360                                 }
4361                             }.start();
4362                         }
4363                     },
4364 
4365                     null, Activity.RESULT_OK, null, null);
4366         } finally {
4367             Binder.restoreCallingIdentity(ident);
4368         }
4369     }
4370 
removeUserState(final @UserIdInt int userId)4371     private void removeUserState(final @UserIdInt int userId) {
4372         try {
4373             mContext.getSystemService(StorageManager.class).destroyUserKey(userId);
4374         } catch (IllegalStateException e) {
4375             // This may be simply because the user was partially created.
4376             Slog.i(LOG_TAG, "Destroying key for user " + userId + " failed, continuing anyway", e);
4377         }
4378 
4379         // Cleanup gatekeeper secure user id
4380         try {
4381             final IGateKeeperService gk = GateKeeper.getService();
4382             if (gk != null) {
4383                 gk.clearSecureUserId(userId);
4384             }
4385         } catch (Exception ex) {
4386             Slog.w(LOG_TAG, "unable to clear GK secure user id");
4387         }
4388 
4389         // Cleanup package manager settings
4390         mPm.cleanUpUser(this, userId);
4391 
4392         // Clean up all data before removing metadata
4393         mUserDataPreparer.destroyUserData(userId,
4394                 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
4395 
4396         // Remove this user from the list
4397         synchronized (mUsersLock) {
4398             mUsers.remove(userId);
4399             mIsUserManaged.delete(userId);
4400         }
4401         synchronized (mUserStates) {
4402             mUserStates.delete(userId);
4403         }
4404         synchronized (mRestrictionsLock) {
4405             mBaseUserRestrictions.remove(userId);
4406             mAppliedUserRestrictions.remove(userId);
4407             mCachedEffectiveUserRestrictions.remove(userId);
4408             // Remove local restrictions affecting user
4409             mDevicePolicyLocalUserRestrictions.delete(userId);
4410             // Remove local restrictions set by user
4411             boolean changed = false;
4412             for (int i = 0; i < mDevicePolicyLocalUserRestrictions.size(); i++) {
4413                 int targetUserId = mDevicePolicyLocalUserRestrictions.keyAt(i);
4414                 changed |= getDevicePolicyLocalRestrictionsForTargetUserLR(targetUserId)
4415                         .remove(userId);
4416             }
4417             changed |= mDevicePolicyGlobalUserRestrictions.remove(userId);
4418             if (changed) {
4419                 applyUserRestrictionsForAllUsersLR();
4420             }
4421         }
4422         // Update the user list
4423         synchronized (mPackagesLock) {
4424             writeUserListLP();
4425         }
4426         // Remove user file
4427         AtomicFile userFile = new AtomicFile(new File(mUsersDir, userId + XML_SUFFIX));
4428         userFile.delete();
4429         updateUserIds();
4430         if (RELEASE_DELETED_USER_ID) {
4431             synchronized (mUsersLock) {
4432                 mRemovingUserIds.delete(userId);
4433             }
4434         }
4435     }
4436 
sendProfileRemovedBroadcast(int parentUserId, int removedUserId)4437     private void sendProfileRemovedBroadcast(int parentUserId, int removedUserId) {
4438         Intent managedProfileIntent = new Intent(Intent.ACTION_MANAGED_PROFILE_REMOVED);
4439         managedProfileIntent.putExtra(Intent.EXTRA_USER, new UserHandle(removedUserId));
4440         managedProfileIntent.putExtra(Intent.EXTRA_USER_HANDLE, removedUserId);
4441         final UserHandle parentHandle = new UserHandle(parentUserId);
4442         getDevicePolicyManagerInternal().broadcastIntentToCrossProfileManifestReceiversAsUser(
4443                 managedProfileIntent, parentHandle, /* requiresPermission= */ false);
4444         managedProfileIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4445                 | Intent.FLAG_RECEIVER_FOREGROUND);
4446         mContext.sendBroadcastAsUser(managedProfileIntent, parentHandle,
4447                 /* receiverPermission= */null);
4448     }
4449 
4450     @Override
getApplicationRestrictions(String packageName)4451     public Bundle getApplicationRestrictions(String packageName) {
4452         return getApplicationRestrictionsForUser(packageName, UserHandle.getCallingUserId());
4453     }
4454 
4455     @Override
getApplicationRestrictionsForUser(String packageName, @UserIdInt int userId)4456     public Bundle getApplicationRestrictionsForUser(String packageName, @UserIdInt int userId) {
4457         if (UserHandle.getCallingUserId() != userId
4458                 || !UserHandle.isSameApp(Binder.getCallingUid(), getUidForPackage(packageName))) {
4459             checkSystemOrRoot("get application restrictions for other user/app " + packageName);
4460         }
4461         synchronized (mAppRestrictionsLock) {
4462             // Read the restrictions from XML
4463             return readApplicationRestrictionsLAr(packageName, userId);
4464         }
4465     }
4466 
4467     @Override
setApplicationRestrictions(String packageName, Bundle restrictions, @UserIdInt int userId)4468     public void setApplicationRestrictions(String packageName, Bundle restrictions,
4469             @UserIdInt int userId) {
4470         checkSystemOrRoot("set application restrictions");
4471         if (restrictions != null) {
4472             restrictions.setDefusable(true);
4473         }
4474         final boolean changed;
4475         synchronized (mAppRestrictionsLock) {
4476             if (restrictions == null || restrictions.isEmpty()) {
4477                 changed = cleanAppRestrictionsForPackageLAr(packageName, userId);
4478             } else {
4479                 // Write the restrictions to XML
4480                 writeApplicationRestrictionsLAr(packageName, restrictions, userId);
4481                 // TODO(b/154323615): avoid unnecessary broadcast when there is no change.
4482                 changed = true;
4483             }
4484         }
4485 
4486         if (!changed) {
4487             return;
4488         }
4489 
4490         // Notify package of changes via an intent - only sent to explicitly registered receivers.
4491         final Intent changeIntent = new Intent(Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED);
4492         changeIntent.setPackage(packageName);
4493         changeIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
4494         mContext.sendBroadcastAsUser(changeIntent, UserHandle.of(userId));
4495     }
4496 
getUidForPackage(String packageName)4497     private int getUidForPackage(String packageName) {
4498         final long ident = Binder.clearCallingIdentity();
4499         try {
4500             return mContext.getPackageManager().getApplicationInfo(packageName,
4501                     PackageManager.MATCH_ANY_USER).uid;
4502         } catch (NameNotFoundException nnfe) {
4503             return -1;
4504         } finally {
4505             Binder.restoreCallingIdentity(ident);
4506         }
4507     }
4508 
4509     @GuardedBy("mAppRestrictionsLock")
readApplicationRestrictionsLAr(String packageName, @UserIdInt int userId)4510     private static Bundle readApplicationRestrictionsLAr(String packageName,
4511             @UserIdInt int userId) {
4512         AtomicFile restrictionsFile =
4513                 new AtomicFile(new File(Environment.getUserSystemDirectory(userId),
4514                         packageToRestrictionsFileName(packageName)));
4515         return readApplicationRestrictionsLAr(restrictionsFile);
4516     }
4517 
4518     @VisibleForTesting
4519     @GuardedBy("mAppRestrictionsLock")
readApplicationRestrictionsLAr(AtomicFile restrictionsFile)4520     static Bundle readApplicationRestrictionsLAr(AtomicFile restrictionsFile) {
4521         final Bundle restrictions = new Bundle();
4522         final ArrayList<String> values = new ArrayList<>();
4523         if (!restrictionsFile.getBaseFile().exists()) {
4524             return restrictions;
4525         }
4526 
4527         FileInputStream fis = null;
4528         try {
4529             fis = restrictionsFile.openRead();
4530             final TypedXmlPullParser parser = Xml.resolvePullParser(fis);
4531             XmlUtils.nextElement(parser);
4532             if (parser.getEventType() != XmlPullParser.START_TAG) {
4533                 Slog.e(LOG_TAG, "Unable to read restrictions file "
4534                         + restrictionsFile.getBaseFile());
4535                 return restrictions;
4536             }
4537             while (parser.next() != XmlPullParser.END_DOCUMENT) {
4538                 readEntry(restrictions, values, parser);
4539             }
4540         } catch (IOException|XmlPullParserException e) {
4541             Slog.w(LOG_TAG, "Error parsing " + restrictionsFile.getBaseFile(), e);
4542         } finally {
4543             IoUtils.closeQuietly(fis);
4544         }
4545         return restrictions;
4546     }
4547 
readEntry(Bundle restrictions, ArrayList<String> values, TypedXmlPullParser parser)4548     private static void readEntry(Bundle restrictions, ArrayList<String> values,
4549             TypedXmlPullParser parser) throws XmlPullParserException, IOException {
4550         int type = parser.getEventType();
4551         if (type == XmlPullParser.START_TAG && parser.getName().equals(TAG_ENTRY)) {
4552             String key = parser.getAttributeValue(null, ATTR_KEY);
4553             String valType = parser.getAttributeValue(null, ATTR_VALUE_TYPE);
4554             int count = parser.getAttributeInt(null, ATTR_MULTIPLE, -1);
4555             if (count != -1) {
4556                 values.clear();
4557                 while (count > 0 && (type = parser.next()) != XmlPullParser.END_DOCUMENT) {
4558                     if (type == XmlPullParser.START_TAG
4559                             && parser.getName().equals(TAG_VALUE)) {
4560                         values.add(parser.nextText().trim());
4561                         count--;
4562                     }
4563                 }
4564                 String [] valueStrings = new String[values.size()];
4565                 values.toArray(valueStrings);
4566                 restrictions.putStringArray(key, valueStrings);
4567             } else if (ATTR_TYPE_BUNDLE.equals(valType)) {
4568                 restrictions.putBundle(key, readBundleEntry(parser, values));
4569             } else if (ATTR_TYPE_BUNDLE_ARRAY.equals(valType)) {
4570                 final int outerDepth = parser.getDepth();
4571                 ArrayList<Bundle> bundleList = new ArrayList<>();
4572                 while (XmlUtils.nextElementWithin(parser, outerDepth)) {
4573                     Bundle childBundle = readBundleEntry(parser, values);
4574                     bundleList.add(childBundle);
4575                 }
4576                 restrictions.putParcelableArray(key,
4577                         bundleList.toArray(new Bundle[bundleList.size()]));
4578             } else {
4579                 String value = parser.nextText().trim();
4580                 if (ATTR_TYPE_BOOLEAN.equals(valType)) {
4581                     restrictions.putBoolean(key, Boolean.parseBoolean(value));
4582                 } else if (ATTR_TYPE_INTEGER.equals(valType)) {
4583                     restrictions.putInt(key, Integer.parseInt(value));
4584                 } else {
4585                     restrictions.putString(key, value);
4586                 }
4587             }
4588         }
4589     }
4590 
readBundleEntry(TypedXmlPullParser parser, ArrayList<String> values)4591     private static Bundle readBundleEntry(TypedXmlPullParser parser, ArrayList<String> values)
4592             throws IOException, XmlPullParserException {
4593         Bundle childBundle = new Bundle();
4594         final int outerDepth = parser.getDepth();
4595         while (XmlUtils.nextElementWithin(parser, outerDepth)) {
4596             readEntry(childBundle, values, parser);
4597         }
4598         return childBundle;
4599     }
4600 
4601     @GuardedBy("mAppRestrictionsLock")
writeApplicationRestrictionsLAr(String packageName, Bundle restrictions, @UserIdInt int userId)4602     private static void writeApplicationRestrictionsLAr(String packageName,
4603             Bundle restrictions, @UserIdInt int userId) {
4604         AtomicFile restrictionsFile = new AtomicFile(
4605                 new File(Environment.getUserSystemDirectory(userId),
4606                         packageToRestrictionsFileName(packageName)));
4607         writeApplicationRestrictionsLAr(restrictions, restrictionsFile);
4608     }
4609 
4610     @VisibleForTesting
4611     @GuardedBy("mAppRestrictionsLock")
writeApplicationRestrictionsLAr(Bundle restrictions, AtomicFile restrictionsFile)4612     static void writeApplicationRestrictionsLAr(Bundle restrictions, AtomicFile restrictionsFile) {
4613         FileOutputStream fos = null;
4614         try {
4615             fos = restrictionsFile.startWrite();
4616             final TypedXmlSerializer serializer = Xml.resolveSerializer(fos);
4617             serializer.startDocument(null, true);
4618             serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
4619 
4620             serializer.startTag(null, TAG_RESTRICTIONS);
4621             writeBundle(restrictions, serializer);
4622             serializer.endTag(null, TAG_RESTRICTIONS);
4623 
4624             serializer.endDocument();
4625             restrictionsFile.finishWrite(fos);
4626         } catch (Exception e) {
4627             restrictionsFile.failWrite(fos);
4628             Slog.e(LOG_TAG, "Error writing application restrictions list", e);
4629         }
4630     }
4631 
writeBundle(Bundle restrictions, TypedXmlSerializer serializer)4632     private static void writeBundle(Bundle restrictions, TypedXmlSerializer serializer)
4633             throws IOException {
4634         for (String key : restrictions.keySet()) {
4635             Object value = restrictions.get(key);
4636             serializer.startTag(null, TAG_ENTRY);
4637             serializer.attribute(null, ATTR_KEY, key);
4638 
4639             if (value instanceof Boolean) {
4640                 serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_BOOLEAN);
4641                 serializer.text(value.toString());
4642             } else if (value instanceof Integer) {
4643                 serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_INTEGER);
4644                 serializer.text(value.toString());
4645             } else if (value == null || value instanceof String) {
4646                 serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_STRING);
4647                 serializer.text(value != null ? (String) value : "");
4648             } else if (value instanceof Bundle) {
4649                 serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_BUNDLE);
4650                 writeBundle((Bundle) value, serializer);
4651             } else if (value instanceof Parcelable[]) {
4652                 serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_BUNDLE_ARRAY);
4653                 Parcelable[] array = (Parcelable[]) value;
4654                 for (Parcelable parcelable : array) {
4655                     if (!(parcelable instanceof Bundle)) {
4656                         throw new IllegalArgumentException("bundle-array can only hold Bundles");
4657                     }
4658                     serializer.startTag(null, TAG_ENTRY);
4659                     serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_BUNDLE);
4660                     writeBundle((Bundle) parcelable, serializer);
4661                     serializer.endTag(null, TAG_ENTRY);
4662                 }
4663             } else {
4664                 serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_STRING_ARRAY);
4665                 String[] values = (String[]) value;
4666                 serializer.attributeInt(null, ATTR_MULTIPLE, values.length);
4667                 for (String choice : values) {
4668                     serializer.startTag(null, TAG_VALUE);
4669                     serializer.text(choice != null ? choice : "");
4670                     serializer.endTag(null, TAG_VALUE);
4671                 }
4672             }
4673             serializer.endTag(null, TAG_ENTRY);
4674         }
4675     }
4676 
4677     @Override
getUserSerialNumber(@serIdInt int userId)4678     public int getUserSerialNumber(@UserIdInt int userId) {
4679         synchronized (mUsersLock) {
4680             final UserInfo userInfo = getUserInfoLU(userId);
4681             return userInfo != null ? userInfo.serialNumber : -1;
4682         }
4683     }
4684 
4685     @Override
isUserNameSet(@serIdInt int userId)4686     public boolean isUserNameSet(@UserIdInt int userId) {
4687         if (!hasManageUsersOrPermission(android.Manifest.permission.GET_ACCOUNTS_PRIVILEGED)) {
4688             throw new SecurityException("You need MANAGE_USERS or GET_ACCOUNTS_PRIVILEGED "
4689                     + "permissions to: get whether user name is set");
4690         }
4691         synchronized (mUsersLock) {
4692             final UserInfo userInfo = getUserInfoLU(userId);
4693             return userInfo != null && userInfo.name != null;
4694         }
4695     }
4696 
4697     @Override
getUserHandle(int userSerialNumber)4698     public int getUserHandle(int userSerialNumber) {
4699         synchronized (mUsersLock) {
4700             for (int userId : mUserIds) {
4701                 UserInfo info = getUserInfoLU(userId);
4702                 if (info != null && info.serialNumber == userSerialNumber) return userId;
4703             }
4704             // Not found
4705             return -1;
4706         }
4707     }
4708 
4709     @Override
getUserCreationTime(@serIdInt int userId)4710     public long getUserCreationTime(@UserIdInt int userId) {
4711         int callingUserId = UserHandle.getCallingUserId();
4712         UserInfo userInfo = null;
4713         synchronized (mUsersLock) {
4714             if (callingUserId == userId) {
4715                 userInfo = getUserInfoLU(userId);
4716             } else {
4717                 UserInfo parent = getProfileParentLU(userId);
4718                 if (parent != null && parent.id == callingUserId) {
4719                     userInfo = getUserInfoLU(userId);
4720                 }
4721             }
4722         }
4723         if (userInfo == null) {
4724             throw new SecurityException("userId can only be the calling user or a "
4725                     + "profile associated with this user");
4726         }
4727         return userInfo.creationTime;
4728     }
4729 
4730     /**
4731      * Caches the list of user ids in an array, adjusting the array size when necessary.
4732      */
updateUserIds()4733     private void updateUserIds() {
4734         int num = 0;
4735         int numIncludingPreCreated = 0;
4736         synchronized (mUsersLock) {
4737             final int userSize = mUsers.size();
4738             for (int i = 0; i < userSize; i++) {
4739                 final UserInfo userInfo = mUsers.valueAt(i).info;
4740                 if (!userInfo.partial) {
4741                     numIncludingPreCreated++;
4742                     if (!userInfo.preCreated) {
4743                         num++;
4744                     }
4745                 }
4746             }
4747             if (DBG) {
4748                 Slog.d(LOG_TAG, "updateUserIds(): numberUsers= " + num
4749                         + " includingPreCreated=" + numIncludingPreCreated);
4750             }
4751             final int[] newUsers = new int[num];
4752             final int[] newUsersIncludingPreCreated = new int[numIncludingPreCreated];
4753 
4754             int n = 0;
4755             int nIncludingPreCreated = 0;
4756             for (int i = 0; i < userSize; i++) {
4757                 final UserInfo userInfo = mUsers.valueAt(i).info;
4758                 if (!userInfo.partial) {
4759                     final int userId = mUsers.keyAt(i);
4760                     newUsersIncludingPreCreated[nIncludingPreCreated++] = userId;
4761                     if (!userInfo.preCreated) {
4762                         newUsers[n++] = userId;
4763                     }
4764                 }
4765             }
4766             mUserIds = newUsers;
4767             mUserIdsIncludingPreCreated = newUsersIncludingPreCreated;
4768             if (DBG) {
4769                 Slog.d(LOG_TAG, "updateUserIds(): userIds= " + Arrays.toString(mUserIds)
4770                         + " includingPreCreated=" + Arrays.toString(mUserIdsIncludingPreCreated));
4771             }
4772         }
4773     }
4774 
4775     /**
4776      * Called right before a user is started. This gives us a chance to prepare
4777      * app storage and apply any user restrictions.
4778      */
onBeforeStartUser(@serIdInt int userId)4779     public void onBeforeStartUser(@UserIdInt int userId) {
4780         UserInfo userInfo = getUserInfo(userId);
4781         if (userInfo == null) {
4782             return;
4783         }
4784         TimingsTraceAndSlog t = new TimingsTraceAndSlog();
4785         t.traceBegin("onBeforeStartUser-" + userId);
4786         final int userSerial = userInfo.serialNumber;
4787         // Migrate only if build fingerprints mismatch
4788         boolean migrateAppsData = !Build.FINGERPRINT.equals(userInfo.lastLoggedInFingerprint);
4789         t.traceBegin("prepareUserData");
4790         mUserDataPreparer.prepareUserData(userId, userSerial, StorageManager.FLAG_STORAGE_DE);
4791         t.traceEnd();
4792         t.traceBegin("reconcileAppsData");
4793         mPm.reconcileAppsData(userId, StorageManager.FLAG_STORAGE_DE, migrateAppsData);
4794         t.traceEnd();
4795 
4796         if (userId != UserHandle.USER_SYSTEM) {
4797             t.traceBegin("applyUserRestrictions");
4798             synchronized (mRestrictionsLock) {
4799                 applyUserRestrictionsLR(userId);
4800             }
4801             t.traceEnd();
4802         }
4803         t.traceEnd(); // onBeforeStartUser
4804     }
4805 
4806     /**
4807      * Called right before a user is unlocked. This gives us a chance to prepare
4808      * app storage.
4809      */
onBeforeUnlockUser(@serIdInt int userId)4810     public void onBeforeUnlockUser(@UserIdInt int userId) {
4811         UserInfo userInfo = getUserInfo(userId);
4812         if (userInfo == null) {
4813             return;
4814         }
4815         final int userSerial = userInfo.serialNumber;
4816         // Migrate only if build fingerprints mismatch
4817         boolean migrateAppsData = !Build.FINGERPRINT.equals(userInfo.lastLoggedInFingerprint);
4818         mUserDataPreparer.prepareUserData(userId, userSerial, StorageManager.FLAG_STORAGE_CE);
4819 
4820         StorageManagerInternal smInternal = LocalServices.getService(StorageManagerInternal.class);
4821         smInternal.markCeStoragePrepared(userId);
4822 
4823         mPm.reconcileAppsData(userId, StorageManager.FLAG_STORAGE_CE, migrateAppsData);
4824     }
4825 
4826     /**
4827      * Examine all users present on given mounted volume, and destroy data
4828      * belonging to users that are no longer valid, or whose user ID has been
4829      * recycled.
4830      */
reconcileUsers(String volumeUuid)4831     void reconcileUsers(String volumeUuid) {
4832         mUserDataPreparer.reconcileUsers(volumeUuid, getUsers(
4833                 /* excludePartial= */ true,
4834                 /* excludeDying= */ true,
4835                 /* excludePreCreated= */ false));
4836     }
4837 
4838     /**
4839      * Make a note of the last started time of a user and do some cleanup.
4840      * This is called with ActivityManagerService lock held.
4841      * @param userId the user that was just foregrounded
4842      */
onUserLoggedIn(@serIdInt int userId)4843     public void onUserLoggedIn(@UserIdInt int userId) {
4844         UserData userData = getUserDataNoChecks(userId);
4845         if (userData == null || userData.info.partial) {
4846             Slog.w(LOG_TAG, "userForeground: unknown user #" + userId);
4847             return;
4848         }
4849 
4850         final long now = System.currentTimeMillis();
4851         if (now > EPOCH_PLUS_30_YEARS) {
4852             userData.info.lastLoggedInTime = now;
4853         }
4854         userData.info.lastLoggedInFingerprint = Build.FINGERPRINT;
4855         scheduleWriteUser(userData);
4856     }
4857 
4858     /**
4859      * Returns the next available user id, filling in any holes in the ids.
4860      */
4861     @VisibleForTesting
getNextAvailableId()4862     int getNextAvailableId() {
4863         int nextId;
4864         synchronized (mUsersLock) {
4865             nextId = scanNextAvailableIdLocked();
4866             if (nextId >= 0) {
4867                 return nextId;
4868             }
4869             // All ids up to MAX_USER_ID were used. Remove all mRemovingUserIds,
4870             // except most recently removed
4871             if (mRemovingUserIds.size() > 0) {
4872                 Slog.i(LOG_TAG, "All available IDs are used. Recycling LRU ids.");
4873                 mRemovingUserIds.clear();
4874                 for (Integer recentlyRemovedId : mRecentlyRemovedIds) {
4875                     mRemovingUserIds.put(recentlyRemovedId, true);
4876                 }
4877                 nextId = scanNextAvailableIdLocked();
4878             }
4879         }
4880         if (nextId < 0) {
4881             throw new IllegalStateException("No user id available!");
4882         }
4883         return nextId;
4884     }
4885 
4886     @GuardedBy("mUsersLock")
scanNextAvailableIdLocked()4887     private int scanNextAvailableIdLocked() {
4888         for (int i = MIN_USER_ID; i < MAX_USER_ID; i++) {
4889             if (mUsers.indexOfKey(i) < 0 && !mRemovingUserIds.get(i)) {
4890                 return i;
4891             }
4892         }
4893         return -1;
4894     }
4895 
packageToRestrictionsFileName(String packageName)4896     private static String packageToRestrictionsFileName(String packageName) {
4897         return RESTRICTIONS_FILE_PREFIX + packageName + XML_SUFFIX;
4898     }
4899 
4900     @Override
setSeedAccountData(@serIdInt int userId, String accountName, String accountType, PersistableBundle accountOptions, boolean persist)4901     public void setSeedAccountData(@UserIdInt int userId, String accountName, String accountType,
4902             PersistableBundle accountOptions, boolean persist) {
4903         checkManageUsersPermission("Require MANAGE_USERS permission to set user seed data");
4904         synchronized (mPackagesLock) {
4905             final UserData userData;
4906             synchronized (mUsersLock) {
4907                 userData = getUserDataLU(userId);
4908                 if (userData == null) {
4909                     Slog.e(LOG_TAG, "No such user for settings seed data u=" + userId);
4910                     return;
4911                 }
4912                 userData.seedAccountName = accountName;
4913                 userData.seedAccountType = accountType;
4914                 userData.seedAccountOptions = accountOptions;
4915                 userData.persistSeedData = persist;
4916             }
4917             if (persist) {
4918                 writeUserLP(userData);
4919             }
4920         }
4921     }
4922 
4923     @Override
getSeedAccountName()4924     public String getSeedAccountName() throws RemoteException {
4925         checkManageUsersPermission("Cannot get seed account information");
4926         synchronized (mUsersLock) {
4927             UserData userData = getUserDataLU(UserHandle.getCallingUserId());
4928             return userData.seedAccountName;
4929         }
4930     }
4931 
4932     @Override
getSeedAccountType()4933     public String getSeedAccountType() throws RemoteException {
4934         checkManageUsersPermission("Cannot get seed account information");
4935         synchronized (mUsersLock) {
4936             UserData userData = getUserDataLU(UserHandle.getCallingUserId());
4937             return userData.seedAccountType;
4938         }
4939     }
4940 
4941     @Override
getSeedAccountOptions()4942     public PersistableBundle getSeedAccountOptions() throws RemoteException {
4943         checkManageUsersPermission("Cannot get seed account information");
4944         synchronized (mUsersLock) {
4945             UserData userData = getUserDataLU(UserHandle.getCallingUserId());
4946             return userData.seedAccountOptions;
4947         }
4948     }
4949 
4950     @Override
clearSeedAccountData()4951     public void clearSeedAccountData() throws RemoteException {
4952         checkManageUsersPermission("Cannot clear seed account information");
4953         synchronized (mPackagesLock) {
4954             UserData userData;
4955             synchronized (mUsersLock) {
4956                 userData = getUserDataLU(UserHandle.getCallingUserId());
4957                 if (userData == null) return;
4958                 userData.clearSeedAccountData();
4959             }
4960             writeUserLP(userData);
4961         }
4962     }
4963 
4964     @Override
someUserHasSeedAccount(String accountName, String accountType)4965     public boolean someUserHasSeedAccount(String accountName, String accountType)
4966             throws RemoteException {
4967         checkManageUsersPermission("Cannot check seed account information");
4968         synchronized (mUsersLock) {
4969             final int userSize = mUsers.size();
4970             for (int i = 0; i < userSize; i++) {
4971                 final UserData data = mUsers.valueAt(i);
4972                 if (data.info.isInitialized()) continue;
4973                 if (data.seedAccountName == null || !data.seedAccountName.equals(accountName)) {
4974                     continue;
4975                 }
4976                 if (data.seedAccountType == null || !data.seedAccountType.equals(accountType)) {
4977                     continue;
4978                 }
4979                 return true;
4980             }
4981         }
4982         return false;
4983     }
4984 
4985     @Override
onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver)4986     public void onShellCommand(FileDescriptor in, FileDescriptor out,
4987             FileDescriptor err, String[] args, ShellCallback callback,
4988             ResultReceiver resultReceiver) {
4989         (new Shell()).exec(this, in, out, err, args, callback, resultReceiver);
4990     }
4991 
onShellCommand(Shell shell, String cmd)4992     int onShellCommand(Shell shell, String cmd) {
4993         if (cmd == null) {
4994             return shell.handleDefaultCommands(cmd);
4995         }
4996 
4997         final PrintWriter pw = shell.getOutPrintWriter();
4998         try {
4999             switch(cmd) {
5000                 case "list":
5001                     return runList(pw, shell);
5002                 case "report-system-user-package-whitelist-problems":
5003                     return runReportPackageWhitelistProblems(pw, shell);
5004                 default:
5005                     return shell.handleDefaultCommands(cmd);
5006             }
5007         } catch (RemoteException e) {
5008             pw.println("Remote exception: " + e);
5009         }
5010         return -1;
5011     }
5012 
runList(PrintWriter pw, Shell shell)5013     private int runList(PrintWriter pw, Shell shell) throws RemoteException {
5014         boolean all = false;
5015         boolean verbose = false;
5016         String opt;
5017         while ((opt = shell.getNextOption()) != null) {
5018             switch (opt) {
5019                 case "-v":
5020                     verbose = true;
5021                     break;
5022                 case "--all":
5023                     all = true;
5024                     break;
5025                 default:
5026                     pw.println("Invalid option: " + opt);
5027                     return -1;
5028             }
5029         }
5030         final IActivityManager am = ActivityManager.getService();
5031         final List<UserInfo> users = getUsers(/* excludePartial= */ !all,
5032                 /* excludingDying=*/ false, /* excludePreCreated= */ !all);
5033         if (users == null) {
5034             pw.println("Error: couldn't get users");
5035             return 1;
5036         } else {
5037             final int size = users.size();
5038             int currentUser = UserHandle.USER_NULL;
5039             if (verbose) {
5040                 pw.printf("%d users:\n\n", size);
5041                 currentUser = am.getCurrentUser().id;
5042             } else {
5043                 // NOTE: the standard "list users" command is used by integration tests and
5044                 // hence should not be changed. If you need to add more info, use the
5045                 // verbose option.
5046                 pw.println("Users:");
5047             }
5048             for (int i = 0; i < size; i++) {
5049                 final UserInfo user = users.get(i);
5050                 final boolean running = am.isUserRunning(user.id, 0);
5051                 final boolean current = user.id == currentUser;
5052                 final boolean hasParent = user.profileGroupId != user.id
5053                         && user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID;
5054                 if (verbose) {
5055                     final DevicePolicyManagerInternal dpm = getDevicePolicyManagerInternal();
5056                     String deviceOwner = "";
5057                     String profileOwner = "";
5058                     if (dpm != null) {
5059                         final long ident = Binder.clearCallingIdentity();
5060                         // NOTE: dpm methods below CANNOT be called while holding the mUsersLock
5061                         try {
5062                             if (dpm.getDeviceOwnerUserId() == user.id) {
5063                                 deviceOwner = " (device-owner)";
5064                             }
5065                             if (dpm.getProfileOwnerAsUser(user.id) != null) {
5066                                 profileOwner = " (profile-owner)";
5067                             }
5068                         } finally {
5069                             Binder.restoreCallingIdentity(ident);
5070                         }
5071                     }
5072                     pw.printf("%d: id=%d, name=%s, flags=%s%s%s%s%s%s%s%s%s\n", i, user.id,
5073                             user.name,
5074                             UserInfo.flagsToString(user.flags),
5075                             hasParent ? " (parentId=" + user.profileGroupId + ")" : "",
5076                             running ? " (running)" : "",
5077                             user.partial ? " (partial)" : "",
5078                             user.preCreated ? " (pre-created)" : "",
5079                             user.convertedFromPreCreated ? " (converted)" : "",
5080                             deviceOwner, profileOwner,
5081                             current ? " (current)" : "");
5082                 } else {
5083                     // NOTE: the standard "list users" command is used by integration tests and
5084                     // hence should not be changed. If you need to add more info, use the
5085                     // verbose option.
5086                     pw.printf("\t%s%s\n", user, running ? " running" : "");
5087                 }
5088             }
5089             return 0;
5090         }
5091     }
5092 
runReportPackageWhitelistProblems(PrintWriter pw, Shell shell)5093     private int runReportPackageWhitelistProblems(PrintWriter pw, Shell shell) {
5094         boolean verbose = false;
5095         boolean criticalOnly = false;
5096         int mode = UserSystemPackageInstaller.USER_TYPE_PACKAGE_WHITELIST_MODE_NONE;
5097         String opt;
5098         while ((opt = shell.getNextOption()) != null) {
5099             switch (opt) {
5100                 case "-v":
5101                 case "--verbose":
5102                     verbose = true;
5103                     break;
5104                 case "--critical-only":
5105                     criticalOnly = true;
5106                     break;
5107                 case "--mode":
5108                     mode = Integer.parseInt(shell.getNextArgRequired());
5109                     break;
5110                 default:
5111                     pw.println("Invalid option: " + opt);
5112                     return -1;
5113             }
5114         }
5115 
5116         Slog.d(LOG_TAG, "runReportPackageWhitelistProblems(): verbose=" + verbose
5117                 + ", criticalOnly=" + criticalOnly
5118                 + ", mode=" + UserSystemPackageInstaller.modeToString(mode));
5119 
5120         try (IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ")) {
5121             mSystemPackageInstaller.dumpPackageWhitelistProblems(ipw, mode, verbose, criticalOnly);
5122         }
5123         return 0;
5124     }
5125 
5126     @Override
dump(FileDescriptor fd, PrintWriter pw, String[] args)5127     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
5128         if (!DumpUtils.checkDumpPermission(mContext, LOG_TAG, pw)) return;
5129 
5130         long now = System.currentTimeMillis();
5131         final long nowRealtime = SystemClock.elapsedRealtime();
5132 
5133         final ActivityManagerInternal amInternal = LocalServices
5134                 .getService(ActivityManagerInternal.class);
5135         pw.print("Current user: ");
5136         if (amInternal != null) {
5137             pw.println(amInternal.getCurrentUserId());
5138         } else {
5139             pw.println("N/A");
5140         }
5141 
5142         pw.println();
5143         StringBuilder sb = new StringBuilder();
5144         synchronized (mPackagesLock) {
5145             synchronized (mUsersLock) {
5146                 pw.println("Users:");
5147                 for (int i = 0; i < mUsers.size(); i++) {
5148                     UserData userData = mUsers.valueAt(i);
5149                     if (userData == null) {
5150                         continue;
5151                     }
5152                     UserInfo userInfo = userData.info;
5153                     final int userId = userInfo.id;
5154                     pw.print("  "); pw.print(userInfo);
5155                     pw.print(" serialNo="); pw.print(userInfo.serialNumber);
5156                     pw.print(" isPrimary="); pw.print(userInfo.isPrimary());
5157                     if (userInfo.profileGroupId != userInfo.id
5158                             &&  userInfo.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
5159                         pw.print(" parentId="); pw.print(userInfo.profileGroupId);
5160                     }
5161 
5162                     if (mRemovingUserIds.get(userId)) {
5163                         pw.print(" <removing> ");
5164                     }
5165                     if (userInfo.partial) {
5166                         pw.print(" <partial>");
5167                     }
5168                     if (userInfo.preCreated) {
5169                         pw.print(" <pre-created>");
5170                     }
5171                     if (userInfo.convertedFromPreCreated) {
5172                         pw.print(" <converted>");
5173                     }
5174                     pw.println();
5175                     pw.print("    Type: "); pw.println(userInfo.userType);
5176                     pw.print("    Flags: "); pw.print(userInfo.flags); pw.print(" (");
5177                     pw.print(UserInfo.flagsToString(userInfo.flags)); pw.println(")");
5178                     pw.print("    State: ");
5179                     final int state;
5180                     synchronized (mUserStates) {
5181                         state = mUserStates.get(userId, -1);
5182                     }
5183                     pw.println(UserState.stateToString(state));
5184                     pw.print("    Created: ");
5185                     dumpTimeAgo(pw, sb, now, userInfo.creationTime);
5186 
5187                     pw.print("    Last logged in: ");
5188                     dumpTimeAgo(pw, sb, now, userInfo.lastLoggedInTime);
5189 
5190                     pw.print("    Last logged in fingerprint: ");
5191                     pw.println(userInfo.lastLoggedInFingerprint);
5192 
5193                     pw.print("    Start time: ");
5194                     dumpTimeAgo(pw, sb, nowRealtime, userData.startRealtime);
5195 
5196                     pw.print("    Unlock time: ");
5197                     dumpTimeAgo(pw, sb, nowRealtime, userData.unlockRealtime);
5198 
5199                     pw.print("    Has profile owner: ");
5200                     pw.println(mIsUserManaged.get(userId));
5201                     pw.println("    Restrictions:");
5202                     synchronized (mRestrictionsLock) {
5203                         UserRestrictionsUtils.dumpRestrictions(
5204                                 pw, "      ", mBaseUserRestrictions.getRestrictions(userInfo.id));
5205                         pw.println("    Device policy global restrictions:");
5206                         UserRestrictionsUtils.dumpRestrictions(
5207                                 pw, "      ",
5208                                 mDevicePolicyGlobalUserRestrictions.getRestrictions(userInfo.id));
5209                         pw.println("    Device policy local restrictions:");
5210                         getDevicePolicyLocalRestrictionsForTargetUserLR(
5211                                 userInfo.id).dumpRestrictions(pw, "      ");
5212                         pw.println("    Effective restrictions:");
5213                         UserRestrictionsUtils.dumpRestrictions(
5214                                 pw, "      ",
5215                                 mCachedEffectiveUserRestrictions.getRestrictions(userInfo.id));
5216                     }
5217 
5218                     if (userData.account != null) {
5219                         pw.print("    Account name: " + userData.account);
5220                         pw.println();
5221                     }
5222 
5223                     if (userData.seedAccountName != null) {
5224                         pw.print("    Seed account name: " + userData.seedAccountName);
5225                         pw.println();
5226                         if (userData.seedAccountType != null) {
5227                             pw.print("         account type: " + userData.seedAccountType);
5228                             pw.println();
5229                         }
5230                         if (userData.seedAccountOptions != null) {
5231                             pw.print("         account options exist");
5232                             pw.println();
5233                         }
5234                     }
5235                 }
5236             }
5237 
5238             pw.println();
5239             pw.println("Device properties:");
5240             pw.println("  Device owner id:" + mDeviceOwnerUserId);
5241             pw.println();
5242             pw.println("  Guest restrictions:");
5243             synchronized (mGuestRestrictions) {
5244                 UserRestrictionsUtils.dumpRestrictions(pw, "    ", mGuestRestrictions);
5245             }
5246             synchronized (mUsersLock) {
5247                 pw.println();
5248                 pw.println("  Device managed: " + mIsDeviceManaged);
5249                 if (mRemovingUserIds.size() > 0) {
5250                     pw.println();
5251                     pw.println("  Recently removed userIds: " + mRecentlyRemovedIds);
5252                 }
5253             }
5254             synchronized (mUserStates) {
5255                 pw.print("  Started users state: [");
5256                 final int size = mUserStates.states.size();
5257                 for (int i = 0; i < size; i++) {
5258                     final int userId = mUserStates.states.keyAt(i);
5259                     final int state = mUserStates.states.valueAt(i);
5260                     pw.print(userId);
5261                     pw.print('=');
5262                     pw.print(UserState.stateToString(state));
5263                     if (i != size - 1) pw.print(", ");
5264                 }
5265                 pw.println(']');
5266             }
5267             synchronized (mUsersLock) {
5268                 pw.print("  Cached user IDs: ");
5269                 pw.println(Arrays.toString(mUserIds));
5270                 pw.print("  Cached user IDs (including pre-created): ");
5271                 pw.println(Arrays.toString(mUserIdsIncludingPreCreated));
5272             }
5273 
5274         } // synchronized (mPackagesLock)
5275 
5276         // Dump some capabilities
5277         pw.println();
5278         pw.print("  Max users: " + UserManager.getMaxSupportedUsers());
5279         pw.println(" (limit reached: " + isUserLimitReached() + ")");
5280         pw.println("  Supports switchable users: " + UserManager.supportsMultipleUsers());
5281         pw.println("  All guests ephemeral: " + Resources.getSystem().getBoolean(
5282                 com.android.internal.R.bool.config_guestUserEphemeral));
5283         pw.println("  Force ephemeral users: " + mForceEphemeralUsers);
5284         pw.println("  Is split-system user: " + UserManager.isSplitSystemUser());
5285         pw.println("  Is headless-system mode: " + UserManager.isHeadlessSystemUserMode());
5286         pw.println("  User version: " + mUserVersion);
5287         pw.println("  Owner name: " + getOwnerName());
5288         if (DBG_ALLOCATION) {
5289             pw.println("  System user allocations: " + mUser0Allocations.get());
5290         }
5291 
5292         pw.println();
5293         pw.println("Number of listeners for");
5294         synchronized (mUserRestrictionsListeners) {
5295             pw.println("  restrictions: " + mUserRestrictionsListeners.size());
5296         }
5297         synchronized (mUserLifecycleListeners) {
5298             pw.println("  user lifecycle events: " + mUserLifecycleListeners.size());
5299         }
5300 
5301         // Dump UserTypes
5302         pw.println();
5303         pw.println("User types version: " + mUserTypeVersion);
5304         pw.println("User types (" + mUserTypes.size() + " types):");
5305         for (int i = 0; i < mUserTypes.size(); i++) {
5306             pw.println("    " + mUserTypes.keyAt(i) + ": ");
5307             mUserTypes.valueAt(i).dump(pw, "        ");
5308         }
5309 
5310         // TODO: create IndentingPrintWriter at the beginning of dump() and use the proper
5311         // indentation methods instead of explicit printing "  "
5312         try (IndentingPrintWriter ipw = new IndentingPrintWriter(pw)) {
5313 
5314             // Dump SystemPackageInstaller info
5315             ipw.println();
5316             mSystemPackageInstaller.dump(ipw);
5317 
5318             // NOTE: pw's not available after this point as it's auto-closed by ipw, so new dump
5319             // statements should use ipw below
5320         }
5321     }
5322 
dumpTimeAgo(PrintWriter pw, StringBuilder sb, long nowTime, long time)5323     private static void dumpTimeAgo(PrintWriter pw, StringBuilder sb, long nowTime, long time) {
5324         if (time == 0) {
5325             pw.println("<unknown>");
5326         } else {
5327             sb.setLength(0);
5328             TimeUtils.formatDuration(nowTime - time, sb);
5329             sb.append(" ago");
5330             pw.println(sb);
5331         }
5332     }
5333 
5334     final class MainHandler extends Handler {
5335 
5336         @Override
handleMessage(Message msg)5337         public void handleMessage(Message msg) {
5338             switch (msg.what) {
5339                 case WRITE_USER_MSG:
5340                     removeMessages(WRITE_USER_MSG, msg.obj);
5341                     synchronized (mPackagesLock) {
5342                         int userId = ((UserData) msg.obj).info.id;
5343                         UserData userData = getUserDataNoChecks(userId);
5344                         if (userData != null) {
5345                             writeUserLP(userData);
5346                         } else {
5347                             Slog.i(LOG_TAG, "handle(WRITE_USER_MSG): no data for user " + userId
5348                                     + ", it was probably removed before handler could handle it");
5349                         }
5350                     }
5351             }
5352         }
5353     }
5354 
5355     /**
5356      * @param userId
5357      * @return whether the user has been initialized yet
5358      */
isUserInitialized(@serIdInt int userId)5359     boolean isUserInitialized(@UserIdInt int userId) {
5360         return mLocalService.isUserInitialized(userId);
5361     }
5362 
5363     private class LocalService extends UserManagerInternal {
5364         @Override
setDevicePolicyUserRestrictions(@serIdInt int originatingUserId, @NonNull Bundle global, @NonNull RestrictionsSet local, boolean isDeviceOwner)5365         public void setDevicePolicyUserRestrictions(@UserIdInt int originatingUserId,
5366                 @NonNull Bundle global, @NonNull RestrictionsSet local,
5367                 boolean isDeviceOwner) {
5368             UserManagerService.this.setDevicePolicyUserRestrictionsInner(originatingUserId,
5369                     global, local, isDeviceOwner);
5370         }
5371 
5372         @Override
getBaseUserRestrictions(@serIdInt int userId)5373         public Bundle getBaseUserRestrictions(@UserIdInt int userId) {
5374             synchronized (mRestrictionsLock) {
5375                 return mBaseUserRestrictions.getRestrictions(userId);
5376             }
5377         }
5378 
5379         @Override
setBaseUserRestrictionsByDpmsForMigration( @serIdInt int userId, Bundle baseRestrictions)5380         public void setBaseUserRestrictionsByDpmsForMigration(
5381                 @UserIdInt int userId, Bundle baseRestrictions) {
5382             synchronized (mRestrictionsLock) {
5383                 if (mBaseUserRestrictions.updateRestrictions(userId,
5384                         new Bundle(baseRestrictions))) {
5385                     invalidateEffectiveUserRestrictionsLR(userId);
5386                 }
5387             }
5388 
5389             final UserData userData = getUserDataNoChecks(userId);
5390             synchronized (mPackagesLock) {
5391                 if (userData != null) {
5392                     writeUserLP(userData);
5393                 } else {
5394                     Slog.w(LOG_TAG, "UserInfo not found for " + userId);
5395                 }
5396             }
5397         }
5398 
5399         @Override
getUserRestriction(@serIdInt int userId, String key)5400         public boolean getUserRestriction(@UserIdInt int userId, String key) {
5401             return getUserRestrictions(userId).getBoolean(key);
5402         }
5403 
5404         @Override
addUserRestrictionsListener(UserRestrictionsListener listener)5405         public void addUserRestrictionsListener(UserRestrictionsListener listener) {
5406             synchronized (mUserRestrictionsListeners) {
5407                 mUserRestrictionsListeners.add(listener);
5408             }
5409         }
5410 
5411         @Override
removeUserRestrictionsListener(UserRestrictionsListener listener)5412         public void removeUserRestrictionsListener(UserRestrictionsListener listener) {
5413             synchronized (mUserRestrictionsListeners) {
5414                 mUserRestrictionsListeners.remove(listener);
5415             }
5416         }
5417 
5418         @Override
addUserLifecycleListener(UserLifecycleListener listener)5419         public void addUserLifecycleListener(UserLifecycleListener listener) {
5420             synchronized (mUserLifecycleListeners) {
5421                 mUserLifecycleListeners.add(listener);
5422             }
5423         }
5424 
5425         @Override
removeUserLifecycleListener(UserLifecycleListener listener)5426         public void removeUserLifecycleListener(UserLifecycleListener listener) {
5427             synchronized (mUserLifecycleListeners) {
5428                 mUserLifecycleListeners.remove(listener);
5429             }
5430         }
5431 
5432         @Override
setDeviceManaged(boolean isManaged)5433         public void setDeviceManaged(boolean isManaged) {
5434             synchronized (mUsersLock) {
5435                 mIsDeviceManaged = isManaged;
5436             }
5437         }
5438 
5439         @Override
isDeviceManaged()5440         public boolean isDeviceManaged() {
5441             synchronized (mUsersLock) {
5442                 return mIsDeviceManaged;
5443             }
5444         }
5445 
5446         @Override
setUserManaged(@serIdInt int userId, boolean isManaged)5447         public void setUserManaged(@UserIdInt int userId, boolean isManaged) {
5448             synchronized (mUsersLock) {
5449                 mIsUserManaged.put(userId, isManaged);
5450             }
5451         }
5452 
5453         @Override
isUserManaged(@serIdInt int userId)5454         public boolean isUserManaged(@UserIdInt int userId) {
5455             synchronized (mUsersLock) {
5456                 return mIsUserManaged.get(userId);
5457             }
5458         }
5459 
5460         @Override
setUserIcon(@serIdInt int userId, Bitmap bitmap)5461         public void setUserIcon(@UserIdInt int userId, Bitmap bitmap) {
5462             final long ident = Binder.clearCallingIdentity();
5463             try {
5464                 synchronized (mPackagesLock) {
5465                     UserData userData = getUserDataNoChecks(userId);
5466                     if (userData == null || userData.info.partial) {
5467                         Slog.w(LOG_TAG, "setUserIcon: unknown user #" + userId);
5468                         return;
5469                     }
5470                     writeBitmapLP(userData.info, bitmap);
5471                     writeUserLP(userData);
5472                 }
5473                 sendUserInfoChangedBroadcast(userId);
5474             } finally {
5475                 Binder.restoreCallingIdentity(ident);
5476             }
5477         }
5478 
5479         @Override
setForceEphemeralUsers(boolean forceEphemeralUsers)5480         public void setForceEphemeralUsers(boolean forceEphemeralUsers) {
5481             synchronized (mUsersLock) {
5482                 mForceEphemeralUsers = forceEphemeralUsers;
5483             }
5484         }
5485 
5486         @Override
removeAllUsers()5487         public void removeAllUsers() {
5488             if (UserHandle.USER_SYSTEM == ActivityManager.getCurrentUser()) {
5489                 // Remove the non-system users straight away.
5490                 removeNonSystemUsers();
5491             } else {
5492                 // Switch to the system user first and then remove the other users.
5493                 BroadcastReceiver userSwitchedReceiver = new BroadcastReceiver() {
5494                     @Override
5495                     public void onReceive(Context context, Intent intent) {
5496                         int userId =
5497                                 intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
5498                         if (userId != UserHandle.USER_SYSTEM) {
5499                             return;
5500                         }
5501                         mContext.unregisterReceiver(this);
5502                         removeNonSystemUsers();
5503                     }
5504                 };
5505                 IntentFilter userSwitchedFilter = new IntentFilter();
5506                 userSwitchedFilter.addAction(Intent.ACTION_USER_SWITCHED);
5507                 mContext.registerReceiver(
5508                         userSwitchedReceiver, userSwitchedFilter, null, mHandler);
5509 
5510                 // Switch to the system user.
5511                 ActivityManager am =
5512                         (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
5513                 am.switchUser(UserHandle.USER_SYSTEM);
5514             }
5515         }
5516 
5517         @Override
onEphemeralUserStop(@serIdInt int userId)5518         public void onEphemeralUserStop(@UserIdInt int userId) {
5519             synchronized (mUsersLock) {
5520                UserInfo userInfo = getUserInfoLU(userId);
5521                if (userInfo != null && userInfo.isEphemeral()) {
5522                     // Do not allow switching back to the ephemeral user again as the user is going
5523                     // to be deleted.
5524                     userInfo.flags |= UserInfo.FLAG_DISABLED;
5525                     if (userInfo.isGuest()) {
5526                         // Indicate that the guest will be deleted after it stops.
5527                         userInfo.guestToRemove = true;
5528                     }
5529                }
5530             }
5531         }
5532 
5533         @Override
createUserEvenWhenDisallowed(String name, @NonNull String userType, @UserInfoFlag int flags, String[] disallowedPackages, @Nullable Object token)5534         public UserInfo createUserEvenWhenDisallowed(String name, @NonNull String userType,
5535                 @UserInfoFlag int flags, String[] disallowedPackages, @Nullable Object token)
5536                 throws UserManager.CheckedUserOperationException {
5537             return createUserInternalUnchecked(name, userType, flags,
5538                     UserHandle.USER_NULL, /* preCreated= */ false, disallowedPackages, token);
5539         }
5540 
5541         @Override
removeUserEvenWhenDisallowed(@serIdInt int userId)5542         public boolean removeUserEvenWhenDisallowed(@UserIdInt int userId) {
5543             return removeUserUnchecked(userId);
5544         }
5545 
5546         @Override
isUserRunning(@serIdInt int userId)5547         public boolean isUserRunning(@UserIdInt int userId) {
5548             synchronized (mUserStates) {
5549                 return mUserStates.get(userId, -1) >= 0;
5550             }
5551         }
5552 
5553         @Override
setUserState(@serIdInt int userId, int userState)5554         public void setUserState(@UserIdInt int userId, int userState) {
5555             synchronized (mUserStates) {
5556                 mUserStates.put(userId, userState);
5557             }
5558         }
5559 
5560         @Override
removeUserState(@serIdInt int userId)5561         public void removeUserState(@UserIdInt int userId) {
5562             synchronized (mUserStates) {
5563                 mUserStates.delete(userId);
5564             }
5565         }
5566 
5567         @Override
getUserIds()5568         public int[] getUserIds() {
5569             return UserManagerService.this.getUserIds();
5570         }
5571 
5572         @Override
getUsers(boolean excludeDying)5573         public @NonNull List<UserInfo> getUsers(boolean excludeDying) {
5574             return getUsers(/*excludePartial= */ true, excludeDying, /* excludePreCreated= */ true);
5575         }
5576 
5577         @Override
getUsers(boolean excludePartial, boolean excludeDying, boolean excludePreCreated)5578         public @NonNull List<UserInfo> getUsers(boolean excludePartial, boolean excludeDying,
5579                 boolean excludePreCreated) {
5580             return UserManagerService.this.getUsersInternal(excludePartial, excludeDying,
5581                     excludePreCreated);
5582         }
5583 
5584         @Override
isUserUnlockingOrUnlocked(@serIdInt int userId)5585         public boolean isUserUnlockingOrUnlocked(@UserIdInt int userId) {
5586             int state;
5587             synchronized (mUserStates) {
5588                 state = mUserStates.get(userId, -1);
5589             }
5590             // Special case, in the stopping/shutdown state user key can still be unlocked
5591             if (state == UserState.STATE_STOPPING || state == UserState.STATE_SHUTDOWN) {
5592                 return StorageManager.isUserKeyUnlocked(userId);
5593             }
5594             return (state == UserState.STATE_RUNNING_UNLOCKING)
5595                     || (state == UserState.STATE_RUNNING_UNLOCKED);
5596         }
5597 
5598         /**
5599          * The return values of this method are cached in clients.  If the
5600          * logic in this function changes then the cache invalidation code
5601          * may need to be revisited.
5602          */
5603         @Override
isUserUnlocked(@serIdInt int userId)5604         public boolean isUserUnlocked(@UserIdInt int userId) {
5605             int state;
5606             synchronized (mUserStates) {
5607                 state = mUserStates.get(userId, -1);
5608             }
5609             // Special case, in the stopping/shutdown state user key can still be unlocked
5610             if (state == UserState.STATE_STOPPING || state == UserState.STATE_SHUTDOWN) {
5611                 return StorageManager.isUserKeyUnlocked(userId);
5612             }
5613             return state == UserState.STATE_RUNNING_UNLOCKED;
5614         }
5615 
5616         @Override
isUserInitialized(@serIdInt int userId)5617         public boolean isUserInitialized(@UserIdInt int userId) {
5618             return (getUserInfo(userId).flags & UserInfo.FLAG_INITIALIZED) != 0;
5619         }
5620 
5621         @Override
exists(@serIdInt int userId)5622         public boolean exists(@UserIdInt int userId) {
5623             return getUserInfoNoChecks(userId) != null;
5624         }
5625 
5626         @Override
isProfileAccessible(int callingUserId, int targetUserId, String debugMsg, boolean throwSecurityException)5627         public boolean isProfileAccessible(int callingUserId, int targetUserId, String debugMsg,
5628                 boolean throwSecurityException) {
5629             if (targetUserId == callingUserId) {
5630                 return true;
5631             }
5632             synchronized (mUsersLock) {
5633                 UserInfo callingUserInfo = getUserInfoLU(callingUserId);
5634                 if (callingUserInfo == null || callingUserInfo.isProfile()) {
5635                     if (throwSecurityException) {
5636                         throw new SecurityException(
5637                                 debugMsg + " for another profile "
5638                                         + targetUserId + " from " + callingUserId);
5639                     }
5640                     Slog.w(LOG_TAG, debugMsg + " for another profile "
5641                             + targetUserId + " from " + callingUserId);
5642                     return false;
5643                 }
5644 
5645                 UserInfo targetUserInfo = getUserInfoLU(targetUserId);
5646                 if (targetUserInfo == null || !targetUserInfo.isEnabled()) {
5647                     // Do not throw any exception here as this could happen due to race conditions
5648                     // between the system updating its state and the client getting notified.
5649                     if (throwSecurityException) {
5650                         Slog.w(LOG_TAG, debugMsg + " for disabled profile "
5651                                 + targetUserId + " from " + callingUserId);
5652                     }
5653                     return false;
5654                 }
5655 
5656                 if (targetUserInfo.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID ||
5657                         targetUserInfo.profileGroupId != callingUserInfo.profileGroupId) {
5658                     if (throwSecurityException) {
5659                         throw new SecurityException(
5660                                 debugMsg + " for unrelated profile " + targetUserId);
5661                     }
5662                     return false;
5663                 }
5664             }
5665             return true;
5666         }
5667 
5668         @Override
getProfileParentId(@serIdInt int userId)5669         public int getProfileParentId(@UserIdInt int userId) {
5670             synchronized (mUsersLock) {
5671                 UserInfo profileParent = getProfileParentLU(userId);
5672                 if (profileParent == null) {
5673                     return userId;
5674                 }
5675                 return profileParent.id;
5676             }
5677         }
5678 
5679         @Override
isSettingRestrictedForUser(String setting, @UserIdInt int userId, String value, int callingUid)5680         public boolean isSettingRestrictedForUser(String setting, @UserIdInt int userId,
5681                 String value, int callingUid) {
5682             return UserManagerService.this.isSettingRestrictedForUser(setting, userId,
5683                     value, callingUid);
5684         }
5685 
5686         @Override
hasUserRestriction(String restrictionKey, @UserIdInt int userId)5687         public boolean hasUserRestriction(String restrictionKey, @UserIdInt int userId) {
5688             if (!UserRestrictionsUtils.isValidRestriction(restrictionKey)) {
5689                 return false;
5690             }
5691             Bundle restrictions = getEffectiveUserRestrictions(userId);
5692             return restrictions != null && restrictions.getBoolean(restrictionKey);
5693         }
5694 
5695         @Override
getUserInfo(@serIdInt int userId)5696         public @Nullable UserInfo getUserInfo(@UserIdInt int userId) {
5697             UserData userData;
5698             synchronized (mUsersLock) {
5699                 userData = mUsers.get(userId);
5700             }
5701             return userData == null ? null : userData.info;
5702         }
5703 
5704         @Override
getUserInfos()5705         public @NonNull UserInfo[] getUserInfos() {
5706             synchronized (mUsersLock) {
5707                 int userSize = mUsers.size();
5708                 UserInfo[] allInfos = new UserInfo[userSize];
5709                 for (int i = 0; i < userSize; i++) {
5710                     allInfos[i] = mUsers.valueAt(i).info;
5711                 }
5712                 return allInfos;
5713             }
5714         }
5715 
5716         @Override
setDefaultCrossProfileIntentFilters( @serIdInt int parentUserId, @UserIdInt int profileUserId)5717         public void setDefaultCrossProfileIntentFilters(
5718                 @UserIdInt int parentUserId, @UserIdInt int profileUserId) {
5719             final UserTypeDetails userTypeDetails = getUserTypeDetailsNoChecks(profileUserId);
5720             final Bundle restrictions = getEffectiveUserRestrictions(profileUserId);
5721             UserManagerService.this.setDefaultCrossProfileIntentFilters(
5722                     profileUserId, userTypeDetails, restrictions, parentUserId);
5723         }
5724     }
5725 
5726     /**
5727      * Check if user has restrictions
5728      * @param restriction restrictions to check
5729      * @param userId id of the user
5730      *
5731      * @throws {@link android.os.UserManager.CheckedUserOperationException} if user has any of the
5732      *      specified restrictions
5733      */
enforceUserRestriction(String restriction, @UserIdInt int userId, String message)5734     private void enforceUserRestriction(String restriction, @UserIdInt int userId, String message)
5735             throws UserManager.CheckedUserOperationException {
5736         if (hasUserRestriction(restriction, userId)) {
5737             String errorMessage = (message != null ? (message + ": ") : "")
5738                     + restriction + " is enabled.";
5739             Slog.w(LOG_TAG, errorMessage);
5740             throw new UserManager.CheckedUserOperationException(errorMessage,
5741                     UserManager.USER_OPERATION_ERROR_UNKNOWN);
5742         }
5743     }
5744 
5745     /**
5746      * Throws CheckedUserOperationException and shows error log
5747      * @param message message for exception and logging
5748      * @param userOperationResult result/error code
5749      * @throws UserManager.CheckedUserOperationException
5750      */
throwCheckedUserOperationException(@onNull String message, @UserManager.UserOperationResult int userOperationResult)5751     private void throwCheckedUserOperationException(@NonNull String message,
5752             @UserManager.UserOperationResult int userOperationResult)
5753             throws UserManager.CheckedUserOperationException {
5754         Slog.e(LOG_TAG, message);
5755         throw new UserManager.CheckedUserOperationException(message, userOperationResult);
5756     }
5757 
5758     /* Remove all the users except of the system one. */
removeNonSystemUsers()5759     private void removeNonSystemUsers() {
5760         ArrayList<UserInfo> usersToRemove = new ArrayList<>();
5761         synchronized (mUsersLock) {
5762             final int userSize = mUsers.size();
5763             for (int i = 0; i < userSize; i++) {
5764                 UserInfo ui = mUsers.valueAt(i).info;
5765                 if (ui.id != UserHandle.USER_SYSTEM) {
5766                     usersToRemove.add(ui);
5767                 }
5768             }
5769         }
5770         for (UserInfo ui: usersToRemove) {
5771             removeUser(ui.id);
5772         }
5773     }
5774 
5775     private class Shell extends ShellCommand {
5776         @Override
onCommand(String cmd)5777         public int onCommand(String cmd) {
5778             return onShellCommand(this, cmd);
5779         }
5780 
5781         @Override
onHelp()5782         public void onHelp() {
5783             final PrintWriter pw = getOutPrintWriter();
5784             pw.println("User manager (user) commands:");
5785             pw.println("  help");
5786             pw.println("    Prints this help text.");
5787             pw.println("");
5788             pw.println("  list [-v] [-all]");
5789             pw.println("    Prints all users on the system.");
5790             pw.println("  report-system-user-package-whitelist-problems [-v | --verbose] "
5791                     + "[--critical-only] [--mode MODE]");
5792             pw.println("    Reports all issues on user-type package whitelist XML files. Options:");
5793             pw.println("    -v | --verbose : shows extra info, like number of issues");
5794             pw.println("    --critical-only: show only critical issues, excluding warnings");
5795             pw.println("    --mode MODE: shows what errors would be if device used mode MODE (where"
5796                     + " MODE is the whitelist mode integer as defined by "
5797                     + "config_userTypePackageWhitelistMode)");
5798         }
5799     }
5800 
debug(String message)5801     private static void debug(String message) {
5802         Slog.d(LOG_TAG, message
5803                 + (DBG_WITH_STACKTRACE ? " called at\n" + Debug.getCallers(10, "  ") : ""));
5804     }
5805 
5806     /** @see #getMaxUsersOfTypePerParent(UserTypeDetails) */
5807     @VisibleForTesting
getMaxUsersOfTypePerParent(String userType)5808     int getMaxUsersOfTypePerParent(String userType) {
5809         final UserTypeDetails type = mUserTypes.get(userType);
5810         if (type == null) {
5811             return 0;
5812         }
5813         return getMaxUsersOfTypePerParent(type);
5814     }
5815 
5816     /**
5817      * Returns the maximum number of users allowed for the given userTypeDetails per parent user.
5818      * This is applicable for user types that are {@link UserTypeDetails#isProfile()}.
5819      * If there is no maximum, {@link UserTypeDetails#UNLIMITED_NUMBER_OF_USERS} is returned.
5820      * Under certain circumstances (such as after a change-user-type) the max value can actually
5821      * be exceeded: this is allowed in order to keep the device in a usable state.
5822      * An error is logged in {@link UserManagerService#upgradeProfileToTypeLU}
5823      */
getMaxUsersOfTypePerParent(UserTypeDetails userTypeDetails)5824     private static int getMaxUsersOfTypePerParent(UserTypeDetails userTypeDetails) {
5825         final int defaultMax = userTypeDetails.getMaxAllowedPerParent();
5826         if (!Build.IS_DEBUGGABLE) {
5827             return defaultMax;
5828         } else {
5829             if (userTypeDetails.isManagedProfile()) {
5830                 return SystemProperties.getInt("persist.sys.max_profiles", defaultMax);
5831             }
5832         }
5833         return defaultMax;
5834     }
5835 
5836     @GuardedBy("mUsersLock")
5837     @VisibleForTesting
getFreeProfileBadgeLU(int parentUserId, String userType)5838     int getFreeProfileBadgeLU(int parentUserId, String userType) {
5839         Set<Integer> usedBadges = new ArraySet<>();
5840         final int userSize = mUsers.size();
5841         for (int i = 0; i < userSize; i++) {
5842             UserInfo ui = mUsers.valueAt(i).info;
5843             // Check which badge indexes are already used by this profile group.
5844             if (ui.userType.equals(userType)
5845                     && ui.profileGroupId == parentUserId
5846                     && !mRemovingUserIds.get(ui.id)) {
5847                 usedBadges.add(ui.profileBadge);
5848             }
5849         }
5850         int maxUsersOfType = getMaxUsersOfTypePerParent(userType);
5851         if (maxUsersOfType == UserTypeDetails.UNLIMITED_NUMBER_OF_USERS) {
5852             maxUsersOfType = Integer.MAX_VALUE;
5853         }
5854         for (int i = 0; i < maxUsersOfType; i++) {
5855             if (!usedBadges.contains(i)) {
5856                 return i;
5857             }
5858         }
5859         return 0;
5860     }
5861 
5862     /**
5863      * Checks if the given user has a managed profile associated with it.
5864      * @param userId The parent user
5865      * @return
5866      */
hasManagedProfile(@serIdInt int userId)5867     boolean hasManagedProfile(@UserIdInt int userId) {
5868         synchronized (mUsersLock) {
5869             UserInfo userInfo = getUserInfoLU(userId);
5870             final int userSize = mUsers.size();
5871             for (int i = 0; i < userSize; i++) {
5872                 UserInfo profile = mUsers.valueAt(i).info;
5873                 if (userId != profile.id && isProfileOf(userInfo, profile)) {
5874                     return true;
5875                 }
5876             }
5877             return false;
5878         }
5879     }
5880 
5881     /**
5882      * Checks if the calling package name matches with the calling UID, throw
5883      * {@link SecurityException} if not.
5884      */
verifyCallingPackage(String callingPackage, int callingUid)5885     private void verifyCallingPackage(String callingPackage, int callingUid) {
5886         int packageUid = mPm.getPackageUid(callingPackage, 0,  UserHandle.getUserId(callingUid));
5887         if (packageUid != callingUid) {
5888             throw new SecurityException("Specified package " + callingPackage
5889                     + " does not match the calling uid " + callingUid);
5890         }
5891     }
5892 
5893     /** Retrieves the internal package manager interface. */
getPackageManagerInternal()5894     private PackageManagerInternal getPackageManagerInternal() {
5895         // Don't need to synchonize; worst-case scenario LocalServices will be called twice.
5896         if (mPmInternal == null) {
5897             mPmInternal = LocalServices.getService(PackageManagerInternal.class);
5898         }
5899         return mPmInternal;
5900     }
5901 
5902     /** Returns the internal device policy manager interface. */
getDevicePolicyManagerInternal()5903     private DevicePolicyManagerInternal getDevicePolicyManagerInternal() {
5904         if (mDevicePolicyManagerInternal == null) {
5905             mDevicePolicyManagerInternal =
5906                     LocalServices.getService(DevicePolicyManagerInternal.class);
5907         }
5908         return mDevicePolicyManagerInternal;
5909     }
5910 }
5911