Mojo For Chromium Developers
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
A 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.
A 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的更多相关文章
- Mojo For Chromium Developers1
Mojo For Chromium Developers Overview This document contains the minimum amount of information neede ...
- [Chromium文档转载,第002章]Mojo C++ Bindings API
Mojo C++ Bindings API This document is a subset of the Mojo documentation. Contents Overview Getting ...
- Converting Legacy Chrome IPC To Mojo
Converting Legacy Chrome IPC To Mojo Looking for Mojo Documentation? Contents Overview Deciding What ...
- Mojo C++ Bindings API
This document is a subset of the Mojo documentation. Contents Overview Getting Started Interfaces Ba ...
- Chromium Embedded Framework 中文文档(简介)
转自:http://www.cnblogs.com/think/archive/2011/10/06/CEF-Introduce.html 简介 Chromium Embedded Framework ...
- 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 ...
- Why mobile web apps are slow
http://sealedabstract.com/rants/why-mobile-web-apps-are-slow/ I’ve had an unusual number of interest ...
- Network Stack
Network Stack 目录 1 Overview 2 Code Layout 3 Anatomy of a Network Request (focused on HTTP) 3.1 URLRe ...
- React中autoComplete="off" 失效
Turning Off Autocomplete in Chrome with React tl;dr Add a hidden input with an arbitrary value attri ...
随机推荐
- UVa 11520 Fill in the Square
题意:给出 n*n的格子,把剩下的格子填上大写字母,使得任意两个相邻的格子的字母不同,且从上到下,从左到右的字典序最小 从A到Z枚举每个格子填哪一个字母,再判断是否合法 #include<ios ...
- ABBYY FineReader双十一优惠享不停,战绩如何?
随着双十一的火热来袭,购物达人也是不吝啬囊中票子,各种姿势剁手齐全,立誓过后吃土半月,双十一的好与不好?自己也是门清,反正真真的是促进消费了! 就ABBYYFineReader而言,此次的双十一力度就 ...
- css3动画机制原理和实战
这段时间喜欢上css3动画效果了,关于这个每个人都有不同的看法,在我个人看来css3在做一些小页面的动画效果还是很好用的,一些简单的小动画要是用js的话,未免浪费. 要是做大一点的话最好js+css3 ...
- Pyhton学习——Day58
From表单验证 <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...
- Pyhton学习——Day26
#多态:多态指的是一类事物有多种形态# import abc# class Animal(metaclass = abc.ABCMeta):# 同一类事物:动物# @abc.abstractclass ...
- [USACO07OPEN]Catch That Cow
题目:洛谷P1588.HDU2717 题目大意:有一个人在点$n$,一头牛在点$k$,人每秒能从$x$移动到点$x+1$.$x-1$.$2x$,牛不会动,求最少多少秒后人能移动到牛所在的$k$. 思路 ...
- MBR和GPT分区学习
1.MBR 早期的windows和linux都采用的MBR的方法来处理开机引导程序和分区表,对于linux的MBR分区来讲,0柱面0磁道1扇区用于引导驱动程序,第一扇区有512个字节,前446字节存放 ...
- Python及相应软件安装
Python安装 这是下载地址:Linux下载链接,windows下载链接 1.下载压缩包 wget https://www.python.org/ftp/python/3.7.1/Python-3. ...
- struts2解决动态多文件上传的问题(上传文件与数据库字段一一对应)(转)
struts2多文件上传我想只要会用struts2的朋友都不会陌生,但是怎么在action中根据用户上传的文 件把文件路径写到数据库中对应的字段上呢?ps:我的意思是这样,页面上有固定的5个上传文件的 ...
- 【【henuacm2016级暑期训练】动态规划专题 M】Little Pony and Harmony Chest
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 每一位显然只要取1..60这些数字. 然后需要保证每个这些数字里面,每个数字所用到的质因子都它所唯一拥有的.别人不能用 因为如果别人 ...