Open Harmony——包管理子系统包安装模块源码解析

弱龄寄事外,委怀在琴书。这篇文章主要讲述Open Harmony——包管理子系统包安装模块源码解析相关的知识,希望能为你提供帮助。
作者:李小慧
简介包管理子系统负责应用安装包的管理,提供安装包的信息查询、安装、更新、卸载和包信息存储等能力。
包管理子系统架构如下图所示:

Open Harmony——包管理子系统包安装模块源码解析

文章图片

代码目录
foundation/appexecfwk/standard ├── kits │└── appkit# Appkit实现的核心代码 ├── common │└── log# 日志组件目录 ├── interfaces │└── innerkits# 内部接口存放目录 ├── services │└── bundlemgr# 包管理服务框架代码 │└── dbms# 分布式包管理服务框架代码 ├── test# 测试目录 └── tools# bm命令存放目录

包安装类间关系及关键类介绍 类图
Open Harmony——包管理子系统包安装模块源码解析

文章图片

BaseBundleInstaller是安装流程中最重要的类,最终的安装、卸载功能都是在其中实现的。
IBundleMgr中定义了获取IBundleInstaller实例的方法GetBundleInstaller。
IBundleInstaller类是BundleInstallerProxy和BundleInstallerHost的基类,只是在类中声明了Install,Uninstall等函数,具体实现是在这两个子类中实现的。
BundleInstallerProxy类实现了Install,Uninstall功能,利用IPC Proxy向service层发送安装或卸载请求。
服务层Host接收到Proxy发送过来的请求处理消息,调用BundleInstallerHost类的Install功能,调用BundleInstallerManager类的创建安装任务CreateInstallTask函数,在此函数中调用BundleInstaller类的Install功能。
BundleInstaller类的基类是BaseBundleInstaller,它的Install功能实际上调用的是BaseBundleInstaller类的InstallBundle函数。
BMSEventHandler类是继承EventHandler类的,由它来处理系统应用包的安装。它调用SystemBundleInstaller类的InstallSystemBundle函数。
SystemBundleInstaller类也是BaseBundleInstaller的子类,所以最终调用的还是BaseBundleInstaller的InstallBundle功能。
关键类介绍
类名 功能简介
IBundleMgr 包管理类,声明了获取和查询APP信息、包信息等接口。
IBundleInstaller 包安装类,声明了安装、卸载等接口。
BundleInstallerProxy interface层包安装代理类,继承了IBundleInstaller类,实现了安装、卸载等功能。
BundleInstallerHost service层host侧包安装类,继承了IBundleInstaller类,处理来自proxy的安装、卸载信息,实现了host侧安装、卸载等功能,。
BundleInstallerManager 包安装服务类,创建安装、卸载等任务。
BundleInstaller 包安装类,实现安装、卸载第三方应用包功能。
BMSEventHandler 继承EventHandler,实现了处理系统应用包安装等功能。
SystemBundleInstaller 系统应用包安装类,实现安装、卸载系统应用包功能。
BaseBundleInstaller 包安装基类,实现安装、卸载包功能。
第三方应用包安装流程图
Open Harmony——包管理子系统包安装模块源码解析

文章图片

