Android多用户之UserManagerService源码分析

Android可以支持多个用户使用系统,通常第一个在系统中注册的用户将默认成为系统管理员。
不同用户的设置各不相同,并且不同用户安装的应用及应用数据也不相同。但是系统中和硬件相关的设置则是共用的,如网络设置等。

用户切换后前面用户运行的后台进程还可以继续运行,这样进行用户切换时无须中断一些后台进行的耗时操作(如下载)。

管理用户的系统服务–UserManagerService

UserManagerService的主要功能是创建和删除用户,以及查询用户信息。
1.在PackageManagerService中进行初始化

final ArrayMap<String, PackageParser.Package> mPackages =
            new ArrayMap<String, PackageParser.Package>();

public PackageManagerService(Context context, Installer installer,
        boolean factoryTest, boolean onlyCore) {
	...
    synchronized (mInstallLock) {
        // writer
        synchronized (mPackages) {
			...
            sUserManager = new UserManagerService(context, this, mPackages);
			...
        } // synchronized (mPackages)
    } // synchronized (mInstallLock)
	...
}

@Override
public void systemReady() {
	...
	sUserManager.systemReady();
	...
}

UserManagerService的构造方法如下:

UserManagerService(Context context, PackageManagerService pm, Object packagesLock) {
    this(context, pm, packagesLock, Environment.getDataDirectory());
}

调用了另一个构造方法,并多传递了一个参数:/data目录

private static final String USER_INFO_DIR = "system" + File.separator + "users";

private UserManagerService(Context context, PackageManagerService pm,
        Object packagesLock, File dataDir) {
    mContext = context;
    mPm = pm;
    mPackagesLock = packagesLock;
    mHandler = new MainHandler();
    synchronized (mPackagesLock) {
	// /data/system/users
        mUsersDir = new File(dataDir, USER_INFO_DIR);
        mUsersDir.mkdirs();
        // Make zeroth user directory, for services to migrate their files to that location
        File userZeroDir = new File(mUsersDir, String.valueOf(UserHandle.USER_SYSTEM));
	// 创建第一个用户目录:/data/system/users/0
        userZeroDir.mkdirs();
	// 设置访问文件的权限
        FileUtils.setPermissions(mUsersDir.toString(),
                FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IROTH | FileUtils.S_IXOTH,
                -1, -1);
	// /data/system/users/userlist.xml
        mUserListFile = new File(mUsersDir, USER_LIST_FILENAME);
	// 初始化来宾账户的默认限制条件
        initDefaultGuestRestrictions();
	// 从/data/system/users/userlist.xml文件读取用户信息
        readUserListLP();
        sInstance = this;
    }
    mLocalService = new LocalService();
    LocalServices.addService(UserManagerInternal.class, mLocalService);
    mLockPatternUtils = new LockPatternUtils(mContext);
    mUserStates.put(UserHandle.USER_SYSTEM, UserState.STATE_BOOTING);
}

private final Bundle mGuestRestrictions = new Bundle();

// 初始化来宾账户的默认限制条件
private void initDefaultGuestRestrictions() {
    synchronized (mGuestRestrictions) {
        if (mGuestRestrictions.isEmpty()) {
	    // "no_config_wifi",不允许配置WiFi
            mGuestRestrictions.putBoolean(UserManager.DISALLOW_CONFIG_WIFI, true);
	    // "no_install_unknown_sources",不允许安装未知来源的应用
            mGuestRestrictions.putBoolean(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, true);
	    // "no_outgoing_calls",不允许呼叫电话
            mGuestRestrictions.putBoolean(UserManager.DISALLOW_OUTGOING_CALLS, true);
	    // "no_sms",不允许收发短信
            mGuestRestrictions.putBoolean(UserManager.DISALLOW_SMS, true);
        }
    }
}

先看下/data/system/users/userlist.xml文件的内容,再分析读取过程,文件内容如下:

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<users nextSerialNumber="10" version="5">
    <guestRestrictions>
        <restrictions no_config_wifi="true" no_outgoing_calls="true" no_sms="true" />
    </guestRestrictions>
    <user id="0" />
</users>

// 从/data/system/users/userlist.xml文件读取用户信息
private final SparseArray<UserData> mUsers = new SparseArray<>();

