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 this link.

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 manifest file and the content_renderer service manifest file.

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<mojom::MemlogClient>(this, std::move(request)));
}
void Ping(PingCallback callback) { std::move(callback).Run(4); }
std::unique_ptr<mojo::Binding<mojom::PingResponder>> binding_;
}; RenderThreadImpl::Init() {
...
this->ping_responder = std::make_unique<PingResponderImpl>();
auto registry = base::MakeUnique<service_manager::BinderRegistry>(); // 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<SimpleConnectionFilter>(std::move(registry)));
...

Mojo For Chromium Developers的更多相关文章

  1. Mojo For Chromium Developers1

    Mojo For Chromium Developers Overview This document contains the minimum amount of information neede ...

  2. [Chromium文档转载,第002章]Mojo C++ Bindings API

    Mojo C++ Bindings API This document is a subset of the Mojo documentation. Contents Overview Getting ...

  3. Converting Legacy Chrome IPC To Mojo

    Converting Legacy Chrome IPC To Mojo Looking for Mojo Documentation? Contents Overview Deciding What ...

  4. Mojo C++ Bindings API

    This document is a subset of the Mojo documentation. Contents Overview Getting Started Interfaces Ba ...

  5. Chromium Embedded Framework 中文文档(简介)

    转自:http://www.cnblogs.com/think/archive/2011/10/06/CEF-Introduce.html 简介 Chromium Embedded Framework ...

  6. How to steal any developer's local database

    原文链接: http://bouk.co/blog/hacking-developers/ If you’re reading this and you’re a software developer ...

  7. Why mobile web apps are slow

    http://sealedabstract.com/rants/why-mobile-web-apps-are-slow/ I’ve had an unusual number of interest ...

  8. Network Stack

    Network Stack 目录 1 Overview 2 Code Layout 3 Anatomy of a Network Request (focused on HTTP) 3.1 URLRe ...

  9. React中autoComplete="off" 失效

    Turning Off Autocomplete in Chrome with React tl;dr Add a hidden input with an arbitrary value attri ...

随机推荐

  1. MeayunDB-高性能分布式内存数据库

    MeayunDB(www.meayun.com)是一款分布式的NoSQL列式内存数据库,由C#编写,主要为高性能,高并发,高可伸缩及大数据系统提供技术解决方案.基于MeayunDB,可以简单,快速的构 ...

  2. ajax第一天总结

    AJAX开发步骤 步一:创建AJAX异步对象,例如:createAJAX() 步二:准备发送异步请求,例如:ajax.open(method,url) 步三:如果是POST请求的话,一定要设置AJAX ...

  3. java导出html页面

    http://blog.csdn.net/zhyh1986/article/details/8727523#t6 http://blog.csdn.net/zuozuofuwaiwai/article ...

  4. jupyter的安装

    3.6:\Lib\site-packages\pip\models\index.py # PyPI = Index('https://pypi.python.org/') # 替换成 PyPI = I ...

  5. HDU 2049 不容易系列之(4)——考新郎( 错排 )

    链接:传送门 思路:错排水题,从N个人中选出M个人进行错排,即 C(n,m)*d[m] 补充:组合数C(n,m)能用double计算吗?第二部分有解释 Part 1. 分别求出来组合数的分子和分母然后 ...

  6. NOIP2016 天天爱跑步 (树上差分+dfs)

    题目大意:给你一颗树,树上每个点都有一个观察员,他们仅会在 w[i] 时刻出现,观察正在跑步的玩家 一共有m个玩家,他们分别从节点 s[i] 同时出发,以每秒跑一条边的速度,沿着到 t[i] 的唯一路 ...

  7. Flask-Babel 使用简介(翻译文档)

    最近用flask-bable翻译一个项目,在网站上查找到有一个示例文档,地址:http://translations.readthedocs.io/en/latest/flask-babel.html ...

  8. Django REST Framework 数码宝贝 - 3步进化 - 混合类 -->

    读了我这篇博客, 你会刷新对面对对象的认知, 之前的面对对象都是LJ~~~ 表结构 class Publisher(models.Model): name = models.CharField(max ...

  9. [luogu] P4364 [九省联考2018]IIIDX(贪心)

    P4364 [九省联考2018]IIIDX 题目背景 Osu 听过没?那是Konano 最喜欢的一款音乐游戏,而他的梦想就是有一天自己也能做个独特酷炫的音乐游戏.现在,他在世界知名游戏公司KONMAI ...

  10. tp框架 JS里面获取session

    var var_name="{:session('xxxxx')}"; 用大括号 这个方法可以获取session