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