chromium官网对mojo的描述,地址如下,英语不太好,所以进行进行翻译如下:

https://chromium.googlesource.com/chromium/src.git/+/51.0.2704.48/docs/mojo_in_chromium.md。

Chromium的Mojo

本文档旨在用作Chromium开发人员的Mojo入门。 假定没有Mojo的相关认知。

目录

  • 我应该读这个吗?
  • 为什么选择Mojo?
  • Mojo概述
    • 消息管道
    • Mojom
    • 绑定管道
    • 回应请求
  • 在Chromium中公开服务
  • Mojo in Blink
  • 问题讨论等

我应该读这个吗?

如果您打算构建需要IPC的Chromium功能,并且尚未使用Mojo,那就可以! 旧版IPC已弃用。

为什么选择Mojo?

TL;DR: 长远的目的是将Chromium重构为一大批较小的服务。

我们可以更精明一些:

  • 我们提供或不提供哪些服务
  • 我们如何隔离这些服务以提高安全性和稳定性
  • 我们向一个或另一个用户提供哪些二进制功能

更强大的消息传递层为许多有趣的可能性打开了大门。 特别是,它允许我们集成大量组件而没有链接时的相互依赖性,并且打破了整个代码库中越来越多的有趣的跨语言边界。

在过去的几年中,从使用Chromium IPC和维护Chromium依赖关系中学到了很多东西,我们认为现在有很大的机会可以使开发人员的工作更轻松,并帮助他们更快,更轻松地构建更多更好的功能。 降低用户成本

Mojo概述

Mojo系统API提供了一小套低级IPC原语:消息管道,数据管道和共享缓冲区。 在此API之上,我们构建了更高级别的绑定API,以简化编写C ++,Java或JavaScript代码的消费者的消息传递。

本文档主要侧重于将C ++绑定与消息管道一起使用,这可能是Chromium开发人员遇到的最常见用法。

消息管道

消息管道是一种轻量级的原语,用于可靠地双向传输相对较小的数据包。 毫不奇怪,管道具有两个端点,并且任一端点都可以通过另一个消息管道进行传输。

因为我们在浏览器进程和每个子进程之间引入了原始消息管道,所以这意味着您可以创建一个新管道,并最终将任一端发送到任何进程,并且两端仍然可以无缝地相互通信。

尽管消息管道可以携带任意非结构化数据包,但我们通常将它们与生成的绑定结合使用,以确保所有端点上的一致性,定义良好的版本化消息结构。

Mojom

Mojom是Mojo接口的IDL。 给定一个.mojom文件,绑定生成器输出当前所有三种受支持语言的绑定。

For example:

// src/components/frob/public/interfaces/frobinator.mojom
module frob.mojom;interface Frobinator {Frobinate();
};

would generate the following outputs:

out/Debug/gen/components/frob/public/interfaces/frobinator.mojom.cc
out/Debug/gen/components/frob/public/interfaces/frobinator.mojom.h
out/Debug/gen/components/frob/public/interfaces/frobinator.mojom.js
out/Debug/gen/components/frob/public/interfaces/frobinator.mojom.srcjar
...

生成的代码隐藏了在管道的两端对消息进行序列化和反序列化的所有详细信息。

C ++头(frobinator.mojom.h)为每个指定的mojom接口定义一个抽象类。 命名空间是从模块名称派生的。.

注意: chromium约定组件foo模块名称的为foo.mojom。 这意味着组件foo的所有由mojom生成的C ++类型名都将存在于foo :: mojom命名空间中,以避免与未生成的类型名发生冲突。

在此示例中,生成的frob :: mojom :: Frobinator具有单个纯虚函数:

namespace frob {class Frobinator {public:virtual void Frobinate() = 0;
};}  // namespace frob

要创建Frobinator服务,只需实现foo :: Frobinator并提供一种将管道绑定到它的方法。

绑定到管道

让我们看一些示例代码:

// src/components/frob/frobinator_impl.cc#include "components/frob/public/interfaces/frobinator.mojom.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/bindings/interface_request.h"namespace frob {class FrobinatorImpl : public mojom::Frobinator {public:FrobinatorImpl(mojom::FrobinatorRequest request): binding_(this, std::move(request)) {}~FrobinatorImpl() override {}// mojom::Frobinator:void Frobinate() override { DLOG(INFO) << "I can't stop frobinating!"; }private:mojo::Binding<mojom::Frobinator> binding_;
};}  // namespace frob

首先要注意的是mojo :: Binding <T>将消息管道的一端绑定到服务的实现。 这意味着它将监视管道的末端是否有传入消息。 它知道如何解码接口T的消息,并将其分派到绑定T实现的方法中。

mojom :: FrobinatorRequest是mojo :: InterfaceRequest <mojom :: Frobinator>的生成类型别名,本质上是强类型消息管道端点的语义糖。 创建新消息管道的常用方法是通过在interface_request.h中定义的GetProxy调用:

mojom::FrobinatorPtr proxy;
mojom::FrobinatorRequest request = mojo::GetProxy(&proxy);

