Android APK安装过程介绍

课题路径:从Myfile中点击应用进行安装,到安装完成,过程分析

思想方法:在研究PreloadInstaller的时候我们直接从整个apk的文件结构入手,由整体到部分的分析;但现在整个PMS非常庞大。我们采取抓住某个功能点分析,由点到面,直到掌控全部


目录
现象    1
log分析    3
PackageInstaller 功能的提取    4
PackageInstaller/AndroidManifest.xml    4
PackageInstallerActivity.java    4
InstallAppProgress.java    4
PackageManager.java分析    5
1. installPackageWithVerificationAndEncryption    5
2. pm.installExistingPackage    5
PM/APM/PMS的关系    5
Apk安装流程图总纲    6
ApplicationPackageManager分析    6
PackageManagerService分析    8
installPackage    8
installPackageAsUser    8

现象
果宝三国.apk

 

 

log分析

ActivityManager:   START u0 {act=android.intent.action.VIEW dat=file:///storage/emulated/0/果宝三国.apk typ=application/vnd.android.package-archive cmp=com.android.packageinstaller/.PackageInstallerActivity (has extras)} from uid 10037 pid 7437 on display 0
ActivityManager:   Start proc com.android.packageinstaller for activity com.android.packageinstaller/.PackageInstallerActivity: pid=8691 uid=10095 gids={50095, 9997, 1028} abi=armeabi-v7a

要安装apk,ActivityManager根据Intent筛选 打开PackageInstaller

PackageInstaller:Launching settings 
PackageManager:  Failed to generatePackageInfoFromSettingsLPw, There isnt package setting object for com.centurysoft.fruityrobo 
PackageManager:  START_PACKAGE_INSTALL: observer{532627611} 
PackageManager:            originPath{/storage/emulated/0/果宝三国.apk} 
PackageManager:            flag{0} 
PackageManager:            Request from{null} 
PackageManager:            VerificationParams{VerificationParams{,mOriginatingUid=1000,mManifestDigest=ManifestDigest {mDigest=60,e1,a0,c0,72,ef,1c,21,4c,b9,a3,d8,bd,af,0e,af,05,8c,16,5b,ce,65,6a,ab,ac,45,d5,f9,66,8e,91,fa,},mInstallerUid=10095}} 
PackageManager:  [MSG] INIT_COPY: observer{532627611} 
PackageManager:            idx{0} 
PackageManager:            for_user{UserHandle{0}} 
PackageManager:  [MSG] MCS_BOUND: observer{532627611} 
PackageManager:            for_user{UserHandle{0}} 
PackageManager:  remove MCS_UNBIND message and Posting MCS_UNBIND 10 secs later 
PackageManager:  [MSG] PROCESS_PENDING_INSTALL: observer{532627611} 
PackageManager:  currentStatus{1} 
PackageManager:  installPackageLI: path=/data/app/vmdl679148838.tmp 
PackageManager:  verifying app can be installed or not 
PackageManager:  Renaming /data/app/vmdl679148838.tmp to /data/app/com.centurysoft.fruityrobo-1 
PackageManager:  installNewPackageLI: Package{1af2bbac com.centurysoft.fruityrobo} 
PackageManager:  scanFileNewer : com.centurysoft.fruityrobo 
PackageManager:  Resolved nativeLibraryRoot for com.centurysoft.fruityrobo to root=/data/app/com.centurysoft.fruityrobo-1/lib, isa=true 
PackageManager:  Abis for package[com.centurysoft.fruityrobo] are primary=armeabi secondary=null 
PackageManager:  Running dexopt on: /data/app/com.centurysoft.fruityrobo-1/base.apk pkg=com.centurysoft.fruityrobo isa=arm vmSafeMode=false interpret_only=false 
PackageManager:  do mInstaller.dexopt : 0 
PackageManager:  Time to dexopt com.centurysoft.fruityrobo: 4.943 seconds 
PackageManager:  New package installed in /data/app/com.centurysoft.fruityrobo-1 
PackageManager:  Not granting permission android.permission.MOUNT_UNMOUNT_FILESYSTEMS to package com.centurysoft.fruityrobo (protectionLevel=18 flags=0x8be44) 
PackageManager:  Unknown permission com.android.launcher3.permission.READ_SETTINGS in package com.centurysoft.fruityrobo 
PackageManager:  Unknown permission com.android.launcher2.permission.READ_SETTINGS in package com.centurysoft.fruityrobo 
PackageManager:  doPostInstall for uid{10156} 
PackageManager:  token 11 to BM for possible restore 
PackageManager:  BM finishing package install for 11 
PackageManager:  [MSG] POST_INSTALL: observer{532627611} 
PackageManager:            Handling post-install for 11 
Launcher.PackageChangeReceiver: onReceive = Intent { act=android.intent.action.PACKAGE_ADDED dat=package:com.centurysoft.fruityrobo flg=0x4000010 (has extras) } 
PackageManager: result of install: 1{532627611}

 

PackageInstaller 通过一系列的校验之后 调用PMS来实现安装过程

PackageManager: result of install: 1{532627611} 表示安装成功,如果是其他的返回值表示安装不成功

 

PackageInstaller 功能的提取

 

PackageInstaller/AndroidManifest.xml

刚才的log如下:

act=android.intent.action.VIEW

dat=file:///storage/emulated/0/果宝三国.apk

typ=application/vnd.android.package-archive

 

PackageInstallerActivity.java

PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java

找构造方法和onCreate方法

构造方法:无

onCreate方法:

 

InstallAppProgress.java

PackageInstaller/src/com/android/packageinstaller/InstallAppProgress.java

搜关键字“pm.” 关于安装的只有两个地方

搜索“pm =”,可以看到依赖 PackageManager 中的方法

 

PackageManager.java分析

1. installPackageWithVerificationAndEncryption

public abstract void installPackageWithVerificationAndEncryption(Uri packageURI,
        IPackageInstallObserver observer, int flags, String installerPackageName,
        VerificationParams verificationParams, ContainerEncryptionParams encryptionParams);

public abstract void installPackageWithVerificationAndEncryption(Uri packageURI,
        PackageInstallObserver observer, int flags, String installerPackageName,
        VerificationParams verificationParams, ContainerEncryptionParams encryptionParams);
installerPackageName 安装程序来自于哪,由哪个程序安装的

2. pm.installExistingPackage

因为这是首次安装,所以不走这个路径

 

 

Apk安装流程图总纲

 

 

 

ApplicationPackageManager分析

 

installPackageWithVerificationAndEncryption

installCommon

 

 

 

PackageManagerService 是 IPackageManager的实现类

 

PackageManagerService分析

installPackage

 

installPackageAsUser

对userId和callingUid判断是否合法

判断安装请求 来自于哪里ADB还是其他程序

判断是对所有用户安装还是只针对当前用户

EnterpriseDeviceManager对请求进行判断

 

 

各种检查完成,开始进入安装阶段

打出要安装的apk的信息

KNOX的feature,强制apk安装到SD卡

 

获取Apk默认安装路径

 

以不信任的方式获取apk,确定要安装的路径(内部存储器、外部存储器)

 

封装一个异步消息 INIT_COPY,发送 (含义:启动复制)

 

 

 

/android/frameworks/base/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java

DefaultContainerService中实现了 IMediaContainerService.Stub

MCS服务在创建连接时会发送MCS_BOUND异步消息

 

处理MCS_BOUND异步消息

 

 

 

由上面的分析可以得出,代码实际调用的是InstallParams

InstallParams.handleStartCopy流程图如下:

 

 

FileInstallArgs

int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException

 

AsecInstallArgs

int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException

 

/android/frameworks/base/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java

 

 

 

posted @ 2015-10-14 16:22  carlo-z  阅读(3977)  评论(0编辑  收藏  举报