Android多用户之UserManagerService源码分析

2024-06-05 16:18

本文主要是介绍Android多用户之UserManagerService源码分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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

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

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

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

[java]  view plain  copy
  1. final ArrayMap<String, PackageParser.Package> mPackages =  
  2.             new ArrayMap<String, PackageParser.Package>();  
  3.   
  4. public PackageManagerService(Context context, Installer installer,  
  5.         boolean factoryTest, boolean onlyCore) {  
  6.     ...  
  7.     synchronized (mInstallLock) {  
  8.         // writer  
  9.         synchronized (mPackages) {  
  10.             ...  
  11.             sUserManager = new UserManagerService(context, this, mPackages);  
  12.             ...  
  13.         } // synchronized (mPackages)  
  14.     } // synchronized (mInstallLock)  
  15.     ...  
  16. }  
  17.   
  18. @Override  
  19. public void systemReady() {  
  20.     ...  
  21.     sUserManager.systemReady();  
  22.     ...  
  23. }  

UserManagerService的构造方法如下:

[java]  view plain  copy
  1. UserManagerService(Context context, PackageManagerService pm, Object packagesLock) {  
  2.     this(context, pm, packagesLock, Environment.getDataDirectory());  
  3. }  

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

[java]  view plain  copy
  1. private static final String USER_INFO_DIR = "system" + File.separator + "users";  
  2.   
  3. private UserManagerService(Context context, PackageManagerService pm,  
  4.         Object packagesLock, File dataDir) {  
  5.     mContext = context;  
  6.     mPm = pm;  
  7.     mPackagesLock = packagesLock;  
  8.     mHandler = new MainHandler();  
  9.     synchronized (mPackagesLock) {  
  10.     // /data/system/users  
  11.         mUsersDir = new File(dataDir, USER_INFO_DIR);  
  12.         mUsersDir.mkdirs();  
  13.         // Make zeroth user directory, for services to migrate their files to that location  
  14.         File userZeroDir = new File(mUsersDir, String.valueOf(UserHandle.USER_SYSTEM));  
  15.     // 创建第一个用户目录:/data/system/users/0  
  16.         userZeroDir.mkdirs();  
  17.     // 设置访问文件的权限  
  18.         FileUtils.setPermissions(mUsersDir.toString(),  
  19.                 FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IROTH | FileUtils.S_IXOTH,  
  20.                 -1, -1);  
  21.     // /data/system/users/userlist.xml  
  22.         mUserListFile = new File(mUsersDir, USER_LIST_FILENAME);  
  23.     // 初始化来宾账户的默认限制条件  
  24.         initDefaultGuestRestrictions();  
  25.     // 从/data/system/users/userlist.xml文件读取用户信息  
  26.         readUserListLP();  
  27.         sInstance = this;  
  28.     }  
  29.     mLocalService = new LocalService();  
  30.     LocalServices.addService(UserManagerInternal.class, mLocalService);  
  31.     mLockPatternUtils = new LockPatternUtils(mContext);  
  32.     mUserStates.put(UserHandle.USER_SYSTEM, UserState.STATE_BOOTING);  
  33. }  
  34.   
  35. private final Bundle mGuestRestrictions = new Bundle();  
  36.   
  37. // 初始化来宾账户的默认限制条件  
  38. private void initDefaultGuestRestrictions() {  
  39.     synchronized (mGuestRestrictions) {  
  40.         if (mGuestRestrictions.isEmpty()) {  
  41.         // "no_config_wifi",不允许配置WiFi  
  42.             mGuestRestrictions.putBoolean(UserManager.DISALLOW_CONFIG_WIFI, true);  
  43.         // "no_install_unknown_sources",不允许安装未知来源的应用  
  44.             mGuestRestrictions.putBoolean(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, true);  
  45.         // "no_outgoing_calls",不允许呼叫电话  
  46.             mGuestRestrictions.putBoolean(UserManager.DISALLOW_OUTGOING_CALLS, true);  
  47.         // "no_sms",不允许收发短信  
  48.             mGuestRestrictions.putBoolean(UserManager.DISALLOW_SMS, true);  
  49.         }  
  50.     }  
  51. }  

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

[html]  view plain  copy
  1. <?xml version='1.0' encoding='utf-8' standalone='yes' ?>  
  2. <users nextSerialNumber="10" version="5">  
  3.     <guestRestrictions>  
  4.         <restrictions no_config_wifi="true" no_outgoing_calls="true" no_sms="true" />  
  5.     </guestRestrictions>  
  6.     <user id="0" />  
  7. </users>  