private void readUserListLP() {
    // 如果文件不存在,则创建管理员用户并返回
    if (!mUserListFile.exists()) {
        fallbackToSingleUserLP();
        return;
    }
    FileInputStream fis = null;
    AtomicFile userListFile = new AtomicFile(mUserListFile);
    try {
        fis = userListFile.openRead();
        XmlPullParser parser = Xml.newPullParser();
        parser.setInput(fis, StandardCharsets.UTF_8.name());
        int type;
        while ((type = parser.next()) != XmlPullParser.START_TAG
                && type != XmlPullParser.END_DOCUMENT) {
            // Skip
        }

        if (type != XmlPullParser.START_TAG) {
            Slog.e(LOG_TAG, "Unable to read user list");
	    // 如果文件异常,则创建管理员用户并返回
            fallbackToSingleUserLP();
            return;
        }

        mNextSerialNumber = -1;
	// 解析文件
        if (parser.getName().equals(TAG_USERS)) {
            String lastSerialNumber = parser.getAttributeValue(null, ATTR_NEXT_SERIAL_NO);
            if (lastSerialNumber != null) {
                mNextSerialNumber = Integer.parseInt(lastSerialNumber);
            }
            String versionNumber = parser.getAttributeValue(null, ATTR_USER_VERSION);
            if (versionNumber != null) {
                mUserVersion = Integer.parseInt(versionNumber);
            }
        }

        final Bundle newDevicePolicyGlobalUserRestrictions = new Bundle();

        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
            if (type == XmlPullParser.START_TAG) {
                final String name = parser.getName();
                if (name.equals(TAG_USER)) {
                    String id = parser.getAttributeValue(null, ATTR_ID);

		    // 初始化UserData对象保存从 /data/system/users/${id}.xml 文件中读取到的用户信息
                    UserData userData = readUserLP(Integer.parseInt(id));

                    if (userData != null) {
                        synchronized (mUsersLock) {
			    // 把解析到的用户信息保存到mUsers中
                            mUsers.put(userData.info.id, userData);
                            if (mNextSerialNumber < 0
                                    || mNextSerialNumber <= userData.info.id) {
                                mNextSerialNumber = userData.info.id + 1;
                            }
                        }
                    }
                } else if (name.equals(TAG_GUEST_RESTRICTIONS)) {
                    while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
                            && type != XmlPullParser.END_TAG) {
                        if (type == XmlPullParser.START_TAG) {
                            if (parser.getName().equals(TAG_RESTRICTIONS)) {
                                synchronized (mGuestRestrictions) {
                                    UserRestrictionsUtils
                                            .readRestrictions(parser, mGuestRestrictions);
                                }
                            } else if (parser.getName().equals(TAG_DEVICE_POLICY_RESTRICTIONS)
                                    ) {
                                UserRestrictionsUtils.readRestrictions(parser,
                                        newDevicePolicyGlobalUserRestrictions);
                            }
                            break;
                        }
                    }
                } else if (name.equals(TAG_GLOBAL_RESTRICTION_OWNER_ID)) {
                    String ownerUserId = parser.getAttributeValue(null, ATTR_ID);
                    if (ownerUserId != null) {
                        mGlobalRestrictionOwnerUserId = Integer.parseInt(ownerUserId);
                    }
                }
            }
        }
        synchronized (mRestrictionsLock) {
            mDevicePolicyGlobalUserRestrictions = newDevicePolicyGlobalUserRestrictions;
        }
	// 解析完文件后,更新用户ID
        updateUserIds();
	// 如果有必要,则升级Version
        upgradeIfNecessaryLP();
    } catch (IOException | XmlPullParserException e) {
        fallbackToSingleUserLP();
    } finally {
        IoUtils.closeQuietly(fis);
    }
}

// 创建管理员用户
private void fallbackToSingleUserLP() {
    int flags = UserInfo.FLAG_INITIALIZED;
    // In split system user mode, the admin and primary flags are assigned to the first human
    // user.
    if (!UserManager.isSplitSystemUser()) {
        flags |= UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY;
    }
    // Create the system user
    UserInfo system = new UserInfo(UserHandle.USER_SYSTEM, null, null, flags);
    UserData userData = new UserData();
    userData.info = system;
    synchronized (mUsersLock) {
        mUsers.put(system.id, userData);
    }
    mNextSerialNumber = MIN_USER_ID;
    mUserVersion = USER_VERSION;

    Bundle restrictions = new Bundle();
    synchronized (mRestrictionsLock) {
        mBaseUserRestrictions.append(UserHandle.USER_SYSTEM, restrictions);
    }

    // 更新用户ID
    updateUserIds();
    // 初始化来宾账户的默认限制条件
    initDefaultGuestRestrictions();

    /*
     * 把用户信息写到 /data/system/users/${id}.xml文件中,简单的写文件,不再看源码
     * Writes the user file in this format:
     *
     * <user flags="20039023" id="0">
     *   <name>Primary</name>
     * </user>
     */
    writeUserLP(userData);
    /*
     * 把用户信息写到 /data/system/users/userlist.xml文件中
     * Writes the user list file in this format:
     *
     * <users nextSerialNumber="3">
     *   <user id="0"></user>
     *   <user id="2"></user>
     * </users>
     */
    writeUserListLP();
}

这样UserManagerService的初始化工作就完成了,主要的工作就是解析userlist.xml文件,并创建了mUsers列表中的UserData对象。

2.UserData的定义

private static class UserData {
    // Basic user information and properties
    UserInfo info;
    // Account name used when there is a strong association between a user and an account
    String account;
    // Account information for seeding into a newly created user. This could also be
    // used for login validation for an existing user, for updating their credentials.
    // In the latter case, data may not need to be persisted as it is only valid for the
    // current login session.
    String seedAccountName;
    String seedAccountType;
    PersistableBundle seedAccountOptions;
    // Whether to perist the seed account information to be available after a boot
    boolean persistSeedData;

    void clearSeedAccountData() {
        seedAccountName = null;
        seedAccountType = null;
        seedAccountOptions = null;
        persistSeedData = false;
    }
}


public class UserInfo implements Parcelable {

    /** 8 bits for user type 用户类型*/
    public static final int FLAG_MASK_USER_TYPE = 0x000000FF;

    /**
     * *************************** NOTE ***************************
     * These flag values CAN NOT CHANGE because they are written
     * directly to storage.
     */

    /**
     * Primary user. Only one user can have this flag set. It identifies the first human user
     * on a device.主用户标志,通常是第一个ID为0的用户
     */
    public static final int FLAG_PRIMARY = 0x00000001;

    /**
     * User with administrative privileges. Such a user can create and
     * delete users.admin用户标志,有此标志才有创建和删除用户的权限
     */
    public static final int FLAG_ADMIN   = 0x00000002;

    /**
     * Indicates a guest user that may be transient.guest用户标志
     */
    public static final int FLAG_GUEST   = 0x00000004;

    /**
     * Indicates the user has restrictions in privileges, in addition to those for normal users.
     * Exact meaning TBD. For instance, maybe they can't install apps or administer WiFi access pts.
	 * 标志权限受限的用户,具体受限功能未定
     */
    public static final int FLAG_RESTRICTED = 0x00000008;

    /**
     * Indicates that this user has gone through its first-time initialization.
	 * 标志该用户是否已经初始化
     */
    public static final int FLAG_INITIALIZED = 0x00000010;

