【從一個APK安裝另一個APK】
首先是從context獲得PackageManager句柄,然後調用installPackage()進行安裝
ContextImpl.java::getPackageManager()
pm = ActivityThread.java::getPackageManager(){
//最終獲得PackageManagerService服務
ServiceManager.getService("package");
}
new ApplicationPackageManager.java:ApplicationPackageManager(pm)
}
ContextImpl::getPackageManager()獲得的是ApplicationPackageManager實例,ApplicationPackageManager通過構造函數傳入的pm句柄訪問PackageManagerService的部分接口。
ApplicationPackageManager.java::installPackage(){
ApplicationPackageManager.java::installCommon(){
PackageManagerService.java::installPackageAsUser(){
PackageManagerService.java::PackageHandler.doHandleMessage(INIT_COPY)
//MCS=Media Contain Service
PackageManagerService.java::PackageHandler.doHandleMessage(MCS_BOUND)
//拷貝安裝
PackageManagerService.java::HandlerParams.startCopy(){
PackageManagerService.java::InstallParams.startCopy(){
//拷貝
PackageManagerService.java::InstallParams.handleStartCopy(){
DefaultContainerService.java::getMinimalPackageInfo(){
PackageHelper.resolveInstallLocation(){
//決定目標安裝位置
}}
PackageManagerService.java::FileInstallArgs.copyApk(){
PackageManagerService.java::FileInstallArgs.doCopyApk(){
DefaultContainerService.java::copyPackage(){
DefaultContainerService.java::copyPackageInner(){
DefaultContainerService.java::copyFile(){
Streams.copy(in, out);
}}}}}}
//安裝
PackageManagerService.java::InstallParams.handleReturnCode(){
PackageManagerService.java::processPendingInstall(){
mHandler.post(new Runnable()){:
//安裝前準備
PackageManagerService.java::InstallArgs.doPreInstall()
//執行安裝
PackageManagerService.java::installPackageTracedLI(){
PackageManagerService.java::installPackageLI(){
PackageParser.parsePackage()
//if replace: 替換安裝
PackageManagerService.java::replacePackageLIF()
//else : 新包安裝
PackageManagerService.java::installNewPackageLIF(){
//掃描Package
PackageManagerService.java::scanPackageTracedLI(){
PackageManagerService.java::scanPackageLI(){
PackageManagerService.java::scanPackageLI(){
PackageManagerService.java::scanPackageInternalLI()
}}}}
//把Package更新到Settings裏
PackageManagerService.java::updateSettingsLI(){
PackageManagerService.java::updateSettingsInternalLI(){
//更新apk的權限
PackageManagerService.java::updatePermissionsLPw()
//再次把已安裝apk的信息寫入/data/system/package.xml
Settings.java::writeLPr()
}}
}}
//安裝收尾
PackageManagerService.java::doPostInstall()
}}
}}}}}
要點:
- PKMS的一個安裝入口:PackageManagerService.java::installPackageAsUser()
【adb install】
Pm.java::main(){
Pm.java::run(){
Pm.java::runInstall(){
final InstallParams params = makeInstallParams();
//打開一個Session
Pm.java::doCreateSession(){
PackageInstaller.java::createSession(){
PackageInstallerService.java::createSession(){
PackageInstallerService.java::createSessionInternal(){
PackageInstallerSession.java::PackageInstallerSession(){
}}}}
//把要安裝的APK寫入Session
Pm.java::doWriteSession(){
PackageInstaller.java::openSession(){
PackageInstallerService.java::openSession(){
PackageInstallerService.java::openSessionInternal(){
PackageInstallerSession.java::open(){
}}}
out = PackageInstaller.java::openWrite(){
PackageInstallerSession.java::openWrite(){
PackageInstallerSession.java::openWriteInternal(){
new RevocableFileDescriptor.java::RevocableFileDescriptor()
}}
ParcelFileDescriptor.java::AutoCloseOutputStream()
}
while(1){
in.read(buffer) //從inPath中讀取
out.write(buffer) //寫入out
}}
//提交:告訴PKMS開始安裝
Pm.java::doCommitSession(){
PackageInstaller.java::Session.commit(){
PackageInstallerSession.java::commit(){
mHandler.obtainMessage(MSG_COMMIT).sendToTarget()
PackageInstallerSession.java::commitLocked(){
PackageManagerService.java::installStage(){
mHandler.sendMessage(INIT_COPY);//往後過程與上節部分重疊
}}}}}
}}}
要點:
- adb install會創建一個新進程,從pm.main函數開始執行
- 先創建與PackageInstallerService的連接
- PKMS的另一個安裝入口:PackageManagerService.java::installStage()
未完待續……