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