    /**
     * Indicates that this user is a profile of another user, for example holding a users
     * corporate data.标志该UserInfo是另一个用户的profile
     */
    public static final int FLAG_MANAGED_PROFILE = 0x00000020;

    /**
     * Indicates that this user is disabled.标志该用户已被禁止
     *
     * <p>Note: If an ephemeral user is disabled, it shouldn't be later re-enabled. Ephemeral users
     * are disabled as their removal is in progress to indicate that they shouldn't be re-entered.
     */
    public static final int FLAG_DISABLED = 0x00000040;

    public static final int FLAG_QUIET_MODE = 0x00000080;

    /**
     * Indicates that this user is ephemeral. I.e. the user will be removed after leaving
     * the foreground.
     */
    public static final int FLAG_EPHEMERAL = 0x00000100;

    public static final int NO_PROFILE_GROUP_ID = UserHandle.USER_NULL;

    public int id; // 用户ID
    public int serialNumber; // 用户的序列号,不会重复
    public String name; // 用户名称
    public String iconPath; // 用户头像路径
    public int flags; // 用户标志
    public long creationTime; // 创建用户的时间
    public long lastLoggedInTime; // 最后一次登录的时间
    public String lastLoggedInFingerprint; // 最后一次用指纹登录的时间
    public int profileGroupId; // 用户profile的group ID
    public int restrictedProfileParentId;

    /** User is only partially created. */
    public boolean partial; // true表示该用户没有创建完成
    public boolean guestToRemove;
	...
}

3.添加用户

UserManagerService中添加用户的方法是createUser():

@Override
public UserInfo createUser(String name, int flags) {
    if (DBG) Slog.i(LOG_TAG, "createUser name " + name);
    // 检查添加用户的权限
    checkManageOrCreateUsersPermission(flags);
    return createUserInternal(name, flags, UserHandle.USER_NULL);
}

private UserInfo createUserInternal(String name, int flags, int parentId) {
    // 如果没有添加用户的权限则返回null
    if (hasUserRestriction(UserManager.DISALLOW_ADD_USER, UserHandle.getCallingUserId())) {
        Log.w(LOG_TAG, "Cannot add user. DISALLOW_ADD_USER is enabled.");
        return null;
    }
    return createUserInternalUnchecked(name, flags, parentId);
}