[java]  view plain  copy
  1. // 从/data/system/users/userlist.xml文件读取用户信息  
  2. private final SparseArray<UserData> mUsers = new SparseArray<>();  
  3.   
  4. private void readUserListLP() {  
  5.     // 如果文件不存在,则创建管理员用户并返回  
  6.     if (!mUserListFile.exists()) {  
  7.         fallbackToSingleUserLP();  
  8.         return;  
  9.     }  
  10.     FileInputStream fis = null;  
  11.     AtomicFile userListFile = new AtomicFile(mUserListFile);  
  12.     try {  
  13.         fis = userListFile.openRead();  
  14.         XmlPullParser parser = Xml.newPullParser();  
  15.         parser.setInput(fis, StandardCharsets.UTF_8.name());  
  16.         int type;  
  17.         while ((type = parser.next()) != XmlPullParser.START_TAG  
  18.                 && type != XmlPullParser.END_DOCUMENT) {  
  19.             // Skip  
  20.         }  
  21.   
  22.         if (type != XmlPullParser.START_TAG) {  
  23.             Slog.e(LOG_TAG, "Unable to read user list");  
  24.         // 如果文件异常,则创建管理员用户并返回  
  25.             fallbackToSingleUserLP();  
  26.             return;  
  27.         }  
  28.   
  29.         mNextSerialNumber = -1;  
  30.     // 解析文件  
  31.         if (parser.getName().equals(TAG_USERS)) {  
  32.             String lastSerialNumber = parser.getAttributeValue(null, ATTR_NEXT_SERIAL_NO);  
  33.             if (lastSerialNumber != null) {  
  34.                 mNextSerialNumber = Integer.parseInt(lastSerialNumber);  
  35.             }  
  36.             String versionNumber = parser.getAttributeValue(null, ATTR_USER_VERSION);  
  37.             if (versionNumber != null) {  
  38.                 mUserVersion = Integer.parseInt(versionNumber);  
  39.             }  
  40.         }  
  41.   
  42.         final Bundle newDevicePolicyGlobalUserRestrictions = new Bundle();  
  43.   
  44.         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {  
  45.             if (type == XmlPullParser.START_TAG) {  
  46.                 final String name = parser.getName();  
  47.                 if (name.equals(TAG_USER)) {  
  48.                     String id = parser.getAttributeValue(null, ATTR_ID);  
  49.   
  50.             // 初始化UserData对象保存从 /data/system/users/${id}.xml 文件中读取到的用户信息  
  51.                     UserData userData = readUserLP(Integer.parseInt(id));  
  52.   
  53.                     if (userData != null) {  
  54.                         synchronized (mUsersLock) {  
  55.                 // 把解析到的用户信息保存到mUsers中  
  56.                             mUsers.put(userData.info.id, userData);  
  57.                             if (mNextSerialNumber < 0  
  58.                                     || mNextSerialNumber <= userData.info.id) {  
  59.                                 mNextSerialNumber = userData.info.id + 1;  
  60.                             }  
  61.                         }  
  62.                     }  
  63.                 } else if (name.equals(TAG_GUEST_RESTRICTIONS)) {  
  64.                     while ((type = parser.next()) != XmlPullParser.END_DOCUMENT  
  65.                             && type != XmlPullParser.END_TAG) {  
  66.                         if (type == XmlPullParser.START_TAG) {  
  67.                             if (parser.getName().equals(TAG_RESTRICTIONS)) {  
  68.                                 synchronized (mGuestRestrictions) {  
  69.                                     UserRestrictionsUtils  
  70.                                             .readRestrictions(parser, mGuestRestrictions);  
  71.                                 }  
  72.                             } else if (parser.getName().equals(TAG_DEVICE_POLICY_RESTRICTIONS)  
  73.                                     ) {  
  74.                                 UserRestrictionsUtils.readRestrictions(parser,  
  75.                                         newDevicePolicyGlobalUserRestrictions);  
  76.                             }  
  77.                             break;  
  78.                         }  
  79.                     }  
  80.                 } else if (name.equals(TAG_GLOBAL_RESTRICTION_OWNER_ID)) {  
  81.                     String ownerUserId = parser.getAttributeValue(null, ATTR_ID);  
  82.                     if (ownerUserId != null) {  
  83.                         mGlobalRestrictionOwnerUserId = Integer.parseInt(ownerUserId);  
  84.                     }  
  85.                 }  
  86.             }  
  87.         }  
  88.         synchronized (mRestrictionsLock) {  
  89.             mDevicePolicyGlobalUserRestrictions = newDevicePolicyGlobalUserRestrictions;  
  90.         }  
  91.     // 解析完文件后,更新用户ID  
  92.         updateUserIds();  
  93.     // 如果有必要,则升级Version  
  94.         upgradeIfNecessaryLP();  
  95.     } catch (IOException | XmlPullParserException e) {  
  96.         fallbackToSingleUserLP();  
  97.     } finally {  
  98.         IoUtils.closeQuietly(fis);  
  99.     }  
  100. }  
  101.   
  102. // 创建管理员用户  
  103. private void fallbackToSingleUserLP() {  
  104.     int flags = UserInfo.FLAG_INITIALIZED;  
  105.     // In split system user mode, the admin and primary flags are assigned to the first human  
  106.     // user.  
  107.     if (!UserManager.isSplitSystemUser()) {  
  108.         flags |= UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY;  
  109.     }  
  110.     // Create the system user  
  111.     UserInfo system = new UserInfo(UserHandle.USER_SYSTEM, nullnull, flags);  
  112.     UserData userData = new UserData();  
  113.     userData.info = system;  
  114.     synchronized (mUsersLock) {  
  115.         mUsers.put(system.id, userData);  
  116.     }  
  117.     mNextSerialNumber = MIN_USER_ID;  
  118.     mUserVersion = USER_VERSION;  
  119.   
  120.     Bundle restrictions = new Bundle();  
  121.     synchronized (mRestrictionsLock) {  
  122.         mBaseUserRestrictions.append(UserHandle.USER_SYSTEM, restrictions);  
  123.     }  
  124.   
  125.     // 更新用户ID  
  126.     updateUserIds();  
  127.     // 初始化来宾账户的默认限制条件  
  128.     initDefaultGuestRestrictions();  
  129.   
  130.     /* 
  131.      * 把用户信息写到 /data/system/users/${id}.xml文件中,简单的写文件,不再看源码 
  132.      * Writes the user file in this format: 
  133.      * 
  134.      * <user flags="20039023" id="0"> 
  135.      *   <name>Primary</name> 
  136.      * </user> 
  137.      */  
  138.     writeUserLP(userData);  
  139.     /* 
  140.      * 把用户信息写到 /data/system/users/userlist.xml文件中 
  141.      * Writes the user list file in this format: 
  142.      * 
  143.      * <users nextSerialNumber="3"> 
  144.      *   <user id="0"></user> 
  145.      *   <user id="2"></user> 
  146.      * </users> 
  147.      */  
  148.     writeUserListLP();  
  149. }  

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

2.UserData的定义

[java]  view plain  copy
  1. private static class UserData {  
  2.     // Basic user information and properties  
  3.     UserInfo info;  
  4.     // Account name used when there is a strong association between a user and an account  
  5.     String account;  
  6.     // Account information for seeding into a newly created user. This could also be  
  7.     // used for login validation for an existing user, for updating their credentials.  
  8.     // In the latter case, data may not need to be persisted as it is only valid for the  
  9.     // current login session.  
  10.     String seedAccountName;  
  11.     String seedAccountType;  
  12.     PersistableBundle seedAccountOptions;  
  13.     // Whether to perist the seed account information to be available after a boot  
  14.     boolean persistSeedData;  
  15.   
  16.     void clearSeedAccountData() {  
  17.         seedAccountName = null;  
  18.         seedAccountType = null;  
  19.         seedAccountOptions = null;  
  20.         persistSeedData = false;  
  21.     }  
  22. }  
  23.   
  24.   
  25. public class UserInfo implements Parcelable {  
  26.   
  27.     /** 8 bits for user type 用户类型*/  
  28.     public static final int FLAG_MASK_USER_TYPE = 0x000000FF;  
  29.   
  30.     /** 
  31.      * *************************** NOTE *************************** 
  32.      * These flag values CAN NOT CHANGE because they are written 
  33.      * directly to storage. 
  34.      */  
  35.   
  36.     /** 
  37.      * Primary user. Only one user can have this flag set. It identifies the first human user 
  38.      * on a device.主用户标志,通常是第一个ID为0的用户 
  39.      */  
  40.     public static final int FLAG_PRIMARY = 0x00000001;  
  41.   
  42.     /** 
  43.      * User with administrative privileges. Such a user can create and 
  44.      * delete users.admin用户标志,有此标志才有创建和删除用户的权限 
  45.      */  
  46.     public static final int FLAG_ADMIN   = 0x00000002;  
  47.   
  48.     /** 
  49.      * Indicates a guest user that may be transient.guest用户标志 
  50.      */  
  51.     public static final int FLAG_GUEST   = 0x00000004;  
  52.   
  53.     /** 
  54.      * Indicates the user has restrictions in privileges, in addition to those for normal users. 
  55.      * Exact meaning TBD. For instance, maybe they can't install apps or administer WiFi access pts. 
  56.      * 标志权限受限的用户,具体受限功能未定 
  57.      */  
  58.     public static final int FLAG_RESTRICTED = 0x00000008;  
  59.   
  60.     /** 
  61.      * Indicates that this user has gone through its first-time initialization. 
  62.      * 标志该用户是否已经初始化 
  63.      */  
  64.     public static final int FLAG_INITIALIZED = 0x00000010;  
  65.   
  66.     /** 
  67.      * Indicates that this user is a profile of another user, for example holding a users 
  68.      * corporate data.标志该UserInfo是另一个用户的profile 
  69.      */  
  70.     public static final int FLAG_MANAGED_PROFILE = 0x00000020;  
  71.   
  72.     /** 
  73.      * Indicates that this user is disabled.标志该用户已被禁止 
  74.      * 
  75.      * <p>Note: If an ephemeral user is disabled, it shouldn't be later re-enabled. Ephemeral users 
  76.      * are disabled as their removal is in progress to indicate that they shouldn't be re-entered. 
  77.      */  
  78.     public static final int FLAG_DISABLED = 0x00000040;  
  79.   
  80.     public static final int FLAG_QUIET_MODE = 0x00000080;  
  81.   
  82.     /** 
  83.      * Indicates that this user is ephemeral. I.e. the user will be removed after leaving 
  84.      * the foreground. 
  85.      */  
  86.     public static final int FLAG_EPHEMERAL = 0x00000100;  
  87.   
  88.     public static final int NO_PROFILE_GROUP_ID = UserHandle.USER_NULL;  
  89.   
  90.     public int id; // 用户ID  
  91.     public int serialNumber; // 用户的序列号,不会重复  
  92.     public String name; // 用户名称  
  93.     public String iconPath; // 用户头像路径  
  94.     public int flags; // 用户标志  
  95.     public long creationTime; // 创建用户的时间  
  96.     public long lastLoggedInTime; // 最后一次登录的时间  
  97.     public String lastLoggedInFingerprint; // 最后一次用指纹登录的时间  
  98.     public int profileGroupId; // 用户profile的group ID  
  99.     public int restrictedProfileParentId;  
  100.   
  101.     /** User is only partially created. */  
  102.     public boolean partial; // true表示该用户没有创建完成  
  103.     public boolean guestToRemove;  
  104.     ...  
  105. }  

