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


    一. 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 虚拟机创建过程
     
  • 相关阅读:
    点击鼠标获得坐标位置
    广告的字一个一个的显示出来
    纯css实现下拉菜单的效果
    用css3写出的倒三角形
    MySQL(三)
    Navicat之MySQL连接(二)
    MySQL 的安装与使用(一)
    Servlet(二)
    Servlet(一)
    Linux常用命令大全
  • 原文地址:https://www.cnblogs.com/bugzone/p/PackageManagerService.html
Copyright © 2020-2023  润新知