UserManagerService.java revision 965da39942f9a8736f785f7c57a6c351a8c89d6b
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 android.annotation.NonNull;
20import android.annotation.Nullable;
21import android.app.Activity;
22import android.app.ActivityManager;
23import android.app.ActivityManagerInternal;
24import android.app.ActivityManagerNative;
25import android.app.IActivityManager;
26import android.app.IStopUserCallback;
27import android.app.admin.DevicePolicyManager;
28import android.app.admin.DevicePolicyManagerInternal;
29import android.content.BroadcastReceiver;
30import android.content.Context;
31import android.content.Intent;
32import android.content.pm.ApplicationInfo;
33import android.content.pm.PackageManager;
34import android.content.pm.PackageManager.NameNotFoundException;
35import android.content.pm.UserInfo;
36import android.graphics.Bitmap;
37import android.os.Binder;
38import android.os.Bundle;
39import android.os.Environment;
40import android.os.FileUtils;
41import android.os.Handler;
42import android.os.IUserManager;
43import android.os.Message;
44import android.os.ParcelFileDescriptor;
45import android.os.Parcelable;
46import android.os.Process;
47import android.os.RemoteException;
48import android.os.ResultReceiver;
49import android.os.ServiceManager;
50import android.os.ShellCommand;
51import android.os.SystemProperties;
52import android.os.UserHandle;
53import android.os.UserManager;
54import android.os.UserManagerInternal;
55import android.os.storage.StorageManager;
56import android.os.storage.VolumeInfo;
57import android.system.ErrnoException;
58import android.system.Os;
59import android.system.OsConstants;
60import android.util.AtomicFile;
61import android.util.Log;
62import android.util.Slog;
63import android.util.SparseArray;
64import android.util.SparseBooleanArray;
65import android.util.TimeUtils;
66import android.util.Xml;
67
68import com.android.internal.annotations.GuardedBy;
69import com.android.internal.annotations.VisibleForTesting;
70import com.android.internal.app.IAppOpsService;
71import com.android.internal.util.FastXmlSerializer;
72import com.android.internal.util.Preconditions;
73import com.android.internal.util.XmlUtils;
74import com.android.server.LocalServices;
75
76import org.xmlpull.v1.XmlPullParser;
77import org.xmlpull.v1.XmlPullParserException;
78import org.xmlpull.v1.XmlSerializer;
79
80import java.io.BufferedOutputStream;
81import java.io.File;
82import java.io.FileDescriptor;
83import java.io.FileInputStream;
84import java.io.FileNotFoundException;
85import java.io.FileOutputStream;
86import java.io.IOException;
87import java.io.PrintWriter;
88import java.nio.charset.StandardCharsets;
89import java.util.ArrayList;
90import java.util.List;
91
92import libcore.io.IoUtils;
93
94/**
95 * Service for {@link UserManager}.
96 *
97 * Method naming convention:
98 * <ul>
99 * <li> Methods suffixed with "LILP" should be called within {@link #mInstallLock} and
100 * {@link #mPackagesLock} locks obtained in the respective order.
101 * <li> Methods suffixed with "LR" should be called within the {@link #mRestrictionsLock} lock.
102 * <li> Methods suffixed with "LU" should be called within the {@link #mUsersLock} lock.
103 * </ul>
104 */
105public class UserManagerService extends IUserManager.Stub {
106    private static final String LOG_TAG = "UserManagerService";
107    private static final boolean DBG = false; // DO NOT SUBMIT WITH TRUE
108
109    private static final String TAG_NAME = "name";
110    private static final String ATTR_FLAGS = "flags";
111    private static final String ATTR_ICON_PATH = "icon";
112    private static final String ATTR_ID = "id";
113    private static final String ATTR_CREATION_TIME = "created";
114    private static final String ATTR_LAST_LOGGED_IN_TIME = "lastLoggedIn";
115    private static final String ATTR_SERIAL_NO = "serialNumber";
116    private static final String ATTR_NEXT_SERIAL_NO = "nextSerialNumber";
117    private static final String ATTR_PARTIAL = "partial";
118    private static final String ATTR_GUEST_TO_REMOVE = "guestToRemove";
119    private static final String ATTR_USER_VERSION = "version";
120    private static final String ATTR_PROFILE_GROUP_ID = "profileGroupId";
121    private static final String ATTR_RESTRICTED_PROFILE_PARENT_ID = "restrictedProfileParentId";
122    private static final String TAG_GUEST_RESTRICTIONS = "guestRestrictions";
123    private static final String TAG_USERS = "users";
124    private static final String TAG_USER = "user";
125    private static final String TAG_RESTRICTIONS = "restrictions";
126    private static final String TAG_ENTRY = "entry";
127    private static final String TAG_VALUE = "value";
128    private static final String ATTR_KEY = "key";
129    private static final String ATTR_VALUE_TYPE = "type";
130    private static final String ATTR_MULTIPLE = "m";
131
132    private static final String ATTR_TYPE_STRING_ARRAY = "sa";
133    private static final String ATTR_TYPE_STRING = "s";
134    private static final String ATTR_TYPE_BOOLEAN = "b";
135    private static final String ATTR_TYPE_INTEGER = "i";
136    private static final String ATTR_TYPE_BUNDLE = "B";
137    private static final String ATTR_TYPE_BUNDLE_ARRAY = "BA";
138
139    private static final String USER_INFO_DIR = "system" + File.separator + "users";
140    private static final String USER_LIST_FILENAME = "userlist.xml";
141    private static final String USER_PHOTO_FILENAME = "photo.png";
142    private static final String USER_PHOTO_FILENAME_TMP = USER_PHOTO_FILENAME + ".tmp";
143
144    private static final String RESTRICTIONS_FILE_PREFIX = "res_";
145    private static final String XML_SUFFIX = ".xml";
146
147    private static final int MIN_USER_ID = 10;
148    // We need to keep process uid within Integer.MAX_VALUE.
149    private static final int MAX_USER_ID = Integer.MAX_VALUE / UserHandle.PER_USER_RANGE;
150
151    private static final int USER_VERSION = 6;
152
153    private static final long EPOCH_PLUS_30_YEARS = 30L * 365 * 24 * 60 * 60 * 1000L; // ms
154
155    // Maximum number of managed profiles permitted per user is 1. This cannot be increased
156    // without first making sure that the rest of the framework is prepared for it.
157    private static final int MAX_MANAGED_PROFILES = 1;
158
159    static final int WRITE_USER_MSG = 1;
160    static final int WRITE_USER_DELAY = 2*1000;  // 2 seconds
161
162    private static final String XATTR_SERIAL = "user.serial";
163
164    private final Context mContext;
165    private final PackageManagerService mPm;
166    private final Object mInstallLock;
167    private final Object mPackagesLock;
168    // Short-term lock for internal state, when interaction/sync with PM is not required
169    private final Object mUsersLock = new Object();
170    private final Object mRestrictionsLock = new Object();
171
172    private final Handler mHandler;
173
174    private final File mUsersDir;
175    private final File mUserListFile;
176
177    @GuardedBy("mUsersLock")
178    private final SparseArray<UserInfo> mUsers = new SparseArray<>();
179
180    /**
181     * User restrictions set via UserManager.  This doesn't include restrictions set by
182     * device owner / profile owners.
183     *
184     * DO NOT Change existing {@link Bundle} in it.  When changing a restriction for a user,
185     * a new {@link Bundle} should always be created and set.  This is because a {@link Bundle}
186     * maybe shared between {@link #mBaseUserRestrictions} and
187     * {@link #mCachedEffectiveUserRestrictions}, but they should always updated separately.
188     * (Otherwise we won't be able to detect what restrictions have changed in
189     * {@link #updateUserRestrictionsInternalLR}.
190     */
191    @GuardedBy("mRestrictionsLock")
192    private final SparseArray<Bundle> mBaseUserRestrictions = new SparseArray<>();
193
194    /**
195     * Cached user restrictions that are in effect -- i.e. {@link #mBaseUserRestrictions} combined
196     * with device / profile owner restrictions.  We'll initialize it lazily; use
197     * {@link #getEffectiveUserRestrictions} to access it.
198     *
199     * DO NOT Change existing {@link Bundle} in it.  When changing a restriction for a user,
200     * a new {@link Bundle} should always be created and set.  This is because a {@link Bundle}
201     * maybe shared between {@link #mBaseUserRestrictions} and
202     * {@link #mCachedEffectiveUserRestrictions}, but they should always updated separately.
203     * (Otherwise we won't be able to detect what restrictions have changed in
204     * {@link #updateUserRestrictionsInternalLR}.
205     */
206    @GuardedBy("mRestrictionsLock")
207    private final SparseArray<Bundle> mCachedEffectiveUserRestrictions = new SparseArray<>();
208
209    /**
210     * User restrictions that have already been applied in {@link #applyUserRestrictionsLR}.  We
211     * use it to detect restrictions that have changed since the last
212     * {@link #applyUserRestrictionsLR} call.
213     */
214    @GuardedBy("mRestrictionsLock")
215    private final SparseArray<Bundle> mAppliedUserRestrictions = new SparseArray<>();
216
217    private final Bundle mGuestRestrictions = new Bundle();
218
219    /**
220     * Set of user IDs being actively removed. Removed IDs linger in this set
221     * for several seconds to work around a VFS caching issue.
222     */
223    @GuardedBy("mUsersLock")
224    private final SparseBooleanArray mRemovingUserIds = new SparseBooleanArray();
225
226    @GuardedBy("mUsersLock")
227    private int[] mUserIds;
228    private int mNextSerialNumber;
229    private int mUserVersion = 0;
230
231    private IAppOpsService mAppOpsService;
232
233    private final LocalService mLocalService;
234
235    private static UserManagerService sInstance;
236
237    public static UserManagerService getInstance() {
238        synchronized (UserManagerService.class) {
239            return sInstance;
240        }
241    }
242
243    /**
244     * Available for testing purposes.
245     */
246    UserManagerService(File dataDir, File baseUserPath) {
247        this(null, null, new Object(), new Object(), dataDir, baseUserPath);
248    }
249
250    /**
251     * Called by package manager to create the service.  This is closely
252     * associated with the package manager, and the given lock is the
253     * package manager's own lock.
254     */
255    UserManagerService(Context context, PackageManagerService pm,
256            Object installLock, Object packagesLock) {
257        this(context, pm, installLock, packagesLock,
258                Environment.getDataDirectory(),
259                new File(Environment.getDataDirectory(), "user"));
260    }
261
262    /**
263     * Available for testing purposes.
264     */
265    private UserManagerService(Context context, PackageManagerService pm,
266            Object installLock, Object packagesLock,
267            File dataDir, File baseUserPath) {
268        mContext = context;
269        mPm = pm;
270        mInstallLock = installLock;
271        mPackagesLock = packagesLock;
272        mHandler = new MainHandler();
273        synchronized (mInstallLock) {
274            synchronized (mPackagesLock) {
275                mUsersDir = new File(dataDir, USER_INFO_DIR);
276                mUsersDir.mkdirs();
277                // Make zeroth user directory, for services to migrate their files to that location
278                File userZeroDir = new File(mUsersDir, String.valueOf(UserHandle.USER_SYSTEM));
279                userZeroDir.mkdirs();
280                FileUtils.setPermissions(mUsersDir.toString(),
281                        FileUtils.S_IRWXU|FileUtils.S_IRWXG
282                        |FileUtils.S_IROTH|FileUtils.S_IXOTH,
283                        -1, -1);
284                mUserListFile = new File(mUsersDir, USER_LIST_FILENAME);
285                initDefaultGuestRestrictions();
286                readUserListLILP();
287                sInstance = this;
288            }
289        }
290        mLocalService = new LocalService();
291        LocalServices.addService(UserManagerInternal.class, mLocalService);
292    }
293
294    void systemReady() {
295        synchronized (mInstallLock) {
296            synchronized (mPackagesLock) {
297                synchronized (mUsersLock) {
298                    // Prune out any partially created/partially removed users.
299                    ArrayList<UserInfo> partials = new ArrayList<UserInfo>();
300                    final int userSize = mUsers.size();
301                    for (int i = 0; i < userSize; i++) {
302                        UserInfo ui = mUsers.valueAt(i);
303                        if ((ui.partial || ui.guestToRemove) && i != 0) {
304                            partials.add(ui);
305                        }
306                    }
307                    final int partialsSize = partials.size();
308                    for (int i = 0; i < partialsSize; i++) {
309                        UserInfo ui = partials.get(i);
310                        Slog.w(LOG_TAG, "Removing partially created user " + ui.id
311                                + " (name=" + ui.name + ")");
312                        removeUserStateLILP(ui.id);
313                    }
314                }
315            }
316        }
317        onUserForeground(UserHandle.USER_SYSTEM);
318        mAppOpsService = IAppOpsService.Stub.asInterface(
319                ServiceManager.getService(Context.APP_OPS_SERVICE));
320        for (int i = 0; i < mUserIds.length; ++i) {
321            final int userId = mUserIds[i];
322            try {
323                mAppOpsService.setUserRestrictions(getEffectiveUserRestrictions(userId), userId);
324            } catch (RemoteException e) {
325                Log.w(LOG_TAG, "Unable to notify AppOpsService of UserRestrictions");
326            }
327        }
328    }
329
330    @Override
331    public UserInfo getPrimaryUser() {
332        checkManageUsersPermission("query users");
333        synchronized (mUsersLock) {
334            final int userSize = mUsers.size();
335            for (int i = 0; i < userSize; i++) {
336                UserInfo ui = mUsers.valueAt(i);
337                if (ui.isPrimary()) {
338                    return ui;
339                }
340            }
341        }
342        return null;
343    }
344
345    @Override
346    public @NonNull List<UserInfo> getUsers(boolean excludeDying) {
347        checkManageUsersPermission("query users");
348        synchronized (mUsersLock) {
349            ArrayList<UserInfo> users = new ArrayList<UserInfo>(mUsers.size());
350            final int userSize = mUsers.size();
351            for (int i = 0; i < userSize; i++) {
352                UserInfo ui = mUsers.valueAt(i);
353                if (ui.partial) {
354                    continue;
355                }
356                if (!excludeDying || !mRemovingUserIds.get(ui.id)) {
357                    users.add(ui);
358                }
359            }
360            return users;
361        }
362    }
363
364    @Override
365    public List<UserInfo> getProfiles(int userId, boolean enabledOnly) {
366        if (userId != UserHandle.getCallingUserId()) {
367            checkManageUsersPermission("getting profiles related to user " + userId);
368        }
369        final long ident = Binder.clearCallingIdentity();
370        try {
371            synchronized (mUsersLock) {
372                return getProfilesLU(userId, enabledOnly);
373            }
374        } finally {
375            Binder.restoreCallingIdentity(ident);
376        }
377    }
378
379    /** Assume permissions already checked and caller's identity cleared */
380    private List<UserInfo> getProfilesLU(int userId, boolean enabledOnly) {
381        UserInfo user = getUserInfoLU(userId);
382        ArrayList<UserInfo> users = new ArrayList<UserInfo>(mUsers.size());
383        if (user == null) {
384            // Probably a dying user
385            return users;
386        }
387        final int userSize = mUsers.size();
388        for (int i = 0; i < userSize; i++) {
389            UserInfo profile = mUsers.valueAt(i);
390            if (!isProfileOf(user, profile)) {
391                continue;
392            }
393            if (enabledOnly && !profile.isEnabled()) {
394                continue;
395            }
396            if (mRemovingUserIds.get(profile.id)) {
397                continue;
398            }
399            users.add(profile);
400        }
401        return users;
402    }
403
404    @Override
405    public int getCredentialOwnerProfile(int userHandle) {
406        checkManageUsersPermission("get the credential owner");
407        if (!mContext.getSystemService(StorageManager.class).isPerUserEncryptionEnabled()) {
408            synchronized (mUsersLock) {
409                UserInfo profileParent = getProfileParentLU(userHandle);
410                if (profileParent != null) {
411                    return profileParent.id;
412                }
413            }
414        }
415
416        return userHandle;
417    }
418
419    @Override
420    public boolean isSameProfileGroup(int userId, int otherUserId) {
421        if (userId == otherUserId) return true;
422        checkManageUsersPermission("check if in the same profile group");
423        synchronized (mPackagesLock) {
424            return isSameProfileGroupLP(userId, otherUserId);
425        }
426    }
427
428    private boolean isSameProfileGroupLP(int userId, int otherUserId) {
429        synchronized (mUsersLock) {
430            UserInfo userInfo = getUserInfoLU(userId);
431            if (userInfo == null || userInfo.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID) {
432                return false;
433            }
434            UserInfo otherUserInfo = getUserInfoLU(otherUserId);
435            if (otherUserInfo == null
436                    || otherUserInfo.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID) {
437                return false;
438            }
439            return userInfo.profileGroupId == otherUserInfo.profileGroupId;
440        }
441    }
442
443    @Override
444    public UserInfo getProfileParent(int userHandle) {
445        checkManageUsersPermission("get the profile parent");
446        synchronized (mUsersLock) {
447            return getProfileParentLU(userHandle);
448        }
449    }
450
451    private UserInfo getProfileParentLU(int userHandle) {
452        UserInfo profile = getUserInfoLU(userHandle);
453        if (profile == null) {
454            return null;
455        }
456        int parentUserId = profile.profileGroupId;
457        if (parentUserId == UserInfo.NO_PROFILE_GROUP_ID) {
458            return null;
459        } else {
460            return getUserInfoLU(parentUserId);
461        }
462    }
463
464    private static boolean isProfileOf(UserInfo user, UserInfo profile) {
465        return user.id == profile.id ||
466                (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID
467                && user.profileGroupId == profile.profileGroupId);
468    }
469
470    @Override
471    public void setUserEnabled(int userId) {
472        checkManageUsersPermission("enable user");
473        synchronized (mPackagesLock) {
474            UserInfo info;
475            synchronized (mUsersLock) {
476                info = getUserInfoLU(userId);
477            }
478            if (info != null && !info.isEnabled()) {
479                info.flags ^= UserInfo.FLAG_DISABLED;
480                writeUserLP(info);
481            }
482        }
483    }
484
485    @Override
486    public UserInfo getUserInfo(int userId) {
487        checkManageUsersPermission("query user");
488        synchronized (mUsersLock) {
489            return getUserInfoLU(userId);
490        }
491    }
492
493    @Override
494    public boolean isRestricted() {
495        synchronized (mUsersLock) {
496            return getUserInfoLU(UserHandle.getCallingUserId()).isRestricted();
497        }
498    }
499
500    @Override
501    public boolean canHaveRestrictedProfile(int userId) {
502        checkManageUsersPermission("canHaveRestrictedProfile");
503        synchronized (mUsersLock) {
504            final UserInfo userInfo = getUserInfoLU(userId);
505            if (userInfo == null || !userInfo.canHaveProfile()) {
506                return false;
507            }
508            if (!userInfo.isAdmin()) {
509                return false;
510            }
511        }
512        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
513                Context.DEVICE_POLICY_SERVICE);
514        // restricted profile can be created if there is no DO set and the admin user has no PO
515        return dpm.getDeviceOwner() == null && dpm.getProfileOwnerAsUser(userId) == null;
516    }
517
518    /*
519     * Should be locked on mUsers before calling this.
520     */
521    private UserInfo getUserInfoLU(int userId) {
522        UserInfo ui = mUsers.get(userId);
523        // If it is partial and not in the process of being removed, return as unknown user.
524        if (ui != null && ui.partial && !mRemovingUserIds.get(userId)) {
525            Slog.w(LOG_TAG, "getUserInfo: unknown user #" + userId);
526            return null;
527        }
528        return ui;
529    }
530
531    /**
532     * Obtains {@link #mUsersLock} and return UserInfo from mUsers.
533     * <p>No permissions checking or any addition checks are made</p>
534     */
535    private UserInfo getUserInfoNoChecks(int userId) {
536        synchronized (mUsersLock) {
537            return mUsers.get(userId);
538        }
539    }
540
541    /** Called by PackageManagerService */
542    public boolean exists(int userId) {
543        return getUserInfoNoChecks(userId) != null;
544    }
545
546    @Override
547    public void setUserName(int userId, String name) {
548        checkManageUsersPermission("rename users");
549        boolean changed = false;
550        synchronized (mPackagesLock) {
551            UserInfo info = getUserInfoNoChecks(userId);
552            if (info == null || info.partial) {
553                Slog.w(LOG_TAG, "setUserName: unknown user #" + userId);
554                return;
555            }
556            if (name != null && !name.equals(info.name)) {
557                info.name = name;
558                writeUserLP(info);
559                changed = true;
560            }
561        }
562        if (changed) {
563            sendUserInfoChangedBroadcast(userId);
564        }
565    }
566
567    @Override
568    public void setUserIcon(int userId, Bitmap bitmap) {
569        checkManageUsersPermission("update users");
570        long ident = Binder.clearCallingIdentity();
571        try {
572            synchronized (mPackagesLock) {
573                UserInfo info = getUserInfoNoChecks(userId);
574                if (info == null || info.partial) {
575                    Slog.w(LOG_TAG, "setUserIcon: unknown user #" + userId);
576                    return;
577                }
578                writeBitmapLP(info, bitmap);
579                writeUserLP(info);
580            }
581            sendUserInfoChangedBroadcast(userId);
582        } finally {
583            Binder.restoreCallingIdentity(ident);
584        }
585    }
586
587    private void sendUserInfoChangedBroadcast(int userId) {
588        Intent changedIntent = new Intent(Intent.ACTION_USER_INFO_CHANGED);
589        changedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
590        changedIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
591        mContext.sendBroadcastAsUser(changedIntent, UserHandle.ALL);
592    }
593
594    @Override
595    public ParcelFileDescriptor getUserIcon(int userId) {
596        String iconPath;
597        synchronized (mPackagesLock) {
598            UserInfo info = getUserInfoNoChecks(userId);
599            if (info == null || info.partial) {
600                Slog.w(LOG_TAG, "getUserIcon: unknown user #" + userId);
601                return null;
602            }
603            int callingGroupId = getUserInfoNoChecks(UserHandle.getCallingUserId()).profileGroupId;
604            if (callingGroupId == UserInfo.NO_PROFILE_GROUP_ID
605                    || callingGroupId != info.profileGroupId) {
606                checkManageUsersPermission("get the icon of a user who is not related");
607            }
608            if (info.iconPath == null) {
609                return null;
610            }
611            iconPath = info.iconPath;
612        }
613
614        try {
615            return ParcelFileDescriptor.open(
616                    new File(iconPath), ParcelFileDescriptor.MODE_READ_ONLY);
617        } catch (FileNotFoundException e) {
618            Log.e(LOG_TAG, "Couldn't find icon file", e);
619        }
620        return null;
621    }
622
623    public void makeInitialized(int userId) {
624        checkManageUsersPermission("makeInitialized");
625        synchronized (mPackagesLock) {
626            UserInfo info = getUserInfoNoChecks(userId);
627            if (info == null || info.partial) {
628                Slog.w(LOG_TAG, "makeInitialized: unknown user #" + userId);
629                // TODO Check if we should return here instead of a null check below
630            }
631            if (info != null && (info.flags&UserInfo.FLAG_INITIALIZED) == 0) {
632                info.flags |= UserInfo.FLAG_INITIALIZED;
633                scheduleWriteUserLP(info);
634            }
635        }
636    }
637
638    /**
639     * If default guest restrictions haven't been initialized yet, add the basic
640     * restrictions.
641     */
642    private void initDefaultGuestRestrictions() {
643        if (mGuestRestrictions.isEmpty()) {
644            mGuestRestrictions.putBoolean(UserManager.DISALLOW_OUTGOING_CALLS, true);
645            mGuestRestrictions.putBoolean(UserManager.DISALLOW_SMS, true);
646        }
647    }
648
649    @Override
650    public Bundle getDefaultGuestRestrictions() {
651        checkManageUsersPermission("getDefaultGuestRestrictions");
652        // TODO Switch to mGuestRestrictions for locking
653        synchronized (mPackagesLock) {
654            return new Bundle(mGuestRestrictions);
655        }
656    }
657
658    @Override
659    public void setDefaultGuestRestrictions(Bundle restrictions) {
660        checkManageUsersPermission("setDefaultGuestRestrictions");
661        synchronized (mInstallLock) {
662            synchronized (mPackagesLock) {
663                mGuestRestrictions.clear();
664                mGuestRestrictions.putAll(restrictions);
665                writeUserListLILP();
666            }
667        }
668    }
669
670    @GuardedBy("mRestrictionsLock")
671    private Bundle computeEffectiveUserRestrictionsLR(int userId) {
672        final DevicePolicyManagerInternal dpmi =
673                LocalServices.getService(DevicePolicyManagerInternal.class);
674        final Bundle systemRestrictions = mBaseUserRestrictions.get(userId);
675
676        final Bundle effective;
677        if (dpmi == null) {
678            // TODO Make sure it's because DPMS is disabled and not because we called it too early.
679            effective = systemRestrictions;
680        } else {
681            effective = dpmi.getComposedUserRestrictions(userId, systemRestrictions);
682        }
683        return effective;
684    }
685
686    @GuardedBy("mRestrictionsLock")
687    private void invalidateEffectiveUserRestrictionsLR(int userId) {
688        if (DBG) {
689            Log.d(LOG_TAG, "invalidateEffectiveUserRestrictions userId=" + userId);
690        }
691        mCachedEffectiveUserRestrictions.remove(userId);
692    }
693
694    private Bundle getEffectiveUserRestrictions(int userId) {
695        synchronized (mRestrictionsLock) {
696            Bundle restrictions = mCachedEffectiveUserRestrictions.get(userId);
697            if (restrictions == null) {
698                restrictions = computeEffectiveUserRestrictionsLR(userId);
699                mCachedEffectiveUserRestrictions.put(userId, restrictions);
700            }
701            return restrictions;
702        }
703    }
704
705    /** @return a specific user restriction that's in effect currently. */
706    @Override
707    public boolean hasUserRestriction(String restrictionKey, int userId) {
708        Bundle restrictions = getEffectiveUserRestrictions(userId);
709        return restrictions != null && restrictions.getBoolean(restrictionKey);
710    }
711
712    /**
713     * @return UserRestrictions that are in effect currently.  This always returns a new
714     * {@link Bundle}.
715     */
716    @Override
717    public Bundle getUserRestrictions(int userId) {
718        Bundle restrictions = getEffectiveUserRestrictions(userId);
719        return restrictions != null ? new Bundle(restrictions) : new Bundle();
720    }
721
722    @Override
723    public void setUserRestriction(String key, boolean value, int userId) {
724        checkManageUsersPermission("setUserRestriction");
725        if (!UserRestrictionsUtils.SYSTEM_CONTROLLED_USER_RESTRICTIONS.contains(key)) {
726            setUserRestrictionNoCheck(key, value, userId);
727        }
728    }
729
730    @Override
731    public void setSystemControlledUserRestriction(String key, boolean value, int userId) {
732        checkSystemOrRoot("setSystemControlledUserRestriction");
733        setUserRestrictionNoCheck(key, value, userId);
734    }
735
736    private void setUserRestrictionNoCheck(String key, boolean value, int userId) {
737        synchronized (mRestrictionsLock) {
738            // Note we can't modify Bundles stored in mBaseUserRestrictions directly, so create
739            // a copy.
740            final Bundle newRestrictions = new Bundle();
741            UserRestrictionsUtils.merge(newRestrictions, mBaseUserRestrictions.get(userId));
742            newRestrictions.putBoolean(key, value);
743
744            updateUserRestrictionsInternalLR(newRestrictions, userId);
745        }
746    }
747
748    /**
749     * Optionally updating user restrictions, calculate the effective user restrictions by
750     * consulting {@link com.android.server.devicepolicy.DevicePolicyManagerService} and also
751     * apply it to {@link com.android.server.AppOpsService}.
752     * TODO applyUserRestrictionsLocked() should also apply to system settings.
753     *
754     * @param newRestrictions User restrictions to set.  If null, only the effective restrictions
755     *     will be updated.  Note don't pass an existing Bundle in {@link #mBaseUserRestrictions}
756     *     or {@link #mCachedEffectiveUserRestrictions}; that'll most likely cause a sub
757     * @param userId target user ID.
758     */
759    @GuardedBy("mRestrictionsLock")
760    private void updateUserRestrictionsInternalLR(
761            @Nullable Bundle newRestrictions, int userId) {
762        if (DBG) {
763            Log.d(LOG_TAG, "updateUserRestrictionsInternalLocked userId=" + userId
764                    + " bundle=" + newRestrictions);
765        }
766        // Update system restrictions.
767        if (newRestrictions != null) {
768            // If newRestrictions == the current one, it's probably a bug.
769            Preconditions.checkState(mBaseUserRestrictions.get(userId) != newRestrictions);
770            Preconditions.checkState(mCachedEffectiveUserRestrictions.get(userId)
771                    != newRestrictions);
772            mBaseUserRestrictions.put(userId, newRestrictions);
773        }
774
775        final Bundle effective = computeEffectiveUserRestrictionsLR(userId);
776
777        mCachedEffectiveUserRestrictions.put(userId, effective);
778
779        applyUserRestrictionsLR(userId, effective);
780    }
781
782    @GuardedBy("mRestrictionsLock")
783    private void applyUserRestrictionsLR(int userId, Bundle newRestrictions) {
784        final Bundle prevRestrictions = mAppliedUserRestrictions.get(userId);
785
786        if (DBG) {
787            Log.d(LOG_TAG, "applyUserRestrictionsRL userId=" + userId
788                    + " new=" + newRestrictions + " prev=" + prevRestrictions);
789        }
790
791        final long token = Binder.clearCallingIdentity();
792        try {
793            mAppOpsService.setUserRestrictions(newRestrictions, userId);
794        } catch (RemoteException e) {
795            Log.w(LOG_TAG, "Unable to notify AppOpsService of UserRestrictions");
796        } finally {
797            Binder.restoreCallingIdentity(token);
798        }
799
800        UserRestrictionsUtils.applyUserRestrictions(
801                mContext, userId, newRestrictions, prevRestrictions);
802
803        mAppliedUserRestrictions.put(userId, new Bundle(newRestrictions));
804    }
805
806    @GuardedBy("mRestrictionsLock")
807    private void updateEffectiveUserRestrictionsLR(int userId) {
808        updateUserRestrictionsInternalLR(null, userId);
809    }
810
811    @GuardedBy("mRestrictionsLock")
812    private void updateEffectiveUserRestrictionsForAllUsersLR() {
813        // First, invalidate all cached values.
814        mCachedEffectiveUserRestrictions.clear();
815
816        // We don't want to call into ActivityManagerNative while taking a lock, so we'll call
817        // it on a handler.
818        final Runnable r = new Runnable() {
819            @Override
820            public void run() {
821                // Then get the list of running users.
822                final int[] runningUsers;
823                try {
824                    runningUsers = ActivityManagerNative.getDefault().getRunningUserIds();
825                } catch (RemoteException e) {
826                    Log.w(LOG_TAG, "Unable to access ActivityManagerNative");
827                    return;
828                }
829                // Then re-calculate the effective restrictions and apply, only for running users.
830                // It's okay if a new user has started after the getRunningUserIds() call,
831                // because we'll do the same thing (re-calculate the restrictions and apply)
832                // when we start a user.
833                // TODO: "Apply restrictions upon user start hasn't been implemented.  Implement it.
834                synchronized (mRestrictionsLock) {
835                    for (int i = 0; i < runningUsers.length; i++) {
836                        updateUserRestrictionsInternalLR(null, runningUsers[i]);
837                    }
838                }
839            }
840        };
841        mHandler.post(r);
842    }
843
844    /**
845     * Check if we've hit the limit of how many users can be created.
846     */
847    private boolean isUserLimitReached() {
848        int count;
849        synchronized (mUsersLock) {
850            count = getAliveUsersExcludingGuestsCountLU();
851        }
852        return count >= UserManager.getMaxSupportedUsers();
853    }
854
855    @Override
856    public boolean canAddMoreManagedProfiles(int userId) {
857        checkManageUsersPermission("check if more managed profiles can be added.");
858        if (ActivityManager.isLowRamDeviceStatic()) {
859            return false;
860        }
861        if (!mContext.getPackageManager().hasSystemFeature(
862                PackageManager.FEATURE_MANAGED_USERS)) {
863            return false;
864        }
865        // Limit number of managed profiles that can be created
866        int managedProfilesCount = getProfiles(userId, true).size() - 1;
867        if (managedProfilesCount >= MAX_MANAGED_PROFILES) {
868            return false;
869        }
870        synchronized(mUsersLock) {
871            UserInfo userInfo = getUserInfoLU(userId);
872            if (!userInfo.canHaveProfile()) {
873                return false;
874            }
875            int usersCount = getAliveUsersExcludingGuestsCountLU();
876            // We allow creating a managed profile in the special case where there is only one user.
877            return usersCount == 1 || usersCount < UserManager.getMaxSupportedUsers();
878        }
879    }
880
881    private int getAliveUsersExcludingGuestsCountLU() {
882        int aliveUserCount = 0;
883        final int totalUserCount = mUsers.size();
884        // Skip over users being removed
885        for (int i = 0; i < totalUserCount; i++) {
886            UserInfo user = mUsers.valueAt(i);
887            if (!mRemovingUserIds.get(user.id)
888                    && !user.isGuest() && !user.partial) {
889                aliveUserCount++;
890            }
891        }
892        return aliveUserCount;
893    }
894
895    /**
896     * Enforces that only the system UID or root's UID or apps that have the
897     * {@link android.Manifest.permission#MANAGE_USERS MANAGE_USERS}
898     * permission can make certain calls to the UserManager.
899     *
900     * @param message used as message if SecurityException is thrown
901     * @throws SecurityException if the caller is not system or root
902     */
903    private static final void checkManageUsersPermission(String message) {
904        final int uid = Binder.getCallingUid();
905        if (uid != Process.SYSTEM_UID && uid != 0
906                && ActivityManager.checkComponentPermission(
907                        android.Manifest.permission.MANAGE_USERS,
908                        uid, -1, true) != PackageManager.PERMISSION_GRANTED) {
909            throw new SecurityException("You need MANAGE_USERS permission to: " + message);
910        }
911    }
912
913    private static void checkSystemOrRoot(String message) {
914        final int uid = Binder.getCallingUid();
915        if (uid != Process.SYSTEM_UID && uid != 0) {
916            throw new SecurityException("Only system may call: " + message);
917        }
918    }
919
920    private void writeBitmapLP(UserInfo info, Bitmap bitmap) {
921        try {
922            File dir = new File(mUsersDir, Integer.toString(info.id));
923            File file = new File(dir, USER_PHOTO_FILENAME);
924            File tmp = new File(dir, USER_PHOTO_FILENAME_TMP);
925            if (!dir.exists()) {
926                dir.mkdir();
927                FileUtils.setPermissions(
928                        dir.getPath(),
929                        FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
930                        -1, -1);
931            }
932            FileOutputStream os;
933            if (bitmap.compress(Bitmap.CompressFormat.PNG, 100, os = new FileOutputStream(tmp))
934                    && tmp.renameTo(file)) {
935                info.iconPath = file.getAbsolutePath();
936            }
937            try {
938                os.close();
939            } catch (IOException ioe) {
940                // What the ... !
941            }
942            tmp.delete();
943        } catch (FileNotFoundException e) {
944            Slog.w(LOG_TAG, "Error setting photo for user ", e);
945        }
946    }
947
948    /**
949     * Returns an array of user ids. This array is cached here for quick access, so do not modify or
950     * cache it elsewhere.
951     * @return the array of user ids.
952     */
953    public int[] getUserIds() {
954        synchronized (mUsersLock) {
955            return mUserIds;
956        }
957    }
958
959    private void readUserListLILP() {
960        if (!mUserListFile.exists()) {
961            fallbackToSingleUserLILP();
962            return;
963        }
964        FileInputStream fis = null;
965        AtomicFile userListFile = new AtomicFile(mUserListFile);
966        try {
967            fis = userListFile.openRead();
968            XmlPullParser parser = Xml.newPullParser();
969            parser.setInput(fis, StandardCharsets.UTF_8.name());
970            int type;
971            while ((type = parser.next()) != XmlPullParser.START_TAG
972                    && type != XmlPullParser.END_DOCUMENT) {
973                ;
974            }
975
976            if (type != XmlPullParser.START_TAG) {
977                Slog.e(LOG_TAG, "Unable to read user list");
978                fallbackToSingleUserLILP();
979                return;
980            }
981
982            mNextSerialNumber = -1;
983            if (parser.getName().equals(TAG_USERS)) {
984                String lastSerialNumber = parser.getAttributeValue(null, ATTR_NEXT_SERIAL_NO);
985                if (lastSerialNumber != null) {
986                    mNextSerialNumber = Integer.parseInt(lastSerialNumber);
987                }
988                String versionNumber = parser.getAttributeValue(null, ATTR_USER_VERSION);
989                if (versionNumber != null) {
990                    mUserVersion = Integer.parseInt(versionNumber);
991                }
992            }
993
994            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
995                if (type == XmlPullParser.START_TAG) {
996                    final String name = parser.getName();
997                    if (name.equals(TAG_USER)) {
998                        String id = parser.getAttributeValue(null, ATTR_ID);
999                        UserInfo user = readUserLILP(Integer.parseInt(id));
1000
1001                        if (user != null) {
1002                            synchronized (mUsersLock) {
1003                                mUsers.put(user.id, user);
1004                                if (mNextSerialNumber < 0 || mNextSerialNumber <= user.id) {
1005                                    mNextSerialNumber = user.id + 1;
1006                                }
1007                            }
1008                        }
1009                    } else if (name.equals(TAG_GUEST_RESTRICTIONS)) {
1010                        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1011                                && type != XmlPullParser.END_TAG) {
1012                            if (type == XmlPullParser.START_TAG) {
1013                                if (parser.getName().equals(TAG_RESTRICTIONS)) {
1014                                    UserRestrictionsUtils
1015                                            .readRestrictions(parser, mGuestRestrictions);
1016                                }
1017                                break;
1018                            }
1019                        }
1020                    }
1021                }
1022            }
1023            updateUserIds();
1024            upgradeIfNecessaryLILP();
1025        } catch (IOException ioe) {
1026            fallbackToSingleUserLILP();
1027        } catch (XmlPullParserException pe) {
1028            fallbackToSingleUserLILP();
1029        } finally {
1030            if (fis != null) {
1031                try {
1032                    fis.close();
1033                } catch (IOException e) {
1034                }
1035            }
1036        }
1037    }
1038
1039    /**
1040     * Upgrade steps between versions, either for fixing bugs or changing the data format.
1041     */
1042    private void upgradeIfNecessaryLILP() {
1043        int userVersion = mUserVersion;
1044        if (userVersion < 1) {
1045            // Assign a proper name for the owner, if not initialized correctly before
1046            UserInfo user = getUserInfoNoChecks(UserHandle.USER_SYSTEM);
1047            if ("Primary".equals(user.name)) {
1048                user.name = mContext.getResources().getString(com.android.internal.R.string.owner_name);
1049                scheduleWriteUserLP(user);
1050            }
1051            userVersion = 1;
1052        }
1053
1054        if (userVersion < 2) {
1055            // Owner should be marked as initialized
1056            UserInfo user = getUserInfoNoChecks(UserHandle.USER_SYSTEM);
1057            if ((user.flags & UserInfo.FLAG_INITIALIZED) == 0) {
1058                user.flags |= UserInfo.FLAG_INITIALIZED;
1059                scheduleWriteUserLP(user);
1060            }
1061            userVersion = 2;
1062        }
1063
1064
1065        if (userVersion < 4) {
1066            userVersion = 4;
1067        }
1068
1069        if (userVersion < 5) {
1070            initDefaultGuestRestrictions();
1071            userVersion = 5;
1072        }
1073
1074        if (userVersion < 6) {
1075            final boolean splitSystemUser = UserManager.isSplitSystemUser();
1076            synchronized (mUsersLock) {
1077                for (int i = 0; i < mUsers.size(); i++) {
1078                    UserInfo user = mUsers.valueAt(i);
1079                    // In non-split mode, only user 0 can have restricted profiles
1080                    if (!splitSystemUser && user.isRestricted()
1081                            && (user.restrictedProfileParentId == UserInfo.NO_PROFILE_GROUP_ID)) {
1082                        user.restrictedProfileParentId = UserHandle.USER_SYSTEM;
1083                        scheduleWriteUserLP(user);
1084                    }
1085                }
1086            }
1087            userVersion = 6;
1088        }
1089
1090        if (userVersion < USER_VERSION) {
1091            Slog.w(LOG_TAG, "User version " + mUserVersion + " didn't upgrade as expected to "
1092                    + USER_VERSION);
1093        } else {
1094            mUserVersion = userVersion;
1095            writeUserListLILP();
1096        }
1097    }
1098
1099    private void fallbackToSingleUserLILP() {
1100        int flags = UserInfo.FLAG_INITIALIZED;
1101        // In split system user mode, the admin and primary flags are assigned to the first human
1102        // user.
1103        if (!UserManager.isSplitSystemUser()) {
1104            flags |= UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY;
1105        }
1106        // Create the system user
1107        UserInfo system = new UserInfo(UserHandle.USER_SYSTEM,
1108                mContext.getResources().getString(com.android.internal.R.string.owner_name), null,
1109                flags);
1110        synchronized (mUsersLock) {
1111            mUsers.put(system.id, system);
1112        }
1113        mNextSerialNumber = MIN_USER_ID;
1114        mUserVersion = USER_VERSION;
1115
1116        Bundle restrictions = new Bundle();
1117        synchronized (mRestrictionsLock) {
1118            mBaseUserRestrictions.append(UserHandle.USER_SYSTEM, restrictions);
1119        }
1120
1121        updateUserIds();
1122        initDefaultGuestRestrictions();
1123
1124        writeUserListLILP();
1125        writeUserLP(system);
1126    }
1127
1128    private void scheduleWriteUserLP(UserInfo userInfo) {
1129        if (!mHandler.hasMessages(WRITE_USER_MSG, userInfo)) {
1130            Message msg = mHandler.obtainMessage(WRITE_USER_MSG, userInfo);
1131            mHandler.sendMessageDelayed(msg, WRITE_USER_DELAY);
1132        }
1133    }
1134
1135    /*
1136     * Writes the user file in this format:
1137     *
1138     * <user flags="20039023" id="0">
1139     *   <name>Primary</name>
1140     * </user>
1141     */
1142    private void writeUserLP(UserInfo userInfo) {
1143        FileOutputStream fos = null;
1144        AtomicFile userFile = new AtomicFile(new File(mUsersDir, userInfo.id + XML_SUFFIX));
1145        try {
1146            fos = userFile.startWrite();
1147            final BufferedOutputStream bos = new BufferedOutputStream(fos);
1148
1149            // XmlSerializer serializer = XmlUtils.serializerInstance();
1150            final XmlSerializer serializer = new FastXmlSerializer();
1151            serializer.setOutput(bos, StandardCharsets.UTF_8.name());
1152            serializer.startDocument(null, true);
1153            serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
1154
1155            serializer.startTag(null, TAG_USER);
1156            serializer.attribute(null, ATTR_ID, Integer.toString(userInfo.id));
1157            serializer.attribute(null, ATTR_SERIAL_NO, Integer.toString(userInfo.serialNumber));
1158            serializer.attribute(null, ATTR_FLAGS, Integer.toString(userInfo.flags));
1159            serializer.attribute(null, ATTR_CREATION_TIME, Long.toString(userInfo.creationTime));
1160            serializer.attribute(null, ATTR_LAST_LOGGED_IN_TIME,
1161                    Long.toString(userInfo.lastLoggedInTime));
1162            if (userInfo.iconPath != null) {
1163                serializer.attribute(null,  ATTR_ICON_PATH, userInfo.iconPath);
1164            }
1165            if (userInfo.partial) {
1166                serializer.attribute(null, ATTR_PARTIAL, "true");
1167            }
1168            if (userInfo.guestToRemove) {
1169                serializer.attribute(null, ATTR_GUEST_TO_REMOVE, "true");
1170            }
1171            if (userInfo.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
1172                serializer.attribute(null, ATTR_PROFILE_GROUP_ID,
1173                        Integer.toString(userInfo.profileGroupId));
1174            }
1175            if (userInfo.restrictedProfileParentId != UserInfo.NO_PROFILE_GROUP_ID) {
1176                serializer.attribute(null, ATTR_RESTRICTED_PROFILE_PARENT_ID,
1177                        Integer.toString(userInfo.restrictedProfileParentId));
1178            }
1179            serializer.startTag(null, TAG_NAME);
1180            serializer.text(userInfo.name);
1181            serializer.endTag(null, TAG_NAME);
1182            Bundle restrictions;
1183            synchronized (mRestrictionsLock) {
1184                restrictions = mBaseUserRestrictions.get(userInfo.id);
1185            }
1186            if (restrictions != null) {
1187                UserRestrictionsUtils
1188                        .writeRestrictions(serializer, restrictions, TAG_RESTRICTIONS);
1189            }
1190            serializer.endTag(null, TAG_USER);
1191
1192            serializer.endDocument();
1193            userFile.finishWrite(fos);
1194        } catch (Exception ioe) {
1195            Slog.e(LOG_TAG, "Error writing user info " + userInfo.id + "\n" + ioe);
1196            userFile.failWrite(fos);
1197        }
1198    }
1199
1200    /*
1201     * Writes the user list file in this format:
1202     *
1203     * <users nextSerialNumber="3">
1204     *   <user id="0"></user>
1205     *   <user id="2"></user>
1206     * </users>
1207     */
1208    private void writeUserListLILP() {
1209        // TODO Investigate removing a dependency on mInstallLock
1210        FileOutputStream fos = null;
1211        AtomicFile userListFile = new AtomicFile(mUserListFile);
1212        try {
1213            fos = userListFile.startWrite();
1214            final BufferedOutputStream bos = new BufferedOutputStream(fos);
1215
1216            // XmlSerializer serializer = XmlUtils.serializerInstance();
1217            final XmlSerializer serializer = new FastXmlSerializer();
1218            serializer.setOutput(bos, StandardCharsets.UTF_8.name());
1219            serializer.startDocument(null, true);
1220            serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
1221
1222            serializer.startTag(null, TAG_USERS);
1223            serializer.attribute(null, ATTR_NEXT_SERIAL_NO, Integer.toString(mNextSerialNumber));
1224            serializer.attribute(null, ATTR_USER_VERSION, Integer.toString(mUserVersion));
1225
1226            serializer.startTag(null, TAG_GUEST_RESTRICTIONS);
1227            UserRestrictionsUtils
1228                    .writeRestrictions(serializer, mGuestRestrictions, TAG_RESTRICTIONS);
1229            serializer.endTag(null, TAG_GUEST_RESTRICTIONS);
1230            int[] userIdsToWrite;
1231            synchronized (mUsersLock) {
1232                userIdsToWrite = new int[mUsers.size()];
1233                for (int i = 0; i < userIdsToWrite.length; i++) {
1234                    UserInfo user = mUsers.valueAt(i);
1235                    userIdsToWrite[i] = user.id;
1236                }
1237            }
1238            for (int id : userIdsToWrite) {
1239                serializer.startTag(null, TAG_USER);
1240                serializer.attribute(null, ATTR_ID, Integer.toString(id));
1241                serializer.endTag(null, TAG_USER);
1242            }
1243
1244            serializer.endTag(null, TAG_USERS);
1245
1246            serializer.endDocument();
1247            userListFile.finishWrite(fos);
1248        } catch (Exception e) {
1249            userListFile.failWrite(fos);
1250            Slog.e(LOG_TAG, "Error writing user list");
1251        }
1252    }
1253
1254    private UserInfo readUserLILP(int id) {
1255        int flags = 0;
1256        int serialNumber = id;
1257        String name = null;
1258        String iconPath = null;
1259        long creationTime = 0L;
1260        long lastLoggedInTime = 0L;
1261        int profileGroupId = UserInfo.NO_PROFILE_GROUP_ID;
1262        int restrictedProfileParentId = UserInfo.NO_PROFILE_GROUP_ID;
1263        boolean partial = false;
1264        boolean guestToRemove = false;
1265        Bundle restrictions = new Bundle();
1266
1267        FileInputStream fis = null;
1268        try {
1269            AtomicFile userFile =
1270                    new AtomicFile(new File(mUsersDir, Integer.toString(id) + XML_SUFFIX));
1271            fis = userFile.openRead();
1272            XmlPullParser parser = Xml.newPullParser();
1273            parser.setInput(fis, StandardCharsets.UTF_8.name());
1274            int type;
1275            while ((type = parser.next()) != XmlPullParser.START_TAG
1276                    && type != XmlPullParser.END_DOCUMENT) {
1277                ;
1278            }
1279
1280            if (type != XmlPullParser.START_TAG) {
1281                Slog.e(LOG_TAG, "Unable to read user " + id);
1282                return null;
1283            }
1284
1285            if (type == XmlPullParser.START_TAG && parser.getName().equals(TAG_USER)) {
1286                int storedId = readIntAttribute(parser, ATTR_ID, -1);
1287                if (storedId != id) {
1288                    Slog.e(LOG_TAG, "User id does not match the file name");
1289                    return null;
1290                }
1291                serialNumber = readIntAttribute(parser, ATTR_SERIAL_NO, id);
1292                flags = readIntAttribute(parser, ATTR_FLAGS, 0);
1293                iconPath = parser.getAttributeValue(null, ATTR_ICON_PATH);
1294                creationTime = readLongAttribute(parser, ATTR_CREATION_TIME, 0);
1295                lastLoggedInTime = readLongAttribute(parser, ATTR_LAST_LOGGED_IN_TIME, 0);
1296                profileGroupId = readIntAttribute(parser, ATTR_PROFILE_GROUP_ID,
1297                        UserInfo.NO_PROFILE_GROUP_ID);
1298                restrictedProfileParentId = readIntAttribute(parser,
1299                        ATTR_RESTRICTED_PROFILE_PARENT_ID, UserInfo.NO_PROFILE_GROUP_ID);
1300                String valueString = parser.getAttributeValue(null, ATTR_PARTIAL);
1301                if ("true".equals(valueString)) {
1302                    partial = true;
1303                }
1304                valueString = parser.getAttributeValue(null, ATTR_GUEST_TO_REMOVE);
1305                if ("true".equals(valueString)) {
1306                    guestToRemove = true;
1307                }
1308
1309                int outerDepth = parser.getDepth();
1310                while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1311                       && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1312                    if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1313                        continue;
1314                    }
1315                    String tag = parser.getName();
1316                    if (TAG_NAME.equals(tag)) {
1317                        type = parser.next();
1318                        if (type == XmlPullParser.TEXT) {
1319                            name = parser.getText();
1320                        }
1321                    } else if (TAG_RESTRICTIONS.equals(tag)) {
1322                        UserRestrictionsUtils.readRestrictions(parser, restrictions);
1323                    }
1324                }
1325            }
1326
1327            UserInfo userInfo = new UserInfo(id, name, iconPath, flags);
1328            userInfo.serialNumber = serialNumber;
1329            userInfo.creationTime = creationTime;
1330            userInfo.lastLoggedInTime = lastLoggedInTime;
1331            userInfo.partial = partial;
1332            userInfo.guestToRemove = guestToRemove;
1333            userInfo.profileGroupId = profileGroupId;
1334            userInfo.restrictedProfileParentId = restrictedProfileParentId;
1335            synchronized (mRestrictionsLock) {
1336                mBaseUserRestrictions.append(id, restrictions);
1337            }
1338            return userInfo;
1339
1340        } catch (IOException ioe) {
1341        } catch (XmlPullParserException pe) {
1342        } finally {
1343            if (fis != null) {
1344                try {
1345                    fis.close();
1346                } catch (IOException e) {
1347                }
1348            }
1349        }
1350        return null;
1351    }
1352
1353    private int readIntAttribute(XmlPullParser parser, String attr, int defaultValue) {
1354        String valueString = parser.getAttributeValue(null, attr);
1355        if (valueString == null) return defaultValue;
1356        try {
1357            return Integer.parseInt(valueString);
1358        } catch (NumberFormatException nfe) {
1359            return defaultValue;
1360        }
1361    }
1362
1363    private long readLongAttribute(XmlPullParser parser, String attr, long defaultValue) {
1364        String valueString = parser.getAttributeValue(null, attr);
1365        if (valueString == null) return defaultValue;
1366        try {
1367            return Long.parseLong(valueString);
1368        } catch (NumberFormatException nfe) {
1369            return defaultValue;
1370        }
1371    }
1372
1373    private boolean isPackageInstalled(String pkg, int userId) {
1374        final ApplicationInfo info = mPm.getApplicationInfo(pkg,
1375                PackageManager.GET_UNINSTALLED_PACKAGES,
1376                userId);
1377        if (info == null || (info.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
1378            return false;
1379        }
1380        return true;
1381    }
1382
1383    /**
1384     * Removes all the restrictions files (res_<packagename>) for a given user.
1385     * Does not do any permissions checking.
1386     */
1387    private void cleanAppRestrictions(int userId) {
1388        synchronized (mPackagesLock) {
1389            File dir = Environment.getUserSystemDirectory(userId);
1390            String[] files = dir.list();
1391            if (files == null) return;
1392            for (String fileName : files) {
1393                if (fileName.startsWith(RESTRICTIONS_FILE_PREFIX)) {
1394                    File resFile = new File(dir, fileName);
1395                    if (resFile.exists()) {
1396                        resFile.delete();
1397                    }
1398                }
1399            }
1400        }
1401    }
1402
1403    /**
1404     * Removes the app restrictions file for a specific package and user id, if it exists.
1405     */
1406    private void cleanAppRestrictionsForPackage(String pkg, int userId) {
1407        synchronized (mPackagesLock) {
1408            File dir = Environment.getUserSystemDirectory(userId);
1409            File resFile = new File(dir, packageToRestrictionsFileName(pkg));
1410            if (resFile.exists()) {
1411                resFile.delete();
1412            }
1413        }
1414    }
1415
1416    @Override
1417    public UserInfo createProfileForUser(String name, int flags, int userId) {
1418        checkManageUsersPermission("Only the system can create users");
1419        return createUserInternal(name, flags, userId);
1420    }
1421
1422    @Override
1423    public UserInfo createUser(String name, int flags) {
1424        checkManageUsersPermission("Only the system can create users");
1425        return createUserInternal(name, flags, UserHandle.USER_NULL);
1426    }
1427
1428    private UserInfo createUserInternal(String name, int flags, int parentId) {
1429        if (getUserRestrictions(UserHandle.getCallingUserId()).getBoolean(
1430                UserManager.DISALLOW_ADD_USER, false)) {
1431            Log.w(LOG_TAG, "Cannot add user. DISALLOW_ADD_USER is enabled.");
1432            return null;
1433        }
1434        if (ActivityManager.isLowRamDeviceStatic()) {
1435            return null;
1436        }
1437        final boolean isGuest = (flags & UserInfo.FLAG_GUEST) != 0;
1438        final boolean isManagedProfile = (flags & UserInfo.FLAG_MANAGED_PROFILE) != 0;
1439        final boolean isRestricted = (flags & UserInfo.FLAG_RESTRICTED) != 0;
1440        final long ident = Binder.clearCallingIdentity();
1441        UserInfo userInfo = null;
1442        final int userId;
1443        try {
1444            synchronized (mInstallLock) {
1445                synchronized (mPackagesLock) {
1446                    UserInfo parent = null;
1447                    if (parentId != UserHandle.USER_NULL) {
1448                        synchronized (mUsersLock) {
1449                            parent = getUserInfoLU(parentId);
1450                        }
1451                        if (parent == null) return null;
1452                    }
1453                    if (isManagedProfile && !canAddMoreManagedProfiles(parentId)) {
1454                        Log.e(LOG_TAG, "Cannot add more managed profiles for user " + parentId);
1455                        return null;
1456                    }
1457                    if (!isGuest && !isManagedProfile && isUserLimitReached()) {
1458                        // If we're not adding a guest user or a managed profile and the limit has
1459                        // been reached, cannot add a user.
1460                        return null;
1461                    }
1462                    // If we're adding a guest and there already exists one, bail.
1463                    if (isGuest && findCurrentGuestUser() != null) {
1464                        return null;
1465                    }
1466                    // In legacy mode, restricted profile's parent can only be the owner user
1467                    if (isRestricted && !UserManager.isSplitSystemUser()
1468                            && (parentId != UserHandle.USER_SYSTEM)) {
1469                        Log.w(LOG_TAG, "Cannot add restricted profile - parent user must be owner");
1470                        return null;
1471                    }
1472                    if (isRestricted && UserManager.isSplitSystemUser()) {
1473                        if (parent == null) {
1474                            Log.w(LOG_TAG, "Cannot add restricted profile - parent user must be "
1475                                    + "specified");
1476                            return null;
1477                        }
1478                        if (!parent.canHaveProfile()) {
1479                            Log.w(LOG_TAG, "Cannot add restricted profile - profiles cannot be "
1480                                    + "created for the specified parent user id " + parentId);
1481                            return null;
1482                        }
1483                    }
1484                    // In split system user mode, we assign the first human user the primary flag.
1485                    // And if there is no device owner, we also assign the admin flag to primary
1486                    // user.
1487                    if (UserManager.isSplitSystemUser()
1488                            && !isGuest && !isManagedProfile && getPrimaryUser() == null) {
1489                        flags |= UserInfo.FLAG_PRIMARY;
1490                        DevicePolicyManager devicePolicyManager = (DevicePolicyManager)
1491                                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
1492                        if (devicePolicyManager == null
1493                                || devicePolicyManager.getDeviceOwner() == null) {
1494                            flags |= UserInfo.FLAG_ADMIN;
1495                        }
1496                    }
1497                    userId = getNextAvailableId();
1498                    userInfo = new UserInfo(userId, name, null, flags);
1499                    userInfo.serialNumber = mNextSerialNumber++;
1500                    long now = System.currentTimeMillis();
1501                    userInfo.creationTime = (now > EPOCH_PLUS_30_YEARS) ? now : 0;
1502                    userInfo.partial = true;
1503                    Environment.getUserSystemDirectory(userInfo.id).mkdirs();
1504                    mUsers.put(userId, userInfo);
1505                    writeUserListLILP();
1506                    if (parent != null) {
1507                        if (isManagedProfile) {
1508                            if (parent.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID) {
1509                                parent.profileGroupId = parent.id;
1510                                scheduleWriteUserLP(parent);
1511                            }
1512                            userInfo.profileGroupId = parent.profileGroupId;
1513                        } else if (isRestricted) {
1514                            if (!parent.canHaveProfile()) {
1515                                Log.w(LOG_TAG, "Cannot add restricted profile - parent user must be owner");
1516                            }
1517                            if (parent.restrictedProfileParentId == UserInfo.NO_PROFILE_GROUP_ID) {
1518                                parent.restrictedProfileParentId = parent.id;
1519                                scheduleWriteUserLP(parent);
1520                            }
1521                            userInfo.restrictedProfileParentId = parent.restrictedProfileParentId;
1522                        }
1523                    }
1524                    final StorageManager storage = mContext.getSystemService(StorageManager.class);
1525                    for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
1526                        final String volumeUuid = vol.getFsUuid();
1527                        try {
1528                            final File userDir = Environment.getDataUserDirectory(volumeUuid,
1529                                    userId);
1530                            prepareUserDirectory(mContext, volumeUuid, userId);
1531                            enforceSerialNumber(userDir, userInfo.serialNumber);
1532                        } catch (IOException e) {
1533                            Log.wtf(LOG_TAG, "Failed to create user directory on " + volumeUuid, e);
1534                        }
1535                    }
1536                    mPm.createNewUserLILPw(userId);
1537                    userInfo.partial = false;
1538                    scheduleWriteUserLP(userInfo);
1539                    updateUserIds();
1540                    Bundle restrictions = new Bundle();
1541                    synchronized (mRestrictionsLock) {
1542                        mBaseUserRestrictions.append(userId, restrictions);
1543                    }
1544                }
1545            }
1546            mPm.newUserCreated(userId);
1547            if (userInfo != null) {
1548                Intent addedIntent = new Intent(Intent.ACTION_USER_ADDED);
1549                addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userInfo.id);
1550                mContext.sendBroadcastAsUser(addedIntent, UserHandle.ALL,
1551                        android.Manifest.permission.MANAGE_USERS);
1552            }
1553        } finally {
1554            Binder.restoreCallingIdentity(ident);
1555        }
1556        return userInfo;
1557    }
1558
1559    /**
1560     * @hide
1561     */
1562    public UserInfo createRestrictedProfile(String name, int parentUserId) {
1563        checkManageUsersPermission("setupRestrictedProfile");
1564        final UserInfo user = createProfileForUser(name, UserInfo.FLAG_RESTRICTED, parentUserId);
1565        if (user == null) {
1566            return null;
1567        }
1568        setUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS, true, user.id);
1569        // Change the setting before applying the DISALLOW_SHARE_LOCATION restriction, otherwise
1570        // the putIntForUser() will fail.
1571        android.provider.Settings.Secure.putIntForUser(mContext.getContentResolver(),
1572                android.provider.Settings.Secure.LOCATION_MODE,
1573                android.provider.Settings.Secure.LOCATION_MODE_OFF, user.id);
1574        setUserRestriction(UserManager.DISALLOW_SHARE_LOCATION, true, user.id);
1575        return user;
1576    }
1577
1578    /**
1579     * Find the current guest user. If the Guest user is partial,
1580     * then do not include it in the results as it is about to die.
1581     */
1582    private UserInfo findCurrentGuestUser() {
1583        synchronized (mUsersLock) {
1584            final int size = mUsers.size();
1585            for (int i = 0; i < size; i++) {
1586                final UserInfo user = mUsers.valueAt(i);
1587                if (user.isGuest() && !user.guestToRemove && !mRemovingUserIds.get(user.id)) {
1588                    return user;
1589                }
1590            }
1591        }
1592        return null;
1593    }
1594
1595    /**
1596     * Mark this guest user for deletion to allow us to create another guest
1597     * and switch to that user before actually removing this guest.
1598     * @param userHandle the userid of the current guest
1599     * @return whether the user could be marked for deletion
1600     */
1601    public boolean markGuestForDeletion(int userHandle) {
1602        checkManageUsersPermission("Only the system can remove users");
1603        if (getUserRestrictions(UserHandle.getCallingUserId()).getBoolean(
1604                UserManager.DISALLOW_REMOVE_USER, false)) {
1605            Log.w(LOG_TAG, "Cannot remove user. DISALLOW_REMOVE_USER is enabled.");
1606            return false;
1607        }
1608
1609        long ident = Binder.clearCallingIdentity();
1610        try {
1611            final UserInfo user;
1612            synchronized (mPackagesLock) {
1613                synchronized (mUsersLock) {
1614                    user = mUsers.get(userHandle);
1615                    if (userHandle == 0 || user == null || mRemovingUserIds.get(userHandle)) {
1616                        return false;
1617                    }
1618                }
1619                if (!user.isGuest()) {
1620                    return false;
1621                }
1622                // We set this to a guest user that is to be removed. This is a temporary state
1623                // where we are allowed to add new Guest users, even if this one is still not
1624                // removed. This user will still show up in getUserInfo() calls.
1625                // If we don't get around to removing this Guest user, it will be purged on next
1626                // startup.
1627                user.guestToRemove = true;
1628                // Mark it as disabled, so that it isn't returned any more when
1629                // profiles are queried.
1630                user.flags |= UserInfo.FLAG_DISABLED;
1631                writeUserLP(user);
1632            }
1633        } finally {
1634            Binder.restoreCallingIdentity(ident);
1635        }
1636        return true;
1637    }
1638
1639    /**
1640     * Removes a user and all data directories created for that user. This method should be called
1641     * after the user's processes have been terminated.
1642     * @param userHandle the user's id
1643     */
1644    public boolean removeUser(int userHandle) {
1645        checkManageUsersPermission("Only the system can remove users");
1646        if (getUserRestrictions(UserHandle.getCallingUserId()).getBoolean(
1647                UserManager.DISALLOW_REMOVE_USER, false)) {
1648            Log.w(LOG_TAG, "Cannot remove user. DISALLOW_REMOVE_USER is enabled.");
1649            return false;
1650        }
1651
1652        long ident = Binder.clearCallingIdentity();
1653        try {
1654            final UserInfo user;
1655            int currentUser = ActivityManager.getCurrentUser();
1656            if (currentUser == userHandle) {
1657                Log.w(LOG_TAG, "Current user cannot be removed");
1658                return false;
1659            }
1660            synchronized (mPackagesLock) {
1661                synchronized (mUsersLock) {
1662                    user = mUsers.get(userHandle);
1663                    if (userHandle == 0 || user == null || mRemovingUserIds.get(userHandle)) {
1664                        return false;
1665                    }
1666
1667                    // We remember deleted user IDs to prevent them from being
1668                    // reused during the current boot; they can still be reused
1669                    // after a reboot.
1670                    mRemovingUserIds.put(userHandle, true);
1671                }
1672
1673                try {
1674                    mAppOpsService.removeUser(userHandle);
1675                } catch (RemoteException e) {
1676                    Log.w(LOG_TAG, "Unable to notify AppOpsService of removing user", e);
1677                }
1678                // Set this to a partially created user, so that the user will be purged
1679                // on next startup, in case the runtime stops now before stopping and
1680                // removing the user completely.
1681                user.partial = true;
1682                // Mark it as disabled, so that it isn't returned any more when
1683                // profiles are queried.
1684                user.flags |= UserInfo.FLAG_DISABLED;
1685                writeUserLP(user);
1686            }
1687
1688            if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID
1689                    && user.isManagedProfile()) {
1690                // Send broadcast to notify system that the user removed was a
1691                // managed user.
1692                sendProfileRemovedBroadcast(user.profileGroupId, user.id);
1693            }
1694
1695            if (DBG) Slog.i(LOG_TAG, "Stopping user " + userHandle);
1696            int res;
1697            try {
1698                res = ActivityManagerNative.getDefault().stopUser(userHandle,
1699                        new IStopUserCallback.Stub() {
1700                            @Override
1701                            public void userStopped(int userId) {
1702                                finishRemoveUser(userId);
1703                            }
1704                            @Override
1705                            public void userStopAborted(int userId) {
1706                            }
1707                        });
1708            } catch (RemoteException e) {
1709                return false;
1710            }
1711            return res == ActivityManager.USER_OP_SUCCESS;
1712        } finally {
1713            Binder.restoreCallingIdentity(ident);
1714        }
1715    }
1716
1717    void finishRemoveUser(final int userHandle) {
1718        if (DBG) Slog.i(LOG_TAG, "finishRemoveUser " + userHandle);
1719        // Let other services shutdown any activity and clean up their state before completely
1720        // wiping the user's system directory and removing from the user list
1721        long ident = Binder.clearCallingIdentity();
1722        try {
1723            Intent addedIntent = new Intent(Intent.ACTION_USER_REMOVED);
1724            addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userHandle);
1725            mContext.sendOrderedBroadcastAsUser(addedIntent, UserHandle.ALL,
1726                    android.Manifest.permission.MANAGE_USERS,
1727
1728                    new BroadcastReceiver() {
1729                        @Override
1730                        public void onReceive(Context context, Intent intent) {
1731                            if (DBG) {
1732                                Slog.i(LOG_TAG,
1733                                        "USER_REMOVED broadcast sent, cleaning up user data "
1734                                        + userHandle);
1735                            }
1736                            new Thread() {
1737                                public void run() {
1738                                    // Clean up any ActivityManager state
1739                                    LocalServices.getService(ActivityManagerInternal.class)
1740                                            .onUserRemoved(userHandle);
1741                                    synchronized (mInstallLock) {
1742                                        synchronized (mPackagesLock) {
1743                                            removeUserStateLILP(userHandle);
1744                                        }
1745                                    }
1746                                }
1747                            }.start();
1748                        }
1749                    },
1750
1751                    null, Activity.RESULT_OK, null, null);
1752        } finally {
1753            Binder.restoreCallingIdentity(ident);
1754        }
1755    }
1756
1757    private void removeUserStateLILP(final int userHandle) {
1758        mContext.getSystemService(StorageManager.class)
1759            .deleteUserKey(userHandle);
1760        // Cleanup package manager settings
1761        mPm.cleanUpUserLILPw(this, userHandle);
1762
1763        // Remove this user from the list
1764        synchronized (mUsersLock) {
1765            mUsers.remove(userHandle);
1766        }
1767        // Remove user file
1768        AtomicFile userFile = new AtomicFile(new File(mUsersDir, userHandle + XML_SUFFIX));
1769        userFile.delete();
1770        // Update the user list
1771        writeUserListLILP();
1772        updateUserIds();
1773        removeDirectoryRecursive(Environment.getUserSystemDirectory(userHandle));
1774    }
1775
1776    private void removeDirectoryRecursive(File parent) {
1777        if (parent.isDirectory()) {
1778            String[] files = parent.list();
1779            for (String filename : files) {
1780                File child = new File(parent, filename);
1781                removeDirectoryRecursive(child);
1782            }
1783        }
1784        parent.delete();
1785    }
1786
1787    private void sendProfileRemovedBroadcast(int parentUserId, int removedUserId) {
1788        Intent managedProfileIntent = new Intent(Intent.ACTION_MANAGED_PROFILE_REMOVED);
1789        managedProfileIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY |
1790                Intent.FLAG_RECEIVER_FOREGROUND);
1791        managedProfileIntent.putExtra(Intent.EXTRA_USER, new UserHandle(removedUserId));
1792        mContext.sendBroadcastAsUser(managedProfileIntent, new UserHandle(parentUserId), null);
1793    }
1794
1795    @Override
1796    public Bundle getApplicationRestrictions(String packageName) {
1797        return getApplicationRestrictionsForUser(packageName, UserHandle.getCallingUserId());
1798    }
1799
1800    @Override
1801    public Bundle getApplicationRestrictionsForUser(String packageName, int userId) {
1802        if (UserHandle.getCallingUserId() != userId
1803                || !UserHandle.isSameApp(Binder.getCallingUid(), getUidForPackage(packageName))) {
1804            checkManageUsersPermission("get application restrictions for other users/apps");
1805        }
1806        synchronized (mPackagesLock) {
1807            // Read the restrictions from XML
1808            return readApplicationRestrictionsLP(packageName, userId);
1809        }
1810    }
1811
1812    @Override
1813    public void setApplicationRestrictions(String packageName, Bundle restrictions,
1814            int userId) {
1815        checkManageUsersPermission("set application restrictions");
1816        synchronized (mPackagesLock) {
1817            if (restrictions == null || restrictions.isEmpty()) {
1818                cleanAppRestrictionsForPackage(packageName, userId);
1819            } else {
1820                // Write the restrictions to XML
1821                writeApplicationRestrictionsLP(packageName, restrictions, userId);
1822            }
1823        }
1824
1825        if (isPackageInstalled(packageName, userId)) {
1826            // Notify package of changes via an intent - only sent to explicitly registered receivers.
1827            Intent changeIntent = new Intent(Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED);
1828            changeIntent.setPackage(packageName);
1829            changeIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
1830            mContext.sendBroadcastAsUser(changeIntent, new UserHandle(userId));
1831        }
1832    }
1833
1834    private void unhideAllInstalledAppsForUser(final int userHandle) {
1835        mHandler.post(new Runnable() {
1836            @Override
1837            public void run() {
1838                List<ApplicationInfo> apps =
1839                        mPm.getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES,
1840                                userHandle).getList();
1841                final long ident = Binder.clearCallingIdentity();
1842                try {
1843                    for (ApplicationInfo appInfo : apps) {
1844                        if ((appInfo.flags & ApplicationInfo.FLAG_INSTALLED) != 0
1845                                && (appInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HIDDEN)
1846                                        != 0) {
1847                            mPm.setApplicationHiddenSettingAsUser(appInfo.packageName, false,
1848                                    userHandle);
1849                        }
1850                    }
1851                } finally {
1852                    Binder.restoreCallingIdentity(ident);
1853                }
1854            }
1855        });
1856    }
1857    private int getUidForPackage(String packageName) {
1858        long ident = Binder.clearCallingIdentity();
1859        try {
1860            return mContext.getPackageManager().getApplicationInfo(packageName,
1861                    PackageManager.GET_UNINSTALLED_PACKAGES).uid;
1862        } catch (NameNotFoundException nnfe) {
1863            return -1;
1864        } finally {
1865            Binder.restoreCallingIdentity(ident);
1866        }
1867    }
1868
1869    private Bundle readApplicationRestrictionsLP(String packageName, int userId) {
1870        AtomicFile restrictionsFile =
1871                new AtomicFile(new File(Environment.getUserSystemDirectory(userId),
1872                        packageToRestrictionsFileName(packageName)));
1873        return readApplicationRestrictionsLP(restrictionsFile);
1874    }
1875
1876    @VisibleForTesting
1877    static Bundle readApplicationRestrictionsLP(AtomicFile restrictionsFile) {
1878        final Bundle restrictions = new Bundle();
1879        final ArrayList<String> values = new ArrayList<>();
1880        if (!restrictionsFile.getBaseFile().exists()) {
1881            return restrictions;
1882        }
1883
1884        FileInputStream fis = null;
1885        try {
1886            fis = restrictionsFile.openRead();
1887            XmlPullParser parser = Xml.newPullParser();
1888            parser.setInput(fis, StandardCharsets.UTF_8.name());
1889            XmlUtils.nextElement(parser);
1890            if (parser.getEventType() != XmlPullParser.START_TAG) {
1891                Slog.e(LOG_TAG, "Unable to read restrictions file "
1892                        + restrictionsFile.getBaseFile());
1893                return restrictions;
1894            }
1895            while (parser.next() != XmlPullParser.END_DOCUMENT) {
1896                readEntry(restrictions, values, parser);
1897            }
1898        } catch (IOException|XmlPullParserException e) {
1899            Log.w(LOG_TAG, "Error parsing " + restrictionsFile.getBaseFile(), e);
1900        } finally {
1901            IoUtils.closeQuietly(fis);
1902        }
1903        return restrictions;
1904    }
1905
1906    private static void readEntry(Bundle restrictions, ArrayList<String> values,
1907            XmlPullParser parser) throws XmlPullParserException, IOException {
1908        int type = parser.getEventType();
1909        if (type == XmlPullParser.START_TAG && parser.getName().equals(TAG_ENTRY)) {
1910            String key = parser.getAttributeValue(null, ATTR_KEY);
1911            String valType = parser.getAttributeValue(null, ATTR_VALUE_TYPE);
1912            String multiple = parser.getAttributeValue(null, ATTR_MULTIPLE);
1913            if (multiple != null) {
1914                values.clear();
1915                int count = Integer.parseInt(multiple);
1916                while (count > 0 && (type = parser.next()) != XmlPullParser.END_DOCUMENT) {
1917                    if (type == XmlPullParser.START_TAG
1918                            && parser.getName().equals(TAG_VALUE)) {
1919                        values.add(parser.nextText().trim());
1920                        count--;
1921                    }
1922                }
1923                String [] valueStrings = new String[values.size()];
1924                values.toArray(valueStrings);
1925                restrictions.putStringArray(key, valueStrings);
1926            } else if (ATTR_TYPE_BUNDLE.equals(valType)) {
1927                restrictions.putBundle(key, readBundleEntry(parser, values));
1928            } else if (ATTR_TYPE_BUNDLE_ARRAY.equals(valType)) {
1929                final int outerDepth = parser.getDepth();
1930                ArrayList<Bundle> bundleList = new ArrayList<>();
1931                while (XmlUtils.nextElementWithin(parser, outerDepth)) {
1932                    Bundle childBundle = readBundleEntry(parser, values);
1933                    bundleList.add(childBundle);
1934                }
1935                restrictions.putParcelableArray(key,
1936                        bundleList.toArray(new Bundle[bundleList.size()]));
1937            } else {
1938                String value = parser.nextText().trim();
1939                if (ATTR_TYPE_BOOLEAN.equals(valType)) {
1940                    restrictions.putBoolean(key, Boolean.parseBoolean(value));
1941                } else if (ATTR_TYPE_INTEGER.equals(valType)) {
1942                    restrictions.putInt(key, Integer.parseInt(value));
1943                } else {
1944                    restrictions.putString(key, value);
1945                }
1946            }
1947        }
1948    }
1949
1950    private static Bundle readBundleEntry(XmlPullParser parser, ArrayList<String> values)
1951            throws IOException, XmlPullParserException {
1952        Bundle childBundle = new Bundle();
1953        final int outerDepth = parser.getDepth();
1954        while (XmlUtils.nextElementWithin(parser, outerDepth)) {
1955            readEntry(childBundle, values, parser);
1956        }
1957        return childBundle;
1958    }
1959
1960    private void writeApplicationRestrictionsLP(String packageName,
1961            Bundle restrictions, int userId) {
1962        AtomicFile restrictionsFile = new AtomicFile(
1963                new File(Environment.getUserSystemDirectory(userId),
1964                        packageToRestrictionsFileName(packageName)));
1965        writeApplicationRestrictionsLP(restrictions, restrictionsFile);
1966    }
1967
1968    @VisibleForTesting
1969    static void writeApplicationRestrictionsLP(Bundle restrictions, AtomicFile restrictionsFile) {
1970        FileOutputStream fos = null;
1971        try {
1972            fos = restrictionsFile.startWrite();
1973            final BufferedOutputStream bos = new BufferedOutputStream(fos);
1974
1975            final XmlSerializer serializer = new FastXmlSerializer();
1976            serializer.setOutput(bos, StandardCharsets.UTF_8.name());
1977            serializer.startDocument(null, true);
1978            serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
1979
1980            serializer.startTag(null, TAG_RESTRICTIONS);
1981            writeBundle(restrictions, serializer);
1982            serializer.endTag(null, TAG_RESTRICTIONS);
1983
1984            serializer.endDocument();
1985            restrictionsFile.finishWrite(fos);
1986        } catch (Exception e) {
1987            restrictionsFile.failWrite(fos);
1988            Slog.e(LOG_TAG, "Error writing application restrictions list", e);
1989        }
1990    }
1991
1992    private static void writeBundle(Bundle restrictions, XmlSerializer serializer)
1993            throws IOException {
1994        for (String key : restrictions.keySet()) {
1995            Object value = restrictions.get(key);
1996            serializer.startTag(null, TAG_ENTRY);
1997            serializer.attribute(null, ATTR_KEY, key);
1998
1999            if (value instanceof Boolean) {
2000                serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_BOOLEAN);
2001                serializer.text(value.toString());
2002            } else if (value instanceof Integer) {
2003                serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_INTEGER);
2004                serializer.text(value.toString());
2005            } else if (value == null || value instanceof String) {
2006                serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_STRING);
2007                serializer.text(value != null ? (String) value : "");
2008            } else if (value instanceof Bundle) {
2009                serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_BUNDLE);
2010                writeBundle((Bundle) value, serializer);
2011            } else if (value instanceof Parcelable[]) {
2012                serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_BUNDLE_ARRAY);
2013                Parcelable[] array = (Parcelable[]) value;
2014                for (Parcelable parcelable : array) {
2015                    if (!(parcelable instanceof Bundle)) {
2016                        throw new IllegalArgumentException("bundle-array can only hold Bundles");
2017                    }
2018                    serializer.startTag(null, TAG_ENTRY);
2019                    serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_BUNDLE);
2020                    writeBundle((Bundle) parcelable, serializer);
2021                    serializer.endTag(null, TAG_ENTRY);
2022                }
2023            } else {
2024                serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_STRING_ARRAY);
2025                String[] values = (String[]) value;
2026                serializer.attribute(null, ATTR_MULTIPLE, Integer.toString(values.length));
2027                for (String choice : values) {
2028                    serializer.startTag(null, TAG_VALUE);
2029                    serializer.text(choice != null ? choice : "");
2030                    serializer.endTag(null, TAG_VALUE);
2031                }
2032            }
2033            serializer.endTag(null, TAG_ENTRY);
2034        }
2035    }
2036
2037    @Override
2038    public int getUserSerialNumber(int userHandle) {
2039        synchronized (mUsersLock) {
2040            if (!exists(userHandle)) return -1;
2041            return getUserInfoLU(userHandle).serialNumber;
2042        }
2043    }
2044
2045    @Override
2046    public int getUserHandle(int userSerialNumber) {
2047        synchronized (mUsersLock) {
2048            for (int userId : mUserIds) {
2049                UserInfo info = getUserInfoLU(userId);
2050                if (info != null && info.serialNumber == userSerialNumber) return userId;
2051            }
2052            // Not found
2053            return -1;
2054        }
2055    }
2056
2057    @Override
2058    public long getUserCreationTime(int userHandle) {
2059        int callingUserId = UserHandle.getCallingUserId();
2060        UserInfo userInfo = null;
2061        synchronized (mUsersLock) {
2062            if (callingUserId == userHandle) {
2063                userInfo = getUserInfoLU(userHandle);
2064            } else {
2065                UserInfo parent = getProfileParentLU(userHandle);
2066                if (parent != null && parent.id == callingUserId) {
2067                    userInfo = getUserInfoLU(userHandle);
2068                }
2069            }
2070        }
2071        if (userInfo == null) {
2072            throw new SecurityException("userHandle can only be the calling user or a managed "
2073                    + "profile associated with this user");
2074        }
2075        return userInfo.creationTime;
2076    }
2077
2078    /**
2079     * Caches the list of user ids in an array, adjusting the array size when necessary.
2080     */
2081    private void updateUserIds() {
2082        int num = 0;
2083        synchronized (mUsersLock) {
2084            final int userSize = mUsers.size();
2085            for (int i = 0; i < userSize; i++) {
2086                if (!mUsers.valueAt(i).partial) {
2087                    num++;
2088                }
2089            }
2090            final int[] newUsers = new int[num];
2091            int n = 0;
2092            for (int i = 0; i < userSize; i++) {
2093                if (!mUsers.valueAt(i).partial) {
2094                    newUsers[n++] = mUsers.keyAt(i);
2095                }
2096            }
2097            mUserIds = newUsers;
2098        }
2099    }
2100
2101    /**
2102     * Make a note of the last started time of a user and do some cleanup.
2103     * @param userId the user that was just foregrounded
2104     */
2105    public void onUserForeground(int userId) {
2106        synchronized (mPackagesLock) {
2107            UserInfo user = getUserInfoNoChecks(userId);
2108            long now = System.currentTimeMillis();
2109            if (user == null || user.partial) {
2110                Slog.w(LOG_TAG, "userForeground: unknown user #" + userId);
2111                return;
2112            }
2113            if (now > EPOCH_PLUS_30_YEARS) {
2114                user.lastLoggedInTime = now;
2115                scheduleWriteUserLP(user);
2116            }
2117        }
2118    }
2119
2120    /**
2121     * Returns the next available user id, filling in any holes in the ids.
2122     * TODO: May not be a good idea to recycle ids, in case it results in confusion
2123     * for data and battery stats collection, or unexpected cross-talk.
2124     * @return
2125     */
2126    private int getNextAvailableId() {
2127        synchronized (mUsersLock) {
2128            int i = MIN_USER_ID;
2129            while (i < MAX_USER_ID) {
2130                if (mUsers.indexOfKey(i) < 0 && !mRemovingUserIds.get(i)) {
2131                    return i;
2132                }
2133                i++;
2134            }
2135        }
2136        throw new IllegalStateException("No user id available!");
2137    }
2138
2139    private String packageToRestrictionsFileName(String packageName) {
2140        return RESTRICTIONS_FILE_PREFIX + packageName + XML_SUFFIX;
2141    }
2142
2143    /**
2144     * Create new {@code /data/user/[id]} directory and sets default
2145     * permissions.
2146     */
2147    public static void prepareUserDirectory(Context context, String volumeUuid, int userId) {
2148        final StorageManager storage = context.getSystemService(StorageManager.class);
2149        final File userDir = Environment.getDataUserDirectory(volumeUuid, userId);
2150        storage.createNewUserDir(userId, userDir);
2151    }
2152
2153    /**
2154     * Enforce that serial number stored in user directory inode matches the
2155     * given expected value. Gracefully sets the serial number if currently
2156     * undefined.
2157     *
2158     * @throws IOException when problem extracting serial number, or serial
2159     *             number is mismatched.
2160     */
2161    public static void enforceSerialNumber(File file, int serialNumber) throws IOException {
2162        final int foundSerial = getSerialNumber(file);
2163        Slog.v(LOG_TAG, "Found " + file + " with serial number " + foundSerial);
2164
2165        if (foundSerial == -1) {
2166            Slog.d(LOG_TAG, "Serial number missing on " + file + "; assuming current is valid");
2167            try {
2168                setSerialNumber(file, serialNumber);
2169            } catch (IOException e) {
2170                Slog.w(LOG_TAG, "Failed to set serial number on " + file, e);
2171            }
2172
2173        } else if (foundSerial != serialNumber) {
2174            throw new IOException("Found serial number " + foundSerial
2175                    + " doesn't match expected " + serialNumber);
2176        }
2177    }
2178
2179    /**
2180     * Set serial number stored in user directory inode.
2181     *
2182     * @throws IOException if serial number was already set
2183     */
2184    private static void setSerialNumber(File file, int serialNumber)
2185            throws IOException {
2186        try {
2187            final byte[] buf = Integer.toString(serialNumber).getBytes(StandardCharsets.UTF_8);
2188            Os.setxattr(file.getAbsolutePath(), XATTR_SERIAL, buf, OsConstants.XATTR_CREATE);
2189        } catch (ErrnoException e) {
2190            throw e.rethrowAsIOException();
2191        }
2192    }
2193
2194    /**
2195     * Return serial number stored in user directory inode.
2196     *
2197     * @return parsed serial number, or -1 if not set
2198     */
2199    private static int getSerialNumber(File file) throws IOException {
2200        try {
2201            final byte[] buf = new byte[256];
2202            final int len = Os.getxattr(file.getAbsolutePath(), XATTR_SERIAL, buf);
2203            final String serial = new String(buf, 0, len);
2204            try {
2205                return Integer.parseInt(serial);
2206            } catch (NumberFormatException e) {
2207                throw new IOException("Bad serial number: " + serial);
2208            }
2209        } catch (ErrnoException e) {
2210            if (e.errno == OsConstants.ENODATA) {
2211                return -1;
2212            } else {
2213                throw e.rethrowAsIOException();
2214            }
2215        }
2216    }
2217
2218    @Override
2219    public void onShellCommand(FileDescriptor in, FileDescriptor out,
2220            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
2221        (new Shell()).exec(this, in, out, err, args, resultReceiver);
2222    }
2223
2224    int onShellCommand(Shell shell, String cmd) {
2225        if (cmd == null) {
2226            return shell.handleDefaultCommands(cmd);
2227        }
2228
2229        final PrintWriter pw = shell.getOutPrintWriter();
2230        try {
2231            switch(cmd) {
2232                case "list":
2233                    return runList(pw);
2234            }
2235        } catch (RemoteException e) {
2236            pw.println("Remote exception: " + e);
2237        }
2238        return -1;
2239    }
2240
2241    private int runList(PrintWriter pw) throws RemoteException {
2242        final IActivityManager am = ActivityManagerNative.getDefault();
2243        final List<UserInfo> users = getUsers(false);
2244        if (users == null) {
2245            pw.println("Error: couldn't get users");
2246            return 1;
2247        } else {
2248            pw.println("Users:");
2249            for (int i = 0; i < users.size(); i++) {
2250                String running = am.isUserRunning(users.get(i).id, false) ? " running" : "";
2251                pw.println("\t" + users.get(i).toString() + running);
2252            }
2253            return 0;
2254        }
2255    }
2256
2257    @Override
2258    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2259        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
2260                != PackageManager.PERMISSION_GRANTED) {
2261            pw.println("Permission Denial: can't dump UserManager from from pid="
2262                    + Binder.getCallingPid()
2263                    + ", uid=" + Binder.getCallingUid()
2264                    + " without permission "
2265                    + android.Manifest.permission.DUMP);
2266            return;
2267        }
2268
2269        long now = System.currentTimeMillis();
2270        StringBuilder sb = new StringBuilder();
2271        synchronized (mPackagesLock) {
2272            synchronized (mUsersLock) {
2273                pw.println("Users:");
2274                for (int i = 0; i < mUsers.size(); i++) {
2275                    UserInfo user = mUsers.valueAt(i);
2276                    if (user == null) {
2277                        continue;
2278                    }
2279                    pw.print("  "); pw.print(user);
2280                    pw.print(" serialNo="); pw.print(user.serialNumber);
2281                    if (mRemovingUserIds.get(mUsers.keyAt(i))) {
2282                        pw.print(" <removing> ");
2283                    }
2284                    if (user.partial) {
2285                        pw.print(" <partial>");
2286                    }
2287                    pw.println();
2288                    pw.print("    Created: ");
2289                    if (user.creationTime == 0) {
2290                        pw.println("<unknown>");
2291                    } else {
2292                        sb.setLength(0);
2293                        TimeUtils.formatDuration(now - user.creationTime, sb);
2294                        sb.append(" ago");
2295                        pw.println(sb);
2296                    }
2297                    pw.print("    Last logged in: ");
2298                    if (user.lastLoggedInTime == 0) {
2299                        pw.println("<unknown>");
2300                    } else {
2301                        sb.setLength(0);
2302                        TimeUtils.formatDuration(now - user.lastLoggedInTime, sb);
2303                        sb.append(" ago");
2304                        pw.println(sb);
2305                    }
2306                    pw.println("    Restrictions:");
2307                    synchronized (mRestrictionsLock) {
2308                        UserRestrictionsUtils.dumpRestrictions(
2309                                pw, "      ", mBaseUserRestrictions.get(user.id));
2310                        pw.println("    Effective restrictions:");
2311                        UserRestrictionsUtils.dumpRestrictions(
2312                                pw, "      ", mCachedEffectiveUserRestrictions.get(user.id));
2313                    }
2314                }
2315            }
2316            pw.println();
2317            pw.println("Guest restrictions:");
2318            UserRestrictionsUtils.dumpRestrictions(pw, "  ", mGuestRestrictions);
2319        }
2320    }
2321
2322    final class MainHandler extends Handler {
2323
2324        @Override
2325        public void handleMessage(Message msg) {
2326            switch (msg.what) {
2327                case WRITE_USER_MSG:
2328                    removeMessages(WRITE_USER_MSG, msg.obj);
2329                    synchronized (mPackagesLock) {
2330                        int userId = ((UserInfo) msg.obj).id;
2331                        UserInfo userInfo = getUserInfoNoChecks(userId);
2332                        if (userInfo != null) {
2333                            writeUserLP(userInfo);
2334                        }
2335                    }
2336            }
2337        }
2338    }
2339
2340    /**
2341     * @param userId
2342     * @return whether the user has been initialized yet
2343     */
2344    boolean isInitialized(int userId) {
2345        return (getUserInfo(userId).flags & UserInfo.FLAG_INITIALIZED) != 0;
2346    }
2347
2348    private class LocalService extends UserManagerInternal {
2349
2350        @Override
2351        public Object getUserRestrictionsLock() {
2352            return mRestrictionsLock;
2353        }
2354
2355        @Override
2356        @GuardedBy("mRestrictionsLock")
2357        public void updateEffectiveUserRestrictionsLR(int userId) {
2358            UserManagerService.this.updateEffectiveUserRestrictionsLR(userId);
2359        }
2360
2361        @Override
2362        @GuardedBy("mRestrictionsLock")
2363        public void updateEffectiveUserRestrictionsForAllUsersLR() {
2364            UserManagerService.this.updateEffectiveUserRestrictionsForAllUsersLR();
2365        }
2366
2367        @Override
2368        public Bundle getBaseUserRestrictions(int userId) {
2369            synchronized (mRestrictionsLock) {
2370                return mBaseUserRestrictions.get(userId);
2371            }
2372        }
2373
2374        @Override
2375        public void setBaseUserRestrictionsByDpmsForMigration(
2376                int userId, Bundle baseRestrictions) {
2377            synchronized (mRestrictionsLock) {
2378                mBaseUserRestrictions.put(userId, new Bundle(baseRestrictions));
2379                invalidateEffectiveUserRestrictionsLR(userId);
2380            }
2381
2382            final UserInfo userInfo = getUserInfoNoChecks(userId);
2383            synchronized (mPackagesLock) {
2384                if (userInfo != null) {
2385                    writeUserLP(userInfo);
2386                } else {
2387                    Slog.w(LOG_TAG, "UserInfo not found for " + userId);
2388                }
2389            }
2390        }
2391    }
2392
2393    private class Shell extends ShellCommand {
2394        @Override
2395        public int onCommand(String cmd) {
2396            return onShellCommand(this, cmd);
2397        }
2398
2399        @Override
2400        public void onHelp() {
2401            final PrintWriter pw = getOutPrintWriter();
2402            pw.println("User manager (user) commands:");
2403            pw.println("  help");
2404            pw.println("    Print this help text.");
2405            pw.println("");
2406            pw.println("  list");
2407            pw.println("    Prints all users on the system.");
2408        }
2409    }
2410}
2411