这将创建一个新的消息管道,其一端由代理拥有,另一端由请求拥有。 它具有将普通类型信息附加到管道两端的不错的属性。

请注意,InterfaceRequest <T>实际上并没有任何作用。 它只是作用域管道端点,并在编译时将其与接口类型关联。 因此,其他类型的服务绑定原语(例如mojo :: Binding <T>)在需要端点绑定时将这些对象用作输入。

mojom :: FrobinatorPtr是mojo :: InterfacePtr <mojom :: Frobinator>的生成的类型别名。 InterfacePtr <T>也可以监视消息管道端点,但是它还通过序列化相应的消息并将其写入管道在内部实现T上的每个方法。

因此,我们可以将其放在一起以通过管道与FrobinatorImpl进行对话:

frob:mojom::FrobinatorPtr frobinator;
frob::FrobinatorImpl impl(GetProxy(&frobinator));// Tada!
frobinator->Frobinate();

这会序列化与Frobinate请求相对应的消息并将其写入管道的一端。 最终,impl的内部mojo :: Binding将解码此消息并调度对impl.Frobinate()的调用。

注意: 在此示例中,服务和客户端处于同一过程中,并且工作正常。 如果它们处于不同的流程中(请参见下面的``在Chromium中公开服务''中的示例),则对Frobinate()的调用将看起来完全相同!

回应请求

Chromium IPC中的一个常见习惯是使用某种不透明标识符(即整数请求ID)来跟踪IPC请求,以便您以后可以在另一个方向上使用一些名义上相关的消息来响应特定请求。

我们可以像这样扩展我们的Frobinator服务:

module frob.mojom;interface Frobinator {Frobinate();GetFrobinationLevels() => (int min, int max);
};

and update our implementation:

class FrobinatorImpl : public mojom::Frobinator {public:// ...// mojom::Frobinator:void Frobinate() override { /* ... */ }void GetFrobinationLevels(const GetFrobinationLevelsCallback& callback) {callback.Run(1, 42);}
};

当服务实现运行回调时,响应参数被序列化并通过管道发送回。 另一端的代理知道如何读取此响应,然后将其分派到该端的回调:

void ShowLevels(int min, int max) {DLOG(INFO) << "Frobinator min=" << min << " max=" << max;
}// ...mojom::FrobinatorPtr frobinator;FrobinatorImpl impl(GetProxy(&frobinator));frobinator->GetFrobinatorLevels(base::Bind(&ShowLevels));

这正是您所期望的

在Chromium中公开服务

可以通过多种方式在浏览器的各个表面上公开服务。 现在一种常见的方法是使用content :: ServiceRegistry(link)。 这些通常成对出现,跨进程边界,并且它们提供原始服务注册和连接接口。 例如,每个RenderFrameHost和每个对应的RenderFrame都有一个ServiceRegistry。 这些注册表是交织在一起的。

要点是,您可以将服务添加到注册表的本地端(这只是从接口名称到工厂功能的映射),也可以按名称连接到在远程端注册的服务。

注意: 在这种情况下,“工厂功能”只是一个回调,它接受管道端点并对其执行某些操作。 期望您将其绑定到某种服务实现中,或者将其关闭,以有效地拒绝连接请求。

我们可以构建一个简单的浏览器端FrobinatorImpl服务,该服务可以访问与其连接的任何框架的BrowserContext:

#include "base/macros.h"
#include "components/frob/public/interfaces/frobinator.mojom.h"
#include "content/public/browser/browser_context.h"
#include "mojo/public/cpp/system/interface_request.h"
#include "mojo/public/cpp/system/strong_binding.h"namespace frob {class FrobinatorImpl : public mojom::Frobinator {public:FrobinatorImpl(content::BrowserContext* context,mojom::FrobinatorRequest request): context_(context), binding_(this, std::move(request)) {}~FrobinatorImpl() override {}// A factory function to use in conjunction with ServiceRegistry.static void Create(content::BrowserContext* context,mojom::FrobinatorRequest request) {// See comment below for why this doesn't leak.new FrobinatorImpl(context, std::move(request));}private:// mojom::Frobinator:void Frobinate() override { /* ... */ }content::BrowserContext* context_;// A StrongBinding is just like a Binding, except that it takes ownership of// its bound implementation and deletes itself (and the impl) if and when the// bound pipe encounters an error or is closed on the other end.mojo::StrongBinding<mojom::Frobinator> binding_;DISALLOW_COPY_AND_ASSIGN(FrobinatorImpl);
};}  // namespace frob

Now somewhere in the browser we register the Frobinator service with each RenderFrameHost (this is a popular spot):

frame_host->GetServiceRegistry()->AddService<frob::mojom::Frobinator>(base::Bind(&frob::FrobinatorImpl::Create,base::Unretained(frame_host->GetProcess()->GetBrowserContext())));

And in the render process we can now do something like:

mojom::FrobinatorPtr frobinator;
render_frame->GetServiceRegistry()->ConnectToRemoteService(mojo::GetProxy(&frobinator));// It's IPC!
frobinator->Frobinate();

