程序員自我修養(yǎng)之PMS 啟動(dòng)流程

一、關(guān)鍵類(lèi)的介紹

1、核心類(lèi)介紹

/frameworks/base/core/java/android/app/ApplicationPackageManager.java
/frameworks/base/services/java/com/android/server/SystemServer.java
/frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
/frameworks/base/services/core/java/com/android/server/pm/PackageInstallerService.java
/frameworks/base/services/core/java/com/android/server/pm/PackageDexOptimizer.java
/frameworks/base/services/core/java/com/android/server/pm/Installer.java
/frameworks/base/services/core/java/com/android/server/pm/Settings.java
/frameworks/base/services/core/java/com/android/server/pm/permission/BasePermission.java
/frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
/frameworks/base/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
/frameworks/base/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
/frameworks/base/core/java/android/content/pm/IPackageManager.aidl
/frameworks/base/core/java/android/content/pm/PackageManager.java
/frameworks/base/core/java/com/android/server/SystemConfig.java

2、PackageManager

  • 提供一個(gè)ApplicationInfo的所有信息

  • 提供權(quán)限相關(guān)信息

  • 提供一個(gè)安裝包信息

  • 安裝、卸載、更新app功能

3、Installer :對(duì)app進(jìn)行操作

  • 安裝

  • 卸載

  • 更新

  • 遷移

3、Settings

  • 創(chuàng)建”data/system”目錄
  • 創(chuàng)建一些xml文件

    packages.xml 記錄所有安裝app的信息,當(dāng)系統(tǒng)進(jìn)行程序安裝、卸載和更新等操作時(shí),均會(huì)更新該文件。
    packages-backup.xml 備份文件
    packages-stopped.xml 記錄被用戶(hù)強(qiáng)行停止的應(yīng)用的Package信息
    packages-stopped-backup.xml 備份文件
    packages.list 記錄非系統(tǒng)自帶的APK的數(shù)據(jù)信息,這些APK有變化時(shí)會(huì)更新該文件

  • 配置相應(yīng)的權(quán)限
  • readLPw()函數(shù):

從/data/system/packages.xml或packages-backup.xml文件中獲得packages、permissions相關(guān)信息,添加到相關(guān)內(nèi)存列表中。packages.xml文件記錄了系統(tǒng)的permisssions以及每個(gè)APK的name、codePath、flags、version等信息這些信息主要通過(guò)APK的AndroidManifest.xml解析獲取,解析完APK后將更新信息寫(xiě)入這個(gè)文件,下次開(kāi)機(jī)直接從里面讀取相關(guān)信息添加到內(nèi)存相關(guān)結(jié)構(gòu)中。當(dāng)有APK升級(jí)、安裝或刪除時(shí)會(huì)更新這個(gè)文件。

  • writeLPr函數(shù):

將解析出的每個(gè)APK的配置信息(mSetting.mPackages)保存到packages.xml和packages.list文件。packages.list記錄了如下數(shù)據(jù):pkgName, userId, debugFlag, dataPath(包的數(shù)據(jù)路徑)

4、SystemConfig

通過(guò)readPermissions解析指定目錄下的xml文件:

  • /system/etc/sysconfig
  • /system/etc/permissions
  • /odm/etc/sysconfig
  • /odm/etc/permissions
  • /oem/etc/sysconfig
  • /oem/etc/permissions

readPermissions函數(shù)最終會(huì)調(diào)用readPermissionsFromXml()使用XMLPullParser的方式解析這些XML文件,然后把解析出來(lái)的數(shù)據(jù)結(jié)構(gòu)保存到PMS中。

5、DefaultPermissionGrantPolicy

默認(rèn)組件提前授予運(yùn)行時(shí)權(quán)限,DefaultPermissionGrantPolicy在PermissionManagerService的構(gòu)造函數(shù)中被創(chuàng)建。

6、PackageInstallerService

管理應(yīng)用的安裝過(guò)程。

二、PMS初始化

查看系統(tǒng)網(wǎng)址: http://androidxref.com/9.0.0_r3/

1、啟動(dòng)SystemServer服務(wù)

