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