3.添加用户

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

[java]  view plain  copy
  1. @Override  
  2. public UserInfo createUser(String name, int flags) {  
  3.     if (DBG) Slog.i(LOG_TAG, "createUser name " + name);  
  4.     // 检查添加用户的权限  
  5.     checkManageOrCreateUsersPermission(flags);  
  6.     return createUserInternal(name, flags, UserHandle.USER_NULL);  
  7. }  
  8.   
  9. private UserInfo createUserInternal(String name, int flags, int parentId) {  
  10.     // 如果没有添加用户的权限则返回null  
  11.     if (hasUserRestriction(UserManager.DISALLOW_ADD_USER, UserHandle.getCallingUserId())) {  
  12.         Log.w(LOG_TAG, "Cannot add user. DISALLOW_ADD_USER is enabled.");  
  13.         return null;  
  14.     }  
  15.     return createUserInternalUnchecked(name, flags, parentId);  
  16. }  
  17.   
  18. private UserInfo createUserInternalUnchecked(String name, int flags, int parentId) {  
  19.     // 如果是一个低内存设备,则返回null  
  20.     if (ActivityManager.isLowRamDeviceStatic()) {  
  21.         return null;  
  22.     }  
  23.     final boolean isGuest = (flags & UserInfo.FLAG_GUEST) != 0;  
  24.     final boolean isManagedProfile = (flags & UserInfo.FLAG_MANAGED_PROFILE) != 0;  
  25.     final boolean isRestricted = (flags & UserInfo.FLAG_RESTRICTED) != 0;  
  26.     final long ident = Binder.clearCallingIdentity();  
  27.     UserInfo userInfo;  
  28.     UserData userData;  
  29.     final int userId;  
  30.     try {  
  31.         synchronized (mPackagesLock) {  
  32.             UserData parent = null;  
  33.             if (parentId != UserHandle.USER_NULL) {  
  34.                 synchronized (mUsersLock) {  
  35.             // 根据userId获取UserData信息  
  36.                     parent = getUserDataLU(parentId);  
  37.                 }  
  38.                 if (parent == nullreturn null;  
  39.             }  
  40.         // 判断是否可以添加更多profile  
  41.             if (isManagedProfile && !canAddMoreManagedProfiles(parentId, false)) {  
  42.                 Log.e(LOG_TAG, "Cannot add more managed profiles for user " + parentId);  
  43.                 return null;  
  44.             }  
  45.         // 判断是否达到用户上限  
  46.             if (!isGuest && !isManagedProfile && isUserLimitReached()) {  
  47.                 // If we're not adding a guest user or a managed profile and the limit has  
  48.                 // been reached, cannot add a user.  
  49.                 return null;  
  50.             }  
  51.             // If we're adding a guest and there already exists one, bail.  
  52.         // 如果创建的是guest用户且guest用户已经存在则返回  
  53.             if (isGuest && findCurrentGuestUser() != null) {  
  54.                 return null;  
  55.             }  
  56.             // In legacy mode, restricted profile's parent can only be the owner user  
  57.             if (isRestricted && !UserManager.isSplitSystemUser()  
  58.                     && (parentId != UserHandle.USER_SYSTEM)) {  
  59.                 Log.w(LOG_TAG, "Cannot add restricted profile - parent user must be owner");  
  60.                 return null;  
  61.             }  
  62.             if (isRestricted && UserManager.isSplitSystemUser()) {  
  63.                 if (parent == null) {  
  64.                     Log.w(LOG_TAG, "Cannot add restricted profile - parent user must be "  
  65.                             + "specified");  
  66.                     return null;  
  67.                 }  
  68.                 if (!parent.info.canHaveProfile()) {  
  69.                     Log.w(LOG_TAG, "Cannot add restricted profile - profiles cannot be "  
  70.                             + "created for the specified parent user id " + parentId);  
  71.                     return null;  
  72.                 }  
  73.             }  
  74.             if (!UserManager.isSplitSystemUser() && (flags & UserInfo.FLAG_EPHEMERAL) != 0) {  
  75.                 Log.e(LOG_TAG,  
  76.                         "Ephemeral users are supported on split-system-user systems only.");  
  77.                 return null;  
  78.             }  
  79.             // In split system user mode, we assign the first human user the primary flag.  
  80.             // And if there is no device owner, we also assign the admin flag to primary user.  
  81.             if (UserManager.isSplitSystemUser()  
  82.                     && !isGuest && !isManagedProfile && getPrimaryUser() == null) {  
  83.                 flags |= UserInfo.FLAG_PRIMARY;  
  84.                 synchronized (mUsersLock) {  
  85.                     if (!mIsDeviceManaged) {  
  86.                         flags |= UserInfo.FLAG_ADMIN;  
  87.                     }  
  88.                 }  
  89.             }  
  90.   
  91.         // 获取下一个可用的userId  
  92.             userId = getNextAvailableId();  
  93.         // 创建/data/system/users/userId文件夹  
  94.             Environment.getUserSystemDirectory(userId).mkdirs();  
  95.             boolean ephemeralGuests = Resources.getSystem()  
  96.                     .getBoolean(com.android.internal.R.bool.config_guestUserEphemeral);  
  97.   
  98.             synchronized (mUsersLock) {  
  99.                 // Add ephemeral flag to guests/users if required. Also inherit it from parent.  
  100.                 if ((isGuest && ephemeralGuests) || mForceEphemeralUsers  
  101.                         || (parent != null && parent.info.isEphemeral())) {  
  102.                     flags |= UserInfo.FLAG_EPHEMERAL;  
  103.                 }  
  104.   
  105.         // 初始化新用户  
  106.                 userInfo = new UserInfo(userId, name, null, flags);  
  107.                 userInfo.serialNumber = mNextSerialNumber++;  
  108.                 long now = System.currentTimeMillis();  
  109.                 userInfo.creationTime = (now > EPOCH_PLUS_30_YEARS) ? now : 0;  
  110.         // 设置partial变量为true,表示用户还没有创建完成  
  111.                 userInfo.partial = true;  
  112.                 userInfo.lastLoggedInFingerprint = Build.FINGERPRINT;  
  113.                 userData = new UserData();  
  114.                 userData.info = userInfo;  
  115.                 mUsers.put(userId, userData);  
  116.             }  
  117.         // 保存用户信息  
  118.             writeUserLP(userData);  
  119.             writeUserListLP();  
  120.             if (parent != null) {  
  121.                 if (isManagedProfile) {  
  122.                     if (parent.info.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID) {  
  123.                         parent.info.profileGroupId = parent.info.id;  
  124.                         writeUserLP(parent);  
  125.                     }  
  126.                     userInfo.profileGroupId = parent.info.profileGroupId;  
  127.                 } else if (isRestricted) {  
  128.                     if (parent.info.restrictedProfileParentId == UserInfo.NO_PROFILE_GROUP_ID) {  
  129.                         parent.info.restrictedProfileParentId = parent.info.id;  
  130.                         writeUserLP(parent);  
  131.                     }  
  132.                     userInfo.restrictedProfileParentId = parent.info.restrictedProfileParentId;  
  133.                 }  
  134.             }  
  135.         }  
  136.     // 为新建用户准备存储区域  
  137.         final StorageManager storage = mContext.getSystemService(StorageManager.class);  
  138.         storage.createUserKey(userId, userInfo.serialNumber, userInfo.isEphemeral());  
  139.         mPm.prepareUserData(userId, userInfo.serialNumber,  
  140.                 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);  
  141.     // 保存所有安装应用在新建用户目录下的安装状态  
  142.         mPm.createNewUser(userId);  
  143.     // 创建完新用户后修改partial变量为false,表示用户创建完成,并重新保存用户信息  
  144.         userInfo.partial = false;  
  145.         synchronized (mPackagesLock) {  
  146.             writeUserLP(userData);  
  147.         }  
  148.         updateUserIds();  
  149.         Bundle restrictions = new Bundle();  
  150.         if (isGuest) {  
  151.             synchronized (mGuestRestrictions) {  
  152.                 restrictions.putAll(mGuestRestrictions);  
  153.             }  
  154.         }  
  155.         synchronized (mRestrictionsLock) {  
  156.             mBaseUserRestrictions.append(userId, restrictions);  
  157.         }  
  158.     // 发送成功添加新用户的广播  
  159.         Intent addedIntent = new Intent(Intent.ACTION_USER_ADDED);  
  160.         addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);  
  161.         mContext.sendBroadcastAsUser(addedIntent, UserHandle.ALL,  
  162.                 android.Manifest.permission.MANAGE_USERS);  
  163.         MetricsLogger.count(mContext, isGuest ? TRON_GUEST_CREATED : TRON_USER_CREATED, 1);  
  164.     } finally {  
  165.         Binder.restoreCallingIdentity(ident);  
  166.     }  
  167.     return userInfo;  
  168. }  
  169.   
  170. // 根据userId获取UserData信息  
  171. private UserData getUserDataLU(int userId) {  
  172.     final UserData userData = mUsers.get(userId);  
  173.     // If it is partial and not in the process of being removed, return as unknown user.  
  174.     if (userData != null && userData.info.partial && !mRemovingUserIds.get(userId)) {  
  175.         return null;  
  176.     }  
  177.     return userData;  
  178. }  
  179.   
  180.   
  181. final Settings mSettings;  
  182.   
  183. /** Called by UserManagerService */  
  184. // 保存所有安装应用在新建用户目录下的安装状态  
  185. void createNewUser(int userId) {  
  186.     synchronized (mInstallLock) {  
  187.     // 把所有已安装的应用数据拷贝到新建用户对应目录(/data/user/0/)下  
  188.         mSettings.createNewUserLI(this, mInstaller, userId);  
  189.     }  
  190.     synchronized (mPackages) {  
  191.     // 在/data/system/users/0/package-restrictions.xml文件中保存应用的限制信息  
  192.         scheduleWritePackageRestrictionsLocked(userId);  
  193.     // 更新/data/system/packages.list文件  
  194.         scheduleWritePackageListLocked(userId);  
  195.     // 保存默认浏览器应用,并更新/data/system/users/0/package-restrictions.xml文件  
  196.         applyFactoryDefaultBrowserLPw(userId);  
  197.     // 主要域名验证  
  198.         primeDomainVerificationsLPw(userId);  
  199.     }  
  200. }  
  201.   
  202.   
  203. /** Map from package name to settings 每个包名对应一个PackageSetting*/  
  204. final ArrayMap<String, PackageSetting> mPackages = new ArrayMap<>();  
  205.   
  206. // 把所有已安装的系统应用数据拷贝到新建用户对应目录下  
  207. void createNewUserLI(@NonNull PackageManagerService service, @NonNull Installer installer,  
  208.         int userHandle) {  
  209.     String[] volumeUuids;  
  210.     String[] names;  
  211.     int[] appIds;  
  212.     String[] seinfos;  
  213.     int[] targetSdkVersions;  
  214.     int packagesCount;  
  215.     synchronized (mPackages) {  
  216.     // 从map中获取出所有的settings  
  217.         Collection<PackageSetting> packages = mPackages.values();  
  218.         packagesCount = packages.size();  
  219.         volumeUuids = new String[packagesCount];  
  220.         names = new String[packagesCount];  
  221.         appIds = new int[packagesCount];  
  222.         seinfos = new String[packagesCount];  
  223.         targetSdkVersions = new int[packagesCount];  
  224.         Iterator<PackageSetting> packagesIterator = packages.iterator();  
  225.     // 遍历所有的PackageSetting  
  226.         for (int i = 0; i < packagesCount; i++) {  
  227.             PackageSetting ps = packagesIterator.next();  
  228.             if (ps.pkg == null || ps.pkg.applicationInfo == null) {  
  229.                 continue;  
  230.             }  
  231.             // Only system apps are initially installed.初始化时只安装系统应用  
  232.             /** M: [Operator] Operator package should also be installed @{ */  
  233.             boolean curInstalledStatus = ps.isSystem()  
  234.                                 || (ps.pkgFlagsEx & ApplicationInfo.FLAG_EX_OPERATOR) != 0;  
  235.         // 设置每一个应用在新创建用户下的安装状态,系统应用为true  
  236.             ps.setInstalled(curInstalledStatus, userHandle);  
  237.             /** @} */  
  238.             // Need to create a data directory for all apps under this user. Accumulate all  
  239.             // required args and call the installer after mPackages lock has been released  
  240.             volumeUuids[i] = ps.volumeUuid;  
  241.             names[i] = ps.name;  
  242.             appIds[i] = ps.appId;  
  243.             seinfos[i] = ps.pkg.applicationInfo.seinfo;  
  244.             targetSdkVersions[i] = ps.pkg.applicationInfo.targetSdkVersion;  
  245.         }  
  246.     }  
  247.     for (int i = 0; i < packagesCount; i++) {  
  248.         if (names[i] == null) {  
  249.             continue;  
  250.         }  
  251.         // TODO: triage flags!  
  252.         final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE;  
  253.         try {  
  254.         // 在新建用户目录(/data/user/0/)下创建每个应用的数据目录(包名命名的文件夹)  
  255.             installer.createAppData(volumeUuids[i], names[i], userHandle, flags, appIds[i],  
  256.                     seinfos[i], targetSdkVersions[i]);  
  257.         } catch (InstallerException e) {  
  258.             Slog.w(TAG, "Failed to prepare app data", e);  
  259.         }  
  260.     }  
  261.     synchronized (mPackages) {  
  262.     // 解析"etc/preferred-apps"目录下所有XML文件,XML文件中保存的是设备使用者指定的响应某个Intent  
  263.     // 的最合适的组件信息  
  264.         applyDefaultPreferredAppsLPw(service, userHandle);  
  265.     }  
  266. }  