frameworks/base/services/java/com/android/server/SystemServer.java

 /**
     * The main entry point from zygote.  SystemServer啟動(dòng)入口
     */
    public static void main(String[] args) {
        new SystemServer().run();
    }

    private void run() {
     .........
        // Start services : 分開(kāi)啟動(dòng)目的:加快手機(jī)啟動(dòng)速度
        try {
            //啟動(dòng)AMS、PMS、WMS
            startBootstrapServices();
            //啟動(dòng)核心服務(wù)
            startCoreServices();
            //啟動(dòng)三方服務(wù)(Launcher啟動(dòng))
            startOtherServices();
            SystemServerInitThreadPool.shutdown();
        } catch (Throwable ex) {
            Slog.e("System", "******************************************");
            Slog.e("System", "************ Failure starting system services", ex);
            throw ex;
        } finally {
            traceEnd();
        }
        .........
    }


    private void startBootstrapServices() {
        .......
        /**
         * 以便它有機(jī)會(huì)創(chuàng)建關(guān)鍵目錄,如/data/user具有適當(dāng)?shù)臋?quán)限。其他service都會(huì)用到此對(duì)象
         **/
        traceBeginAndSlog("StartInstaller");  //加系統(tǒng)日志,起始位置
        Installer installer = mSystemServiceManager.startService(Installer.class);
        traceEnd();  // 日志結(jié)束
        .......

        // Start the package manager.   啟動(dòng)PMS服務(wù)
        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();

        ......
    }

2、初始化PMS

frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java

  • 創(chuàng)建類(lèi)時(shí)候會(huì)把Data分區(qū)一些目錄創(chuàng)建好,比如/data/app。
  • PackageManagerService構(gòu)造方法
    /**
      加載類(lèi)之前在Data分區(qū)創(chuàng)建一些目錄
    **/
    /**
     * Directory where installed applications are stored
     */
    private static final File sAppInstallDir =
            new File(Environment.getDataDirectory(), "app");
    /**
     * Directory where installed application's 32-bit native libraries are copied.
     */
    private static final File sAppLib32InstallDir =
            new File(Environment.getDataDirectory(), "app-lib");
    /**
     * Directory where code and non-resource assets of forward-locked applications are stored
     */
    private static final File sDrmAppPrivateInstallDir =
            new File(Environment.getDataDirectory(), "app-private");

    //PackageManagerService的入口
      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;
    }

3、PMS構(gòu)造方法

  • BOOT_PROGRESS_PMS_START : PMS開(kāi)始掃描安裝的應(yīng)用

