#过年不停更# OpenHarmony IPC通信(L2) 原创 精华
碼磚民工
发布于 2022-2-11 19:25
浏览
13收藏
@toc
一、简介
此文章以OpenHarmony3.0代码为基础,Hi3516DV300开发板来进行编写测试。
OpenHarmony的IPC通信,几乎所有模块都有用到。
对IPC通信流程的理解,为熟悉了解其他模块有很重要的帮助。
IPC通信(仓库:communication_ipc)
与safwk系统服务框架(仓库:distributedschedule_safwk)
和samgr系统服务管理(仓库:distributedschedule_samgr)
有很紧密的联系。
二、IPC通信
2.1 IPC通信注册流程
以foundation\communication\ipc\ipc\test\auxiliary\native为例,对IPC进行梳理。
IPC通信包括客户端(client)和服务端(service)。
- 服务端
TestService
继承自IPCObjectStub
。 - 客户端
TestServiceClient
通过iface_cast<ITestService>(object)
获取到一个TestServiceProxy
对象。TestServiceProxy
继承自PeerHolder
,里面包含指向IPCObjectProxy
的指针。 - 客户端的
IPCObjectProxy
和服务端IPCObjectStub
是对应关系。
流程图:
流程图解释
- 服务端以
IPC_TEST_SERVICE
为saId
,将继承自IPCObjectStub
的对象经dbinder驱动,注册到samgr系统服务管理进程中去。
binder_translate_binder有一个将标志为BINDER_TYPE_BINDER
转换成BINDER_TYPE_HANDLE
的过程。samgr响应注册消息,通过BinderInvoker::UnflattenObject
解析对象,实际上是根据注册的IPCObjectStub
new一个IPCObjectProxy
对象存储在samgr的map中。
- 客户端以
IPC_TEST_SERVICE
去samgr中取IPCObjectProxy
对象。并通过iface_cast
new一个包含取的IPCObjectProxy
的TestServiceProxy
对象。这样客户端和服务端就建立起了关系,可以进行下一步相互通信。
2.2 IPC通信交互
- OpenHarmony的IPC通信,有点类似http协议:客户发送数据==>服务端响应处理数据==>服务端回复==>客户端获取到回复数据
流程图如下:
客户端与服务端的交互
客户端通过:Remote()->SendRequest
向服务端发消息,等待结果。
服务端通过:xxxServiceStub::OnRemoteRequest
处理客户端消息,并回复。 - 客户端和服务端读写数据中转函数
读写驱动:BinderInvoker::TransactWithDriver
数据处理:BinderInvoker::HandleCommands(uint32_t cmd)
数据流可以参考文章:openHarmony IPC数据传输情景分析
binder驱动目录://kernel/linux/linux-4.19/drivers/android
,驱动的起始调用函数:device_initcall
。驱动名称如下图:
BinderInvoker中调用,驱动响应命令BINDER_WRITE_READ
如下图:
三、samgr系统服务管理进程
主要管理各个模块服务端注册的saId
和IPCObjectProxy
对象键值对。
四、safwk系统服务框架
IPC客户端服务端注册拉起框架。
4.1 服务端的注册
xxxInterface是客户端和服务端都需要实现的接口继承类。
- 注册方式1,基本上自己有main函数入口:
xxxService继承IPCObjectStub 和 xxxInterface
auto saMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
sptr<IRemoteObject> newInstance = new xxxService();
int result = saMgr->AddSystemAbility(xxxSaId, newInstance);
- 注册方式2, 本身没有main函数入口,需要借助safwk的main入口:
xxxService继承IPCObjectStub,xxxInterface 和 SystemAbility
// 注册方式2的第一种方式
REGISTER_SYSTEM_ABILITY_BY_ID(xxxService, xxxSaId, true); // 添加ability信息
Publish(this); // 在重写的OnStart函数中调用,注册到samgr中
// 注册方式2的第二种方式
SystemAbility::MakeAndRegisterAbility
Publish(this)
4.2 服务拉起
- 注册方式1:有main入口,是一个独立进程。直接运行即可。
- 注册方式2:编译出来是一个动态库,
通过:/system/bin/sa_main /system/profile/xxx_sa.xml
拉起来,xml文件中配置了动态库信息。可以参考文档
【OpenHarmony SA 动态库服务 拉起的main入口】了解拉起流程
4.3 客户端类定义
xxxServiceProxy继承PeerHolder 和 xxxInterface
客户端类中定义一个静态变量:
// 定义静态变量,才能通过iface_cast创建一个包含IPCObjectProxy的xxxServiceProxy对象
static inline BrokerDelegator<xxxServiceProxy> delegator_;
4.4 客户端获取注册信息
auto saMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
sptr<IRemoteObject> object = saMgr->GetSystemAbility(SaId);
client = iface_cast<xxxInterface >(object);
以foundation\communication\ipc\ipc\test\auxiliary\native为例继承图:
以上是个人对于IPC通信的理解,欢迎一起学习指正。
©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
分类
文章中的图片.rar 116.45K 235次下载
IPC通信继承关系_软件StarUML.rar 14.3K 176次下载
已于2022-11-18 10:56:00修改
赞
12
收藏 13
回复
相关推荐
好贴,点赞
好文,附件里的图片也非常清晰
内容不错,干货满满
必须点赞!
demo可以开源么? 在调试相关的问题, 想参考下,谢谢了
这个demo就是源码中的:foundation\communication\ipc\ipc\test\auxiliary\native
你好。请问一下,在编译源码的时候没有编译测试用例,有啥启用测试用例编译的方法么,想要测试一下