private UserInfo createUserInternalUnchecked(String name, int flags, int parentId) {
    // 如果是一个低内存设备,则返回null
    if (ActivityManager.isLowRamDeviceStatic()) {
        return null;
    }
    final boolean isGuest = (flags & UserInfo.FLAG_GUEST) != 0;
    final boolean isManagedProfile = (flags & UserInfo.FLAG_MANAGED_PROFILE) != 0;
    final boolean isRestricted = (flags & UserInfo.FLAG_RESTRICTED) != 0;
    final long ident = Binder.clearCallingIdentity();
    UserInfo userInfo;
    UserData userData;
    final int userId;
    try {
        synchronized (mPackagesLock) {
            UserData parent = null;
            if (parentId != UserHandle.USER_NULL) {
                synchronized (mUsersLock) {
		    // 根据userId获取UserData信息
                    parent = getUserDataLU(parentId);
                }
                if (parent == null) return null;
            }
	    // 判断是否可以添加更多profile
            if (isManagedProfile && !canAddMoreManagedProfiles(parentId, false)) {
                Log.e(LOG_TAG, "Cannot add more managed profiles for user " + parentId);
                return null;
            }
	    // 判断是否达到用户上限
            if (!isGuest && !isManagedProfile && isUserLimitReached()) {
                // If we're not adding a guest user or a managed profile and the limit has
                // been reached, cannot add a user.
                return null;
            }
            // If we're adding a guest and there already exists one, bail.
	    // 如果创建的是guest用户且guest用户已经存在则返回
            if (isGuest && findCurrentGuestUser() != null) {
                return null;
            }
            // In legacy mode, restricted profile's parent can only be the owner user
            if (isRestricted && !UserManager.isSplitSystemUser()
                    && (parentId != UserHandle.USER_SYSTEM)) {
                Log.w(LOG_TAG, "Cannot add restricted profile - parent user must be owner");
                return null;
            }
            if (isRestricted && UserManager.isSplitSystemUser()) {
                if (parent == null) {
                    Log.w(LOG_TAG, "Cannot add restricted profile - parent user must be "
                            + "specified");
                    return null;
                }
                if (!parent.info.canHaveProfile()) {
                    Log.w(LOG_TAG, "Cannot add restricted profile - profiles cannot be "
                            + "created for the specified parent user id " + parentId);
                    return null;
                }
            }
            if (!UserManager.isSplitSystemUser() && (flags & UserInfo.FLAG_EPHEMERAL) != 0) {
                Log.e(LOG_TAG,
                        "Ephemeral users are supported on split-system-user systems only.");
                return null;
            }
            // In split system user mode, we assign the first human user the primary flag.
            // And if there is no device owner, we also assign the admin flag to primary user.
            if (UserManager.isSplitSystemUser()
                    && !isGuest && !isManagedProfile && getPrimaryUser() == null) {
                flags |= UserInfo.FLAG_PRIMARY;
                synchronized (mUsersLock) {
                    if (!mIsDeviceManaged) {
                        flags |= UserInfo.FLAG_ADMIN;
                    }
                }
            }

	    // 获取下一个可用的userId
            userId = getNextAvailableId();
	    // 创建/data/system/users/userId文件夹
            Environment.getUserSystemDirectory(userId).mkdirs();
            boolean ephemeralGuests = Resources.getSystem()
                    .getBoolean(com.android.internal.R.bool.config_guestUserEphemeral);

            synchronized (mUsersLock) {
                // Add ephemeral flag to guests/users if required. Also inherit it from parent.
                if ((isGuest && ephemeralGuests) || mForceEphemeralUsers
                        || (parent != null && parent.info.isEphemeral())) {
                    flags |= UserInfo.FLAG_EPHEMERAL;
                }

		// 初始化新用户
                userInfo = new UserInfo(userId, name, null, flags);
                userInfo.serialNumber = mNextSerialNumber++;
                long now = System.currentTimeMillis();
                userInfo.creationTime = (now > EPOCH_PLUS_30_YEARS) ? now : 0;
		// 设置partial变量为true,表示用户还没有创建完成
                userInfo.partial = true;
                userInfo.lastLoggedInFingerprint = Build.FINGERPRINT;
                userData = new UserData();
                userData.info = userInfo;
                mUsers.put(userId, userData);
            }
	    // 保存用户信息
            writeUserLP(userData);
            writeUserListLP();
            if (parent != null) {
                if (isManagedProfile) {
                    if (parent.info.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID) {
                        parent.info.profileGroupId = parent.info.id;
                        writeUserLP(parent);
                    }
                    userInfo.profileGroupId = parent.info.profileGroupId;
                } else if (isRestricted) {
                    if (parent.info.restrictedProfileParentId == UserInfo.NO_PROFILE_GROUP_ID) {
                        parent.info.restrictedProfileParentId = parent.info.id;
                        writeUserLP(parent);
                    }
                    userInfo.restrictedProfileParentId = parent.info.restrictedProfileParentId;
                }
            }
        }
	// 为新建用户准备存储区域
        final StorageManager storage = mContext.getSystemService(StorageManager.class);
        storage.createUserKey(userId, userInfo.serialNumber, userInfo.isEphemeral());
        mPm.prepareUserData(userId, userInfo.serialNumber,
                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
	// 保存所有安装应用在新建用户目录下的安装状态
        mPm.createNewUser(userId);
	// 创建完新用户后修改partial变量为false,表示用户创建完成,并重新保存用户信息
        userInfo.partial = false;
        synchronized (mPackagesLock) {
            writeUserLP(userData);
        }
        updateUserIds();
        Bundle restrictions = new Bundle();
        if (isGuest) {
            synchronized (mGuestRestrictions) {
                restrictions.putAll(mGuestRestrictions);
            }
        }
        synchronized (mRestrictionsLock) {
            mBaseUserRestrictions.append(userId, restrictions);
        }
	// 发送成功添加新用户的广播
        Intent addedIntent = new Intent(Intent.ACTION_USER_ADDED);
        addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
        mContext.sendBroadcastAsUser(addedIntent, UserHandle.ALL,
                android.Manifest.permission.MANAGE_USERS);
        MetricsLogger.count(mContext, isGuest ? TRON_GUEST_CREATED : TRON_USER_CREATED, 1);
    } finally {
        Binder.restoreCallingIdentity(ident);
    }
    return userInfo;
}

// 根据userId获取UserData信息
private UserData getUserDataLU(int userId) {
    final UserData userData = mUsers.get(userId);
    // If it is partial and not in the process of being removed, return as unknown user.
    if (userData != null && userData.info.partial && !mRemovingUserIds.get(userId)) {
        return null;
    }
    return userData;
}


final Settings mSettings;

/** Called by UserManagerService */
// 保存所有安装应用在新建用户目录下的安装状态
void createNewUser(int userId) {
    synchronized (mInstallLock) {
	// 把所有已安装的应用数据拷贝到新建用户对应目录(/data/user/0/)下
        mSettings.createNewUserLI(this, mInstaller, userId);
    }
    synchronized (mPackages) {
	// 在/data/system/users/0/package-restrictions.xml文件中保存应用的限制信息
        scheduleWritePackageRestrictionsLocked(userId);
	// 更新/data/system/packages.list文件
        scheduleWritePackageListLocked(userId);
	// 保存默认浏览器应用,并更新/data/system/users/0/package-restrictions.xml文件
        applyFactoryDefaultBrowserLPw(userId);
	// 主要域名验证
        primeDomainVerificationsLPw(userId);
    }
}


/** Map from package name to settings 每个包名对应一个PackageSetting*/
final ArrayMap<String, PackageSetting> mPackages = new ArrayMap<>();

// 把所有已安装的系统应用数据拷贝到新建用户对应目录下
void createNewUserLI(@NonNull PackageManagerService service, @NonNull Installer installer,
        int userHandle) {
    String[] volumeUuids;
    String[] names;
    int[] appIds;
    String[] seinfos;
    int[] targetSdkVersions;
    int packagesCount;
    synchronized (mPackages) {
	// 从map中获取出所有的settings
        Collection<PackageSetting> packages = mPackages.values();
        packagesCount = packages.size();
        volumeUuids = new String[packagesCount];
        names = new String[packagesCount];
        appIds = new int[packagesCount];
        seinfos = new String[packagesCount];
        targetSdkVersions = new int[packagesCount];
        Iterator<PackageSetting> packagesIterator = packages.iterator();
	// 遍历所有的PackageSetting
        for (int i = 0; i < packagesCount; i++) {
            PackageSetting ps = packagesIterator.next();
            if (ps.pkg == null || ps.pkg.applicationInfo == null) {
                continue;
            }
            // Only system apps are initially installed.初始化时只安装系统应用
            /** M: [Operator] Operator package should also be installed @{ */
            boolean curInstalledStatus = ps.isSystem()
                                || (ps.pkgFlagsEx & ApplicationInfo.FLAG_EX_OPERATOR) != 0;
	    // 设置每一个应用在新创建用户下的安装状态,系统应用为true
            ps.setInstalled(curInstalledStatus, userHandle);
            /** @} */
            // Need to create a data directory for all apps under this user. Accumulate all
            // required args and call the installer after mPackages lock has been released
            volumeUuids[i] = ps.volumeUuid;
            names[i] = ps.name;
            appIds[i] = ps.appId;
            seinfos[i] = ps.pkg.applicationInfo.seinfo;
            targetSdkVersions[i] = ps.pkg.applicationInfo.targetSdkVersion;
        }
    }
    for (int i = 0; i < packagesCount; i++) {
        if (names[i] == null) {
            continue;
        }
        // TODO: triage flags!
        final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE;
        try {
	    // 在新建用户目录(/data/user/0/)下创建每个应用的数据目录(包名命名的文件夹)
            installer.createAppData(volumeUuids[i], names[i], userHandle, flags, appIds[i],
                    seinfos[i], targetSdkVersions[i]);
        } catch (InstallerException e) {
            Slog.w(TAG, "Failed to prepare app data", e);
        }
    }
    synchronized (mPackages) {
	// 解析"etc/preferred-apps"目录下所有XML文件,XML文件中保存的是设备使用者指定的响应某个Intent
	// 的最合适的组件信息
        applyDefaultPreferredAppsLPw(service, userHandle);
    }
}

4.删除用户

/**
 * Removes a user and all data directories created for that user. This method should be called
 * after the user's processes have been terminated.
 * @param userHandle the user's id
 */
@Override
public boolean removeUser(int userHandle) {
    // 检查调用者是否有删除用户的权限
    checkManageOrCreateUsersPermission("Only the system can remove users");
    if (getUserRestrictions(UserHandle.getCallingUserId()).getBoolean(
            UserManager.DISALLOW_REMOVE_USER, false)) {
        Log.w(LOG_TAG, "Cannot remove user. DISALLOW_REMOVE_USER is enabled.");
        return false;
    }

    long ident = Binder.clearCallingIdentity();
    try {
        final UserData userData;
        int currentUser = ActivityManager.getCurrentUser();
        if (currentUser == userHandle) {
            Log.w(LOG_TAG, "Current user cannot be removed");
            return false;
        }
        synchronized (mPackagesLock) {
            synchronized (mUsersLock) {
                userData = mUsers.get(userHandle);
                if (userHandle == 0 || userData == null || mRemovingUserIds.get(userHandle)) {
                    return false;
                }

                // We remember deleted user IDs to prevent them from being
                // reused during the current boot; they can still be reused
                // after a reboot.保存要删除的userId,防止重复删除
                mRemovingUserIds.put(userHandle, true);
            }

            try {
                mAppOpsService.removeUser(userHandle);
            } catch (RemoteException e) {
                Log.w(LOG_TAG, "Unable to notify AppOpsService of removing user", e);
            }
            // Set this to a partially created user, so that the user will be purged
            // on next startup, in case the runtime stops now before stopping and
            // removing the user completely.
	    // 删除用户并没有删除相关用户文件,只是把partial变量修改为true,
	    // 开机后如果该变量还是true会删除相关文件
            userData.info.partial = true;
            // Mark it as disabled, so that it isn't returned any more when
            // profiles are queried.
            userData.info.flags |= UserInfo.FLAG_DISABLED;
	    // 更新/data/system/users/${id}.xml文件
            writeUserLP(userData);
        }

        if (userData.info.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID
                && userData.info.isManagedProfile()) {
            // Send broadcast to notify system that the user removed was a
            // managed user.发送删除用户的广播
            sendProfileRemovedBroadcast(userData.info.profileGroupId, userData.info.id);
        }

        if (DBG) Slog.i(LOG_TAG, "Stopping user " + userHandle);
        int res;
        try {
	    // 停止正在运行的用户
            res = ActivityManagerNative.getDefault().stopUser(userHandle, /* force= */ true,
            new IStopUserCallback.Stub() {
                        @Override
                        public void userStopped(int userId) {
			    // 删除用户相关应用信息
                            finishRemoveUser(userId);
                        }
                        @Override
                        public void userStopAborted(int userId) {
                        }
                    });
        } catch (RemoteException e) {
            return false;
        }
        return res == ActivityManager.USER_OP_SUCCESS;
    } finally {
        Binder.restoreCallingIdentity(ident);
    }
}

5.多用户管理

UserManagerService主要管理用户的账号信息,运行中的用户管理由ActivityManagerService来负责。
用户的状态有5种,定义在UserState类中:

public final class UserState {
    // User is first coming up.启动中
    public final static int STATE_BOOTING = 0;
    // User is in the locked state.锁定
    public final static int STATE_RUNNING_LOCKED = 1;
    // User is in the unlocking state.未锁定
    public final static int STATE_RUNNING_UNLOCKING = 2;
    // User is in the running state.运行中
    public final static int STATE_RUNNING_UNLOCKED = 3;
    // User is in the initial process of being stopped.停止的初始过程中
    public final static int STATE_STOPPING = 4;
    // User is in the final phase of stopping, sending Intent.ACTION_SHUTDOWN.停止的最后阶段
    public final static int STATE_SHUTDOWN = 5;
	...
}

@Override
public boolean switchUser(final int targetUserId) {
    // 检查调用者是否有切换用户的权限
    enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
    UserInfo currentUserInfo;
    UserInfo targetUserInfo;
    synchronized (this) {
	// 获取当用用户的相关信息
        int currentUserId = mUserController.getCurrentUserIdLocked();
        currentUserInfo = mUserController.getUserInfo(currentUserId);
	// 获取切换目标用户的相关信息
        targetUserInfo = mUserController.getUserInfo(targetUserId);
        if (targetUserInfo == null) {
            Slog.w(TAG, "No user info for user #" + targetUserId);
            return false;
        }
	// 如果目标用户不支持切换,则返回
        if (!targetUserInfo.supportsSwitchTo()) {
            Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
            return false;
        }
	// 如果目标用户是另一个用户的profile,则返回
        if (targetUserInfo.isManagedProfile()) {
            Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
            return false;
        }
        mUserController.setTargetUserIdLocked(targetUserId);
    }
    // 发送切换用户的消息
    Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
    mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
    mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
    return true;
}

final class UiHandler extends Handler {
    public UiHandler() {
        super(com.android.server.UiThread.get().getLooper(), null, true);
    }

    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
			...
			case START_USER_SWITCH_UI_MSG: {
				mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
				break;
			}
			...
        }
    }
}

