鸿蒙子系统解读-包管理子系统篇
本文作者:江苏润和软件股份有限公司 戴海
1. 框架简介
包管理子系统,是OpenHarmony为开发者提供的安装包管理框架,应用程序的安装、卸载、升级、权限管理等一系列操作都是通过包管理器完成的。包管理子系统由如下图模块组成:
· BundleKit:是包管理服务对外提供的接口,有安装/卸载接口、包信息查询接口、包状态变化监听接口。
· 包扫描器:用来解析本地预制或者安装的安装包,提取里面的各种信息,供管理子模块进行管理,持久化。
· 包安装子模块:安装,卸载,升级一个包;包安装服务一个单独进程的用于创建删除安装目录,具有较高的权限。
· 包管理子模块:管理安装包相关的信息,存储持久化包信息。
· 包安全管理子模块:签名检查、权限授予、权限管理。
2. 代码目录结构
foundation/appexecfwk/interfaces/kits/bundle_lite | BundleKit为开发者提供的接口 |
---|---|
foundation/appexecfwk/interfaces/innerkits/bundlemgr_lite | BundleKit实现的核心代码,及包管理服务为其它子系统提供的接口 |
foundation/appexecfwk/frameworks/bundle_lite | 管理BundleKit与包管理服务通信的客户端代码 |
foundation/appexecfwk/utils/bundle_lite | 包管理服务实现中用到的工具性的代码 |
foundation/appexecfwk/services/bundlemgr_lite | 包管理服务的实现代码 |
3. 实例讲解
为了能够熟悉包管理的是如何工作的,接下来将以包安装和包信息查询来进行详解。
Ø 案例一:包安装
Install是包安装的入口函数,首先创建了GetBmsInnerClient对象,这是用于和Server端进行IPC通讯的IClientProxy,通过Invoke发送了ID为INSTALL的消息,在Server端(bundlems)将对INSTALL进行功能实现,安装结果通过BundleSelfCallback回调回来。需要注意这里的Client和Server并不是直接进行IPC通讯的,而是通过/dev/lite_ipc驱动中转调用到Server端,这个中转过程就不在本章进行详细讲解。
//bundle_manager.cpp
bool Install(const char *hapPath, const InstallParam *installParam, InstallerCallback installerCallback)
{
……
const SvcIdentity *svc = OHOS::BundleSelfCallback::GetInstance().RegisterBundleSelfCallback(installerCallback); //注册回调,用于反馈包安装的状态结果
IpcIoPushSvc(&ipcIo, svc);
……
auto bmsInnerClient = GetBmsInnerClient();
……
int32_t ret = bmsInnerClient->Invoke(bmsInnerClient, INSTALL, &ipcIo, &result, Notify);//通过IPC和包管理服务通讯
……
}
static IClientProxy *GetBmsInnerClient()
{
……
IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(BMS_SERVICE, BMS_INNER_FEATURE);//获取BMS_SERVICE的FeatureApi,用于调用包安装接口
……
}
定义INSTALL的Invoke ID,在Server端通过ID来映射到对应的包安装接口函数,这里同时还定义了卸载、包信息查询等,GET_BUNDLE_INFO后面的包信息查询中会用到。
// bundle_inner_interface.h
enum BmsCmd {
……
GET_BUNDLE_INFO,
……
INSTALL = BMS_INNER_BEGIN, // bms install application
……
};
刚才提到了Client端IClientProxy的创建,那对应Server端则有一个IServerProxy,用于远程接口调用。g_bmsInnerImpl 就是声明了IServerProxy,当收到INSTALL的消息时,则会通过BundleMsInvokeFuc根据Invoke ID来映射到对应的函数指针InstallInnerBundle。 由于包安装是个较为耗时的操作,所以采用异步线程Request的请求方式。包安装完成后向Client端反馈包安装状态。
//bundle_inner_feature.cpp
static BmsInnerImpl g_bmsInnerImpl = {