业务场景
1.开机启动安装
2.通过adb安装
3.通过安装器安装
4.未知来源
研究
注:代码来自Android 10
frameworks/base/services/core/java/com/android/server/pm/
PackageManagerService.java
Installer.java
PackageInstallerService.java
PackageInstallerSession.java
PackageManagerShellCommand.java
frameworks/base/core/java/android/content/pm/
PackageInstaller.java
frameworks/base/packages/PackageInstaller/src/com/android/packageinstaller
PackageInstallerActivity.java
Installlnstalling.java
frameworks/native/cmds/installd/
***
1.开机启动安装
PackageManagerService构造方法
scanDirLI
scanPackageChildLI
addForInitLI
scanPackageNewLI
scanPackageOnlyLI
注:
扫描提取对应的数据结构,其实就是安装
拓展
这里可以自定义安装目录,例如system/presetapp。实现的方法就是
scanDirLI传入对应参数即可
2.通过adb安装
adb shell pm install apk
PackageManagerService
onShellCommand
PackageManagerShellCommand
runInstall()
doCreateSession --> 创建PackageInstallerSession,这里涉及安装器包名传参
doWriteSplit
doCommitSession
PackageInstaller --> 接口类,实现类PackageInstallerService,可创建PackageInstallerSession对象
.Session --> 接口类,实现类PackageInstallerSession
commit
PackageInstallerSession
commit
commitNonStagedLocked
PackageManagerService
installStage --> 创建InstallParams(extends HandlerParams)
startCopy --> 可以进行安装卡控
handleStartCopy --> 清除缓存,给安装提供足够的空间
handleReturnCode --> apk拷贝及安装
InstallArgs.copyApk() --> FileInstallArgs apk拷贝
processPendingInstall --> 安装
processInstallRequestsAsync
installPackagesTracedLI
installPackagesLI
preparePackageLI
scanPackageTracedLI
reconcilePackagesLocked
commitPackagesLocked
executePostCommitSteps --> 这里涉及的就是installed操作
注:
mInterface.getPackageInstaller() --> PackageInstallerService
拓展
这里可以限制apk安装,也可以理解只允许自己的安装器安装。
3.通过安装器安装
PackageInstaller
PackageInstallerActivity
Installlnstalling
InstallingAsyncTask
PackageInstaller.Session session
session.commit(pendingIntent.getIntentSender());
之后的流程关注adb shell pm安装
4.installd分析
注:
安装器和adb安装,最后都跑到installd中
adb shell service list可查对应的服务
adb shell
cd /system/bin
可查installd
启动
frameworks/native/cmds/installd/installd.rc
installd.rc
运行:
frameworks/native/cmds/installd
installd.cpp
int main(const int argc, char *argv[]) {
return android::installd::installd_main(argc, argv);
}
static int installd_main(const int argc ATTRIBUTE_UNUSED, char *argv[]) {
····
if ((ret = InstalldNativeService::start()) != android::OK) {
SLOGE("Unable to start InstalldNativeService: %d", ret);
exit(1);
}
····
}
InstalldNativeService.cpp
status_t InstalldNativeService::start() {
IPCThreadState::self()->disableBackgroundScheduling(true);
status_t ret = BinderService<InstalldNativeService>::publish();
if (ret != android::OK) {
return ret;
}
sp<ProcessState> ps(ProcessState::self());
ps->startThreadPool();
ps->giveThreadPoolName();
return android::OK;
}
//BinderService<InstalldNativeService>::publish()
//这里就是注册服务的地方
BinderService.h
static status_t publish(bool allowIsolated = false,
int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT) {
sp<IServiceManager> sm(defaultServiceManager());
return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated,
dumpFlags);//注册服务
}
注:
之前是socket通信,现在是binder通信。
客户端Installer.java
public void onStart() {
if (mIsolated) {
mInstalld = null;
} else {
connect();
}
}
private void connect() {
IBinder binder = ServiceManager.getService("installd");
if (binder != null) {
try {
binder.linkToDeath(new DeathRecipient() {
@Override
public void binderDied() {
Slog.w(TAG, "installd died; reconnecting");
connect();
}
}, 0);
} catch (RemoteException e) {
binder = null;
}
}
if (binder != null) {
mInstalld = IInstalld.Stub.asInterface(binder);
try {
invalidateMounts();
} catch (InstallerException ignored) {
}
} else {
Slog.w(TAG, "installd not found; trying again");
BackgroundThread.getHandler().postDelayed(() -> {
connect();
}, DateUtils.SECOND_IN_MILLIS);
}
}
5.未知来源检测
来源:
来源于PackageInstaller。涉及的类PackageInstallerActivity
ExternalSourcesBlockedDialog.newInstance(mOriginatingPackage)
方法:
final int appOpCode =
AppOpsManager.permissionToOpCode(Manifest.permission.REQUEST_INSTALL_PACKAGES);
final int appOpMode = mAppOpsManager.noteOpNoThrow(appOpCode,
mOriginatingUid, mOriginatingPackage);
switch (appOpMode) {
case AppOpsManager.MODE_DEFAULT:
mAppOpsManager.setMode(appOpCode, mOriginatingUid,
mOriginatingPackage, AppOpsManager.MODE_ERRORED);
// fall through
case AppOpsManager.MODE_ERRORED:
showDialogInner(DLG_EXTERNAL_SOURCE_BLOCKED);
break;
case AppOpsManager.MODE_ALLOWED:
initiateInstall();
break;
default:
Log.e(TAG, "Invalid app op mode " + appOpMode
+ " for OP_REQUEST_INSTALL_PACKAGES found for uid " + mOriginatingUid);
finish();
break;
解析:
也就是对话框为安装器弹。
可通过ExternalSourcesBlockedDialog.newInstance(mOriginatingPackage)分析具体流程。
框架
graph TD
A[需要安装的apk] --> B[PackageInstaller/adb shell pm install]
B --> C[PackageManagerService]
C --> D[Installd]
涉及知识点
ParallelPackageParser涉及的点:
入手分析点:
parallelPackageParser.submit(file, parseFlags);
parallelPackageParser.take();
BlockingQueue队列
ExecutorService线程池
参考学习
https://blog.csdn.net/yiranfeng/article/details/103941371
https://blog.csdn.net/freekiteyu/article/details/82774947