4.删除用户

[java]  view plain  copy
  1. /** 
  2.  * Removes a user and all data directories created for that user. This method should be called 
  3.  * after the user's processes have been terminated. 
  4.  * @param userHandle the user's id 
  5.  */  
  6. @Override  
  7. public boolean removeUser(int userHandle) {  
  8.     // 检查调用者是否有删除用户的权限  
  9.     checkManageOrCreateUsersPermission("Only the system can remove users");  
  10.     if (getUserRestrictions(UserHandle.getCallingUserId()).getBoolean(  
  11.             UserManager.DISALLOW_REMOVE_USER, false)) {  
  12.         Log.w(LOG_TAG, "Cannot remove user. DISALLOW_REMOVE_USER is enabled.");  
  13.         return false;  
  14.     }  
  15.   
  16.     long ident = Binder.clearCallingIdentity();  
  17.     try {  
  18.         final UserData userData;  
  19.         int currentUser = ActivityManager.getCurrentUser();  
  20.         if (currentUser == userHandle) {  
  21.             Log.w(LOG_TAG, "Current user cannot be removed");  
  22.             return false;  
  23.         }  
  24.         synchronized (mPackagesLock) {  
  25.             synchronized (mUsersLock) {  
  26.                 userData = mUsers.get(userHandle);  
  27.                 if (userHandle == 0 || userData == null || mRemovingUserIds.get(userHandle)) {  
  28.                     return false;  
  29.                 }  
  30.   
  31.                 // We remember deleted user IDs to prevent them from being  
  32.                 // reused during the current boot; they can still be reused  
  33.                 // after a reboot.保存要删除的userId,防止重复删除  
  34.                 mRemovingUserIds.put(userHandle, true);  
  35.             }  
  36.   
  37.             try {  
  38.                 mAppOpsService.removeUser(userHandle);  
  39.             } catch (RemoteException e) {  
  40.                 Log.w(LOG_TAG, "Unable to notify AppOpsService of removing user", e);  
  41.             }  
  42.             // Set this to a partially created user, so that the user will be purged  
  43.             // on next startup, in case the runtime stops now before stopping and  
  44.             // removing the user completely.  
  45.         // 删除用户并没有删除相关用户文件,只是把partial变量修改为true,  
  46.         // 开机后如果该变量还是true会删除相关文件  
  47.             userData.info.partial = true;  
  48.             // Mark it as disabled, so that it isn't returned any more when  
  49.             // profiles are queried.  
  50.             userData.info.flags |= UserInfo.FLAG_DISABLED;  
  51.         // 更新/data/system/users/${id}.xml文件  
  52.             writeUserLP(userData);  
  53.         }  
  54.   
  55.         if (userData.info.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID  
  56.                 && userData.info.isManagedProfile()) {  
  57.             // Send broadcast to notify system that the user removed was a  
  58.             // managed user.发送删除用户的广播  
  59.             sendProfileRemovedBroadcast(userData.info.profileGroupId, userData.info.id);  
  60.         }  
  61.   
  62.         if (DBG) Slog.i(LOG_TAG, "Stopping user " + userHandle);  
  63.         int res;  
  64.         try {  
  65.         // 停止正在运行的用户  
  66.             res = ActivityManagerNative.getDefault().stopUser(userHandle, /* force= */ true,  
  67.             new IStopUserCallback.Stub() {  
  68.                         @Override  
  69.                         public void userStopped(int userId) {  
  70.                 // 删除用户相关应用信息  
  71.                             finishRemoveUser(userId);  
  72.                         }  
  73.                         @Override  
  74.                         public void userStopAborted(int userId) {  
  75.                         }  
  76.                     });  
  77.         } catch (RemoteException e) {  
  78.             return false;  
  79.         }  
  80.         return res == ActivityManager.USER_OP_SUCCESS;  
  81.     } finally {  
  82.         Binder.restoreCallingIdentity(ident);  
  83.     }  
  84. }  

