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