void showUserSwitchDialog(Pair<UserInfo, UserInfo> fromToUserPair) {
    // The dialog will show and then initiate the user switch by calling startUserInForeground
    Dialog d = new UserSwitchingDialog(mService, mService.mContext, fromToUserPair.first,
            fromToUserPair.second, true /* above system */);
    d.show();
}

@Override
public void show() {
    // Slog.v(TAG, "show called");
    super.show();
    final View decorView = getWindow().getDecorView();
    if (decorView != null) {
        decorView.getViewTreeObserver().addOnWindowShownListener(this);
    }
    // Add a timeout as a safeguard, in case a race in screen on/off causes the window
    // callback to never come.
    mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_START_USER),
            WINDOW_SHOWN_TIMEOUT_MS);
}

private final Handler mHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case MSG_START_USER:
		// 调用startUser()方法
                startUser();
                break;
        }
    }
};


void startUser() {
    synchronized (this) {
        if (!mStartedUser) {
	    // 调用startUserInForeground方法
            mService.mUserController.startUserInForeground(mUserId, this);
            mStartedUser = true;
            final View decorView = getWindow().getDecorView();
            if (decorView != null) {
                decorView.getViewTreeObserver().removeOnWindowShownListener(this);
            }
            mHandler.removeMessages(MSG_START_USER);
        }
    }
}

