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