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 虛擬機創建過程
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM