【架构分析】Fuchsia FIDL IPC 详解

目录

概述

Fuchsia IPC Architecture Overview

FIDL IPC 详解


概述

Fuchsia使用Fuchsia Interface Definition Language (FIDL) 作为进程IPC的接口描述语言,本文旨在详细分析基于FIDL的IPC原理

 

Fuchsia FIDL IPC Architecture Overview

Fuchsia IPC Overview
  • 通过FIDL描述IPC接口Interface
  • Client 进程使用InterfacePtr<Interface>来调用Interface中的接口获得服务
  • Service进程实现Interface中的接口来提供服务
  • Client和Service通过Message Loop被通知channel上有数据从而进行回调处理(关于Message Loop请参考我的另外一篇文章 https://blog.csdn.net/HaoBBNuanMM/article/details/86774697
  • 为了描述更具体清晰,本文使用view_provider.fidl 作为Interface的具体例子来分析IPC的原理和过程
[Discoverable]
interface ViewProvider {
    // Creates a new View under the control of the ViewProvider.
    //
    // |token| is one half of the shared eventpair which will bind the new View
    // to its associated ViewHolder.  The ViewProvider will use |token| to
    // create its internal View representation.  The caller is expected to use
    // its half to create corresponding ViewHolder object.
    //
    // |incoming_services| allows clients to request services from the
    // ViewProvider implementation.  |outgoing_services| allows clients to
    // provide services of their own to the ViewProvider implementation.
    //
    // Clients can embed a ViewHolder (and by proxy the paired View) into their
    // scene graph by using |Node.AddChild()|.  The ViewHolder cannot itself
    // have any children. A ViewProvider implementation can nest scene objects
    // within its View by using |View.AddChild()|.  The View itself
    // cannot be a child of anything.
    //
    // Modules can use these mechanisms to establish a distributed,
    // inter-process scene graph.
    CreateView(handle<eventpair> token,
               request<fuchsia.sys.ServiceProvider>? incoming_services,
               fuchsia.sys.ServiceProvider? outgoing_services);
};

FIDL IPC 详解

FIDL IPC 类图

FIDL IPC中涉及的Class大致可以分为4种

  1. Client端使用的Class
  2. Service端使用的Class
  3. FIDL自动代码生成的Class
  4. Client和Service都会使用到的Class(包括访问Zircon微内核channel的Class)
Binding过程

理解FIDL IPC通信一定要理解Binding的作用,如上图所示,Service端包括FIDL Interface实现类在内的几个核心数据结构共同完成了将底层channel绑定到FIDL Interface实现类的过程

IPC 数据与控制流

完成了Binding过程后,如上图所示Client通过FIDL Interface的调用就可以IPC到Service端并且派发给对应的实现类来完成需要的功能了

下面依然以FIDL view_provider.fidl 中定义的interface ViewProvider作为具体的例子说明Client与Service的IPC时序

Client通过FIDL接口ViewProvider发起CreateView IPC的调用时序

 

Service通过FIDL接口ViewProvider接收到CreateView IPC的调用时序

 

  ViewProviderService view_provider(startup_context.get());

  // Add our ViewProvider service to the outgoing services.
  startup_context->outgoing().AddPublicService<fuchsia::ui::app::ViewProvider>(
      [&view_provider](fidl::InterfaceRequest<fuchsia::ui::app::ViewProvider> request) {
        view_provider.HandleViewProviderRequest(std::move(request));
      });

其中 FIDL Interface ViewProvider 的Service端bouncing ball应用程序main函数中,通过AddPublicService对外暴露了ViewProvider service,当有新的Client连接ViewProvider service的时候,就会先调用AddPublicService中作为参数的InterfaceRequestHandler函数(上面的代码中是以Lamba函数的形式实现),而该函数中最重要的信息就是参数fidl::InterfaceRequest<fuchsia::ui::app::ViewProvider> request,它代表了链接Client的channel

  void HandleViewProviderRequest(fidl::InterfaceRequest<fuchsia::ui::app::ViewProvider> request) {
    bindings_.AddBinding(this, std::move(request));
  }

ViewProvider service在收到Client的request 后通过Binding 将该request对应的channel绑定到了ViewProvider service的实例即this 对象上,这样就完成了Client channel与Service之间建立IPC链接的过程,为后续Client通过FIDL ViewProvider Interface IPC调用service奠定了通信基础;此处使用bindings的原因是可以有很多个Client的request连接到Service

 

Tips

  • Fuchsia FIDL文件的位置: fuchsia/garnet/public/fidl/<fuchsia.package.name>
  • 编译FIDL后自动生成的代码位置:fuchsia/out/arm64/fidling/gen/fuchsia/<package>/<name>
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值