文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Hi3516的SAMGR--系统服务框架子系统-11-Client与Client的IPC来往

2024-12-03 02:23

关注

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

进程A中的线程Aa(也就是service Aa)想要调用某个service/feature的接口,这个接口可能是进程A自己的线程Ab(也就是service Ab)提供的,也可能是进程B的线程Bc(也就是service Bc)提供的。

如果是同进程的不同服务提供的接口,那Aa只需要向自己进程的SamgrLiteImpl g_samgrImpl查询service/feature名字就可以拿到对应的IUnknown *iUnknown接口,因为是同进程内的相同虚拟地址空间,所以可以直接跨线程调用。如《系统服务框架子系统-4-面向服务架构的实现》中的测试程序所做的那样。

也就是通过调用SAMGR_GetInstance()->GetDefaultFeatureApi(SERVICE_NAME) 或者SAMGR_GetInstance()->FeatureApi(SERVICE_NAME,FEATURE_NAME)来查询接口。

如果Aa想调用的service/feature接口是B进程提供的,那首先这个service,肯定在Aa所在进程的SamgrLiteImpl g_samgrImpl里面是找不到记录的,也就是serviceImpl = NULL:


所以,跨进程的服务/特性的调用,入口就在上面的SAMGR_FindServiceApi(service, feature)。

结合我们的log,搜索一下“%%%%%%%%%%%”这样一个字符串,这是我标记的一处入口(实际上搜索“SAMGR_FindServiceApi”也差不多)。

看一下log:

  1. {[bundle_daemon_client]} Initialize: GetDefaultFeatureApi(bundle_daemon) 

这是“bundle_daemon_client”在Initialize的时候,向自己所在进程的SamgrLiteImpl g_samgrImpl查询名字为“bundle_daemon”的服务的DefaultFeatureApi。

通过前后的log,我们可以知道bundle_daemon_client所在进程的信息“pid[ 5]/uid[ 7]/(*)handle[61](*)”,5号进程是“foundation”,而“bundle_daemon”服务是6号进程提供的。

所以会通过SAMGR_FindServiceApi(S[bundle_daemon],F[(null)])来查询“bundle_daemon”服务提供的接口。

SAMGR_FindServiceApi()及其辅助函数,涉及到了g_remoteRegister.clients 这个字段,我们先来理解一下。

这是一个向量,在本进程的 g_remoteRegister 初始化的时候,也对这个向量做了配置:

  1. g_remoteRegister.clients =  VECTOR_Make((VECTOR_Key)SAMGR_GetSAName,  (VECTOR_Compare)SAMGR_CompareSAName); 

向量的element:data[x]是一个IUnknown *proxy类型的指针,指向的是一个客户端代理的接口entry.iUnknown,通过这个指针,可以转换回IClientProxy类对象、IClientEntry类对象、IDefaultClient类对象,再通过IClientProxy类对象指针去访问后面的Invoke函数,或者通过IDefaultClient类对象指针去访问上面的IClientHeader header字段内的key、target等字段。

向量中每一个element,记录了本进程EP调用过的别的进程提供的服务接口相关的重要身份信息如名字、handle、token等,这样下次再调用的时候,直接在这里查询就能获得这些信息,不需要再次通过IPC去向samgr EP查询了,它的展开图如下:


SAMGR_FindServiceApi()的流程如下:



我们接着上面的log往下看一下,


这是第一次bundle_daemon_client 向samgr EP查询FeatureAPI,但是返回的 handle 是 -1,从接下来的DbgParse_g_server的信息来看,这个时候提供bundle_daemon服务的6号进程,还没有向samge EP注册EP和Feature,所以samgr EP自己也查不到。

再看第二次bundle_daemon_client 向samgr EP查询FeatureAPI,这回查到了,handle是38,token是0,也就是说,SAMGR_CreateIProxy()的第一步,拿到了SvcIdentity identity= {38, 0, 0},跟着接下来的流程跑,就会得到一个完整有效的IDefaultClient对象,把这个对象中的 .iUnknown 地址先保存到g_remoteRegister.clients 向量中去,然后通过这个.iUnknown 地址,就可以调用客户端代理的Invoke()接口,从而再通过IPC去远程调用bundle_daemon服务了。


Privider: Pid[6]/Uid[8]/handle[38]:bundle_daemon -> (null)Consumer: Pid[5]/Uid[7]/Tid[53]

从这两句log可以看出,6号进程的bundle_daemon 服务是provider,查询并使用该服务的5号进程是consumer,这也是面向服务的架构的一种实现。

我们再看另外一个更明显的跨进程调用服务的例子:第一个应用进程launcher的孵化启动。

Log搜索“AppAppAppApp”,这是5号进程通过app_manager准备调用7号进程提供的“appspawn”服务来孵化launcher应用,它拿到了“appspawn”的handle 74、token 0和.iUnknown地址,并把该地址以及相关的重要信息添加到自己的clients向量中。


 接下来app_spawn_client调用上面的Invoke{0x249cc84c},这个Invoke{0x249cc84c}就是ProxyInvoke()函数,通过它发送IPC消息给IpcMsg Rceiver::handle[74],token[0],让它的EP收到和处理该消息,这就到了上一小节提到的Dispatch()和HandleIpc()对IPC消息的处理流程了。


经过消息的转发和处理,最后是appspawn_service的Invoke()函数开始孵化launcher应用进程,桌面应用开始提供服务。

跨进程的服务接口调用到此结束。

刚好刚才去浏览标准系统的 //base/startup/appspawn_standard/目录,看了一下README_zh,看到下面这张图就贴过来了,除了通信方式不一样之外,大体流程是一样的。


想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

 

来源:鸿蒙社区内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