目录
概述
Fuchsia IPC Architecture Overview
FIDL IPC 详解
Fuchsia使用Fuchsia Interface Definition Language (FIDL) 作为进程IPC的接口描述语言,本文旨在详细分析基于FIDL的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 token,
request? incoming_services,
fuchsia.sys.ServiceProvider? outgoing_services);
};
FIDL IPC中涉及的Class大致可以分为4种
理解FIDL IPC通信一定要理解Binding的作用,如上图所示,Service端包括FIDL Interface实现类在内的几个核心数据结构共同完成了将底层channel绑定到FIDL Interface实现类的过程
完成了Binding过程后,如上图所示Client通过FIDL Interface的调用就可以IPC到Service端并且派发给对应的实现类来完成需要的功能了
下面依然以FIDL view_provider.fidl 中定义的interface ViewProvider作为具体的例子说明Client与Service的IPC时序
ViewProviderService view_provider(startup_context.get());
// Add our ViewProvider service to the outgoing services.
startup_context->outgoing().AddPublicService(
[&view_provider](fidl::InterfaceRequest 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
void HandleViewProviderRequest(fidl::InterfaceRequest 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