博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Mojo For Chromium Developers
阅读量:6070 次
发布时间:2019-06-20

本文共 5396 字,大约阅读时间需要 17 分钟。

Overview

This document contains the minimum amount of information needed for a developer to start using Mojo in Chromium. For more detailed documentation on the C++ bindings, see .

Terminology

message pipe is a pair of endpoints. Each endpoint has a queue of incoming messages, and writing a message to one endpoint effectively enqueues that message on the other endpoint. Message pipes are thus bidirectional.

mojom file describes interfaces which describe strongly typed message structures, similar to proto files.

Given a mojom interface and a message pipe, the two endpoints can be given the labels InterfacePtr and Binding. This now describes a strongly typed message pipe which transports messages described by the mojom interface. The InterfacePtr is the endpoint which “sends” messages, and the Binding “receives” messages. Note that the message pipe itself is still bidirectional, and it's possible for a message to have a response callback, which the InterfacePtr would receive.

Another way to think of this is that an InterfacePtr is capable of making remote calls on an implementation of the mojom interface associated with the Binding.

The Binding itself is just glue that wires the endpoint's message queue up to some implementation of the interface provided by the developer.

Example

Let‘s apply this to Chrome. Let’s say we want to send a “Ping” message from a Browser to a Renderer. First we need to define the mojom interface.

module example.mojom;interface PingResponder {  // Receives a "Ping" and responds with a random integer.  Ping() => (int random);};

Now let's make a MessagePipe.

example::mojom::PingResponderPtr ping_responder; example::mojom::PingResponderRequest request = mojo::MakeRequest(&ping_responder);

In this example, ping_responder is the InterfacePtr, and request is an InterfaceRequest, which is a Binding precursor that will shortly be turned into a Binding. Now we can send our Ping message.

auto callback = base::Bind(&OnPong); ping_responder->Ping(callback);

Important aside: If we want to receive the the response, we must keep the object ping_responder alive. After all, it‘s just a wrapper around a Message Pipe endpoint, if it were to go away, there’d be nothing left to receive the response.

We‘re done! Of course, if everything were this easy, this document wouldn’t need to exist. We've taken the hard problem of sending a message from the Browser to a Renderer, and transformed it into a problem where we just need to take the request object, pass it to the Renderer, turn it into a Binding, and implement the interface.

In Chrome, processes host services, and the services themselves are connected to a Service Manager via message pipes. It‘s easy to pass request to the appropriate Renderer using the Service Manager, but this requires explicitly declaring our intentions via manifest files. For this example, we’ll use the content_browser service  and the content_renderer service .

content_renderer_manifest.json:... "interface_provider_specs": { "service_manager:connector": { "provides": { "cool_ping_feature": [ "example::mojom::PingResponder" ] }, }, ...
content_browser_manifest.json:... "interface_provider_specs": { "service_manager:connector": { "requires": { "content_renderer": [ "cool_ping_feature" ], }, }, }, ...

These changes indicate that the content_renderer service provides the interface PingResponder, under the capability named “cool_ping_feature”. And the content_browser services intends to use this feature. content::BindInterface is a helper function that takes request and sends it to the renderer process via the Service Manager.

content::RenderProcessHost* host = GetRenderProcessHost(); content::BindInterface(host, std::move(request));

Putting this all together for the browser process:

example::mojom::PingResponderPtr ping_responder; // Make sure to keep this alive! Otherwise the response will never be received. example::mojom::PingResponderRequest request = mojo::MakeRequest(&ping_responder); ping_responder->Ping(base::BindOnce(&OnPong)); content::RenderProcessHost* host = GetRenderProcessHost(); content::BindInterface(host, std::move(request));

In the Renderer process, we need to write an implementation for PingResponder, and ensure that a Binding is created using the transported request. In a standalone Mojo service, this would require us to implement service_manager::Service::OnBindInterface(). In Chrome, this is abstracted behind content::ConnectionFilters and service_manager::BinderRegistry. This is typically done in RenderThreadImpl::Init.

class PingResponderImpl : mojom::PingResponder { void BindToInterface(example::mojom::PingResponderRequest request) { binding_.reset( new mojo::Binding
(this, std::move(request))); } void Ping(PingCallback callback) { std::move(callback).Run(4); } std::unique_ptr
> binding_; }; RenderThreadImpl::Init() { ... this->ping_responder = std::make_unique
(); auto registry = base::MakeUnique
(); // This makes the assumption that |this->ping_responder| will outlive |registry|. registry->AddInterface(base::Bind(&PingResponderImpl::BindToInterface), base::Unretained(this->ping_responder.get())); GetServiceManagerConnection()->AddConnectionFilter( base::MakeUnique
(std::move(registry))); ...

转载于:https://www.cnblogs.com/huangguanyuan/p/10321063.html

你可能感兴趣的文章
JAVA的String 类
查看>>
cocos2d 的touch事件要点
查看>>
程序入口
查看>>
Spring MVC 3.0 RestTemplate
查看>>
ADO.NET访问数据集的表、行和列
查看>>
Flink - Working with State
查看>>
svn add xxx.txt 提示A (bin) xxx.txt
查看>>
数据库设计
查看>>
C语言 · 分数统计
查看>>
推断两条单链表是否相交
查看>>
Linux ftrace框架介绍及运用
查看>>
UVA 12295 Optimal Symmetric Paths
查看>>
【技术贴】tomcat启动失败 can not find a free socket的解决办法
查看>>
根据结构体里面元素的某个地址计算机构体地址
查看>>
如何使用 ADO.NET 和 Visual C# .NET 以编程方式创建 SQL Server 数据库
查看>>
Hash碰撞与拒绝服务攻击
查看>>
atmega8 例程:按键输入检测
查看>>
坑爹的AVR编译器中文路径问题
查看>>
(转)程序员真的是吃青春饭的吗?(献给即将进入职场的程序员们)
查看>>
C++获取一个文件夹下的所有文件名(转)
查看>>