源码分析
由于流程较为复杂,受篇幅限制,此处摘取流程中重要的代码段进行说明。详细的代码流程需要对照OpenHarmony源码进行学习。
1.包管理的NAPI Init()函数中注册包安装installfoundation\\appexecfwk\\standard\\kits\\appkit\\napi\\bundlemgr\\native_module.cpp
```c++
//注册模块
extern " C" attribute((constructor)) void RegisterModule(void)

napi_module_register(& _module);

//包模块描述
static napi_module _module =
.nm_version = 1,
.nm_flags = 0,
.nm_filename = nullptr,
.nm_register_func = Init,
.nm_modname = " bundle" ,
.nm_priv = ((void )0),
.reserved = 0
;
//初始化
static napi_value Init(napi_env env, napi_value exports)

...
napi_property_descriptor properties[] =
DECLARE_NAPI_FUNCTION(" install" , Install),//调用Install流程
DECLARE_NAPI_FUNCTION(" recover" , Recover),
DECLARE_NAPI_FUNCTION(" uninstall" , Uninstall),
;
NAPI_CALL(env,
napi_define_class(env,
" BundleInstaller" ,
NAPI_AUTO_LENGTH,
BundleInstallerConstructor,
nullptr,
sizeof(properties) / sizeof(
properties),
properties,
& m_classBundleInstaller));

#### 2.调用 bundle_mgr.c中的 Installfoundation\\appexecfwk\\standard\\kits\\appkit\\napi\\bundlemgr\\bundle_mgr.cpp```C++ napi_value Install(napi_env env, napi_callback_info info)... napi_create_async_work( env, nullptr, resourceName, [](napi_env env, void *data) AsyncInstallCallbackInfo *asyncCallbackInfo = (AsyncInstallCallbackInfo *)data; if (!asyncCallbackInfo-> errCode) InnerInstall(env, asyncCallbackInfo-> hapFiles, asyncCallbackInfo-> installParam, asyncCallbackInfo-> installResult); //调用InnerInstall, ...

```C++
static void InnerInstall(napi_env env, const std::vector< std::string> & bundleFilePath, InstallParam & installParam,
InstallResult & installResult)

if (bundleFilePath.empty())
installResult.resultCode = static_cast< int32_t> (IStatusReceiver::ERR_INSTALL_FILE_PATH_INVALID);
return;

auto iBundleMgr = GetBundleMgr();
if (!iBundleMgr)
APP_LOGE(" can not get iBundleMgr" );
return;

auto iBundleInstaller = iBundleMgr-> GetBundleInstaller();
if ((iBundleInstaller == nullptr) || (iBundleInstaller-> AsObject() == nullptr))
APP_LOGE(" can not get iBundleInstaller" );
return;

installParam.installFlag = InstallFlag::REPLACE_EXISTING;
OHOS::sptr< InstallerCallback> callback = new InstallerCallback();
if (!callback)
APP_LOGE(" callback nullptr" );
return;

sptr< BundleDeathRecipient> recipient(new BundleDeathRecipient(callback)); iBundleInstaller-> AsObject()-> AddDeathRecipient(recipient); iBundleInstaller-> Install(bundleFilePath, installParam, callback); //调用IBundleInstaller的Install installResult.resultMsg = callback-> GetResultMsg(); APP_LOGD("InnerInstall resultMsg %publics", installResult.resultMsg.c_str()); installResult.resultCode = callback-> GetResultCode(); APP_LOGD("InnerInstall resultCode %publicd", installResult.resultCode);


#### 3.IBundleInstaller的Install在继承类BundleInstallerProxy 中实现,发送安装消息foundation\\appexecfwk\\standard\\interfaces\\innerkits\\appexecfwk_core\\src\\bundlemgr\\bundle_installer_proxy.cpp```C++ bool BundleInstallerProxy::Install( const std::string & bundlePath, const InstallParam & installParam, const sptr< IStatusReceiver> & statusReceiver)BYTRACE_NAME(BYTRACE_TAG_APP, __PRETTY_FUNCTION__); MessageParcel data; MessageParcel reply; MessageOption option(MessageOption::TF_SYNC); PARCEL_WRITE_INTERFACE_TOKEN(data, GetDescriptor()); PARCEL_WRITE(data, String16, Str8ToStr16(bundlePath)); PARCEL_WRITE(data, Parcelable, & installParam); if (!statusReceiver) APP_LOGE("fail to install, for statusReceiver is nullptr"); return false; if (!data.WriteObject< IRemoteObject> (statusReceiver-> AsObject())) APP_LOGE("write parcel failed"); return false; return SendInstallRequest(static_cast< int32_t> (IBundleInstaller::Message::INSTALL), data, reply, option); //发送安装消息

```C++
bool BundleInstallerProxy::SendInstallRequest(const int32_t& code, MessageParcel& data, MessageParcel& reply,
MessageOption& option)

sptr< IRemoteObject> remote = Remote();
if (!remote)
APP_LOGE(" fail to uninstall, for Remote() is nullptr" );
return false;

int32_t ret = remote-> SendRequest(code, data, reply, option); //发送安装消息 if (ret != NO_ERROR) APP_LOGE("fail to sendRequest, for transact is failed and error code is: %publicd", ret); return false; return true;


#### 4.在service层host侧处理安装消息foundation\\appexecfwk\\standard\\services\\bundlemgr\\src\\bundle_installer_host.cpp```C++ int BundleInstallerHost::OnRemoteRequest( uint32_t code, MessageParcel & data, MessageParcel & reply, MessageOption & option)APP_LOGD("bundle installer host onReceived message, the message code is %publicu", code); std::u16string descripter = GetDescriptor(); std::u16string remoteDescripter = data.ReadInterfaceToken(); if (descripter != remoteDescripter) APP_LOGE("fail to write reply message in bundle mgr host due to the reply is nullptr"); return OBJECT_NULL; switch (code) case static_cast< uint32_t> (IBundleInstaller::Message::INSTALL): HandleInstallMessage(data); //处理安装消息 break; case static_cast< uint32_t> (IBundleInstaller::Message::INSTALL_MULTIPLE_HAPS): HandleInstallMultipleHapsMessage(data); break; case static_cast< uint32_t> (IBundleInstaller::Message::UNINSTALL): HandleUninstallMessage(data); break; case static_cast< uint32_t> (IBundleInstaller::Message::UNINSTALL_MODULE): HandleUninstallModuleMessage(data); break; case static_cast< uint32_t> (IBundleInstaller::Message::RECOVER): HandleRecoverMessage(data); break; default: return IPCObjectStub::OnRemoteRequest(code, data, reply, option); return NO_ERROR; void BundleInstallerHost::HandleInstallMessage(Parcel & data)APP_LOGD("handle install message"); std::string bundlePath = Str16ToStr8(data.ReadString16()); std::unique_ptr< InstallParam> installParam(data.ReadParcelable< InstallParam> ()); if (!installParam) APP_LOGE("ReadParcelable< InstallParam> failed"); return; sptr< IRemoteObject> object = data.ReadObject< IRemoteObject> (); if (object == nullptr) APP_LOGE("read failed"); return; sptr< IStatusReceiver> statusReceiver = iface_cast< IStatusReceiver> (object); Install(bundlePath, *installParam, statusReceiver); //调用安装函数 APP_LOGD("handle install message finished"); bool BundleInstallerHost::Install( const std::string & bundleFilePath, const InstallParam & installParam, const sptr< IStatusReceiver> & statusReceiver)if (!CheckBundleInstallerManager(statusReceiver)) APP_LOGE("statusReceiver invalid"); return false; if (!BundlePermissionMgr::VerifyCallingPermission(Constants::PERMISSION_INSTALL_BUNDLE)) APP_LOGE("install permission denied"); statusReceiver-> OnFinished(ERR_APPEXECFWK_INSTALL_PERMISSION_DENIED, ""); return false; manager_-> CreateInstallTask(bundleFilePath, CheckInstallParam(installParam), statusReceiver); //创建安装任务 return true;

5.在service层bundlemgr侧创建安装任务foundation\\appexecfwk\\standard\\services\\bundlemgr\\src\\bundle_installer_manager.cpp
```C++
void BundleInstallerManager::CreateInstallTask(
const std::string & bundleFilePath, const InstallParam & installParam, const sptr< IStatusReceiver> & statusReceiver)

auto installer = CreateInstaller(statusReceiver);
if (!installer)
APP_LOGE(" create installer failed" );
return;

auto task = [installer, bundleFilePath, installParam]
int timerId = HiviewDFX::XCollie::GetInstance().SetTimer(INSTALL_TASK, TIME_OUT_SECONDS,
nullptr, nullptr, HiviewDFX::XCOLLIE_FLAGLOG);
installer-> Install(bundleFilePath, installParam); //调用BundleInstaller的Install函数
HiviewDFX::XCollie::GetInstance().CancelTimer(timerId);
;
installersPool
.AddTask(task);

#### 6.在service层bundlemgr侧安装第三方应用包foundation\\appexecfwk\\standard\\services\\bundlemgr\\src\\bundle_installer.cpp```C++ void BundleInstaller::Install(const std::string & bundleFilePath, const InstallParam & installParam)ErrCode resultCode = ERR_OK; if (installParam.userId == Constants::ALL_USERID) auto userInstallParam = installParam; for (auto userId : GetExistsCommonUserIs()) userInstallParam.userId = userId; userInstallParam.installFlag = InstallFlag::REPLACE_EXISTING; resultCode = InstallBundle( bundleFilePath, userInstallParam, Constants::AppType::THIRD_PARTY_APP); //安装第三方应用的包 ResetInstallProperties(); else resultCode = InstallBundle( bundleFilePath, installParam, Constants::AppType::THIRD_PARTY_APP); //安装第三方应用的包statusReceiver_-> OnFinished(resultCode, ""); SendRemoveEvent();

7.调用BundleInstaller基类BaseBundleInstaller的InstallBundle函数foundation\\appexecfwk\\standard\\services\\bundlemgr\\src\\base_bundle_installer.cpp
```C++
ErrCode BaseBundleInstaller::InstallBundle(
const std::string & bundlePath, const InstallParam & installParam, const Constants::AppType appType)

std::vector< std::string> bundlePathsbundlePath ;
return InstallBundle(bundlePaths, installParam, appType);

ErrCode BaseBundleInstaller::InstallBundle(
const std::vector< std::string> & bundlePaths, const InstallParam & installParam, const Constants::AppType appType)

BYTRACE_NAME(BYTRACE_TAG_APP, __PRETTY_FUNCTION__);
APP_LOGD(" begin to process bundle install" );
PerfProfile::GetInstance().SetBundleInstallStartTime(GetTickCount()); int32_t uid = Constants::INVALID_UID; ErrCode result = ProcessBundleInstall(bundlePaths, installParam, appType, uid); //处理包安装的具体流程 if (installParam.needSendEvent & & dataMgr_ & & !bundleName_.empty()) dataMgr_-> NotifyBundleStatus(bundleName_, Constants::EMPTY_STRING, mainAbility_, result, isAppExist_ ? NotifyType::UPDATE : NotifyType::INSTALL, uid); //包安装完成后反馈包安装状态PerfProfile::GetInstance().SetBundleInstallEndTime(GetTickCount()); APP_LOGD("finish to process bundle install"); return result;


## 系统应用包安装流程图![systeminstall.png](https://dl-harmonyos.51cto.com/images/202205/d236cab14659ae6e8b4956d6e004f9c6aa050e.png?x-oss-process=image/resize,w_626,h_537)### 源码分析限于篇幅,每个调用函数只摘抄关键语句。#### 1.系统应用包安装,调用EventHandler类的继承类BMSEventHandler的ProcessEvent函数foundation\\appexecfwk\\standard\\services\\bundlemgr\\src\\bundle_mgr_service_event_handler.cpp```c++ void BMSEventHandler::ProcessEvent(const InnerEvent::Pointer & event)switch (event-> GetInnerEventId()) case BUNDLE_SCAN_START: OnStartScanning(Constants::DEFAULT_USERID); //启动扫描 SetAllInstallFlag(); DelayedSingleton< BundleMgrService> ::GetInstance()-> RegisterService(); break; case BUNDLE_SCAN_FINISHED: break; case BMS_START_FINISHED: break; case BUNDLE_REBOOT_SCAN_START: RebootStartScanning(); SetAllInstallFlag(); DelayedSingleton< BundleMgrService> ::GetInstance()-> RegisterService(); break; default: APP_LOGE("the eventId is not supported"); break; void BMSEventHandler::OnStartScanning(int32_t userId)auto future = std::async(std::launch::async, [this, userId] ProcessSystemBundleInstall(Constants::AppType::SYSTEM_APP, userId); //处理系统应用包安装 ProcessSystemBundleInstall(Constants::AppType::THIRD_SYSTEM_APP, userId); //处理第三方系统应用包安装 ); future.get(); void BMSEventHandler::ProcessSystemBundleInstall(Constants::AppType appType, int32_t userId) constAPP_LOGD("scan thread start"); auto scanner = std::make_unique< BundleScanner> (); if (!scanner) APP_LOGE("make scanner failed"); return; std::string scanDir = (appType == Constants::AppType::SYSTEM_APP) ? Constants::SYSTEM_APP_SCAN_PATH : Constants::THIRD_SYSTEM_APP_SCAN_PATH; APP_LOGD("scanDir: %publics and userId: %publicd", scanDir.c_str(), userId); std::list< std::string> bundleList = scanner-> Scan(scanDir); auto iter = std::find(bundleList.begin(), bundleList.end(), Constants::SYSTEM_RESOURCES_APP_PATH); if (iter != bundleList.end()) bundleList.erase(iter); bundleList.insert(bundleList.begin(), Constants::SYSTEM_RESOURCES_APP_PATH); for (const auto & item : bundleList) SystemBundleInstaller installer(item); APP_LOGD("scan item %publics", item.c_str()); if (!installer.InstallSystemBundle(appType, userId)) //调用安装系统包流程 APP_LOGW("Install System app:%publics error", item.c_str()); PerfProfile::GetInstance().Dump();

2.调用 SystemBundleInstaller的InstallSystemBundle流程foundation\\appexecfwk\\standard\\services\\bundlemgr\\src\\system_bundle_installer.cpp
```c++
bool SystemBundleInstaller::InstallSystemBundle(Constants::AppType appType, int32_t userId)

InstallParam installParam;
installParam.userId = userId;
installParam.isPreInstallApp = true;
installParam.noSkipsKill = false;
installParam.needSendEvent = false;
if (appType == Constants::AppType::SYSTEM_APP
|| appType == Constants::AppType::THIRD_SYSTEMAPP)
installParam.needSavePreInstallInfo = true;

ErrCode result = InstallBundle(filePath
, installParam, appType);
if (result != ERR_OK)
APP_LOGE(" install system bundle fail, error: %publicd" , result);
return false;

return true;

#### 3.与第三方应用包的安装流程一样,系统应用包安装也是调用SystemBundleInstaller的基类BaseBundleInstaller的InstallBundle函数foundation\\appexecfwk\\standard\\services\\bundlemgr\\src\\base_bundle_installer.cpp```C++ ErrCode BaseBundleInstaller::InstallBundle( const std::string & bundlePath, const InstallParam & installParam, const Constants::AppType appType)std::vector< std::string> bundlePathsbundlePath ; return InstallBundle(bundlePaths, installParam, appType); ErrCode BaseBundleInstaller::InstallBundle( const std::vector< std::string> & bundlePaths, const InstallParam & installParam, const Constants::AppType appType)BYTRACE_NAME(BYTRACE_TAG_APP, __PRETTY_FUNCTION__); APP_LOGD("begin to process bundle install"); PerfProfile::GetInstance().SetBundleInstallStartTime(GetTickCount()); int32_t uid = Constants::INVALID_UID; ErrCode result = ProcessBundleInstall(bundlePaths, installParam, appType, uid); //处理包安装的具体流程 if (installParam.needSendEvent & & dataMgr_ & & !bundleName_.empty()) dataMgr_-> NotifyBundleStatus(bundleName_, Constants::EMPTY_STRING, mainAbility_, result, isAppExist_ ? NotifyType::UPDATE : NotifyType::INSTALL, uid); //包安装完成后反馈包安装状态PerfProfile::GetInstance().SetBundleInstallEndTime(GetTickCount()); APP_LOGD("finish to process bundle install"); return result;

总结本文主要介绍了包管理子系统的关键实现机制、主要类关系及重要的处理流程,为开发人员维护和扩展功能提供参考。
更多原创内容请关注:深开鸿技术团队入门到精通、技巧到案例,系统化分享HarmonyOS开发技术,欢迎投稿和订阅,让我们一起携手前行共建鸿蒙生态。
想了解更多关于开源的内容,请访问:
51CTO 开源基础软件社区
【Open Harmony——包管理子系统包安装模块源码解析】https://ost.51cto.com/#bkwz

    推荐阅读