【Android-PKMS】APK安裝過程

 

【從一個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()

 

 

未完待續……

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章