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