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