/**
 * Start user, if its not already running, and bring it to foreground.
 * 开启用户,如果用户没有在运行,则开启它
 */
boolean startUserInForeground(final int userId, Dialog dlg) {
    boolean result = startUser(userId, /* foreground */ true);
    dlg.dismiss();
    return result;
}

/**
 * Start user, if its not already running.
 * <p>The user will be brought to the foreground, if {@code foreground} parameter is set.
 * When starting the user, multiple intents will be broadcast in the following order:</p>
 * <ul>
 *     <li>{@link Intent#ACTION_USER_STARTED} - sent to registered receivers of the new user
 *     <li>{@link Intent#ACTION_USER_BACKGROUND} - sent to registered receivers of the outgoing
 *     user and all profiles of this user. Sent only if {@code foreground} parameter is true
 *     <li>{@link Intent#ACTION_USER_FOREGROUND} - sent to registered receivers of the new
 *     user and all profiles of this user. Sent only if {@code foreground} parameter is true
 *     <li>{@link Intent#ACTION_USER_SWITCHED} - sent to registered receivers of the new user.
 *     Sent only if {@code foreground} parameter is true
 *     <li>{@link Intent#ACTION_USER_STARTING} - ordered broadcast sent to registered receivers
 *     of the new fg user
 *     <li>{@link Intent#ACTION_LOCKED_BOOT_COMPLETED} - ordered broadcast sent to receivers of
 *     the new user
 *     <li>{@link Intent#ACTION_USER_UNLOCKED} - sent to registered receivers of the new user
 *     <li>{@link Intent#ACTION_PRE_BOOT_COMPLETED} - ordered broadcast sent to receivers of the
 *     new user. Sent only when the user is booting after a system update.
 *     <li>{@link Intent#ACTION_USER_INITIALIZE} - ordered broadcast sent to receivers of the
 *     new user. Sent only the first time a user is starting.
 *     <li>{@link Intent#ACTION_BOOT_COMPLETED} - ordered broadcast sent to receivers of the new
 *     user. Indicates that the user has finished booting.
 * </ul>
 *
 * @param userId ID of the user to start
 * @param foreground true if user should be brought to the foreground
 * @return true if the user has been successfully started
 */
