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