Mojo For Chromium Developers1
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 Developers1的更多相关文章
- Mojo For Chromium Developers
Overview This document contains the minimum amount of information needed for a developer to start us ...
- [Chromium文档转载,第003章]Proposal: Mojo Synchronous Methods
Proposal: Mojo Synchronous Methods yzshen@chromium.org 02/02/2016 Overview Currently there are quite ...
- [Chromium文档转载,第002章]Mojo C++ Bindings API
Mojo C++ Bindings API This document is a subset of the Mojo documentation. Contents Overview Getting ...
- [Chromium文档转载,第001章] Mojo Migration Guide
For Developers > Design Documents > Mojo > Mojo Migration Guide 目录 1 Summary 2 H ...
- [Chromium文档转载,第006章]Chrome IPC To Mojo IPC Cheat Sheet
For Developers > Design Documents > Mojo > Chrome IPC To Mojo IPC Cheat Sheet 目录 1 O ...
- [Chromium文档转载,第005章]Calling Mojo from Blink
For Developers > Design Documents > Mojo > Calling Mojo from Blink Variants Let's as ...
- [Chromium文档转载,第004章]Mojo Synchronous Calls
For Developers > Design Documents > Mojo > Synchronous Calls Think carefully before ...
- chromium源码阅读--进程间通信(IPC)
第一篇就有提到Chromium是目前默认是采用多进程架构,当然,chromium有singe-process的版本. 多进程与多线程的区别,确实有很多可以讲的,我的另一篇博客也讲了一些,这里是从浏览器 ...
- Chromium与CEF的多进程模型及相关參数
CEF基于Chromium,也是多进程模型.关于进程模型.參考这里:https://www.chromium.org/developers/design-documents/process-model ...
随机推荐
- C#各个版本中的新增特性详解【转】
序言 自从2000年初期发布以来,c#编程语言不断的得到改进,使我们能够更加清晰的编写代码,也更加容易维护我们的代码,增强的功能已经从1.0搞到啦7.0甚至7.1,每一次改过都伴随着.NET Fram ...
- 51nod 1268 和为K的组合 dfs
题目: 1268 和为K的组合 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题 给出N个正整数组成的数组A,求能否从中选出若干个,使他们的和为K.如果可以,输出:& ...
- XShell与虚拟机连接的IP问题
这几天在Xshell连接虚拟机这个问题上头疼了好长时间,原因是我在虚拟机内的eth0网卡没有分配IP地址,从而导致无法连接XShell,今天解决了这个问题,做一下记录. 首先我使用的是微软的Hyper ...
- ZBrush中Z球(ZSphere和ZSphereⅡ)
ZSphere可以让用户使用干净的拓扑结构快速建立一个基础网格,然后将其塑造成任何形状.ZSphere的强大在于它非常简单,用户可以从一个单一的ZSphere开始,然后轻松地在其上面增加新的ZSphe ...
- [LOJ2607]【NOIP2012】疫情控制
题意: 题目描述 H 国有n个城市,这n个城市用n-1 条双向道路相互连通构成一棵树,1 号城市是首都,也是树中的根节点. H 国的首都爆发了一种危害性极高的传染病.当局为了控制疫情,不让疫情扩散到边 ...
- [SHOI2009]Booking 会场预约
题目:洛谷P2161. 题目大意:有一些操作,分为两种: A.增加一个从第l天到第r天的预约,并删除与这个预约冲突的其他预约,输出删除了多少个预约. B.输出当前有效预约个数. 两个预约冲突定义为两个 ...
- caioj 1204 Catalan数(模板)
题目中对卡特兰数的总结很不错 以下copy自题目 Catalan数列:1,1,2,5,14,42,(前面几个要背) 即 h(0)=1,h(1)=1,h(2)=2,h(3)=5...公式:h(n)=C( ...
- SpringBoot实战(一)HelloWorld
一:环境准备: JDK:1.8版本 Maven:3.5版本(如果觉得下载速度慢,可以切换为阿里镜向地址) Intellij:2018.2.1版本 二:实际操作: 1.在Intellij中创建一个新的S ...
- Google的10大座右铭
1. 以用户为中心,其他一切纷至沓来. 创建伊始,Google 即以提供最佳的用户体验为其中心任务.虽然很多公司主张客户利益优先,但难以抗拒各种诱惑,往往会牺牲客户的少量利益来增加股东价值. Goog ...
- maven跳过单元测试-maven.test.skip和skipTests的区别以及部分常用命令
-DskipTests,不执行测试用例,但编译测试用例类生成相应的class文件至target/test-classes下. -Dmaven.test.skip=true,不执行测试用例,也不编译测试 ...