5.多用户管理

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

[java]  view plain  copy
  1. public final class UserState {  
  2.     // User is first coming up.启动中  
  3.     public final static int STATE_BOOTING = 0;  
  4.     // User is in the locked state.锁定  
  5.     public final static int STATE_RUNNING_LOCKED = 1;  
  6.     // User is in the unlocking state.未锁定  
  7.     public final static int STATE_RUNNING_UNLOCKING = 2;  
  8.     // User is in the running state.运行中  
  9.     public final static int STATE_RUNNING_UNLOCKED = 3;  
  10.     // User is in the initial process of being stopped.停止的初始过程中  
  11.     public final static int STATE_STOPPING = 4;  
  12.     // User is in the final phase of stopping, sending Intent.ACTION_SHUTDOWN.停止的最后阶段  
  13.     public final static int STATE_SHUTDOWN = 5;  
  14.     ...  
  15. }  
  16.   
  17. @Override  
  18. public boolean switchUser(final int targetUserId) {  
  19.     // 检查调用者是否有切换用户的权限  
  20.     enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);  
  21.     UserInfo currentUserInfo;  
  22.     UserInfo targetUserInfo;  
  23.     synchronized (this) {  
  24.     // 获取当用用户的相关信息  
  25.         int currentUserId = mUserController.getCurrentUserIdLocked();  
  26.         currentUserInfo = mUserController.getUserInfo(currentUserId);  
  27.     // 获取切换目标用户的相关信息  
  28.         targetUserInfo = mUserController.getUserInfo(targetUserId);  
  29.         if (targetUserInfo == null) {  
  30.             Slog.w(TAG, "No user info for user #" + targetUserId);  
  31.             return false;  
  32.         }  
  33.     // 如果目标用户不支持切换,则返回  
  34.         if (!targetUserInfo.supportsSwitchTo()) {  
  35.             Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");  
  36.             return false;  
  37.         }  
  38.     // 如果目标用户是另一个用户的profile,则返回  
  39.         if (targetUserInfo.isManagedProfile()) {  
  40.             Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");  
  41.             return false;  
  42.         }  
  43.         mUserController.setTargetUserIdLocked(targetUserId);  
  44.     }  
  45.     // 发送切换用户的消息  
  46.     Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);  
  47.     mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);  
  48.     mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));  
  49.     return true;  
  50. }  
  51.   
  52. final class UiHandler extends Handler {  
  53.     public UiHandler() {  
  54.         super(com.android.server.UiThread.get().getLooper(), nulltrue);  
  55.     }  
  56.   
  57.     @Override  
  58.     public void handleMessage(Message msg) {  
  59.         switch (msg.what) {  
  60.             ...  
  61.             case START_USER_SWITCH_UI_MSG: {  
  62.                 mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);  
  63.                 break;  
  64.             }  
  65.             ...  
  66.         }  
  67.     }  
  68. }  
  69.   
  70. void showUserSwitchDialog(Pair<UserInfo, UserInfo> fromToUserPair) {  
  71.     // The dialog will show and then initiate the user switch by calling startUserInForeground  
  72.     Dialog d = new UserSwitchingDialog(mService, mService.mContext, fromToUserPair.first,  
  73.             fromToUserPair.second, true /* above system */);  
  74.     d.show();  
  75. }  
  76.   
  77. @Override  
  78. public void show() {  
  79.     // Slog.v(TAG, "show called");  
  80.     super.show();  
  81.     final View decorView = getWindow().getDecorView();  
  82.     if (decorView != null) {  
  83.         decorView.getViewTreeObserver().addOnWindowShownListener(this);  
  84.     }  
  85.     // Add a timeout as a safeguard, in case a race in screen on/off causes the window  
  86.     // callback to never come.  
  87.     mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_START_USER),  
  88.             WINDOW_SHOWN_TIMEOUT_MS);  
  89. }  
  90.   
  91. private final Handler mHandler = new Handler() {  
  92.     @Override  
  93.     public void handleMessage(Message msg) {  
  94.         switch (msg.what) {  
  95.             case MSG_START_USER:  
  96.         // 调用startUser()方法  
  97.                 startUser();  
  98.                 break;  
  99.         }  
  100.     }  
  101. };  
  102.   
  103.   
  104. void startUser() {  
  105.     synchronized (this) {  
  106.         if (!mStartedUser) {  
  107.         // 调用startUserInForeground方法  
  108.             mService.mUserController.startUserInForeground(mUserId, this);  
  109.             mStartedUser = true;  
  110.             final View decorView = getWindow().getDecorView();  
  111.             if (decorView != null) {  
  112.                 decorView.getViewTreeObserver().removeOnWindowShownListener(this);  
  113.             }  
  114.             mHandler.removeMessages(MSG_START_USER);  
  115.         }  
  116.     }  
  117. }  
  118.   
  119. /** 
  120.  * Start user, if its not already running, and bring it to foreground. 
  121.  * 开启用户,如果用户没有在运行,则开启它 
  122.  */  
  123. boolean startUserInForeground(final int userId, Dialog dlg) {  
  124.     boolean result = startUser(userId, /* foreground */ true);  
  125.     dlg.dismiss();  
  126.     return result;  
  127. }  
  128.   
  129. /** 
  130.  * Start user, if its not already running. 
  131.  * <p>The user will be brought to the foreground, if {@code foreground} parameter is set. 
  132.  * When starting the user, multiple intents will be broadcast in the following order:</p> 
  133.  * <ul> 
  134.  *     <li>{@link Intent#ACTION_USER_STARTED} - sent to registered receivers of the new user 
  135.  *     <li>{@link Intent#ACTION_USER_BACKGROUND} - sent to registered receivers of the outgoing 
  136.  *     user and all profiles of this user. Sent only if {@code foreground} parameter is true 
  137.  *     <li>{@link Intent#ACTION_USER_FOREGROUND} - sent to registered receivers of the new 
  138.  *     user and all profiles of this user. Sent only if {@code foreground} parameter is true 
  139.  *     <li>{@link Intent#ACTION_USER_SWITCHED} - sent to registered receivers of the new user. 
  140.  *     Sent only if {@code foreground} parameter is true 
  141.  *     <li>{@link Intent#ACTION_USER_STARTING} - ordered broadcast sent to registered receivers 
  142.  *     of the new fg user 
  143.  *     <li>{@link Intent#ACTION_LOCKED_BOOT_COMPLETED} - ordered broadcast sent to receivers of 
  144.  *     the new user 
  145.  *     <li>{@link Intent#ACTION_USER_UNLOCKED} - sent to registered receivers of the new user 
  146.  *     <li>{@link Intent#ACTION_PRE_BOOT_COMPLETED} - ordered broadcast sent to receivers of the 
  147.  *     new user. Sent only when the user is booting after a system update. 
  148.  *     <li>{@link Intent#ACTION_USER_INITIALIZE} - ordered broadcast sent to receivers of the 
  149.  *     new user. Sent only the first time a user is starting. 
  150.  *     <li>{@link Intent#ACTION_BOOT_COMPLETED} - ordered broadcast sent to receivers of the new 
  151.  *     user. Indicates that the user has finished booting. 
  152.  * </ul> 
  153.  * 
  154.  * @param userId ID of the user to start 
  155.  * @param foreground true if user should be brought to the foreground 
  156.  * @return true if the user has been successfully started 
  157.  */  
  158. boolean startUser(final int userId, final boolean foreground) {  
  159.     // 检查调用者权限  
  160.     if (mService.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)  
  161.             != PackageManager.PERMISSION_GRANTED) {  
  162.         String msg = "Permission Denial: switchUser() from pid="  
  163.                 + Binder.getCallingPid()  
  164.                 + ", uid=" + Binder.getCallingUid()  
  165.                 + " requires " + INTERACT_ACROSS_USERS_FULL;  
  166.         Slog.w(TAG, msg);  
  167.         throw new SecurityException(msg);  
  168.     }  
  169.   
  170.     Slog.i(TAG, "Starting userid:" + userId + " fg:" + foreground);  
  171.   
  172.     final long ident = Binder.clearCallingIdentity();  
  173.     try {  
  174.         synchronized (mService) {  
  175.             final int oldUserId = mCurrentUserId;  
  176.         // 如果要开启的用户已经存在,则直接返回true  
  177.             if (oldUserId == userId) {  
  178.                 return true;  
  179.             }  
  180.   
  181.             mService.mStackSupervisor.setLockTaskModeLocked(null,  
  182.                     ActivityManager.LOCK_TASK_MODE_NONE, "startUser"false);  
  183.   
  184.         // 获取目标用户的相关信息  
  185.             final UserInfo userInfo = getUserInfo(userId);  
  186.             if (userInfo == null) {  
  187.                 Slog.w(TAG, "No user info for user #" + userId);  
  188.                 return false;  
  189.             }  
  190.             if (foreground && userInfo.isManagedProfile()) {  
  191.                 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");  
  192.                 return false;  
  193.             }  
  194.   
  195.         // 如果要把用户切到前台,则播放动画  
  196.             if (foreground) {  
  197.                 mService.mWindowManager.startFreezingScreen(  
  198.                         R.anim.screen_user_exit, R.anim.screen_user_enter);  
  199.             }  
  200.   
  201.             boolean needStart = false;  
  202.   
  203.             // If the user we are switching to is not currently started, then  
  204.             // we need to start it now.如果目标用户不存在,则修改用户状态为正在开启  
  205.         // UserState的状态默认值是STATE_BOOTING  
  206.             if (mStartedUsers.get(userId) == null) {  
  207.                 UserState userState = new UserState(UserHandle.of(userId));  
  208.                 mStartedUsers.put(userId, userState);  
  209.                 getUserManagerInternal().setUserState(userId, userState.state);  
  210.         // 根据用户状态更新已经开启的用户列表  
  211.                 updateStartedUserArrayLocked();  
  212.                 needStart = true;  
  213.             }  
  214.   
  215.             final UserState uss = mStartedUsers.get(userId);  
  216.             final Integer userIdInt = userId;  
  217.             mUserLru.remove(userIdInt);  
  218.         // 调整用户在mUserLru中的位置,当前用户位于末尾  
  219.             mUserLru.add(userIdInt);  
  220.   
  221.             if (foreground) {  
  222.         // 修改当前用户的Id  
  223.                 mCurrentUserId = userId;  
  224.         // 更新用户配置信息  
  225.                 mService.updateUserConfigurationLocked();  
  226.                 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up  
  227.         // 更新与当前用户相关的用户列表  
  228.                 updateCurrentProfileIdsLocked();  
  229.                 mService.mWindowManager.setCurrentUser(userId, mCurrentProfileIds);  
  230.                 // Once the internal notion of the active user has switched, we lock the device  
  231.                 // with the option to show the user switcher on the keyguard.  
  232.                 mService.mWindowManager.lockNow(null);  
  233.             } else {  
  234.                 final Integer currentUserIdInt = mCurrentUserId;  
  235.         // 更新与当前用户相关的用户列表  
  236.                 updateCurrentProfileIdsLocked();  
  237.                 mService.mWindowManager.setCurrentProfileIds(mCurrentProfileIds);  
  238.                 mUserLru.remove(currentUserIdInt);  
  239.                 mUserLru.add(currentUserIdInt);  
  240.             }  
  241.   
  242.             // Make sure user is in the started state.  If it is currently  
  243.             // stopping, we need to knock that off.确保用户处于启动状态,如果处于  
  244.         // 停止的初始阶段,则中止它。如果已经发送过停止运行的广播,则重新设置用户的状态  
  245.             if (uss.state == UserState.STATE_STOPPING) {  
  246.                 // If we are stopping, we haven't sent ACTION_SHUTDOWN,  
  247.                 // so we can just fairly silently bring the user back from  
  248.                 // the almost-dead.  
  249.                 uss.setState(uss.lastState);  
  250.                 getUserManagerInternal().setUserState(userId, uss.state);  
  251.         // 根据用户状态更新已经开启的用户列表  
  252.                 updateStartedUserArrayLocked();  
  253.                 needStart = true;  
  254.             } else if (uss.state == UserState.STATE_SHUTDOWN) {  
  255.                 // This means ACTION_SHUTDOWN has been sent, so we will  
  256.                 // need to treat this as a new boot of the user.  
  257.                 uss.setState(UserState.STATE_BOOTING);  
  258.                 getUserManagerInternal().setUserState(userId, uss.state);  
  259.         // 根据用户状态更新已经开启的用户列表  
  260.                 updateStartedUserArrayLocked();  
  261.                 needStart = true;  
  262.             }  
  263.   
  264.             if (uss.state == UserState.STATE_BOOTING) {  
  265.                 // Give user manager a chance to propagate user restrictions  
  266.                 // to other services and prepare app storage  
  267.         // 在用户启动之前,先准备相关用户的限制及存储  
  268.                 getUserManager().onBeforeStartUser(userId);  
  269.   
  270.                 // Booting up a new user, need to tell system services about it.  
  271.                 // Note that this is on the same handler as scheduling of broadcasts,  
  272.                 // which is important because it needs to go first.  
  273.                 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));  
  274.             }  
  275.   
  276.             if (foreground) {  
  277.         // 发送相关消息  
  278.                 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,  
  279.                         oldUserId));  
  280.                 mHandler.removeMessages(REPORT_USER_SWITCH_MSG);  
  281.                 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);  
  282.                 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,  
  283.                         oldUserId, userId, uss));  
  284.                 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,  
  285.                         oldUserId, userId, uss), USER_SWITCH_TIMEOUT);  
  286.             }  
  287.   
  288.             if (needStart) {  
  289.                 // Send USER_STARTED broadcast 如果需要开启用户,则发送相应广播  
  290.         // 用户切换牵扯到很多模块,如壁纸管理、输入法、账号管理等,都需要收到通知  
  291.                 Intent intent = new Intent(Intent.ACTION_USER_STARTED);  
  292.                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY  
  293.                         | Intent.FLAG_RECEIVER_FOREGROUND);  
  294.                 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);  
  295.                 mService.broadcastIntentLocked(nullnull, intent,  
  296.                         nullnull0nullnullnull, AppOpsManager.OP_NONE,  
  297.                         nullfalsefalse, MY_PID, SYSTEM_UID, userId);  
  298.             }  
  299.   
  300.             if (foreground) {  
  301.         // 把开启的用户设为前台用户  
  302.                 moveUserToForegroundLocked(uss, oldUserId, userId);  
  303.             } else {  
  304.         // 用户启动结束,则切换用户到STATE_RUNNING_LOCKED状态  
  305.                 mService.mUserController.finishUserBoot(uss);  
  306.             }  
  307.   
  308.             if (needStart) {  
  309.         // 如果需要开启用户,则发送相应广播  
  310.                 Intent intent = new Intent(Intent.ACTION_USER_STARTING);  
  311.                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);  
  312.                 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);  
  313.                 mService.broadcastIntentLocked(nullnull, intent,  
  314.                         nullnew IIntentReceiver.Stub() {  
  315.                             @Override  
  316.                             public void performReceive(Intent intent, int resultCode,  
  317.                                     String data, Bundle extras, boolean ordered, boolean sticky,  
  318.                                     int sendingUser) throws RemoteException {  
  319.                             }  
  320.                         }, 0nullnull,  
  321.                         new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,  
  322.                         nulltruefalse, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);  
  323.             }  
  324.         }  
  325.     } finally {  
  326.         Binder.restoreCallingIdentity(ident);  
  327.     }  
  328.   
  329.     return true;  
  330. }  
  331.   
  332. // 根据用户状态更新已经开启的用户列表mStartedUserArray  
  333. private void updateStartedUserArrayLocked() {  
  334.     int num = 0;  
  335.     for (int i = 0; i < mStartedUsers.size(); i++) {  
  336.         UserState uss = mStartedUsers.valueAt(i);  
  337.         // This list does not include stopping users.  
  338.         if (uss.state != UserState.STATE_STOPPING  
  339.                 && uss.state != UserState.STATE_SHUTDOWN) {  
  340.             num++;  
  341.         }  
  342.     }  
  343.     mStartedUserArray = new int[num];  
  344.     num = 0;  
  345.     for (int i = 0; i < mStartedUsers.size(); i++) {  
  346.         UserState uss = mStartedUsers.valueAt(i);  
  347.         if (uss.state != UserState.STATE_STOPPING  
  348.                 && uss.state != UserState.STATE_SHUTDOWN) {  
  349.             mStartedUserArray[num++] = mStartedUsers.keyAt(i);  
  350.         }  
  351.     }  
  352. }  
  353.   
  354.   
  355. 发送的msg消息是在ActivityManagerService中处理的:  
  356. final class UiHandler extends Handler {  
  357.     public UiHandler() {  
  358.         super(com.android.server.UiThread.get().getLooper(), nulltrue);  
  359.     }  
  360.   
  361.     @Override  
  362.     public void handleMessage(Message msg) {  
  363.         switch (msg.what) {  
  364.         ...  
  365.         case SYSTEM_USER_START_MSG: {  
  366.             mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,  
  367.                     Integer.toString(msg.arg1), msg.arg1);  
  368.         // 新建用户时调用  
  369.             mSystemServiceManager.startUser(msg.arg1);  
  370.             break;  
  371.         }  
  372.         case SYSTEM_USER_CURRENT_MSG: {  
  373.             mBatteryStatsService.noteEvent(  
  374.                     BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,  
  375.                     Integer.toString(msg.arg2), msg.arg2);  
  376.             mBatteryStatsService.noteEvent(  
  377.                     BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,  
  378.                     Integer.toString(msg.arg1), msg.arg1);  
  379.         // 切换用户时调用  
  380.             mSystemServiceManager.switchUser(msg.arg1);  
  381.             break;  
  382.         }  
  383.         case REPORT_USER_SWITCH_MSG: {  
  384.             mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);  
  385.             break;  
  386.         }  
  387.         case CONTINUE_USER_SWITCH_MSG: {  
  388.             mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);  
  389.             break;  
  390.         }  
  391.         case USER_SWITCH_TIMEOUT_MSG: {  
  392.             mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);  
  393.             break;  
  394.         }  
  395.         case REPORT_USER_SWITCH_COMPLETE_MSG: {  
  396.             mUserController.dispatchUserSwitchComplete(msg.arg1);  
  397.             break;  
  398.         }   
  399.         ...  
  400.     }  
  401. };  
  402.   
  403. // 该方法主要是调用mUserSwitchObservers列表中的IUserSwitchObserver对象的onUserSwitching方法  
  404. // 如果想知道用户切换,可以调用AMS的registerUserSwitchObserver()方法来注册一个观察者对象  
  405. void dispatchUserSwitch(final UserState uss, final int oldUserId, final int newUserId) {  
  406.     Slog.d(TAG, "Dispatch onUserSwitching oldUser #" + oldUserId + " newUser #" + newUserId);  
  407.     // 获取所有注册回调方法的总数  
  408.     final int observerCount = mUserSwitchObservers.beginBroadcast();  
  409.     if (observerCount > 0) {  
  410.         final IRemoteCallback callback = new IRemoteCallback.Stub() {  
  411.             int mCount = 0;  
  412.             @Override  
  413.             public void sendResult(Bundle data) throws RemoteException {  
  414.                 synchronized (mService) {  
  415.                     if (mCurUserSwitchCallback == this) {  
  416.             // 收到一条回调,就加一  
  417.                         mCount++;  
  418.             // 所有注册的回调方法都执行了,发送继续处理的消息  
  419.                         if (mCount == observerCount) {  
  420.                             sendContinueUserSwitchLocked(uss, oldUserId, newUserId);  
  421.                         }  
  422.                     }  
  423.                 }  
  424.             }  
  425.         };  
  426.         synchronized (mService) {  
  427.             uss.switching = true;  
  428.             mCurUserSwitchCallback = callback;  
  429.         }  
  430.     // 遍历调用所有注册回调对象的onUserSwitching方法  
  431.         for (int i = 0; i < observerCount; i++) {  
  432.             try {  
  433.                 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(  
  434.                         newUserId, callback);  
  435.             } catch (RemoteException e) {  
  436.             }  
  437.         }  
  438.     } else {  
  439.         synchronized (mService) {  
  440.         // 如果没有注册回调方法的,直接调用继续执行用户切换的方法  
  441.             sendContinueUserSwitchLocked(uss, oldUserId, newUserId);  
  442.         }  
  443.     }  
  444.     mUserSwitchObservers.finishBroadcast();  
  445. }  
  446.   
  447. void sendContinueUserSwitchLocked(UserState uss, int oldUserId, int newUserId) {  
  448.     mCurUserSwitchCallback = null;  
  449.     mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);  
  450.     mHandler.sendMessage(mHandler.obtainMessage(ActivityManagerService.CONTINUE_USER_SWITCH_MSG,  
  451.             oldUserId, newUserId, uss));  
  452. }  
  453.   
  454. void continueUserSwitch(UserState uss, int oldUserId, int newUserId) {  
  455.     Slog.d(TAG, "Continue user switch oldUser #" + oldUserId + ", newUser #" + newUserId);  
  456.     synchronized (mService) {  
  457.         mService.mWindowManager.stopFreezingScreen();  
  458.     }  
  459.     uss.switching = false;  
  460.     // 发送完成切换用户的消息  
  461.     mHandler.removeMessages(REPORT_USER_SWITCH_COMPLETE_MSG);  
  462.     mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_COMPLETE_MSG,  
  463.             newUserId, 0));  
  464.     // 停止切换到后台的Guest或临时用户  
  465.     stopGuestOrEphemeralUserIfBackground();  
  466.     // 强制停止后台用户  
  467.     stopBackgroundUsersIfEnforced(oldUserId);  
  468. }  
  469.   
  470. /** Called on handler thread */  
  471. void dispatchUserSwitchComplete(int userId) {  
  472.     final int observerCount = mUserSwitchObservers.beginBroadcast();  
  473.     for (int i = 0; i < observerCount; i++) {  
  474.         try {  
  475.         // 遍历调用所有观察者的onUserSwitchComplete方法  
  476.             mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(userId);  
  477.         } catch (RemoteException e) {  
  478.         }  
  479.     }  
  480.     mUserSwitchObservers.finishBroadcast();  
  481. }  
  482.   
  483. /** 
  484.  * Stops the guest or ephemeral user if it has gone to the background. 
  485.  * 停止切换到后台的Guest或临时用户 
  486.  */  
  487. private void stopGuestOrEphemeralUserIfBackground() {  
  488.     synchronized (mService) {  
  489.         final int num = mUserLru.size();  
  490.         for (int i = 0; i < num; i++) {  
  491.             Integer oldUserId = mUserLru.get(i);  
  492.             UserState oldUss = mStartedUsers.get(oldUserId);  
  493.             if (oldUserId == UserHandle.USER_SYSTEM || oldUserId == mCurrentUserId  
  494.                     || oldUss.state == UserState.STATE_STOPPING  
  495.                     || oldUss.state == UserState.STATE_SHUTDOWN) {  
  496.                 continue;  
  497.             }  
  498.             UserInfo userInfo = getUserInfo(oldUserId);  
  499.             if (userInfo.isEphemeral()) {  
  500.                 LocalServices.getService(UserManagerInternal.class)  
  501.                         .onEphemeralUserStop(oldUserId);  
  502.             }  
  503.             if (userInfo.isGuest() || userInfo.isEphemeral()) {  
  504.                 // This is a user to be stopped.  
  505.                 stopUsersLocked(oldUserId, truenull);  
  506.                 break;  
  507.             }  
  508.         }  
  509.     }  
  510. }  
  511.   
  512. // 强制停止后台用户  
  513. private void stopBackgroundUsersIfEnforced(int oldUserId) {  
  514.     // Never stop system user  
  515.     if (oldUserId == UserHandle.USER_SYSTEM) {  
  516.         return;  
  517.     }  
  518.     // For now, only check for user restriction. Additional checks can be added here  
  519.     boolean disallowRunInBg = hasUserRestriction(UserManager.DISALLOW_RUN_IN_BACKGROUND,  
  520.             oldUserId);  
  521.     if (!disallowRunInBg) {  
  522.         return;  
  523.     }  
  524.     synchronized (mService) {  
  525.         if (DEBUG_MU) Slog.i(TAG, "stopBackgroundUsersIfEnforced stopping " + oldUserId  
  526.                 + " and related users");  
  527.         stopUsersLocked(oldUserId, falsenull);  
  528.     }  
  529. }  
  530.   
  531. void timeoutUserSwitch(UserState uss, int oldUserId, int newUserId) {  
  532.     synchronized (mService) {  
  533.         /// M: Change Slog.wtf to Slog.w to avoid having WTF easily after adding new user  
  534.         Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);  
  535.         sendContinueUserSwitchLocked(uss, oldUserId, newUserId);  
  536.     }  
  537. }  

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


