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