boolean startUser(final int userId, final boolean foreground) {
    // 检查调用者权限
    if (mService.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
            != PackageManager.PERMISSION_GRANTED) {
        String msg = "Permission Denial: switchUser() from pid="
                + Binder.getCallingPid()
                + ", uid=" + Binder.getCallingUid()
                + " requires " + INTERACT_ACROSS_USERS_FULL;
        Slog.w(TAG, msg);
        throw new SecurityException(msg);
    }

    Slog.i(TAG, "Starting userid:" + userId + " fg:" + foreground);

    final long ident = Binder.clearCallingIdentity();
    try {
        synchronized (mService) {
            final int oldUserId = mCurrentUserId;
	    // 如果要开启的用户已经存在,则直接返回true
            if (oldUserId == userId) {
                return true;
            }

            mService.mStackSupervisor.setLockTaskModeLocked(null,
                    ActivityManager.LOCK_TASK_MODE_NONE, "startUser", false);

	    // 获取目标用户的相关信息
            final UserInfo userInfo = getUserInfo(userId);
            if (userInfo == null) {
                Slog.w(TAG, "No user info for user #" + userId);
                return false;
            }
            if (foreground && userInfo.isManagedProfile()) {
                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
                return false;
            }

	    // 如果要把用户切到前台,则播放动画
            if (foreground) {
                mService.mWindowManager.startFreezingScreen(
                        R.anim.screen_user_exit, R.anim.screen_user_enter);
            }

            boolean needStart = false;

            // If the user we are switching to is not currently started, then
            // we need to start it now.如果目标用户不存在,则修改用户状态为正在开启
	    // UserState的状态默认值是STATE_BOOTING
            if (mStartedUsers.get(userId) == null) {
                UserState userState = new UserState(UserHandle.of(userId));
                mStartedUsers.put(userId, userState);
                getUserManagerInternal().setUserState(userId, userState.state);
		// 根据用户状态更新已经开启的用户列表
                updateStartedUserArrayLocked();
                needStart = true;
            }

            final UserState uss = mStartedUsers.get(userId);
            final Integer userIdInt = userId;
            mUserLru.remove(userIdInt);
	    // 调整用户在mUserLru中的位置,当前用户位于末尾
            mUserLru.add(userIdInt);

            if (foreground) {
		// 修改当前用户的Id
                mCurrentUserId = userId;
		// 更新用户配置信息
                mService.updateUserConfigurationLocked();
                mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
		// 更新与当前用户相关的用户列表
                updateCurrentProfileIdsLocked();
                mService.mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
                // Once the internal notion of the active user has switched, we lock the device
                // with the option to show the user switcher on the keyguard.
                mService.mWindowManager.lockNow(null);
            } else {
                final Integer currentUserIdInt = mCurrentUserId;
		// 更新与当前用户相关的用户列表
                updateCurrentProfileIdsLocked();
                mService.mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
                mUserLru.remove(currentUserIdInt);
                mUserLru.add(currentUserIdInt);
            }

            // Make sure user is in the started state.  If it is currently
            // stopping, we need to knock that off.确保用户处于启动状态,如果处于
	    // 停止的初始阶段,则中止它。如果已经发送过停止运行的广播,则重新设置用户的状态
            if (uss.state == UserState.STATE_STOPPING) {
                // If we are stopping, we haven't sent ACTION_SHUTDOWN,
                // so we can just fairly silently bring the user back from
                // the almost-dead.
                uss.setState(uss.lastState);
                getUserManagerInternal().setUserState(userId, uss.state);
		// 根据用户状态更新已经开启的用户列表
                updateStartedUserArrayLocked();
                needStart = true;
            } else if (uss.state == UserState.STATE_SHUTDOWN) {
                // This means ACTION_SHUTDOWN has been sent, so we will
                // need to treat this as a new boot of the user.
                uss.setState(UserState.STATE_BOOTING);
                getUserManagerInternal().setUserState(userId, uss.state);
		// 根据用户状态更新已经开启的用户列表
                updateStartedUserArrayLocked();
                needStart = true;
            }

            if (uss.state == UserState.STATE_BOOTING) {
                // Give user manager a chance to propagate user restrictions
                // to other services and prepare app storage
		// 在用户启动之前,先准备相关用户的限制及存储
                getUserManager().onBeforeStartUser(userId);

                // Booting up a new user, need to tell system services about it.
                // Note that this is on the same handler as scheduling of broadcasts,
                // which is important because it needs to go first.
                mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
            }

            if (foreground) {
		// 发送相关消息
                mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
                        oldUserId));
                mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
                mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
                mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
                        oldUserId, userId, uss));
                mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
                        oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
            }

            if (needStart) {
                // Send USER_STARTED broadcast 如果需要开启用户,则发送相应广播
		// 用户切换牵扯到很多模块,如壁纸管理、输入法、账号管理等,都需要收到通知
                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
                        | Intent.FLAG_RECEIVER_FOREGROUND);
                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
                mService.broadcastIntentLocked(null, null, intent,
                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
                        null, false, false, MY_PID, SYSTEM_UID, userId);
            }

            if (foreground) {
		// 把开启的用户设为前台用户
                moveUserToForegroundLocked(uss, oldUserId, userId);
            } else {
		// 用户启动结束,则切换用户到STATE_RUNNING_LOCKED状态
                mService.mUserController.finishUserBoot(uss);
            }

            if (needStart) {
		// 如果需要开启用户,则发送相应广播
                Intent intent = new Intent(Intent.ACTION_USER_STARTING);
                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
                mService.broadcastIntentLocked(null, null, intent,
                        null, new IIntentReceiver.Stub() {
                            @Override
                            public void performReceive(Intent intent, int resultCode,
                                    String data, Bundle extras, boolean ordered, boolean sticky,
                                    int sendingUser) throws RemoteException {
                            }
                        }, 0, null, null,
                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
                        null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
            }
        }
    } finally {
        Binder.restoreCallingIdentity(ident);
    }

    return true;
}

// 根据用户状态更新已经开启的用户列表mStartedUserArray
private void updateStartedUserArrayLocked() {
    int num = 0;
    for (int i = 0; i < mStartedUsers.size(); i++) {
        UserState uss = mStartedUsers.valueAt(i);
        // This list does not include stopping users.
        if (uss.state != UserState.STATE_STOPPING
                && uss.state != UserState.STATE_SHUTDOWN) {
            num++;
        }
    }
    mStartedUserArray = new int[num];
    num = 0;
    for (int i = 0; i < mStartedUsers.size(); i++) {
        UserState uss = mStartedUsers.valueAt(i);
        if (uss.state != UserState.STATE_STOPPING
                && uss.state != UserState.STATE_SHUTDOWN) {
            mStartedUserArray[num++] = mStartedUsers.keyAt(i);
        }
    }
}


发送的msg消息是在ActivityManagerService中处理的:
final class UiHandler extends Handler {
    public UiHandler() {
        super(com.android.server.UiThread.get().getLooper(), null, true);
    }

    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
		...
		case SYSTEM_USER_START_MSG: {
            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
                    Integer.toString(msg.arg1), msg.arg1);
	    // 新建用户时调用
            mSystemServiceManager.startUser(msg.arg1);
            break;
        }
		case SYSTEM_USER_CURRENT_MSG: {
            mBatteryStatsService.noteEvent(
                    BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
                    Integer.toString(msg.arg2), msg.arg2);
            mBatteryStatsService.noteEvent(
                    BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
                    Integer.toString(msg.arg1), msg.arg1);
	    // 切换用户时调用
            mSystemServiceManager.switchUser(msg.arg1);
            break;
        }
		case REPORT_USER_SWITCH_MSG: {
            mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
            break;
        }
		case CONTINUE_USER_SWITCH_MSG: {
            mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
            break;
        }
        case USER_SWITCH_TIMEOUT_MSG: {
            mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
            break;
        }
		case REPORT_USER_SWITCH_COMPLETE_MSG: {
            mUserController.dispatchUserSwitchComplete(msg.arg1);
			break;
        } 
		...
    }
};

