Android UserManagerService初始化

UserManagerService初始化在哪里?

  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初始化

  由上面得知,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<String, UserTypeDetails>类型types返回结果。
  先看getDefaultBuilders():

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类的成员变量
usertypedetail成员变量结构图

UserTypeDetails成员变量结构图
  再看看执行完毕之后,具体各个用户类型的具体值

用户类型设置内容图

扫描二维码关注公众号,回复: 16494978 查看本文章
各个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。

customizeBuilders(builders, parser)

  用户类型的资源配置,在系统的资源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在这里是直接跳过的。

取得成员变量mOwnerName值

  它主要调用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()

  看看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

    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 。

determineWhitelistedPackagesForUserTypes()

    @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<String, Set>,意味着一个包可以能被多个用户类型装。
  遍历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。

猜你喜欢

转载自blog.csdn.net/q1165328963/article/details/124914339