UserManagerService :多用戶(hù)管理服務(wù)類(lèi)。主要功能是創(chuàng)建和刪除用戶(hù),以及查詢(xún)用戶(hù)信息
PermissionManagerService :權(quán)限管理類(lèi)。創(chuàng)建PermissionSettings類(lèi),它是記錄所有權(quán)限相關(guān)信息
Settings :保存安裝包信息類(lèi)。主要涉及/data/system/目錄的packages.xml(逆向工程??次募?,packages-backup.xml,packages.list,packages-stopped.xml,packages-stopped-backup.xml等文件。
PackageDexOptimizer :創(chuàng)建Dex優(yōu)化工具類(lèi)
PackageHandler : APK的復(fù)制和安裝工作類(lèi)

        public PackageManagerService(Context context, Installer installer,
                                 // Create sub-components that provide services / data. Order here is important.
                                 synchronized (mInstallLock) {
        //打印開(kāi)始階段日志
        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
                SystemClock.uptimeMillis())
        ........
        synchronized (mPackages) {
            // Expose private service for system components to use.
            LocalServices.addService(
                    PackageManagerInternal.class, new PackageManagerInternalImpl());
            //UserManagerService的主要功能是創(chuàng)建和刪除用戶(hù),以及查詢(xún)用戶(hù)信息。
            sUserManager = new UserManagerService(context, this,
                    new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages);
            //PermissionManagerService 權(quán)限管理類(lèi),創(chuàng)建PermissionSettings類(lèi),它是記錄所有權(quán)限相關(guān)信息
            mPermissionManager = PermissionManagerService.create(context,
                    new DefaultPermissionGrantedCallback() {
                        @Override
                        public void onDefaultRuntimePermissionsGranted(int userId) {
                            synchronized (mPackages) {
                                mSettings.onDefaultRuntimePermissionsGrantedLPr(userId);
                            }
                        }
                    }, mPackages /*externalLock*/);
            mDefaultPermissionPolicy = mPermissionManager.getDefaultPermissionGrantPolicy();
            //它是Android全局管理者,用于協(xié)助PMS保存所有的安裝包信息
            mSettings = new Settings(mPermissionManager.getPermissionSettings(), mPackages);
        }
          ........
          //創(chuàng)建Dex優(yōu)化工具類(lèi)
          mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
                "*dexopt*");
          // 權(quán)限變化監(jiān)聽(tīng)器
          mOnPermissionChangeListeners = new OnPermissionChangeListeners(FgThread.get().getLooper());
          ........
         //得到全局系統(tǒng)配置信息。
         SystemConfig systemConfig = SystemConfig.getInstance();
         mAvailableFeatures = systemConfig.getAvailableFeatures();
         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
    }
        ........
        synchronized (mInstallLock) {
            // writer
            synchronized (mPackages) {
                mHandlerThread = new ServiceThread(TAG,
                        Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
                mHandlerThread.start();
                // PMS通過(guò)PackageHandler驅(qū)動(dòng)APK的復(fù)制和安裝工作
                mHandler = new PackageHandler(mHandlerThread.getLooper());
                mProcessLoggingHandler = new ProcessLoggingHandler();
                //mHandler添加到Watchdog的監(jiān)測(cè)導(dǎo)致系統(tǒng)卡住
                Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
                mInstantAppRegistry = new InstantAppRegistry(this);
                // 通過(guò) systemConfig 獲取系統(tǒng)中的共享庫(kù)列表
                ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
                final int builtInLibCount = libConfig.size();
                for (int i = 0; i < builtInLibCount; i++) {
                    String name = libConfig.keyAt(i);
                    String path = libConfig.valueAt(i);
                    //把共享庫(kù)寫(xiě)入系統(tǒng)路徑    L: lock    P: packages一系列xml文件   w: write
                    addSharedLibraryLPw(path, null, name, SharedLibraryInfo.VERSION_UNDEFINED,
                            SharedLibraryInfo.TYPE_BUILTIN, PLATFORM_PACKAGE_NAME, 0);
                }
            }
        }
  • BOOT_PROGRESS_PMS_SYSTEM_SCAN_START :PMS掃描/system目錄下的安裝包

app : 存放系統(tǒng)App,包括了谷歌內(nèi)置的App也有廠商或者運(yùn)營(yíng)商提供的App
framework : 存放應(yīng)用框架層的jar包
priv-app: 存放特權(quán)App
lib : 存放so文件
fonts: 存放系統(tǒng)字體文件
media: 存放系統(tǒng)的各種聲音,比如鈴聲、提示音,以及系統(tǒng)啟動(dòng)播放的動(dòng)畫(huà)
vendor: 它用來(lái)存儲(chǔ)廠商對(duì)Android系統(tǒng)的定制部分。

系統(tǒng)掃描階段的主要工作有以下3點(diǎn):

  • 創(chuàng)建/system的子目錄,比如/system/framework、/system/priv-app和/system/app等等
  • 掃描系統(tǒng)文件,比如/vendor/overlay、/system/framework、/system/app等等目錄下的文件。
  • 對(duì)掃描到的系統(tǒng)文件做后續(xù)處理。
public PackageManagerService(Context context, Installer installer,
            boolean factoryTest, boolean onlyCore) {
            ...
            //打印掃描系統(tǒng)階段日志
            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
                    startTime);
            ...
            //在/system中創(chuàng)建framework目錄
            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
            ...
            //掃描/vendor/overlay目錄下的文件
            scanDirTracedLI(new File(VENDOR_OVERLAY_DIR), mDefParseFlags
                    | PackageParser.PARSE_IS_SYSTEM
                    | PackageParser.PARSE_IS_SYSTEM_DIR
                    | PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
            mParallelPackageParserCallback.findStaticOverlayPackages();
            //掃描/system/framework 目錄下的文件
            scanDirTracedLI(frameworkDir, mDefParseFlags
                    | PackageParser.PARSE_IS_SYSTEM
                    | PackageParser.PARSE_IS_SYSTEM_DIR
                    | PackageParser.PARSE_IS_PRIVILEGED,
                    scanFlags | SCAN_NO_DEX, 0);
            final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
            //掃描 /system/priv-app 目錄下的文件
            scanDirTracedLI(privilegedAppDir, mDefParseFlags
                    | PackageParser.PARSE_IS_SYSTEM
                    | PackageParser.PARSE_IS_SYSTEM_DIR
                    | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);
            final File systemAppDir = new File(Environment.getRootDirectory(), "app");
            //掃描/system/app 目錄下的文件
            scanDirTracedLI(systemAppDir, mDefParseFlags
                    | PackageParser.PARSE_IS_SYSTEM
                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
            File vendorAppDir = new File("/vendor/app");
            try {
                vendorAppDir = vendorAppDir.getCanonicalFile();
            } catch (IOException e) {
                // failed to look up canonical path, continue with original one
            }
            //掃描 /vendor/app 目錄下的文件
            scanDirTracedLI(vendorAppDir, mDefParseFlags
                    | PackageParser.PARSE_IS_SYSTEM
                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);

           //掃描/oem/app 目錄下的文件
            final File oemAppDir = new File(Environment.getOemDirectory(), "app");
            scanDirTracedLI(oemAppDir, mDefParseFlags
                    | PackageParser.PARSE_IS_SYSTEM
                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);

            //這個(gè)列表代表有可能有升級(jí)包的系統(tǒng)App
            final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>();//1
            if (!mOnlyCore) {
                Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
                while (psit.hasNext()) {
                    PackageSetting ps = psit.next();                 
                    if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
                        continue;
                    }
                    //這里的mPackages的是PMS的成員變量,代表scanDirTracedLI方法掃描上面那些目錄得到的 
                    final PackageParser.Package scannedPkg = mPackages.get(ps.name);
                    if (scannedPkg != null) {           
                        if (mSettings.isDisabledSystemPackageLPr(ps.name)) {//2
                           ...
                            //將這個(gè)系統(tǒng)App的PackageSetting從PMS的mPackages中移除
                            removePackageLI(scannedPkg, true);
                            //將升級(jí)包的路徑添加到mExpectingBetter列表中
                            mExpectingBetter.put(ps.name, ps.codePath);
                        }
                        continue;
                    }
                   
                    if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
                       ...   
                    } else {
                        final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);
                        //這個(gè)系統(tǒng)App升級(jí)包信息在mDisabledSysPackages中,但是沒(méi)有發(fā)現(xiàn)這個(gè)升級(jí)包存在
                        if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {//5
                            possiblyDeletedUpdatedSystemApps.add(ps.name);//
                        }
                    }
                }
            }
            ...        
}
  • BOOT_PROGRESS_PMS_DATA_SCAN_START:PMS掃描/data目錄下的安裝包

