Android 10.0 PackageManagerService(一)工作原理及啟動流程


Android 10.0 PackageManagerService(一)工作原理及啟動流程

Android

閱讀本文大約需要花費40分鐘。

專注於Android系統級源碼分析,Android的平臺設計,歡迎關注我,謝謝!

上一節我們講完了應用進程的創建流程和Zygote fork流程,這一節來看看PackageManagerService的工作流程。

1.概述

PackageManagerService是Android系統核心服務之一,在Android中的非常重要,主要負責的功能如下:

  • 解析 AndroidManifest.xml,主要包括AndroidManifest中節點信息的解析和target-name的分析和提煉
  • 掃描本地文件,主要針對apk,主要是系統應用、本地安裝應用等等。這部分會在下面仔細講解。
  • 管理本地apk,主要包括安裝、刪除等等。

下面稱PackageManagerService為PKMS。


2.核心源碼

<code>
/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/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/<code>


3.架構

3.1 PKMS 啟動過程

Android 10.0 PackageManagerService(一)工作原理及啟動流程

3.2 PKMS 繼承關係

Android 10.0 PackageManagerService(一)工作原理及啟動流程

3.3 權限管理

Android 10.0 PackageManagerService(一)工作原理及啟動流程

3.4 APK掃描

掃描APK的AndroidManifest.xml中的各個標籤信息,

例如"application"、"overlay"、"permission"、"uses-permission"等信息。

再針對各個標籤的子標籤進程掃描,

例如application會掃描"activity"、"receiver"、"service"、"provider"等信息

後面會詳細講解掃描過程

Android 10.0 PackageManagerService(一)工作原理及啟動流程

4.啟動過程

4.1 啟動過程

PKMS服務由SystemServer進行啟動,在SystemServer中startBootstrapServices()啟動PKMS服務,再調用startOtherServices()進行dex優化,磁盤管理等功能,並讓PKMS進入systemready狀態。

啟動調用棧如下圖所示:

Android 10.0 PackageManagerService(一)工作原理及啟動流程

4.1.1 [SystemServer.java] startBootstrapServices()

說明:startBootstrapServices()首先啟動Installer服務,也就是安裝器,隨後判斷當前的設備是否處於加密狀態,如果是則只是解析核心應用,接著調用PackageManagerService的靜態方法main來創建pms對象

(1)啟動Installer服務

(2)獲取設備是否加密(手機設置密碼),如果設備加密了,則只解析"core"應用

(3)調用PKMS main方法初始化PackageManagerService,其中調用PackageManagerService()構造函數創建了PKMS對象

(4)如果設備沒有加密,操作它。管理A/B OTA dexopting。

源碼:

Android 10.0 PackageManagerService(一)工作原理及啟動流程

4.1.2 [SystemServer.java]

startOtherServices()

說明:

(5)執行 updatePackagesIfNeeded ,完成dex優化;

(6)執行 performFstrimIfNeeded ,完成磁盤維護;

(7)調用systemReady,準備就緒。

源碼:

Android 10.0 PackageManagerService(一)工作原理及啟動流程

4.1.3 [PackageManagerService.java] main()

說明:

main函數主要工作:

(1)檢查Package編譯相關係統屬性

(2)調用PackageManagerService構造方法

(3)啟用部分應用服務於多用戶場景

(4)往ServiceManager中註冊”package”和”package_native”。

源碼:

Android 10.0 PackageManagerService(一)工作原理及啟動流程

PKMS初始化時的核心部分為PackageManagerService()構造函數的內容,我們下面就來分析該流程


4.2 PKMS構造函數分析

PKMS的構造函數中由兩個重要的鎖(mInstallLock、mPackages) 和5個階段構成,下面會詳細的來分析這些內容。

mInstallLock :用來保護所有安裝apk的訪問權限,此操作通常涉及繁重的磁盤數據讀寫等操作,並且是單線程操作,故有時候會處理很慢。

此鎖不會在已經持有mPackages鎖的情況下火的,反之,在已經持有mInstallLock鎖的情況下,立即獲取mPackages是安全的

mPackages:用來解析內存中所有apk的package信息及相關狀態。


5個階段:

階段1:

BOOT_PROGRESS_PMS_START

階段2:BOOT_PROGRESS_PMS_SYSTEM_SCAN_START

階段3:BOOT_PROGRESS_PMS_DATA_SCAN_START

階段4:BOOT_PROGRESS_PMS_SCAN_END

階段5:BOOT_PROGRESS_PMS_READY

PKMS服務也是通過binder進行通信,IPackageManager.aidl由工具轉換後自動生成binder的服務端IPackageManager.Stub和客戶端IPackageManager.Stub.Proxy,具體關係如圖:

Android 10.0 PackageManagerService(一)工作原理及啟動流程

Binder服務端:PackageManagerService繼承於IPackageManager.Stub;

Binder客戶端:ApplicationPackageManager(簡稱APM)的成員變量mPM繼承於IPackageManager.Stub.Proxy; 本身APM是繼承於PackageManager對象。


4.2.1 [PackageManagerService.java]

說明:IPackageManager.Stub是IPackageManager.aidl自動生成的,正好也說明了PKMS是service端的,通過binder交互

源碼:

Android 10.0 PackageManagerService(一)工作原理及啟動流程

4.2.2 [PackageManagerService.java] PackageManagerService()

說明:PackageManagerService構造函數

源碼:

Android 10.0 PackageManagerService(一)工作原理及啟動流程

4.2.3 階段1:BOOT_PROGRESS_PMS_START

主要工作:

(1)構造 DisplayMetrics ,保存分辨率等相關信息;

