Android源码分析(十四)PackageManagerService服务分析

主宰稳场 提交于 2020-12-04 15:17:19

一. PackageManagerService启动过程分析

 PackageManagerService(PMS)主要是管理应用的安装,卸载,更新,解析以及权限。
  
如果想了解SystemService启动过程请看这篇文章: Android 源码分析(六) SystemServer 进程
如果想了解AMS服务分析请看这篇文章: Android源码分析(十三)ActivityManagerService服务分析
 
同AMS一样,PMS也是由SystemServer启动的.
public final class SystemServer {
    private PackageManagerService mPackageManagerService;
    private PackageManager mPackageManager;
    ...
    // Start the package manager.
    //启动PMS服务
    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());
    }
    ...
}
//PackageManagerService 初始化工作
public class PackageManagerService extends IPackageManager.Stub
        implements PackageSender {
        
    public static PackageManagerService main(Context context, Installer installer,
            boolean factoryTest, boolean onlyCore) {
        // Self-check for initial settings.
        PackageManagerServiceCompilerMapping.checkProperties();
        //构造一个PackageManagerService
        PackageManagerService m = new PackageManagerService(context, installer,
                factoryTest, onlyCore);
        m.enableSystemUserPackages();
        //添加到ServiceManager
        ServiceManager.addService("package", m);
        return m;
    }
    
    public PackageManagerService(Context context, Installer installer,
            boolean factoryTest, boolean onlyCore) {
        
        //installer apk的安装和卸载最终都是调用installd来实现的。
        mInstaller = installer;
        mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
                "*dexopt*");
        mDexManager = new DexManager(this, mPackageDexOptimizer, installer, mInstallLock);
        mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
        
        synchronized (mInstallLock) {
        // writer 
        //环境变量初始化
        synchronized (mPackages) {
            File dataDir = Environment.getDataDirectory();
            mAppInstallDir = new File(dataDir, "app");
            mAppLib32InstallDir = new File(dataDir, "app-lib");
            mAsecInternalPath = new File(dataDir, "app-asec").getPath();
            mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
            sUserManager = new UserManagerService(context, this,
                    new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages);
                    
            
            //权限注册到 package manager,一个权限与几个组ID对应,当一个APK授予这个权限时,它同属于这几个组。
            //权限是一个复杂的过程
            // Propagate permission configuration in to package manager.
            ArrayMap<String, SystemConfig.PermissionEntry> permConfig
                    = systemConfig.getPermissions();
                    //遍历权限配置文件
            for (int i=0; i<permConfig.size(); i++) {
                SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
                //拿到权限
                BasePermission bp = mSettings.mPermissions.get(perm.name);
                if (bp == null) {
                    bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
                    //写入权限
                    mSettings.mPermissions.put(perm.name, bp);
                }
                if (perm.gids != null) {
                    bp.setGids(perm.gids, perm.perUser);
                }
            }
        }
        
    final PackageHandler mHandler;
    class PackageHandler extends Handler {
        void doHandleMessage(Message msg) {
            switch (msg.what) {
            
            }
    }
    
    private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) {
        final File[] files = dir.listFiles();
        if (ArrayUtils.isEmpty(files)) {
            Log.d(TAG, "No files in app dir " + dir);
            return;
        }
        ParallelPackageParser parallelPackageParser = new ParallelPackageParser(
                mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir,
                mParallelPackageParserCallback);

        parallelPackageParser.close();
    
    }
            
    File frameworkDir = new File(Environment.getRootDirectory(), "framework");
    // Find base frameworks (resource packages without code).
    scanDirTracedLI(frameworkDir, mDefParseFlags
            | PackageParser.PARSE_IS_SYSTEM
            | PackageParser.PARSE_IS_SYSTEM_DIR
            | PackageParser.PARSE_IS_PRIVILEGED,
            scanFlags | SCAN_NO_DEX, 0);

    // Collected privileged system packages. 系统安装包
    final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
    scanDirTracedLI(privilegedAppDir, mDefParseFlags
            | PackageParser.PARSE_IS_SYSTEM
            | PackageParser.PARSE_IS_SYSTEM_DIR
            | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);

    // Collect ordinary system packages. 系统app安装包
    final File systemAppDir = new File(Environment.getRootDirectory(), "app");
    scanDirTracedLI(systemAppDir, mDefParseFlags
            | PackageParser.PARSE_IS_SYSTEM
            | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
    
    
        
}

  PMS里面主要完成以下几件事。
   1、通过installer与installd进行连接,进行安装卸载应用操作
   2、创建PacakageHandler线程,处理外部应用的安装卸载请求
   3、处理系统权限相关配置
   4、扫描安装应用,并解析APK安装包信息

二.总结

 一张图总结下PMS主要完成的工作,以及对上与PackageManager交互,向下与Installd的控制。
           

如果想了解桌面Launcher应用启动app过程,请看这篇文章。 Android 源码分析(八) Launcher 桌面启动App过程
最后补充一点,如果想要了解APK的编译过程,可以进一步去了解Android4.4之后使用的ART,可以与Dalivk对比了解。
给个Dalivk的启动过程介绍的文章: Android 源码分析(十) Dalvik 虚拟机创建过程
 
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!