UserManagerService的初始化其实是在PackageManagerService中,因为PackageManagerService启动的时间比UserManagerService早。
它们都是在SystemServer类的startBootstrapServices()中调用,如下:
…………
t.traceBegin("StartPackageManagerService");
try {
Watchdog.getInstance().pauseWatchingCurrentThread("packagemanagermain");
mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
domainVerificationService, mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF,
mOnlyCore);
} finally {
Watchdog.getInstance().resumeWatchingCurrentThread("packagemanagermain");
}
…………
t.traceBegin("StartUserManagerService");
mSystemServiceManager.startService(UserManagerService.LifeCycle.class);
t.traceEnd();
但是在PackageManagerService的main()里,它会执行UserManagerService的初始化。来看一下:
public static PackageManagerService main(Context context, Installer installer,
@NonNull DomainVerificationService domainVerificationService, boolean factoryTest,
boolean onlyCore) {
…………
Injector injector = new Injector(
…………
(i, pm) -> new UserManagerService(context, pm,
new UserDataPreparer(installer, installLock, context, onlyCore),
lock),
…………
);
PackageManagerService m = new PackageManagerService(injector, onlyCore, factoryTest,
Build.FINGERPRINT, Build.IS_ENG, Build.IS_USERDEBUG, Build.VERSION.SDK_INT,
Build.VERSION.INCREMENTAL);
…………
}
PackageManagerService的初始化参数是有Injector 类型injector,在它里面会调用到它
public PackageManagerService(Injector injector, boolean onlyCore, boolean factoryTest,
final String buildFingerprint, final boolean isEngBuild,
final boolean isUserDebugBuild, final int sdkVersion, final String incrementalVersion) {
…………
mUserManager = injector.getUserManagerService();
…………
}
再看看Injector 的getUserManagerService():
public static class Injector {
…………
static class Singleton<T> {
private final Producer<T> mProducer;
private volatile T mInstance = null;
Singleton(Producer<T> producer) {
this.mProducer = producer;
}
T get(Injector injector, PackageManagerService packageManagerService) {
if (mInstance == null) {
mInstance = mProducer.produce(injector, packageManagerService);
}
return mInstance;
}
}
…………
private final Singleton<UserManagerService> mUserManagerProducer;
…………
public UserManagerService getUserManagerService() {
return mUserManagerProducer.get(this, mPackageManager);
}
}
再结合在PackageManagerService main()里声明的Lambda表达式,所以在PackageManagerService的初始化中的时候,会调用UserManagerService的初始化。
由上面得知,UserManagerService的初始化调用的是4个参数的初始化函数:
/**
* Called by package manager to create the service. This is closely
* associated with the package manager, and the given lock is the
* package manager's own lock.
*/
UserManagerService(Context context, PackageManagerService pm, UserDataPreparer userDataPreparer,
Object packagesLock) {
this(context, pm, userDataPreparer, packagesLock, Environment.getDataDirectory());
}
private UserManagerService(Context context, PackageManagerService pm,
UserDataPreparer userDataPreparer, Object packagesLock, File dataDir) {
mContext = context;
mPm = pm;
mPackagesLock = packagesLock;
mHandler = new MainHandler();
mUserDataPreparer = userDataPreparer;
mUserTypes = UserTypeFactory.getUserTypes();
invalidateOwnerNameIfNecessary(context.getResources(), true /* forceUpdate */);
synchronized (mPackagesLock) {
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));
userZeroDir.mkdirs();
FileUtils.setPermissions(mUsersDir.toString(),
FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IROTH | FileUtils.S_IXOTH,
-1, -1);
mUserListFile = new File(mUsersDir, USER_LIST_FILENAME);
initDefaultGuestRestrictions();
readUserListLP();
sInstance = this;
}
mSystemPackageInstaller = new UserSystemPackageInstaller(this, mUserTypes);
mLocalService = new LocalService();
LocalServices.addService(UserManagerInternal.class, mLocalService);
mLockPatternUtils = new LockPatternUtils(mContext);
mUserStates.put(UserHandle.USER_SYSTEM, UserState.STATE_BOOTING);
mUser0Allocations = DBG_ALLOCATION ? new AtomicInteger() : null;
}
初始化主要做了以下几件事:
1、初始化成员变量。
2、得到用户类型,调用UserTypeFactory.getUserTypes(),放到mUserTypes 成员变量中。
3、取得成员变量mOwnerName值。
4、初始化默认客人限制
5、读取用户列表文件,得到用户
6、初始化UserSystemPackageInstaller
7、将LocalService类实例添加到LocalServices维护的列表中,将mUserStates中UserHandle.USER_SYSTEM的状态设置为UserState.STATE_BOOTING。
主要说一下2、3、4、5、6步骤。
UserManagerService在初始化时,调用mUserTypes = UserTypeFactory.getUserTypes(),它的实现在文件UserTypeFactory.java中
public static ArrayMap<String, UserTypeDetails> getUserTypes() {
final ArrayMap<String, UserTypeDetails.Builder> builders = getDefaultBuilders();
try (XmlResourceParser parser =
Resources.getSystem().getXml(com.android.internal.R.xml.config_user_types)) {
customizeBuilders(builders, parser);
}
final ArrayMap<String, UserTypeDetails> types = new ArrayMap<>(builders.size());
for (int i = 0; i < builders.size(); i++) {
types.put(builders.keyAt(i), builders.valueAt(i).createUserTypeDetails());
}
return types;
}
逻辑很简单,先是通过getDefaultBuilders()得到,然后再去资源配置文件config_user_types中取得,最后转化成ArrayMap
先看getDefaultBuilders():
private static ArrayMap<String, UserTypeDetails.Builder> getDefaultBuilders() {
final ArrayMap<String, UserTypeDetails.Builder> builders = new ArrayMap<>();
builders.put(USER_TYPE_PROFILE_MANAGED, getDefaultTypeProfileManaged());
builders.put(USER_TYPE_FULL_SYSTEM, getDefaultTypeFullSystem());
builders.put(USER_TYPE_FULL_SECONDARY, getDefaultTypeFullSecondary());
builders.put(USER_TYPE_FULL_GUEST, getDefaultTypeFullGuest());
builders.put(USER_TYPE_FULL_DEMO, getDefaultTypeFullDemo());
builders.put(USER_TYPE_FULL_RESTRICTED, getDefaultTypeFullRestricted());
builders.put(USER_TYPE_SYSTEM_HEADLESS, getDefaultTypeSystemHeadless());
builders.put(USER_TYPE_PROFILE_CLONE, getDefaultTypeProfileClone());
if (Build.IS_DEBUGGABLE) {
builders.put(USER_TYPE_PROFILE_TEST, getDefaultTypeProfileTest());
}
return builders;
}
这里先添加了8中类型的用户类型,如果当前系统的编译的是userdebug或eng版本时,还会再添加一种USER_TYPE_PROFILE_TEST。如果系统是user版本,则不会加最后一种类型。
看一下UserTypeDetails类的成员变量
其中mMaxAllowed的值有的是UNLIMITED_NUMBER_OF_USERS,为该值,就是不加限制。USER_TYPE_FULL_GUEST类型的mDefaultUserInfoPropertyFlags的值,和资源配置变量config_guestUserEphemeral有关,如果配置为true,mDefaultUserInfoPropertyFlags的值就为FLAG_GUEST | FLAG_EPHEMERAL。这九种用户类型的名字都是"android"开头的。
getDefaultBuilders()得到的是UserTypeDetails的建造类UserTypeDetails.Builder,最后会通过它的createUserTypeDetails()生成UserTypeDetails类对象。
这是通过getDefaultBuilders()得到的,再看看通过资源配置文件得到的UserTypeDetails.Builder。
用户类型的资源配置,在系统的资源xml文件夹下的config_user_types.xml中。找到该文件,里面现在是什么也没配置,都注释掉了。
解析的方法是customizeBuilders(builders, parser),主要就是解析xml文件。
这里主要说的一点就是,配置的用户类型的名字,如果是"android"开头,就得配置成上面9种中的一种,不然会报错。如果配置成上面9种之一,它是可以改变之前的配置的。
xml里面配置的主要是三种标签full-type,profile-type,change-user-type。但customizeBuilders(builders, parser)主要就是处理full-type,profile-type。profile-type开头的,则将BaseType配置为FLAG_PROFILE,新增一个用户类型。change-user-type在这里是直接跳过的。
它主要调用invalidateOwnerNameIfNecessary()实现:
private void invalidateOwnerNameIfNecessary(@NonNull Resources res, boolean forceUpdate) {
final int configChanges = mLastConfiguration.updateFrom(res.getConfiguration());
if (forceUpdate || (configChanges & mOwnerNameTypedValue.changingConfigurations) != 0) {
res.getValue(com.android.internal.R.string.owner_name, mOwnerNameTypedValue, true);
final CharSequence ownerName = mOwnerNameTypedValue.coerceToString();
mOwnerName.set(ownerName != null ? ownerName.toString() : null);
}
}
因为参数forceUpdate为true,所以它是取资源配置文件里的owner_name的值。打开资源文件,看一下它配置的值
<string name="owner_name" msgid="3879126011135546571">Owner</string>
可见,这里将成员变量mOwnerName设置为Owner。
它是调用initDefaultGuestRestrictions()实现的,看一下代码:
private void initDefaultGuestRestrictions() {
synchronized (mGuestRestrictions) {
if (mGuestRestrictions.isEmpty()) {
UserTypeDetails guestType = mUserTypes.get(UserManager.USER_TYPE_FULL_GUEST);
if (guestType == null) {
Slog.wtf(LOG_TAG, "Can't set default guest restrictions: type doesn't exist.");
return;
}
guestType.addDefaultRestrictionsTo(mGuestRestrictions);
}
}
}
从前面我们知道,mUserTypes里面包含各种用户类型的信息。它的key就是用户类型的名字。这里面如果发现mGuestRestrictions是空,则会去找UserManager.USER_TYPE_FULL_GUEST类型的用户类型信息guestType 。然后再调用guestType 的addDefaultRestrictionsTo(mGuestRestrictions),将限制信息赋值给mGuestRestrictions。
从前面我们知道,它的限制为UserManager.DISALLOW_CONFIG_WIFI、UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES、UserManager.DISALLOW_CONFIG_CREDENTIALS。
读取用户列表文件,得到用户,是通过readUserListLP()实现的。先一段一段的看代码
@GuardedBy({"mRestrictionsLock", "mPackagesLock"})
private void readUserListLP() {
if (!mUserListFile.exists()) {
fallbackToSingleUserLP();
return;
}
mUserListFile的完整路径为/data/system/users/userlist.xml。它在刚开始第一次启动的时候,可能不存在。如果不存在,会调用fallbackToSingleUserLP(),通过名字,得知是回落到单用户。如果回落的话,该方法就返回,不再向下执行了。
看看fallbackToSingleUserLP()
@GuardedBy({"mPackagesLock", "mRestrictionsLock"})
private void fallbackToSingleUserLP() {
int flags = UserInfo.FLAG_SYSTEM | UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_ADMIN
| UserInfo.FLAG_PRIMARY;
// Create the system user
String systemUserType = UserManager.isHeadlessSystemUserMode() ?
UserManager.USER_TYPE_SYSTEM_HEADLESS : UserManager.USER_TYPE_FULL_SYSTEM;
flags |= mUserTypes.get(systemUserType).getDefaultUserInfoFlags();
UserInfo system = new UserInfo(UserHandle.USER_SYSTEM, null, null, flags, systemUserType);
UserData userData = putUserInfo(system);
mNextSerialNumber = MIN_USER_ID;
mUserVersion = USER_VERSION;
mUserTypeVersion = UserTypeFactory.getUserTypeVersion();
Bundle restrictions = new Bundle();
try {
final String[] defaultFirstUserRestrictions = mContext.getResources().getStringArray(
com.android.internal.R.array.config_defaultFirstUserRestrictions);
for (String userRestriction : defaultFirstUserRestrictions) {
if (UserRestrictionsUtils.isValidRestriction(userRestriction)) {
restrictions.putBoolean(userRestriction, true);
}
}
} catch (Resources.NotFoundException e) {
Slog.e(LOG_TAG, "Couldn't find resource: config_defaultFirstUserRestrictions", e);
}
if (!restrictions.isEmpty()) {
synchronized (mRestrictionsLock) {
mBaseUserRestrictions.updateRestrictions(UserHandle.USER_SYSTEM,
restrictions);
}
}
updateUserIds();
initDefaultGuestRestrictions();
writeUserLP(userData);
writeUserListLP();
}
UserManager.isHeadlessSystemUserMode()为true,会创建UserManager.USER_TYPE_SYSTEM_HEADLESS类型的用户。但是HeadlessSystemUserMode一般是用在汽车上。所以在这里是创建的是UserManager.USER_TYPE_FULL_SYSTEM用户。所以mUserTypes.get(systemUserType)得到的是UserManager.USER_TYPE_FULL_SYSTEM类型。它的getDefaultUserInfoFlags()得到的是mDefaultUserInfoPropertyFlags | mBaseType的值。所以它的flags为UserInfo.FLAG_SYSTEM | UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY | UserInfo.FLAG_FULL。
这里会生成UserInfo,并转化成UserData,并且将它放入成员变量mUsers中,key值为userInfo.id。
接着会去差本地资源数组config_defaultFirstUserRestrictions。如果配置的限制存在,并且符合要求的话,会将它作为UserHandle.USER_SYSTEM的限制放进成员变量mBaseUserRestrictions中。
再接着调用updateUserIds(),它主要根据mUsers中的值,来更新mUserIds和mUserIdsIncludingPreCreated中的值。
又调用initDefaultGuestRestrictions(),更新客户的限制。这个讲过了。
调用writeUserLP(userData),将刚创建的用户信息存储到xml文件中。
private void writeUserLP(UserData userData) {
if (DBG) {
debug("writeUserLP " + userData);
}
FileOutputStream fos = null;
AtomicFile userFile = new AtomicFile(new File(mUsersDir, userData.info.id + XML_SUFFIX));
try {
fos = userFile.startWrite();
writeUserLP(userData, fos);
userFile.finishWrite(fos);
} catch (Exception ioe) {
Slog.e(LOG_TAG, "Error writing user info " + userData.info.id, ioe);
userFile.failWrite(fos);
}
}
可见写入的文件名称为/data/system/users/0.xml。
接着就是调用writeUserLP(userData, fos)将用户信息按照二进制xml文件格式写入。
fallbackToSingleUserLP()最后就是调用writeUserListLP()写入用户列表文件。因为我们现在是走的回落逻辑,现在用户也已经创建了,所以现在将用户列表信息写入到mUserListFile中去。
它会先写mGuestRestrictions中的内容,然后再写用户id。
写完mUserListFile之后,下次再重启进来调用readUserListLP(),这个时候就存在了。就可以向下执行。不过由于我们写入的列表也就只有一个用户,所以读出来还是单用户。
fallbackToSingleUserLP()的逻辑处理完了,需要接着读readUserListLP()的第二段代码:
FileInputStream fis = null;
AtomicFile userListFile = new AtomicFile(mUserListFile);
try {
fis = userListFile.openRead();
final TypedXmlPullParser parser = Xml.resolvePullParser(fis);
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)) {
mNextSerialNumber =
parser.getAttributeInt(null, ATTR_NEXT_SERIAL_NO, mNextSerialNumber);
mUserVersion =
parser.getAttributeInt(null, ATTR_USER_VERSION, mUserVersion);
mUserTypeVersion =
parser.getAttributeInt(null, ATTR_USER_TYPE_VERSION, mUserTypeVersion);
}
这里开始解析xml列表文件,会去tag为TAG_USERS的属性里取mNextSerialNumber 、mUserVersion 、mUserTypeVersion 的值。
接着读readUserListLP()的第三段代码:
// Pre-O global user restriction were stored as a single bundle (as opposed to per-user
// currently), take care of it in case of upgrade.
Bundle oldDevicePolicyGlobalUserRestrictions = null;
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
if (type == XmlPullParser.START_TAG) {
final String name = parser.getName();
if (name.equals(TAG_USER)) {
UserData userData = readUserLP(parser.getAttributeInt(null, ATTR_ID));
if (userData != null) {
synchronized (mUsersLock) {
mUsers.put(userData.info.id, userData);
if (mNextSerialNumber < 0
|| mNextSerialNumber <= userData.info.id) {
mNextSerialNumber = userData.info.id + 1;
}
}
}
这里接着去处理tag为TAG_USER的情况,parser.getAttributeInt(null, ATTR_ID)得到属性ATTR_ID的id值。然后调用readUserLP()得到用户的信息。readUserLP()主要是根据id值,找到/data/system/users/+(id)+.xml文件,然后接着解析出来用户所有的信息值。然后返回UserData 类型值。readUserLP()还会更新mBaseUserRestrictions中的值,它主要对应着标签TAG_RESTRICTIONS中的值。同样,它也会更新成员变量mDevicePolicyLocalUserRestrictions、mDevicePolicyGlobalUserRestrictions的值。
如果有多个用户,都会放到mUsers中。
接着读readUserListLP()的第四段代码:
} 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);
}
}
break;
}
}
} else if (name.equals(TAG_DEVICE_OWNER_USER_ID)
// Legacy name, should only be encountered when upgrading from pre-O.
|| name.equals(TAG_GLOBAL_RESTRICTION_OWNER_ID)) {
mDeviceOwnerUserId =
parser.getAttributeInt(null, ATTR_ID, mDeviceOwnerUserId);
} else if (name.equals(TAG_DEVICE_POLICY_RESTRICTIONS)) {
// Should only happen when upgrading from pre-O (version < 7).
oldDevicePolicyGlobalUserRestrictions =
UserRestrictionsUtils.readRestrictions(parser);
}
}
}
这块代码主要就是处理tag为TAG_GUEST_RESTRICTIONS、TAG_DEVICE_OWNER_USER_ID、TAG_DEVICE_POLICY_RESTRICTIONS的情况。tag为TAG_GUEST_RESTRICTIONS,就是更新mGuestRestrictions。tag为TAG_DEVICE_OWNER_USER_ID,就得到mDeviceOwnerUserId。tag为TAG_DEVICE_POLICY_RESTRICTIONS,就解析得到oldDevicePolicyGlobalUserRestrictions的值。
接着读readUserListLP()的第五段代码:
updateUserIds();
upgradeIfNecessaryLP(oldDevicePolicyGlobalUserRestrictions);
} catch (IOException | XmlPullParserException e) {
fallbackToSingleUserLP();
} finally {
IoUtils.closeQuietly(fis);
}
}
前面讲过updateUserIds(),主要就是更新一下id值。
这样如果/data/system/users/userlist.xml配置了多个用户,这时,它们就放在mUsers中了。
UserSystemPackageInstaller(UserManagerService um, ArrayMap<String, UserTypeDetails> userTypes) {
mUm = um;
mUserTypes = getAndSortKeysFromMap(userTypes);
if (mUserTypes.length > Long.SIZE) {
throw new IllegalArgumentException("Device contains " + userTypes.size()
+ " user types. However, UserSystemPackageInstaller does not work if there are"
+ " more than " + Long.SIZE + " user types.");
// UserSystemPackageInstaller could use a BitSet instead of Long in this case.
// But, currently, 64 user types is far beyond expectations, so we have not done so.
}
mWhitelistedPackagesForUserTypes =
determineWhitelistedPackagesForUserTypes(SystemConfig.getInstance());
}
先将um赋值给成员变量mUm,然后将用户类型列表的key进行排序,生成mUserTypes ,这里的key是用户类型的名称。
然后会调用determineWhitelistedPackagesForUserTypes()得到成员变量mWhitelistedPackagesForUserTypes 。
@VisibleForTesting
ArrayMap<String, Long> determineWhitelistedPackagesForUserTypes(SystemConfig sysConfig) {
// We first get the list of user types that correspond to FULL, SYSTEM, and PROFILE.
final Map<String, Long> baseTypeBitSets = getBaseTypeBitSets();
final ArrayMap<String, Set<String>> whitelist =
sysConfig.getAndClearPackageToUserTypeWhitelist();
// result maps packageName -> userTypes on which the package should be installed.
final ArrayMap<String, Long> result = new ArrayMap<>(whitelist.size() + 1);
// First, do the allowlisted user types.
for (int i = 0; i < whitelist.size(); i++) {
final String pkgName = whitelist.keyAt(i).intern();
final long typesBitSet = getTypesBitSet(whitelist.valueAt(i), baseTypeBitSets);
if (typesBitSet != 0) {
result.put(pkgName, typesBitSet);
}
}
// Then, un-allowlist any denylisted user types.
final ArrayMap<String, Set<String>> blacklist =
sysConfig.getAndClearPackageToUserTypeBlacklist();
for (int i = 0; i < blacklist.size(); i++) {
final String pkgName = blacklist.keyAt(i).intern();
final long nonTypesBitSet = getTypesBitSet(blacklist.valueAt(i), baseTypeBitSets);
final Long typesBitSet = result.get(pkgName);
if (typesBitSet != null) {
result.put(pkgName, typesBitSet & ~nonTypesBitSet);
} else if (nonTypesBitSet != 0) {
// Package was never allowlisted but is validly denylisted.
result.put(pkgName, 0L);
}
}
// Regardless of the whitelists/blacklists, ensure mandatory packages.
result.put("android", ~0L);
return result;
}
getBaseTypeBitSets() 得到用户类型对应的在mUserTypes 数组的bit位,得到的是一个ArrayMap,通过key:FULL,SYSTEM,PROFILE得到对应的bit位,bit位在第几位,就能在mUserTypes 中的第几位找到对应的用户类型。
sysConfig.getAndClearPackageToUserTypeWhitelist()得到的是哪些包能被哪些类型的用户安装。得到结果是ArrayMap
遍历whitelist,然后调用getTypesBitSet(whitelist.valueAt(i), baseTypeBitSets),whitelist.valueAt(i)是包能安装的用户类型,baseTypeBitSets是通过getBaseTypeBitSets()得到的结果。
private long getTypesBitSet(Iterable<String> userTypes, Map<String, Long> baseTypeBitSets) {
long resultBitSet = 0;
for (String type : userTypes) {
// See if userType is a base type, like FULL.
final Long baseTypeBitSet = baseTypeBitSets.get(type);
if (baseTypeBitSet != null) {
resultBitSet |= baseTypeBitSet;
continue;
}
// userType wasn't a base type, so it should be the name of a specific user type.
final long userTypeBitSet = getUserTypeMask(type);
if (userTypeBitSet != 0) {
resultBitSet |= userTypeBitSet;
continue;
}
Slog.w(TAG, "SystemConfig contained an invalid user type: " + type);
}
return resultBitSet;
}
可以看到,先在baseTypeBitSets中查找,查找到就知道了对应的bit位。放到resultBitSet中。如果没在baseTypeBitSets查找到,还需要调用getUserTypeMask(type)查找对应的位置,看一下:
@VisibleForTesting
long getUserTypeMask(String userType) {
final int userTypeIndex = Arrays.binarySearch(mUserTypes, userType);
final long userTypeMask = userTypeIndex >= 0 ? (1 << userTypeIndex) : 0;
return userTypeMask;
}
可以看到,mUserTypes是已经排好序的用户类型,所以采用二分查找方法,找到对应位置,用位移得到对应的bit位。
getUserTypeMask(),得到结果,也在getTypesBitSet()中,存在resultBitSet中。这样就找到了能被哪些用户类型安装。
sysConfig.getAndClearPackageToUserTypeBlacklist()得到的对应的包不能被哪些用户类型安装,所以要在前面的结果中去除。所以下面的处理也就是这样的。
最后将android包,设置成能被所有用户类型安装。
这样,determineWhitelistedPackagesForUserTypes()得到的成员变量mWhitelistedPackagesForUserTypes 就包含了包能被哪些用户类型安装。
这样,终于将UserManagerService初始化说完了。它主要设置用户类型,得到用户数据。我们知道,在最开始不存在/data/system/users/userlist.xml的情况下,会回落到单用户模式。生成用户以后,它会将用户信息保存成/data/system/users/id.xml,将用户列表保存成/data/system/users/userlist.xml。他还会得到系统包能被哪些用户类型安装。还会将mUserStates中UserHandle.USER_SYSTEM的状态设置为UserState.STATE_BOOTING。