(2)創建Installer對象,與installd交互;

(3)創建mPermissionManager對象,進行權限管理;

(4)構造Settings類,保存安裝包信息,清除路徑不存在的孤立應用,主要涉及/data/system/目錄的packages.xml,packages-backup.xml,packages.list,packages-stopped.xml,packages-stopped-backup.xml等文件。

(5)構造PackageDexOptimizer及DexManager類,處理dex優化;

(6)創建SystemConfig實例,獲取系統配置信息,配置共享lib庫;

(7)創建PackageManager的handler線程,循環處理外部安裝相關消息。

源碼:

Android 10.0 PackageManagerService(一)工作原理及啟動流程

readLPw()會掃描下面5個文件

1) "/data/system/packages.xml"

2) "/data/system/packages-backup.xml"

3) "/data/system/packages.list"

4) "/data/system/packages-stopped.xml"

5) "/data/system/packages-stopped-backup.xml"

5個文件共分為三組,簡單的作用描述如下:

  1. packages.xml:PKMS 掃描完目標文件夾後會創建該文件。當系統進行程序安裝、卸載和更新等操作時,均會更新該文件。該文件保存了系統中與 package 相關的一些信息。
  2. packages.list:描述系統中存在的所有非系統自帶的 APK 的信息。當這些程序有變動時,PKMS 就會更新該文件。
  3. packages-stopped.xml:從系統自帶的設置程序中進入應用程序頁面,然後在選擇強制停止(ForceStop)某個應用時,系統會將該應用的相關信息記錄到此文件中。也就是該文件保存系統中被用戶強制停止的 Package 的信息。

這些目錄的指向,都在Settings中的構造函數完成, 如下所示,得到目錄後調用readLPw()進行掃描

Android 10.0 PackageManagerService(一)工作原理及啟動流程

解析上面這個幾個xml的內容,建立對應的數據結構

Android 10.0 PackageManagerService(一)工作原理及啟動流程

說明:創建 SharedUserSetting 對象並添加到 Settings 的成員變量 mSharedUsers 中,在 Android 系統中,多個 package 通過設置 sharedUserId 屬性可以運行在同一個進程,共享同一個 UID

源碼:

Android 10.0 PackageManagerService(一)工作原理及啟動流程

4.2.4 階段2:BOOT_PROGRESS_PMS_SYSTEM_SCAN_START

主要工作:

(1)從init.rc中獲取環境變量BOOTCLASSPATH和SYSTEMSERVERCLASSPATH;

(2)對於舊版本升級的情況,將安裝時獲取權限變更為運行時申請權限;

(3)掃描system/vendor/product/odm/oem等目錄的priv-app、app、overlay包;

(4)清除安裝時臨時文件以及其他不必要的信息。

源碼:

Android 10.0 PackageManagerService(一)工作原理及啟動流程

4.2.5 階段3:BOOT_PROGRESS_PMS_DATA_SCAN_START

主要工作有:對於不僅僅解析核心應用的情況下,還處理data目錄的應用信息,及時更新,祛除不必要的數據。

源碼:

Android 10.0 PackageManagerService(一)工作原理及啟動流程

4.2.6 階段4:BOOT_PROGRESS_PMS_SCAN_END

主要工作:

(1)sdk版本變更,更新權限;

(2)OTA升級後首次啟動,清除不必要的緩存數據;

(3)權限等默認項更新完後,清理相關數據;

(4)更新package.xml

源碼:

Android 10.0 PackageManagerService(一)工作原理及啟動流程

4.2.7 階段5:BOOT_PROGRESS_PMS_READY

主要工作有:

(1)創建PackageInstallerService對象

(2)GC回收內存

源碼:

Android 10.0 PackageManagerService(一)工作原理及啟動流程

4.3 dex 優化

檢查是否需要去更新Packages並進行dex優化,如果沒有OTA升級、沒有大版本升級、沒有清楚過dalvik虛擬機的緩存,可以去更新packages,

最終調用的是Installer的dexopt()進行優化

調用棧如下:

Android 10.0 PackageManagerService(一)工作原理及啟動流程

4.3.1 [PackageManagerService.java] updatePackagesIfNeeded()

說明:

檢查是否需要去更新Packages並進行dex優化,如果沒有OTA升級、沒有大版本升級、沒有清楚過dalvik虛擬機的緩存,可以去更新packages

更新packages的優先級:core app >system app > other app,調用 performDexOptUpgrade()進行更新

源碼:

Android 10.0 PackageManagerService(一)工作原理及啟動流程

4.3.2 [PackageManagerService.java] performDexOptUpgrade()

說明:判斷是否需要對package進行更新,如果需要更新那麼按照優先級完成dex優化,最終調用Install的dexopt()進行dex優化,參考上面的調用棧

源碼:

Android 10.0 PackageManagerService(一)工作原理及啟動流程

4.4 磁盤維護

磁盤維護最終調用的是vold進程的 fstrim()進行清理操作

調用棧:

Android 10.0 PackageManagerService(一)工作原理及啟動流程

[PackageManagerService.java] performFstrimIfNeeded()

說明:主要是執行磁盤清理工作,釋放磁盤空間

源碼:

Android 10.0 PackageManagerService(一)工作原理及啟動流程

4.5 PKMS 準備就緒

[PackageManagerService.java] systemReady()

說明:systemReady主要完成的是默認授權和更新package的信息,通知在等待pms的一些組件

源碼:

Android 10.0 PackageManagerService(一)工作原理及啟動流程

下一節將會講解PKMS 的權限掃描、APK掃描、安裝等內容,歡迎關注我


分享到:


相關文章: