美文网首页
基于Android9.0的PackageManagerServi

基于Android9.0的PackageManagerServi

作者: android_coder | 来源:发表于2019-04-14 18:29 被阅读0次

    PackageManagerService也是系统里面一个很重要的服务,管理着所有的跟包(package)相关的工作,譬如应用的安装,卸载,升级等,PackageManagerService的启动和其他服务一样也是在SystemServer里面启动,Systemserver启动过程中涉及到PMS的主要在启动引导服务startBootstrapServices和启动其他服务的时候这两个方法中有涉及到,下面就来看看具体的涉及到的点,本文是基于Android9.0来分析的

    PMS的启动

     private void startBootstrapServices() {
            // Wait for installd to finish starting up so that it has a chance to
            // create critical directories such as /data/user with the appropriate
            // permissions.  We need this to complete before we initialize other services.
            traceBeginAndSlog("StartInstaller");
            Installer installer = mSystemServiceManager.startService(Installer.class);
            traceEnd();
            // Only run "core" apps if we're encrypting the device.
            String cryptState = SystemProperties.get("vold.decrypt");
            if (ENCRYPTING_STATE.equals(cryptState)) {
                Slog.w(TAG, "Detected encryption in progress - only parsing core apps");
                mOnlyCore = true;
            } else if (ENCRYPTED_STATE.equals(cryptState)) {
                Slog.w(TAG, "Device encrypted - only parsing core apps");
                mOnlyCore = true;
            }
    
            // Start the package manager.
            if (!mRuntimeRestart) {
                MetricsLogger.histogram(null, "boot_package_manager_init_start",
                        (int) SystemClock.elapsedRealtime());
            }
            traceBeginAndSlog("StartPackageManagerService");
            mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
                    mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
            mFirstBoot = mPackageManagerService.isFirstBoot();
            mPackageManager = mSystemContext.getPackageManager();
            traceEnd();
            if (!mRuntimeRestart && !isFirstBootOrUpgrade()) {
                MetricsLogger.histogram(null, "boot_package_manager_init_ready",
                        (int) SystemClock.elapsedRealtime());
            }
            // Manages A/B OTA dexopting. This is a bootstrap service as we need it to rename
            // A/B artifacts after boot, before anything else might touch/need them.
            // Note: this isn't needed during decryption (we don't have /data anyways).
            if (!mOnlyCore) {
                boolean disableOtaDexopt = SystemProperties.getBoolean("config.disable_otadexopt",
                        false);
                if (!disableOtaDexopt) {
                    traceBeginAndSlog("StartOtaDexOptService");
                    try {
                        OtaDexoptService.main(mSystemContext, mPackageManagerService);
                    } catch (Throwable e) {
                        reportWtf("starting OtaDexOptService", e);
                    } finally {
                        traceEnd();
                    }
                }
            }
    

    该过程中首先有个关键的动作就是启动Installer服务,也就是安装器,随后判断当前的设备是否处于加密状态,如果是则只是解析核心应用,接着调用PackageManagerService的静态方法main来创建pms对象

        public static PackageManagerService main(Context context, Installer installer,
                boolean factoryTest, boolean onlyCore) {
            // Self-check for initial settings.
            PackageManagerServiceCompilerMapping.checkProperties();
    
            PackageManagerService m = new PackageManagerService(context, installer,
                    factoryTest, onlyCore);
            m.enableSystemUserPackages();
            ServiceManager.addService("package", m);
            final PackageManagerNative pmn = m.new PackageManagerNative();
            ServiceManager.addService("package_native", pmn);
            return m;
        }
    

    创建完成之后将其注册到ServiceManager中,serviceManager是所有服务的管家
    接着,根据上面判断设备是否加密来判断是否启动OtaDexoptService服务

         if (!mOnlyCore) {
                boolean disableOtaDexopt = SystemProperties.getBoolean("config.disable_otadexopt",
                        false);
                if (!disableOtaDexopt) {
                    traceBeginAndSlog("StartOtaDexOptService");
                    try {
                        OtaDexoptService.main(mSystemContext, mPackageManagerService);
                    } catch (Throwable e) {
                        reportWtf("starting OtaDexOptService", e);
                    } finally {
                        traceEnd();
                    }
                }
            }
    

    再来看看startOtherService

          traceBeginAndSlog("MakePackageManagerServiceReady");
            mPackageManagerService.systemReady();
            traceEnd();
    

    接下来就分析几个关键的点
    PMS::main方法和systemReady方法

    PMS之构造方法

    主要是分为两部分,需要持有两个同步锁和不需要持锁的部分

            LockGuard.installLock(mPackages, LockGuard.INDEX_PACKAGES);
            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "create package 
          manager");
            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
                    SystemClock.uptimeMillis());
    
            if (mSdkVersion <= 0) { //检查sdk版本
                Slog.w(TAG, "**** ro.build.version.sdk not set!");
            }
            mContext = context;//上下文对象
            mFactoryTest = factoryTest;//工程测试
            mOnlyCore = onlyCore;
            mMetrics = new DisplayMetrics();//构造和显示屏幕相关的信息,分辨率,屏幕尺寸等
            mInstaller = installer;//安装器,和本地守护进程installed交换的,通信方式socket
    

    需要同时持有两个同步锁的部分

           // Create sub-components that provide services / data. Order here is important.
            synchronized (mInstallLock) {
            synchronized (mPackages) {
                // Expose private service for system components to use.
                LocalServices.addService(
                        PackageManagerInternal.class, new PackageManagerInternalImpl());
                sUserManager = new UserManagerService(context, this,//用户管理相关的
                        new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages);
                mPermissionManager = PermissionManagerService.create(context,
                        new DefaultPermissionGrantedCallback() {
                            @Override
                            public void onDefaultRuntimePermissionsGranted(int userId) {
                                synchronized(mPackages) {
                                    mSettings.onDefaultRuntimePermissionsGrantedLPr(userId);
                                }
                            }
                        }, mPackages /*externalLock*/);
                mDefaultPermissionPolicy = mPermissionManager.getDefaultPermissionGrantPolicy();
                mSettings = new Settings(mPermissionManager.getPermissionSettings(), mPackages);
    //settings对象主要是存储系统运行过程中的用户的一些设置信息
            }
    
    mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
                    ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
            mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
                    ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
            mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
                    ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
            mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
                    ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
            mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
                    ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
            mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
                    ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
            mSettings.addSharedUserLPw("android.uid.se", SE_UID,
                    ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
    

    添加七种shardeduserid到settings中

    Settings对象

    构造方法

     Settings(PermissionSettings permissions, Object lock) {
            this(Environment.getDataDirectory(), permissions, lock);
        }
    
        Settings(File dataDir, PermissionSettings permission, Object lock) {
            mLock = lock;
            mPermissions = permission;
            mRuntimePermissionsPersistence = new RuntimePermissionPersistence(mLock);
    
            mSystemDir = new File(dataDir, "system");//创建指向/data/system/目录的文件
            mSystemDir.mkdirs();//创建目录
            FileUtils.setPermissions(mSystemDir.toString(),
                    FileUtils.S_IRWXU|FileUtils.S_IRWXG
                    |FileUtils.S_IROTH|FileUtils.S_IXOTH,
                    -1, -1);
            mSettingsFilename = new File(mSystemDir, "packages.xml");//用于描述系统所安装的package信息
            mBackupSettingsFilename = new File(mSystemDir, "packages-backup.xml");//备份文件,防止由于突然断电等异常情况
            mPackageListFilename = new File(mSystemDir, "packages.list");//记录应用的数据信息
            FileUtils.setPermissions(mPackageListFilename, 0640, SYSTEM_UID, PACKAGE_INFO_GID);
    
            final File kernelDir = new File("/config/sdcardfs");
            mKernelMappingFilename = kernelDir.exists() ? kernelDir : null;
    
            // Deprecated: Needed for migration
           //记录系统中处于stopped状态的应用信息,例如被强制停止运行的,第一次安装(install)的应用
            mStoppedPackagesFilename = new File(mSystemDir, "packages-stopped.xml");
            //上面文件的备份文件
            mBackupStoppedPackagesFilename = new File(mSystemDir, "packages-stopped-backup.xml");
        }
    

    settings构造方法主要的任务是建立与某些系统配置文件、目录之间的关联
    上面有两个备份文件back-up,其实android在修改packages.xml、packages-stopped.xml 之前会对其备份,如果对他们的修改正常完成,则完成之后删除备份文件,如果在修改过程中出现了断电,设备重启等异常情况,下一次操作时发现上面两个文件还存在,系统此时会读取之前的非备份文件,并且认为上一次对这两个文件的修改出现了异常

    Settings之addSharedUserLPw

      mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
                    ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
    

    找到addSharedUserLPw的实现

       SharedUserSetting addSharedUserLPw(String name, int uid, int pkgFlags, int pkgPrivateFlags) {
            SharedUserSetting s = mSharedUsers.get(name);
            if (s != null) {
                if (s.userId == uid) {
                    return s;
                }
                PackageManagerService.reportSettingsProblem(Log.ERROR,
                        "Adding duplicate shared user, keeping first: " + name);
                return null;
            }
            s = new SharedUserSetting(name, pkgFlags, pkgPrivateFlags);
            s.userId = uid;
            if (addUserIdLPw(uid, s, name)) {// 在系统中保存值为uid 的用户id,成功返回 true
                mSharedUsers.put(name, s); //将 name 与 s 键值对添加到 mSharedUsers 中保存
                return s;
            }
            return null;
        }
    

    我们可以看到Settings 中有一个 mSharedUsers 成员,该成员存储的是 【“字符串” 与 “SharedUserSetting” 键值对】,也就是说可以通过 字符串 为 key 得到对应的 SharedUserSetting 对象。

    SharedUserSetting

    如果我们做系统应用的话可以会接触到android:sharedUserId="android.uid.system"
    这句话的意思是让其运行在system进程中,
    1:如果两个应用或是更多都声明了同一个sharedUserId 是可以共享数据的,并且可以运行在同一个进程中
    2:通过声明特定的 sharedUserId,该 APK 所在 进程 将被赋予指定的 UID,其进程就可以享受该用户所对应的权限,譬如system,shell用户的权限
    有 3 个关键点需要注意:
    XML 中 sharedUserId 属性指定了一个字符串,它是 UID 的字符串描述,故对应数据结构中也应该有这样一个字符串,这样就把代码和 XML 中的属性联系起来了。
    在 LINUX 系统中,真正的 uid 是一个整数,所以该数据结构中必然有一个整型变量。
    多个 Package 可声明同一个 sharedUserId,因此该数据结构必然会保存那些声明了相同 sharedUserId 的 Package 的某些信息。
    我们回到上面的方法可以看到
    final ArrayMap<String, SharedUserSetting> mSharedUsers =
    new ArrayMap<String, SharedUserSetting>();
    settings中定义了一个成员变量mSharedUsers,他是ArrayMap类型,它的key类型是String,像android.uid.system,value值是SharedUserSetting对象,SharedUserSetting中定义了 一个packages对象
    final ArraySet<PackageSetting> packages = new ArraySet<PackageSetting>();
    它的类型是packages,类型是ArraySet,保存的是packagesetting信息,我们可以看下PackageSetting描述的有哪些信息

    PackageSetting

    它有四个成员变量

       int appId;//应用的id
        PackageParser.Package pkg; //package对象
        /**
         * WARNING. The object reference is important. We perform integer equality and NOT
         * object equality to check whether shared user settings are the same.
         */
        SharedUserSetting sharedUser;
        /**
         * Temporary holding space for the shared user ID. While parsing package settings, the
         * shared users tag may come after the packages. In this case, we must delay linking the
         * shared user setting with the package setting. The shared user ID lets us link the
         * two objects.
         */
        private int sharedUserId;
    

    PackageSetting本身是继承PackageSettingBase的,PackageSettingBase又继承SettingBase

    public final class PackageSetting extends PackageSettingBase {}
    public abstract class PackageSettingBase extends SettingBase {}
    

    settingBase有三个成员变量
    int pkgFlags;//flag
    int pkgPrivateFlags;//私有的flag
    protected final PermissionsState mPermissionsState;//权限信息,权限分为运行时权限和安装时就赋予的权限,mPermissionsState里面存储的就是这些可用的权限信息

        public boolean hasPermission(String name, int userId) {//判断对应的user是否具有该权限name
            enforceValidUserId(userId);
            if (mPermissions == null) {
                return false;
            }
            PermissionData permissionData = mPermissions.get(name);
            return permissionData != null && permissionData.isGranted(userId);
        }
    

    Dex优化相关

     mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
                    "*dexopt*");//dex优化的辅助类
            DexManager.Listener dexManagerListener = DexLogger.getListener(this,
                    installer, mInstallLock);
            mDexManager = new DexManager(mContext, this, mPackageDexOptimizer, installer, mInstallLock,
                    dexManagerListener);//dex管理器
            mArtManagerService = new ArtManagerService(mContext, this, installer, mInstallLock);
            mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
          //handler工作类,对应于android.fg线程
            mOnPermissionChangeListeners = new OnPermissionChangeListeners(
                    FgThread.get().getLooper());//权限变更监听器
            getDefaultDisplayMetrics(context, mMetrics);
            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "get system config");
            SystemConfig systemConfig = SystemConfig.getInstance();//系统配置
            mAvailableFeatures = systemConfig.getAvailableFeatures();
            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
            mProtectedPackages = new ProtectedPackages(mContext);
    

    SystemConfig

    我们看到SystemConfig的构造方法,主要是从文件中读取权限

      // Read configuration from system
            readPermissions(Environment.buildPath(
                    Environment.getRootDirectory(), "etc", "sysconfig"), ALLOW_ALL);
    
            // Read configuration from the old permissions dir
            readPermissions(Environment.buildPath(
                    Environment.getRootDirectory(), "etc", "permissions"), ALLOW_ALL);
    
            // Vendors are only allowed to customze libs, features and privapp permissions
            int vendorPermissionFlag = ALLOW_LIBS | ALLOW_FEATURES | ALLOW_PRIVAPP_PERMISSIONS;
            if (Build.VERSION.FIRST_SDK_INT <= Build.VERSION_CODES.O_MR1) {
                // For backward compatibility
                vendorPermissionFlag |= (ALLOW_PERMISSIONS | ALLOW_APP_CONFIGS);
            }
            readPermissions(Environment.buildPath(
                    Environment.getVendorDirectory(), "etc", "sysconfig"), vendorPermissionFlag);
            readPermissions(Environment.buildPath(
                    Environment.getVendorDirectory(), "etc", "permissions"), vendorPermissionFlag);
    
            // Allow ODM to customize system configs as much as Vendor, because /odm is another
            // vendor partition other than /vendor.
            int odmPermissionFlag = vendorPermissionFlag;
            readPermissions(Environment.buildPath(
                    Environment.getOdmDirectory(), "etc", "sysconfig"), odmPermissionFlag);
            readPermissions(Environment.buildPath(
                    Environment.getOdmDirectory(), "etc", "permissions"), odmPermissionFlag);
    
            // Allow OEM to customize features and OEM permissions
            int oemPermissionFlag = ALLOW_FEATURES | ALLOW_OEM_PERMISSIONS;
            readPermissions(Environment.buildPath(
                    Environment.getOemDirectory(), "etc", "sysconfig"), oemPermissionFlag);
            readPermissions(Environment.buildPath(
                    Environment.getOemDirectory(), "etc", "permissions"), oemPermissionFlag);
    
            // Allow Product to customize system configs around libs, features, permissions and apps
            int productPermissionFlag = ALLOW_LIBS | ALLOW_FEATURES | ALLOW_PERMISSIONS |
                    ALLOW_APP_CONFIGS | ALLOW_PRIVAPP_PERMISSIONS;
            readPermissions(Environment.buildPath(
                    Environment.getProductDirectory(), "etc", "sysconfig"), productPermissionFlag);
            readPermissions(Environment.buildPath(
                    Environment.getProductDirectory(), "etc", "permissions"), productPermissionFlag);
    

    我们可以看下readPermissions的方法实现

    void readPermissions(File libraryDir, int permissionFlag) {
            // Read permissions from given directory.
            if (!libraryDir.exists() || !libraryDir.isDirectory()) {//判断目录或是文件是否存在
                if (permissionFlag == ALLOW_ALL) {
                    Slog.w(TAG, "No directory " + libraryDir + ", skipping");
                }
                return;
            }
            if (!libraryDir.canRead()) {
                Slog.w(TAG, "Directory " + libraryDir + " cannot be read");
                return;
            }
    
            // Iterate over the files in the directory and scan .xml files
            File platformFile = null;
            for (File f : libraryDir.listFiles()) {
                // We'll read platform.xml last
                if (f.getPath().endsWith("etc/permissions/platform.xml")) {//platform.xml最后处理
                    platformFile = f;
                    continue;
                }
                if (!f.getPath().endsWith(".xml")) {
                    Slog.i(TAG, "Non-xml file " + f + " in " + libraryDir + " directory, ignoring");
                    continue;
                }
                if (!f.canRead()) {
                    Slog.w(TAG, "Permissions library file " + f + " cannot be read");
                    continue;
                }
                readPermissionsFromXml(f, permissionFlag);//从xml中读取权限,也是解析xml的过程
            }
            // Read platform permissions last so it will take precedence
            if (platformFile != null) {
                readPermissionsFromXml(platformFile, permissionFlag);
            }
        }
    

    readPermissionFromXML

    private void readPermissionsFromXml(File permFile, int permissionFlag) {
            FileReader permReader = null;
            try {
                permReader = new FileReader(permFile);
            } catch (FileNotFoundException e) {
                Slog.w(TAG, "Couldn't find or open permissions file " + permFile);
                return;
            }
    
            final boolean lowRam = ActivityManager.isLowRamDeviceStatic();
    
            try {
                XmlPullParser parser = Xml.newPullParser();
                parser.setInput(permReader);
    
                int type;
                while ((type=parser.next()) != parser.START_TAG
                           && type != parser.END_DOCUMENT) {
                    ;
                }
    
                if (type != parser.START_TAG) {
                    throw new XmlPullParserException("No start tag found");
                }
    
                if (!parser.getName().equals("permissions") && !parser.getName().equals("config")) {
                    throw new XmlPullParserException("Unexpected start tag in " + permFile
                            + ": found " + parser.getName() + ", expected 'permissions' or 'config'");
                }
    
                boolean allowAll = permissionFlag == ALLOW_ALL;
                boolean allowLibs = (permissionFlag & ALLOW_LIBS) != 0;
                boolean allowFeatures = (permissionFlag & ALLOW_FEATURES) != 0;
                boolean allowPermissions = (permissionFlag & ALLOW_PERMISSIONS) != 0;
                boolean allowAppConfigs = (permissionFlag & ALLOW_APP_CONFIGS) != 0;
                boolean allowPrivappPermissions = (permissionFlag & ALLOW_PRIVAPP_PERMISSIONS) != 0;
                boolean allowOemPermissions = (permissionFlag & ALLOW_OEM_PERMISSIONS) != 0;
                boolean allowApiWhitelisting = (permissionFlag & ALLOW_HIDDENAPI_WHITELISTING) != 0;
                while (true) {
                    XmlUtils.nextElement(parser);
                    if (parser.getEventType() == XmlPullParser.END_DOCUMENT) {
                        break;
                    }
    
                    String name = parser.getName();
                    if ("group".equals(name) && allowAll) {
                        String gidStr = parser.getAttributeValue(null, "gid");
                        if (gidStr != null) {
                            int gid = android.os.Process.getGidForName(gidStr);
                            mGlobalGids = appendInt(mGlobalGids, gid);
                        } else {
                            Slog.w(TAG, "<group> without gid in " + permFile + " at "
                                    + parser.getPositionDescription());
                        }
    
                        XmlUtils.skipCurrentTag(parser);
                        continue;
                    } else if ("permission".equals(name) && allowPermissions) {
                        String perm = parser.getAttributeValue(null, "name");
                        if (perm == null) {
                            Slog.w(TAG, "<permission> without name in " + permFile + " at "
                                    + parser.getPositionDescription());
                            XmlUtils.skipCurrentTag(parser);
                            continue;
                        }
                        perm = perm.intern();
                        readPermission(parser, perm);
    
                    } else if ("assign-permission".equals(name) && allowPermissions) {
                        String perm = parser.getAttributeValue(null, "name");
                        if (perm == null) {
                            Slog.w(TAG, "<assign-permission> without name in " + permFile + " at "
                                    + parser.getPositionDescription());
                            XmlUtils.skipCurrentTag(parser);
                            continue;
                        }
                        String uidStr = parser.getAttributeValue(null, "uid");
                        if (uidStr == null) {
                            Slog.w(TAG, "<assign-permission> without uid in " + permFile + " at "
                                    + parser.getPositionDescription());
                            XmlUtils.skipCurrentTag(parser);
                            continue;
                        }
                        int uid = Process.getUidForName(uidStr);
                        if (uid < 0) {
                            Slog.w(TAG, "<assign-permission> with unknown uid \""
                                    + uidStr + "  in " + permFile + " at "
                                    + parser.getPositionDescription());
                            XmlUtils.skipCurrentTag(parser);
                            continue;
                        }
                        perm = perm.intern();
                        ArraySet<String> perms = mSystemPermissions.get(uid);
                        if (perms == null) {
                            perms = new ArraySet<String>();
                            mSystemPermissions.put(uid, perms);
                        }
                        perms.add(perm);
                        XmlUtils.skipCurrentTag(parser);
    
                    } else if ("library".equals(name) && allowLibs) {
                        String lname = parser.getAttributeValue(null, "name");
                        String lfile = parser.getAttributeValue(null, "file");
                        if (lname == null) {
                            Slog.w(TAG, "<library> without name in " + permFile + " at "
                                    + parser.getPositionDescription());
                        } else if (lfile == null) {
                            Slog.w(TAG, "<library> without file in " + permFile + " at "
                                    + parser.getPositionDescription());
                        } else {
                            //Log.i(TAG, "Got library " + lname + " in " + lfile);
                            mSharedLibraries.put(lname, lfile);
                        }
                        XmlUtils.skipCurrentTag(parser);
                        continue;
    
                    } else if ("feature".equals(name) && allowFeatures) {
                        String fname = parser.getAttributeValue(null, "name");
                        int fversion = XmlUtils.readIntAttribute(parser, "version", 0);
                        boolean allowed;
                        if (!lowRam) {
                            allowed = true;
                        } else {
                            String notLowRam = parser.getAttributeValue(null, "notLowRam");
                            allowed = !"true".equals(notLowRam);
                        }
                        if (fname == null) {
                            Slog.w(TAG, "<feature> without name in " + permFile + " at "
                                    + parser.getPositionDescription());
                        } else if (allowed) {
                            addFeature(fname, fversion);
                        }
                        XmlUtils.skipCurrentTag(parser);
                        continue;
    
                    } else if ("unavailable-feature".equals(name) && allowFeatures) {
                        String fname = parser.getAttributeValue(null, "name");
                        if (fname == null) {
                            Slog.w(TAG, "<unavailable-feature> without name in " + permFile + " at "
                                    + parser.getPositionDescription());
                        } else {
                            mUnavailableFeatures.add(fname);
                        }
                        XmlUtils.skipCurrentTag(parser);
                        continue;
    
                    } else if ("allow-in-power-save-except-idle".equals(name) && allowAll) {
                        String pkgname = parser.getAttributeValue(null, "package");
                        if (pkgname == null) {
                            Slog.w(TAG, "<allow-in-power-save-except-idle> without package in "
                                    + permFile + " at " + parser.getPositionDescription());
                        } else {
                            mAllowInPowerSaveExceptIdle.add(pkgname);
                        }
                        XmlUtils.skipCurrentTag(parser);
                        continue;
    
                    } else if ("allow-in-power-save".equals(name) && allowAll) {
                        String pkgname = parser.getAttributeValue(null, "package");
                        if (pkgname == null) {
                            Slog.w(TAG, "<allow-in-power-save> without package in " + permFile + " at "
                                    + parser.getPositionDescription());
                        } else {
                            mAllowInPowerSave.add(pkgname);
                        }
                        XmlUtils.skipCurrentTag(parser);
                        continue;
    
                    } else if ("allow-in-data-usage-save".equals(name) && allowAll) {
                        String pkgname = parser.getAttributeValue(null, "package");
                        if (pkgname == null) {
                            Slog.w(TAG, "<allow-in-data-usage-save> without package in " + permFile
                                    + " at " + parser.getPositionDescription());
                        } else {
                            mAllowInDataUsageSave.add(pkgname);
                        }
                        XmlUtils.skipCurrentTag(parser);
                        continue;
    
                    } else if ("allow-unthrottled-location".equals(name) && allowAll) {
                        String pkgname = parser.getAttributeValue(null, "package");
                        if (pkgname == null) {
                            Slog.w(TAG, "<allow-unthrottled-location> without package in "
                                + permFile + " at " + parser.getPositionDescription());
                        } else {
                            mAllowUnthrottledLocation.add(pkgname);
                        }
                        XmlUtils.skipCurrentTag(parser);
                        continue;
    
                    } else if ("allow-implicit-broadcast".equals(name) && allowAll) {
                        String action = parser.getAttributeValue(null, "action");
                        if (action == null) {
                            Slog.w(TAG, "<allow-implicit-broadcast> without action in " + permFile
                                    + " at " + parser.getPositionDescription());
                        } else {
                            mAllowImplicitBroadcasts.add(action);
                        }
                        XmlUtils.skipCurrentTag(parser);
                        continue;
    
                    } else if ("app-link".equals(name) && allowAppConfigs) {
                        String pkgname = parser.getAttributeValue(null, "package");
                        if (pkgname == null) {
                            Slog.w(TAG, "<app-link> without package in " + permFile + " at "
                                    + parser.getPositionDescription());
                        } else {
                            mLinkedApps.add(pkgname);
                        }
                        XmlUtils.skipCurrentTag(parser);
                    } else if ("system-user-whitelisted-app".equals(name) && allowAppConfigs) {
                        String pkgname = parser.getAttributeValue(null, "package");
                        if (pkgname == null) {
                            Slog.w(TAG, "<system-user-whitelisted-app> without package in " + permFile
                                    + " at " + parser.getPositionDescription());
                        } else {
                            mSystemUserWhitelistedApps.add(pkgname);
                        }
                        XmlUtils.skipCurrentTag(parser);
                    } else if ("system-user-blacklisted-app".equals(name) && allowAppConfigs) {
                        String pkgname = parser.getAttributeValue(null, "package");
                        if (pkgname == null) {
                            Slog.w(TAG, "<system-user-blacklisted-app without package in " + permFile
                                    + " at " + parser.getPositionDescription());
                        } else {
                            mSystemUserBlacklistedApps.add(pkgname);
                        }
                        XmlUtils.skipCurrentTag(parser);
                    } else if ("default-enabled-vr-app".equals(name) && allowAppConfigs) {
                        String pkgname = parser.getAttributeValue(null, "package");
                        String clsname = parser.getAttributeValue(null, "class");
                        if (pkgname == null) {
                            Slog.w(TAG, "<default-enabled-vr-app without package in " + permFile
                                    + " at " + parser.getPositionDescription());
                        } else if (clsname == null) {
                            Slog.w(TAG, "<default-enabled-vr-app without class in " + permFile
                                    + " at " + parser.getPositionDescription());
                        } else {
                            mDefaultVrComponents.add(new ComponentName(pkgname, clsname));
                        }
                        XmlUtils.skipCurrentTag(parser);
                    } else if ("backup-transport-whitelisted-service".equals(name) && allowFeatures) {
                        String serviceName = parser.getAttributeValue(null, "service");
                        if (serviceName == null) {
                            Slog.w(TAG, "<backup-transport-whitelisted-service> without service in "
                                    + permFile + " at " + parser.getPositionDescription());
                        } else {
                            ComponentName cn = ComponentName.unflattenFromString(serviceName);
                            if (cn == null) {
                                Slog.w(TAG,
                                        "<backup-transport-whitelisted-service> with invalid service name "
                                        + serviceName + " in "+ permFile
                                        + " at " + parser.getPositionDescription());
                            } else {
                                mBackupTransportWhitelist.add(cn);
                            }
                        }
                        XmlUtils.skipCurrentTag(parser);
                    } else if ("disabled-until-used-preinstalled-carrier-associated-app".equals(name)
                            && allowAppConfigs) {
                        String pkgname = parser.getAttributeValue(null, "package");
                        String carrierPkgname = parser.getAttributeValue(null, "carrierAppPackage");
                        if (pkgname == null || carrierPkgname == null) {
                            Slog.w(TAG, "<disabled-until-used-preinstalled-carrier-associated-app"
                                    + " without package or carrierAppPackage in " + permFile + " at "
                                    + parser.getPositionDescription());
                        } else {
                            List<String> associatedPkgs =
                                    mDisabledUntilUsedPreinstalledCarrierAssociatedApps.get(
                                            carrierPkgname);
                            if (associatedPkgs == null) {
                                associatedPkgs = new ArrayList<>();
                                mDisabledUntilUsedPreinstalledCarrierAssociatedApps.put(
                                        carrierPkgname, associatedPkgs);
                            }
                            associatedPkgs.add(pkgname);
                        }
                        XmlUtils.skipCurrentTag(parser);
                    } else if ("disabled-until-used-preinstalled-carrier-app".equals(name)
                            && allowAppConfigs) {
                        String pkgname = parser.getAttributeValue(null, "package");
                        if (pkgname == null) {
                            Slog.w(TAG,
                                    "<disabled-until-used-preinstalled-carrier-app> without "
                                            + "package in " + permFile + " at "
                                            + parser.getPositionDescription());
                        } else {
                            mDisabledUntilUsedPreinstalledCarrierApps.add(pkgname);
                        }
                        XmlUtils.skipCurrentTag(parser);
                    } else if ("privapp-permissions".equals(name) && allowPrivappPermissions) {
                        // privapp permissions from system, vendor and product partitions are stored
                        // separately. This is to prevent xml files in the vendor partition from
                        // granting permissions to priv apps in the system partition and vice
                        // versa.
                        boolean vendor = permFile.toPath().startsWith(
                                Environment.getVendorDirectory().toPath())
                                || permFile.toPath().startsWith(
                                    Environment.getOdmDirectory().toPath());
                        boolean product = permFile.toPath().startsWith(
                                Environment.getProductDirectory().toPath());
                        if (vendor) {
                            readPrivAppPermissions(parser, mVendorPrivAppPermissions,
                                    mVendorPrivAppDenyPermissions);
                        } else if (product) {
                            readPrivAppPermissions(parser, mProductPrivAppPermissions,
                                    mProductPrivAppDenyPermissions);
                        } else {
                            readPrivAppPermissions(parser, mPrivAppPermissions,
                                    mPrivAppDenyPermissions);
                        }
                    } else if ("oem-permissions".equals(name) && allowOemPermissions) {
                        readOemPermissions(parser);
                    } else if ("hidden-api-whitelisted-app".equals(name) && allowApiWhitelisting) {
                        String pkgname = parser.getAttributeValue(null, "package");
                        if (pkgname == null) {
                            Slog.w(TAG, "<hidden-api-whitelisted-app> without package in " + permFile
                                    + " at " + parser.getPositionDescription());
                        } else {
                            mHiddenApiPackageWhitelist.add(pkgname);
                        }
                        XmlUtils.skipCurrentTag(parser);
                    } else {
                        Slog.w(TAG, "Tag " + name + " is unknown or not allowed in "
                                + permFile.getParent());
                        XmlUtils.skipCurrentTag(parser);
                        continue;
                    }
                }
            } catch (XmlPullParserException e) {
                Slog.w(TAG, "Got exception parsing permissions.", e);
            } catch (IOException e) {
                Slog.w(TAG, "Got exception parsing permissions.", e);
            } finally {
                IoUtils.closeQuietly(permReader);
            }
    
            // Some devices can be field-converted to FBE, so offer to splice in
            // those features if not already defined by the static config
            if (StorageManager.isFileEncryptedNativeOnly()) {
                addFeature(PackageManager.FEATURE_FILE_BASED_ENCRYPTION, 0);
                addFeature(PackageManager.FEATURE_SECURELY_REMOVES_USERS, 0);
            }
    
            // Help legacy devices that may not have updated their static config
            if (StorageManager.hasAdoptable()) {
                addFeature(PackageManager.FEATURE_ADOPTABLE_STORAGE, 0);
            }
    
            if (ActivityManager.isLowRamDeviceStatic()) {
                addFeature(PackageManager.FEATURE_RAM_LOW, 0);
            } else {
                addFeature(PackageManager.FEATURE_RAM_NORMAL, 0);
            }
    
            for (String featureName : mUnavailableFeatures) {
                removeFeature(featureName);
            }
        }
    

    我们可以看到上面主要的作用就是将xml转化为对应的数据结构

    HandleThread之创建

     mHandlerThread = new ServiceThread(TAG,
                        Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);//创建packagemanager线程
                mHandlerThread.start();//启动线程
                mHandler = new PackageHandler(mHandlerThread.getLooper());
                mProcessLoggingHandler = new ProcessLoggingHandler();
                Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
                mInstantAppRegistry = new InstantAppRegistry(this);
    
                ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();//libs库
                final int builtInLibCount = libConfig.size();
                for (int i = 0; i < builtInLibCount; i++) {
                    String name = libConfig.keyAt(i);
                    String path = libConfig.valueAt(i);
                    addSharedLibraryLPw(path, null, name, SharedLibraryInfo.VERSION_UNDEFINED,
                            SharedLibraryInfo.TYPE_BUILTIN, PLATFORM_PACKAGE_NAME, 0);
                }
    
                SELinuxMMAC.readInstallPolicy();
    
                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "loadFallbacks");
                FallbackCategoryProvider.loadFallbacks();
                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
    
                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "read user settings");
                mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false));//是否是首次启动
                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
    
                // Clean up orphaned packages for which the code path doesn't exist
                // and they are an update to a system app - caused by bug/32321269
                final int packageSettingCount = mSettings.mPackages.size();
                for (int i = packageSettingCount - 1; i >= 0; i--) {
                    PackageSetting ps = mSettings.mPackages.valueAt(i);
                    if (!isExternal(ps) && (ps.codePath == null || !ps.codePath.exists())
                            && mSettings.getDisabledSystemPkgLPr(ps.name) != null) {
                        mSettings.mPackages.removeAt(i);//移除不存在的package
                        mSettings.enableSystemPackageLPw(ps.name);
                    }
                }
    
                if (!mOnlyCore && mFirstBoot) {
                    requestCopyPreoptedFiles();
                }
    
                String customResolverActivity = Resources.getSystem().getString(
                        R.string.config_customResolverActivity);//读取自定义的ResolverActivity
                if (TextUtils.isEmpty(customResolverActivity)) {
                    customResolverActivity = null;
                } else {
                    mCustomResolverComponentName = ComponentName.unflattenFromString(
                            customResolverActivity);//获取自定义的组件名称
                }
    
                long startTime = SystemClock.uptimeMillis();//启动时间
           EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
                        startTime);
                final String bootClassPath = System.getenv("BOOTCLASSPATH");
                final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");环境变量SYSTEMSERVERCLASSPATH所执行的文件
    
                if (bootClassPath == null) {
                    Slog.w(TAG, "No BOOTCLASSPATH found!");
                }
    
                if (systemServerClassPath == null) {
                    Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
                }
    
                File frameworkDir = new File(Environment.getRootDirectory(), "framework");//system/framework/目录所对应的文件
                final VersionInfo ver = mSettings.getInternalVersion();
                mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
                if (mIsUpgrade) {
                    logCriticalInfo(Log.INFO,
                            "Upgrading from " + ver.fingerprint + " to " + Build.FINGERPRINT);
                }
    
                // when upgrading from pre-M, promote system app permissions from install to runtime
                mPromoteSystemApps =
                        mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
    
                // When upgrading from pre-N, we need to handle package extraction like first boot,
                // as there is no profiling data available.
                mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N;
    
                mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1;
    
                // save off the names of pre-existing system packages prior to scanning; we don't
                // want to automatically grant runtime permissions for new system apps
                if (mPromoteSystemApps) {
                    Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator();
                    while (pkgSettingIter.hasNext()) {
                        PackageSetting ps = pkgSettingIter.next();
                        if (isSystemApp(ps)) {
                            mExistingSystemPackages.add(ps.name);//遍历系统应用
                        }
                    }
                }
    
                mCacheDir = preparePackageParserCache(mIsUpgrade);
    

    扫描几个系统应用目录

     // Collect vendor/product overlay packages. (Do this before scanning any apps.)
                // For security and version matching reason, only consider
                // overlay packages if they reside in the right directory.
                scanDirTracedLI(new File(VENDOR_OVERLAY_DIR),
                        mDefParseFlags
                        | PackageParser.PARSE_IS_SYSTEM_DIR,
                        scanFlags
                        | SCAN_AS_SYSTEM
                        | SCAN_AS_VENDOR,
                        0);
                // Collect privileged vendor packages.
                File privilegedVendorAppDir = new File(Environment.getVendorDirectory(), "priv-app");
                try {
                    privilegedVendorAppDir = privilegedVendorAppDir.getCanonicalFile();
                } catch (IOException e) {
                    // failed to look up canonical path, continue with original one
                }
                scanDirTracedLI(privilegedVendorAppDir,
                        mDefParseFlags
                        | PackageParser.PARSE_IS_SYSTEM_DIR,
                        scanFlags
                        | SCAN_AS_SYSTEM
                        | SCAN_AS_VENDOR
                        | SCAN_AS_PRIVILEGED,
                        0);
    
                // Collect ordinary vendor packages.
                File vendorAppDir = new File(Environment.getVendorDirectory(), "app");
                try {
                    vendorAppDir = vendorAppDir.getCanonicalFile();
                } catch (IOException e) {
                    // failed to look up canonical path, continue with original one
                }
                // Collect privileged odm packages. /odm is another vendor partition
                // other than /vendor.
                File privilegedOdmAppDir = new File(Environment.getOdmDirectory(),
                            "priv-app");
                try {
                    privilegedOdmAppDir = privilegedOdmAppDir.getCanonicalFile();
                } catch (IOException e) {
                    // failed to look up canonical path, continue with original one
                }
                // Collect ordinary odm packages. /odm is another vendor partition
                // other than /vendor.
                File odmAppDir = new File(Environment.getOdmDirectory(), "app");
                try {
                    odmAppDir = odmAppDir.getCanonicalFile();
                } catch (IOException e) {
                    // failed to look up canonical path, continue with original one
                }
              ...省去部分代码
                scanDirTracedLI(productAppDir,
                        mDefParseFlags
                        | PackageParser.PARSE_IS_SYSTEM_DIR,
                        scanFlags
                        | SCAN_AS_SYSTEM
                        | SCAN_AS_PRODUCT,
                        0);
    

    扫描完之后的工作

     if (!mOnlyCore) {//处理非系统应用的            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
                            SystemClock.uptimeMillis());//data/app目录
                    scanDirTracedLI(sAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
                    scanDirTracedLI(sDrmAppPrivateInstallDir, mDefParseFlags//收集data/app-private
                            | PackageParser.PARSE_FORWARD_LOCK,
                            scanFlags | SCAN_REQUIRE_KNOWN, 0);
                    for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
                        PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
                        mSettings.removeDisabledSystemPackageLPw(deletedAppName);
                        final String msg;
                        if (deletedPkg == null) {
                            // should have found an update, but, we didn't; remove everything
                            msg = "Updated system package " + deletedAppName
                                    + " no longer exists; removing its data";
                            // Actual deletion of code and data will be handled by later
                            // reconciliation step
                        } else {
                            // found an update; revoke system privileges
                            msg = "Updated system package + " + deletedAppName
                                    + " no longer exists; revoking system privileges";
                            final PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
                            deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
                            deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
                        }
                        logCriticalInfo(Log.WARN, msg);
                    }
                    for (int i = 0; i < mExpectingBetter.size(); i++) {
                        final String packageName = mExpectingBetter.keyAt(i);
                        if (!mPackages.containsKey(packageName)) {
                            final File scanFile = mExpectingBetter.valueAt(i);
                            logCriticalInfo(Log.WARN, "Expected better " + packageName
                                    + " but never showed up; reverting to system");
                            final @ParseFlags int reparseFlags;
                            final @ScanFlags int rescanFlags;
                            if (FileUtils.contains(privilegedAppDir, scanFile)) {
                                reparseFlags =
                                        mDefParseFlags |
                                        PackageParser.PARSE_IS_SYSTEM_DIR;
                                rescanFlags =
                                        scanFlags
                                        | SCAN_AS_SYSTEM
                                        | SCAN_AS_PRIVILEGED;
                            } else if (FileUtils.contains(systemAppDir, scanFile)) {
                                reparseFlags =
                                        mDefParseFlags |
                                        PackageParser.PARSE_IS_SYSTEM_DIR;
                                rescanFlags =
                                        scanFlags
                                        | SCAN_AS_SYSTEM;
                            } else if (FileUtils.contains(privilegedVendorAppDir, scanFile)
                                    || FileUtils.contains(privilegedOdmAppDir, scanFile)) {
                                reparseFlags =
                                        mDefParseFlags |
                                        PackageParser.PARSE_IS_SYSTEM_DIR;
                                rescanFlags =
                                        scanFlags
                                        | SCAN_AS_SYSTEM
                                        | SCAN_AS_VENDOR
                                        | SCAN_AS_PRIVILEGED;
                            } else if (FileUtils.contains(vendorAppDir, scanFile)
                                    || FileUtils.contains(odmAppDir, scanFile)) {
                                reparseFlags =
                                        mDefParseFlags |
                                        PackageParser.PARSE_IS_SYSTEM_DIR;
                                rescanFlags =
                                        scanFlags
                                        | SCAN_AS_SYSTEM
                                        | SCAN_AS_VENDOR;
                            } else if (FileUtils.contains(oemAppDir, scanFile)) {
                                reparseFlags =
                                        mDefParseFlags |
                                        PackageParser.PARSE_IS_SYSTEM_DIR;
                                rescanFlags =
                                        scanFlags
                                        | SCAN_AS_SYSTEM
                                        | SCAN_AS_OEM;
                            } else if (FileUtils.contains(privilegedProductAppDir, scanFile)) {
                                reparseFlags =
                                        mDefParseFlags |
                                        PackageParser.PARSE_IS_SYSTEM_DIR;
                                rescanFlags =
                                        scanFlags
                                        | SCAN_AS_SYSTEM
                                        | SCAN_AS_PRODUCT
                                        | SCAN_AS_PRIVILEGED;
                            } else if (FileUtils.contains(productAppDir, scanFile)) {
                                reparseFlags =
                                        mDefParseFlags |
                                        PackageParser.PARSE_IS_SYSTEM_DIR;
                                rescanFlags =
                                        scanFlags
                                        | SCAN_AS_SYSTEM
                                        | SCAN_AS_PRODUCT;
                            } else {
                                Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
                                continue;
                            }
                            mSettings.enableSystemPackageLPw(packageName);
                            try {
                                scanPackageTracedLI(scanFile, reparseFlags, rescanFlags, 0, null);
                            } catch (PackageManagerException e) {
                                Slog.e(TAG, "Failed to parse original system package: "
                                        + e.getMessage());
                            }
                        }
                    }
    

    当monlyCore=false的时候会扫描/data/app/, data/private/目录

    扫描结束

     EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
                        SystemClock.uptimeMillis());
                final boolean sdkUpdated = (ver.sdkVersion != mSdkVersion);
                if (sdkUpdated) {
                    Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
                            + mSdkVersion + "; regranting permissions for internal storage");
                }
                mPermissionManager.updateAllPermissions(
                        StorageManager.UUID_PRIVATE_INTERNAL, sdkUpdated, mPackages.values(),
                        mPermissionCallback);//当sdk版本不一致时则需要更新权限
                ver.sdkVersion = mSdkVersion;
                if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) {
                    for (UserInfo user : sUserManager.getUsers(true)) {
                        mSettings.applyDefaultPreferredAppsLPw(this, user.id);
                        applyFactoryDefaultBrowserLPw(user.id);
                        primeDomainVerificationsLPw(user.id);
                    }
                }
                final int storageFlags;
                if (StorageManager.isFileEncryptedNativeOrEmulated()) {
                    storageFlags = StorageManager.FLAG_STORAGE_DE;
                } else {
                    storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
                }
                List<String> deferPackages = reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL,
                        UserHandle.USER_SYSTEM, storageFlags, true /* migrateAppData */,
                        true /* onlyCoreApps */);
                mPrepareAppDataFuture = SystemServerInitThreadPool.get().submit(() -> {
                    TimingsTraceLog traceLog = new TimingsTraceLog("SystemServerTimingAsync",
                            Trace.TRACE_TAG_PACKAGE_MANAGER);
                    traceLog.traceBegin("AppDataFixup");
                    try {
                        mInstaller.fixupAppData(StorageManager.UUID_PRIVATE_INTERNAL,
                                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
                    } catch (InstallerException e) {
                        Slog.w(TAG, "Trouble fixing GIDs", e);
                    }
                    traceLog.traceEnd();
    
                    traceLog.traceBegin("AppDataPrepare");
                    if (deferPackages == null || deferPackages.isEmpty()) {
                        return;
                    }
                    int count = 0;
                    for (String pkgName : deferPackages) {
                        PackageParser.Package pkg = null;
                        synchronized (mPackages) {
                            PackageSetting ps = mSettings.getPackageLPr(pkgName);
                            if (ps != null && ps.getInstalled(UserHandle.USER_SYSTEM)) {
                                pkg = ps.pkg;
                            }
                        }
                        if (pkg != null) {
                            synchronized (mInstallLock) {
                                prepareAppDataAndMigrateLIF(pkg, UserHandle.USER_SYSTEM, storageFlags,
                                        true /* maybeMigrateAppData */);
                            }
                            count++;
                        }
                    }
                    traceLog.traceEnd();
                    Slog.i(TAG, "Deferred reconcileAppsData finished " + count + " packages");
                }, "prepareAppData");
                if (mIsUpgrade && !onlyCore) {
                    Slog.i(TAG, "Build fingerprint changed; clearing code caches");
                    for (int i = 0; i < mSettings.mPackages.size(); i++) {
                        final PackageSetting ps = mSettings.mPackages.valueAt(i);
                        if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
                            // No apps are running this early, so no need to freeze
                            clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
                                    StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
                                            | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
                        }
                    }
                    ver.fingerprint = Build.FINGERPRINT;
                }
                checkDefaultBrowser();
                // clear only after permissions and other defaults have been updated
                mExistingSystemPackages.clear();//清理动作
                mPromoteSystemApps = false;
                // All the changes are done during package scanning.
                ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
                // can downgrade to reader
                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "write settings");
                mSettings.writeLPr();//写package.xml文件
                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
    

    PMS的准备ready

     EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
                        SystemClock.uptimeMillis());
                if (!mOnlyCore) {//非系统应用
                    mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
                    mRequiredInstallerPackage = getRequiredInstallerLPr();
                    mRequiredUninstallerPackage = getRequiredUninstallerLPr();
                    mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
                    if (mIntentFilterVerifierComponent != null) {
                        mIntentFilterVerifier = new IntentVerifierProxy(mContext,
                                mIntentFilterVerifierComponent);
                    } else {
                        mIntentFilterVerifier = null;
                    }
                    mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
                            PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES,
                            SharedLibraryInfo.VERSION_UNDEFINED);
                    mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
                            PackageManager.SYSTEM_SHARED_LIBRARY_SHARED,
                            SharedLibraryInfo.VERSION_UNDEFINED);
                } else {
                    mRequiredVerifierPackage = null;
                    mRequiredInstallerPackage = null;
                    mRequiredUninstallerPackage = null;
                    mIntentFilterVerifierComponent = null;
                    mIntentFilterVerifier = null;
                    mServicesSystemSharedLibraryPackageName = null;
                    mSharedSystemSharedLibraryPackageName = null;
                }
                mInstallerService = new PackageInstallerService(context, this);//创建一个包安装服务
                final Pair<ComponentName, String> instantAppResolverComponent =
                        getInstantAppResolverLPr();
                if (instantAppResolverComponent != null) {
                    if (DEBUG_INSTANT) {
                        Slog.d(TAG, "Set ephemeral resolver: " + instantAppResolverComponent);
                    }
                    mInstantAppResolverConnection = new InstantAppResolverConnection(
                            mContext, instantAppResolverComponent.first,
                            instantAppResolverComponent.second);
                    mInstantAppResolverSettingsComponent =
                            getInstantAppResolverSettingsLPr(instantAppResolverComponent.first);
                } else {
                    mInstantAppResolverConnection = null;
                    mInstantAppResolverSettingsComponent = null;
                }
                updateInstantAppInstallerLocked(null);
                final Map<Integer, List<PackageInfo>> userPackages = new HashMap<>();
                final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
                for (int userId : currentUserIds) {
                    userPackages.put(userId, getInstalledPackages(/*flags*/ 0, userId).getList());
                }
                mDexManager.load(userPackages);
                if (mIsUpgrade) {
                    MetricsLogger.histogram(null, "ota_package_manager_init_time",
                            (int) (SystemClock.uptimeMillis() - startTime));
                }
            } // synchronized (mPackages)
            } // synchronized (mInstallLock)
    

    PackageInstallerService服务的创建

        public PackageInstallerService(Context context, PackageManagerService pm) {
            mContext = context;
            mPm = pm;
            mPermissionManager = LocalServices.getService(PermissionManagerInternal.class);
            mInstallThread = new HandlerThread(TAG);//PackageInstaller线程创建
            mInstallThread.start();//启动线程
            mInstallHandler = new Handler(mInstallThread.getLooper());//创建一个handler对象,用于处理各种事物
    
            mCallbacks = new Callbacks(mInstallThread.getLooper());
            mSessionsFile = new AtomicFile(
                    new File(Environment.getDataSystemDirectory(), "install_sessions.xml"),
                    "package-session");
            mSessionsDir = new File(Environment.getDataSystemDirectory(), "install_sessions");
            mSessionsDir.mkdirs();//创建data/system/目录
        }
    

    这样pms的初始化阶段基本完成,接下来就是pms在startOtherService部分的工作

    总结

    PMS的初始化分为5个阶段
    1:PMS_START阶段:
    创建Settings对象;
    将6类shareUserId到mSettings;
    初始化SystemConfig;
    创建名为“PackageManager”的handler线程mHandlerThread;
    创建UserManagerService多用户管理服务;
    通过解析4大目录中的xmL文件构造共享mSharedLibraries;
    2:PMS_SYSTEM_SCAN_START阶段:系统应用阶段
    mSharedLibraries共享库中的文件执行dexopt操作;
    system/framework目录中满足条件的apk或jar文件执行dexopt操作;
    扫描系统apk;
    3:PMS_DATA_SCAN_START阶段:非系统应用阶段
    扫描/data/app目录下的apk;
    扫描/data/app-private目录下的apk;
    4:PMS_SCAN_END阶段://扫描结束事件,写xml文件
    将上述信息写回/data/system/packages.xml;
    5:PMS_READY阶段:
    创建服务PackageInstallerService;

    相关文章

      网友评论

          本文标题:基于Android9.0的PackageManagerServi

          本文链接:https://www.haomeiwen.com/subject/nvedwqtx.html