app: 存儲(chǔ)用戶(hù)自己安裝的App
data: 存儲(chǔ)所有已安裝的App數(shù)據(jù)的目錄,每個(gè)App都有自己?jiǎn)为?dú)的子目錄
app-private: App的私有存儲(chǔ)空間
app-lib: 存儲(chǔ)所有App的Jni庫(kù)
system: 存放系統(tǒng)配置文件
anr: 用于存儲(chǔ)ANR發(fā)生時(shí)系統(tǒng)生成的traces.txt文件

掃描Data分區(qū)階段主要做了以下幾件事:

  • 掃描/data/app和/data/app-private目錄下的文件。
  • 遍歷possiblyDeletedUpdatedSystemApps列表,注釋1處如果這個(gè)系統(tǒng)App的包信息不在PMS的變量mPackages中,說(shuō)明是殘留的App信息,后續(xù)會(huì)刪除它的數(shù)據(jù)。注釋2處如果這個(gè)系統(tǒng)App的包信息在mPackages中,說(shuō)明是存在于Data分區(qū),不屬于系統(tǒng)App,那么移除其系統(tǒng)權(quán)限。
  • 遍歷mExpectingBetter列表,注釋3處根據(jù)系統(tǒng)App所在的目錄設(shè)置掃描的解析參數(shù),注釋4處的方法內(nèi)部會(huì)將packageName對(duì)應(yīng)的包設(shè)置數(shù)據(jù)(PackageSetting)添加到mSettings的mPackages中。注釋5處掃描系統(tǒng)App的升級(jí)包,最后清除mExpectingBetter列表。