// 该方法主要是调用mUserSwitchObservers列表中的IUserSwitchObserver对象的onUserSwitching方法
// 如果想知道用户切换,可以调用AMS的registerUserSwitchObserver()方法来注册一个观察者对象
void dispatchUserSwitch(final UserState uss, final int oldUserId, final int newUserId) {
    Slog.d(TAG, "Dispatch onUserSwitching oldUser #" + oldUserId + " newUser #" + newUserId);
    // 获取所有注册回调方法的总数
    final int observerCount = mUserSwitchObservers.beginBroadcast();
    if (observerCount > 0) {
        final IRemoteCallback callback = new IRemoteCallback.Stub() {
            int mCount = 0;
            @Override
            public void sendResult(Bundle data) throws RemoteException {
                synchronized (mService) {
                    if (mCurUserSwitchCallback == this) {
			// 收到一条回调,就加一
                        mCount++;
			// 所有注册的回调方法都执行了,发送继续处理的消息
                        if (mCount == observerCount) {
                            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
                        }
                    }
                }
            }
        };
        synchronized (mService) {
            uss.switching = true;
            mCurUserSwitchCallback = callback;
        }
	// 遍历调用所有注册回调对象的onUserSwitching方法
        for (int i = 0; i < observerCount; i++) {
            try {
                mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
                        newUserId, callback);
            } catch (RemoteException e) {
            }
        }
    } else {
        synchronized (mService) {
	    // 如果没有注册回调方法的,直接调用继续执行用户切换的方法
            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
        }
    }
    mUserSwitchObservers.finishBroadcast();
}

void sendContinueUserSwitchLocked(UserState uss, int oldUserId, int newUserId) {
    mCurUserSwitchCallback = null;
    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
    mHandler.sendMessage(mHandler.obtainMessage(ActivityManagerService.CONTINUE_USER_SWITCH_MSG,
            oldUserId, newUserId, uss));
}

void continueUserSwitch(UserState uss, int oldUserId, int newUserId) {
    Slog.d(TAG, "Continue user switch oldUser #" + oldUserId + ", newUser #" + newUserId);
    synchronized (mService) {
        mService.mWindowManager.stopFreezingScreen();
    }
    uss.switching = false;
    // 发送完成切换用户的消息
    mHandler.removeMessages(REPORT_USER_SWITCH_COMPLETE_MSG);
    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_COMPLETE_MSG,
            newUserId, 0));
    // 停止切换到后台的Guest或临时用户
    stopGuestOrEphemeralUserIfBackground();
    // 强制停止后台用户
    stopBackgroundUsersIfEnforced(oldUserId);
}

/** Called on handler thread */
void dispatchUserSwitchComplete(int userId) {
    final int observerCount = mUserSwitchObservers.beginBroadcast();
    for (int i = 0; i < observerCount; i++) {
        try {
	    // 遍历调用所有观察者的onUserSwitchComplete方法
            mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(userId);
        } catch (RemoteException e) {
        }
    }
    mUserSwitchObservers.finishBroadcast();
}

/**
 * Stops the guest or ephemeral user if it has gone to the background.
 * 停止切换到后台的Guest或临时用户
 */
private void stopGuestOrEphemeralUserIfBackground() {
    synchronized (mService) {
        final int num = mUserLru.size();
        for (int i = 0; i < num; i++) {
            Integer oldUserId = mUserLru.get(i);
            UserState oldUss = mStartedUsers.get(oldUserId);
            if (oldUserId == UserHandle.USER_SYSTEM || oldUserId == mCurrentUserId
                    || oldUss.state == UserState.STATE_STOPPING
                    || oldUss.state == UserState.STATE_SHUTDOWN) {
                continue;
            }
            UserInfo userInfo = getUserInfo(oldUserId);
            if (userInfo.isEphemeral()) {
                LocalServices.getService(UserManagerInternal.class)
                        .onEphemeralUserStop(oldUserId);
            }
            if (userInfo.isGuest() || userInfo.isEphemeral()) {
                // This is a user to be stopped.
                stopUsersLocked(oldUserId, true, null);
                break;
            }
        }
    }
}

// 强制停止后台用户
private void stopBackgroundUsersIfEnforced(int oldUserId) {
    // Never stop system user
    if (oldUserId == UserHandle.USER_SYSTEM) {
        return;
    }
    // For now, only check for user restriction. Additional checks can be added here
    boolean disallowRunInBg = hasUserRestriction(UserManager.DISALLOW_RUN_IN_BACKGROUND,
            oldUserId);
    if (!disallowRunInBg) {
        return;
    }
    synchronized (mService) {
        if (DEBUG_MU) Slog.i(TAG, "stopBackgroundUsersIfEnforced stopping " + oldUserId
                + " and related users");
        stopUsersLocked(oldUserId, false, null);
    }
}

void timeoutUserSwitch(UserState uss, int oldUserId, int newUserId) {
    synchronized (mService) {
        /// M: Change Slog.wtf to Slog.w to avoid having WTF easily after adding new user
        Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
        sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
    }
}

Activity进入Idle状态时会调用activityIdleInternalLocked方法,该方法中会修改用户的状态到STATE_RUNNING_LOCKED状态

    原文作者:Android源码分析
    原文地址: https://blog.csdn.net/zhangyongfeiyong/article/details/77947206
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