【架構分析】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>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章