public PackageManagerService(Context context, Installer installer,
            boolean factoryTest, boolean onlyCore) {
    ...        
    mSettings.pruneSharedUsersLPw();
    //如果沒(méi)有加密設(shè)備,那么就開(kāi)始掃描Data分區(qū)。
    if (!mOnlyCore) {
        //打印掃描Data分區(qū)階段日志
        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
                SystemClock.uptimeMillis());
        //掃描/data/app目錄下的文件       
        scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
        //掃描/data/app-private目錄下的文件   
        scanDirTracedLI(mDrmAppPrivateInstallDir, mDefParseFlags
                | PackageParser.PARSE_FORWARD_LOCK,
                scanFlags | SCAN_REQUIRE_KNOWN, 0);
        //掃描完Data分區(qū)后,處理possiblyDeletedUpdatedSystemApps列表
        for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
            PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
            // 從mSettings.mDisabledSysPackages變量中移除去此應(yīng)用
            mSettings.removeDisabledSystemPackageLPw(deletedAppName);
            String msg;
          //1:如果這個(gè)系統(tǒng)App的包信息不在PMS的變量mPackages中,說(shuō)明是殘留的App信息,后續(xù)會(huì)刪除它的數(shù)據(jù)。
            if (deletedPkg == null) {
                msg = "Updated system package " + deletedAppName
                        + " no longer exists; it's data will be wiped";
                // Actual deletion of code and data will be handled by later
                // reconciliation step
            } else {
            //2:如果這個(gè)系統(tǒng)App在mPackages中,說(shuō)明是存在于Data分區(qū),不屬于系統(tǒng)App,那么移除其系統(tǒng)權(quán)限。
                msg = "Updated system app + " + deletedAppName
                        + " no longer present; removing system privileges for "
                        + deletedAppName;
                deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
                PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
                deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
            }
            logCriticalInfo(Log.WARN, msg);
        }
         //遍歷mExpectingBetter列表
        for (int i = 0; i < mExpectingBetter.size(); i++) {
            final String packageName = mExpectingBetter.keyAt(i);
            if (!mPackages.containsKey(packageName)) {
                //得到系統(tǒng)App的升級(jí)包路徑
                final File scanFile = mExpectingBetter.valueAt(i);
                logCriticalInfo(Log.WARN, "Expected better " + packageName
                        + " but never showed up; reverting to system");
                int reparseFlags = mDefParseFlags;
                //3:根據(jù)系統(tǒng)App所在的目錄設(shè)置掃描的解析參數(shù)
                if (FileUtils.contains(privilegedAppDir, scanFile)) {
                    reparseFlags = PackageParser.PARSE_IS_SYSTEM
                            | PackageParser.PARSE_IS_SYSTEM_DIR
                            | PackageParser.PARSE_IS_PRIVILEGED;
                } 
                ...
                //將packageName對(duì)應(yīng)的包設(shè)置數(shù)據(jù)(PackageSetting)添加到mSettings的mPackages中
                mSettings.enableSystemPackageLPw(packageName);//4
                try {
                    //掃描系統(tǒng)App的升級(jí)包
                    scanPackageTracedLI(scanFile, reparseFlags, scanFlags, 0, null);//5
                } catch (PackageManagerException e) {
                    Slog.e(TAG, "Failed to parse original system package: "
                            + e.getMessage());
                }
            }
        }
    }
   //清除mExpectingBetter列表
    mExpectingBetter.clear();