这篇关于Android多用户之UserManagerService源码分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1033548

相关文章

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

Java ArrayList扩容机制 (源码解读)

结论:初始长度为10,若所需长度小于1.5倍原长度,则按照1.5倍扩容。若不够用则按照所需长度扩容。 一. 明确类内部重要变量含义         1:数组默认长度         2:这是一个共享的空数组实例,用于明确创建长度为0时的ArrayList ,比如通过 new ArrayList<>(0),ArrayList 内部的数组 elementData 会指向这个 EMPTY_EL

如何在Visual Studio中调试.NET源码

今天偶然在看别人代码时,发现在他的代码里使用了Any判断List<T>是否为空。 我一般的做法是先判断是否为null,再判断Count。 看了一下Count的源码如下: 1 [__DynamicallyInvokable]2 public int Count3 {4 [__DynamicallyInvokable]5 get

SWAP作物生长模型安装教程、数据制备、敏感性分析、气候变化影响、R模型敏感性分析与贝叶斯优化、Fortran源代码分析、气候数据降尺度与变化影响分析

查看原文>>>全流程SWAP农业模型数据制备、敏感性分析及气候变化影响实践技术应用 SWAP模型是由荷兰瓦赫宁根大学开发的先进农作物模型,它综合考虑了土壤-水分-大气以及植被间的相互作用;是一种描述作物生长过程的一种机理性作物生长模型。它不但运用Richard方程,使其能够精确的模拟土壤中水分的运动,而且耦合了WOFOST作物模型使作物的生长描述更为科学。 本文让更多的科研人员和农业工作者

MOLE 2.5 分析分子通道和孔隙

软件介绍 生物大分子通道和孔隙在生物学中发挥着重要作用,例如在分子识别和酶底物特异性方面。 我们介绍了一种名为 MOLE 2.5 的高级软件工具,该工具旨在分析分子通道和孔隙。 与其他可用软件工具的基准测试表明,MOLE 2.5 相比更快、更强大、功能更丰富。作为一项新功能,MOLE 2.5 可以估算已识别通道的物理化学性质。 软件下载 https://pan.quark.cn/s/57

工厂ERP管理系统实现源码(JAVA)

工厂进销存管理系统是一个集采购管理、仓库管理、生产管理和销售管理于一体的综合解决方案。该系统旨在帮助企业优化流程、提高效率、降低成本,并实时掌握各环节的运营状况。 在采购管理方面,系统能够处理采购订单、供应商管理和采购入库等流程,确保采购过程的透明和高效。仓库管理方面,实现库存的精准管理,包括入库、出库、盘点等操作,确保库存数据的准确性和实时性。 生产管理模块则涵盖了生产计划制定、物料需求计划、

android-opencv-jni

//------------------start opencv--------------------@Override public void onResume(){ super.onResume(); //通过OpenCV引擎服务加载并初始化OpenCV类库,所谓OpenCV引擎服务即是 //OpenCV_2.4.3.2_Manager_2.4_*.apk程序包,存