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