...
}
  • BOOT_PROGRESS_PMS_SCAN_END:PMS掃描結(jié)束

1、如果當(dāng)前平臺(tái)SDK版本和上次啟動(dòng)時(shí)的SDK版本不同,重新更新APK的授權(quán)。
2、如果是第一次啟動(dòng)或者是Android M升級(jí)后的第一次啟動(dòng),需要初始化所有用戶(hù)定義的默認(rèn)首選App。
3、OTA升級(jí)后的第一次啟動(dòng),會(huì)清除代碼緩存目錄。
4、把Settings的內(nèi)容保存到packages.xml中,這樣此后PMS再次創(chuàng)建時(shí)會(huì)讀到此前保存的Settings的內(nèi)容。

//打印掃描結(jié)束階段日志
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
                  SystemClock.uptimeMillis());
          Slog.i(TAG, "Time to scan packages: "
                  + ((SystemClock.uptimeMillis()-startTime)/1000f)
                  + " seconds");
          int updateFlags = UPDATE_PERMISSIONS_ALL;
          // 如果當(dāng)前平臺(tái)SDK版本和上次啟動(dòng)時(shí)的SDK版本不同,重新更新APK的授權(quán)
          if (ver.sdkVersion != mSdkVersion) {
              Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
                      + mSdkVersion + "; regranting permissions for internal storage");
              updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
          }
          updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags);
          ver.sdkVersion = mSdkVersion;
         //如果是第一次啟動(dòng)或者是Android M升級(jí)后的第一次啟動(dòng),需要初始化所有用戶(hù)定義的默認(rèn)首選App
          if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) {
              for (UserInfo user : sUserManager.getUsers(true)) {
                  mSettings.applyDefaultPreferredAppsLPw(this, user.id);
                  applyFactoryDefaultBrowserLPw(user.id);
                  primeDomainVerificationsLPw(user.id);
              }
          }
         ...
          //OTA后的第一次啟動(dòng),會(huì)清除代碼緩存目錄。
          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)) {
                      clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
                              StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
                                      | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
                  }
              }
              ver.fingerprint = Build.FINGERPRINT;
          }
          ...
         // 把Settings的內(nèi)容保存到packages.xml中
          mSettings.writeLPr();
          Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
  • BOOT_PROGRESS_PMS_READY:PMS就緒

注釋1處創(chuàng)建PackageInstallerService,PackageInstallerService是用于管理安裝會(huì)話(huà)的服務(wù),它會(huì)為每次安裝過(guò)程分配一個(gè)SessionId。
注釋2處進(jìn)行一次垃圾收集。
注釋3處將PackageManagerInternalImpl(PackageManager的本地服務(wù))添加到LocalServices中,
LocalServices用于存儲(chǔ)運(yùn)行在當(dāng)前的進(jìn)程中的本地服務(wù)。

 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
                SystemClock.uptimeMillis());
    ... 
    mInstallerService = new PackageInstallerService(context, this);//1
    ...
    Runtime.getRuntime().gc();//2
    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "loadFallbacks");
    FallbackCategoryProvider.loadFallbacks();
    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
    mInstaller.setWarnIfHeld(mPackages);
    LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl());//3
    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}

PMS構(gòu)造方法大致流程:
1、先讀取packages.xml文件內(nèi)容,解析并保存在成員變量mSettings中。
2、掃描設(shè)備中的幾個(gè)分區(qū)目錄下的應(yīng)用文件,把掃描結(jié)果保存到PMS的mPackages中。這記錄的是當(dāng)前系統(tǒng)中的應(yīng)用狀態(tài)信息
3、后面就是對(duì)兩次的應(yīng)用狀態(tài)信息進(jìn)行:比對(duì)、重新調(diào)整、掃描特定目錄。
4、最后將應(yīng)用信息重新寫(xiě)回packages.xml文件


帶學(xué)習(xí):
SystemConfig 對(duì) platform.xml 文件的操作


image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容