Android多用户之UserManagerService源码分析

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

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

管理用户的系统服务--UserManagerService

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

final ArrayMap mPackages =
            new ArrayMap();

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文件的内容,再分析读取过程,文件内容如下:



    
        
    
    

// 从/data/system/users/userlist.xml文件读取用户信息
private final SparseArray 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:
     *
     * 
     *   Primary
     * 
     */
    writeUserLP(userData);
    /*
     * 把用户信息写到 /data/system/users/userlist.xml文件中
     * Writes the user list file in this format:
     *
     * 
     *   
     *   
     * 
     */
    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.标志该用户已被禁止
     *
     * 

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 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 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 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 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) msg.obj);
				break;
			}
			...
        }
    }
}

void showUserSwitchDialog(Pair 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.
 * 

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:

*
    *
  • {@link Intent#ACTION_USER_STARTED} - sent to registered receivers of the new user *
  • {@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 *
  • {@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 *
  • {@link Intent#ACTION_USER_SWITCHED} - sent to registered receivers of the new user. * Sent only if {@code foreground} parameter is true *
  • {@link Intent#ACTION_USER_STARTING} - ordered broadcast sent to registered receivers * of the new fg user *
  • {@link Intent#ACTION_LOCKED_BOOT_COMPLETED} - ordered broadcast sent to receivers of * the new user *
  • {@link Intent#ACTION_USER_UNLOCKED} - sent to registered receivers of the new user *
  • {@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. *
  • {@link Intent#ACTION_USER_INITIALIZE} - ordered broadcast sent to receivers of the * new user. Sent only the first time a user is starting. *
  • {@link Intent#ACTION_BOOT_COMPLETED} - ordered broadcast sent to receivers of the new * user. Indicates that the user has finished booting. *
* * @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)