现在,在Chromium树中有许多Mojo用法的具体示例。 探究现有的mojom文件,看看它们的实现是如何构建和连接的。

Mojo in Blink

TODO

这是一个进展中的工作。 TL; DR:我们还将很快开始使用Blink的Mojo服务,以便平台层可以直接通过Mojo使用浏览器服务。

问题讨论等

chromium-mojo邮件列表是找到高度集中了解和关心Chromium中Mojo的人的好地方。

chromium Mojo (译)相关推荐

  1. Chromium Mojo IPC

    Mojo 是一个跨平台 IPC 框架,它诞生于 chromium ,用来实现 chromium 进程内/进程间的通信.目前,它也被用于 ChromeOS. 一.Mojo 的分层 从图中看 Mojo 分 ...

  2. chromium android分析,Chromium Android工程迁移编译过程

    本文从Chromium编译的中间产物入手深入分析.学习Chromium Android版本的工程化定制流程.初始工作依赖于Chromium的ninja.GYP构建系统,在构建完成后基于编译中间产物,迁 ...

  3. Chromium浏览器media子系统mojo说明

    Chromium浏览器media子系统mojo说明 该文件夹包含mojo接口.客户端和实现,它们扩展了核心media来支持大多数进程外使用,包括media Player.Metrics(WatchTi ...

  4. [译] APT分析报告:09.伊朗APT34更新武器库——SideTwist变体

    这是作者新开的一个专栏,主要翻译国外知名安全厂商的APT报告,了解它们的安全技术,学习它们溯源APT组织和恶意代码分析的方法,希望对您有所帮助.当然,由于作者英语有限,会借助机翻进行校验,还请包涵!前 ...

  5. 微软 Chromium Edge 禁用 Google?

    微软在Chromium Edge中禁用了Google的部分功能. 去年12月,微软宣布在Google Chromium的基础上重建Edge浏览器.最近,微软发布了首次公开预览.如人们所料,新的Edge ...

  6. Ubuntu安装Chromium

    为什么80%的码农都做不了架构师?>>>    在Ubuntu上使用APT安装Chromium有3种方法: 1.在Ubuntu软件中心输入chromium,然后在结果中选择安装即可. ...

  7. [译] 2019 前端性能优化年度总结 — 第五部分

    原文地址:Front-End Performance Checklist 2019 - 5 原文作者:Vitaly Friedman 译文出自:掘金翻译计划 本文永久链接:github.com/xit ...

  8. (译)2019年前端性能优化清单 — 中篇

    (译)2019年前端性能优化清单 - 上篇 (译)2019年前端性能优化清单 - 中篇 (译)2019年前端性能优化清单 - 下篇 目录 资源优化 17. 使用 Brotli 或 Zopfli 进行纯 ...

  9. chromium 84.0.4122.0 WebView apk 启动流程

    之前的博客介绍了chromium代码的下载和编译,调试环境的搭建.接下来我们根据编译的WebViewInstrumentation.apk来梳理浏览器的入口,看看chromium demo apk的启 ...

最新文章

  1. 2016030204 - git和github结合
  2. linux中html图标格式,如何在Linux上将HTML页面转化成png图片
  3. 在三层交换机上配置DHCP
  4. window安装swagger editor
  5. 【Boost】系列03:内存管理之shared_ptr智能指针
  6. c 语言多参数函数,C/C++实现多参数函数编程
  7. Mysql Order By 字符串排序,mysql 字符串order by
  8. 蒙特卡洛估值几种不同的计算方式(Python)
  9. C语言课后习题(16)
  10. 2寸的照片长宽各是多少_2寸照片的尺寸,1寸和 2 寸相片具体大小尺寸是多
  11. 【通讯录】Excel通讯录导入手机详细教程
  12. mac虚拟机parallels装Ubuntu无法联网
  13. dell主板40针开机针脚_主板开机针脚 ,该怎么插啊 分别有POWER SW, H.D.D LED, RESET SW, P...
  14. YUV/YIQ色彩空间的转换
  15. 程序员都在读的实战书,你看懂封面了吗?
  16. 硬盘分区那点事儿(MBR和GPT)
  17. 七彩虹主板进BIOS设置和打开启动项菜单快捷键
  18. Python Turtle绘制炫酷漂亮图案(turtledemo模块实例)
  19. jQuery_01选择器
  20. windows CE初次接触(一次升级长安致尚XT高德导航的经历)

热门文章

  1. PR 如何设置素材持续时间
  2. 河北省考计算机知识,河北省教育考试网计算机考试
  3. python读取excel超链接
  4. java怎么写函数_java构造函数怎么写
  5. 使用python 画全换手后筹码分布图
  6. springmvc的RequestResponseBodyMethodProcessor解析_晏无心_新浪博客
  7. PHPcms首页模板修改无效
  8. tcl卸载会怎么样 tvac_tcl电视用adb命令免root卸载系统自带第三方软件
  9. 复旦MBA海外短期课程 | 善用ESG金融,共创可持续未来
  10. chatgpt智能提效职场办公-ppt怎么做才好看又快