移动浏览器的开发会更加容易吗?—— Chrome 中的 content 模块
在编译运行了 android 版本的 content shell 之后,觉得Google 的意图是打造一个基本的基于多进程沙盒模型的浏览器雏形,也就是 content shell,可以方便其他浏览器厂商基于它来改造自己的浏览器。因为目前看,多进程沙盒模型会是浏览器的趋势所在,这样可能会使得浏览器的竞争出现一些变化。Chromium 是个开源项目,从道义上讲 Google 这么做是满足人心的,最重要的,我认为这么做和 Google 的根本利益没有产生冲突,相反,从打造更完善的 Web 平台角度来讲,这么做是服务于 Google 的长期利益的。
以下翻译了Content 组件
Content 模块 High-Level Overview
"content" 的代码在 src\content, 是使用多进程沙盒浏览器模型渲染页面的所需要的核心代码。它包含Web平台所有的功能(如HTML5) 和 GPU 加速. 但是它并不包括 Chrome 的功能,如 extensions,autofill,spelling 等。目的是让嵌入者可以从 content 开始构建一个浏览器,然后再从Chrome中选取功能点。
为什么会有 content
随着Chromeium 代码的增长,许多功能不可避免的被放到了错误的位置,导致软件层次之间产生本不应存在的冲突和依赖。就连开发人员也很难指出什么是最好的方式了,因为这些API(当他们存在是)和和功能代码都被放在相同的目录下了。为了避免这个的继续发生,同时也为了更加清晰的吧多进程渲染的核心代码隔离开来,大家最终达成一致意见,将Chrome的核心代码移到 src\content 目录下(并不是 chrome)。
Content 和 Chrome 的关系
从上述讨论可以看出, content 应该只包含渲染页面的核心代码。Chrome 功能使用 content 提供的 APIs 来接受 IPC 消息 和 他们所需事件的 notify。 How to Add New Features (without bloating RenderView/RenderViewHost/WebContents) 描述了如何做。
比如,下表罗列了一些只属于 Chrome 的功能,他们并不在 content 中。这意味着 content 的代码不应该需要了解这些功能的任何信息,只需要提供这些功能所依赖的普通 APIs 。
- Extensions
- ChromeFrame
- SpellCheck
- Autofill
- Prerendering
- Safe Browsing
- Translate
对于一定要供应商提供的在线网络服务,这部分交互功能希望 完全在 content 模块之外实现 。比如上面列表中的 Safe Browsing, Translate, Sync 和 Autofill 都需要各种不同的网络服务才能够工作, chrome 层是封装这些功能的最好地方。对那些个别的案例,我们需要在 content 模块中添加网络服务代码来实现 HTML5 功能,嵌入者(chrome)必须完整定义要连接的端点,典型地可以通过注入服务的 URL。我们不不希望这些策略性的代码被添加到 content,再强调一下,保持 content 的通用性。
架构图
下图展示了各个模块所在的层次关系。一个模块可以包含更低层次的模块代码,但是不能包含比他层次更高的代码。这一点通过依赖规则强制保证。每个模块都可以实现内嵌的 APIs 来方便底层模块可以通过这些API来调用他们。比如 WebKit API 和 content API。
Content API
content 中的代码可以通过Content API间接调用 Chrome。 当可能的时候,Chome 的功能试图通过过滤 IPC 消息和监听事件的方式 hook 进来,参考 How to Add New Features (without bloating RenderView/RenderViewHost/WebContents) 。
当上下文不全的时候(比如缺少从WebKit返回的回调)或者当回调只是一次性的,我们还可以通过嵌入者( chrome )实现ContentClient 接口。ContentClient 在所有进程中都可以使用, 一些进程还可以拥有自己的回调API,比如 ContentBrowserClient, ContentRendererClient, ContentPluginClient.
当上下文不全的时候(比如缺少从WebKit返回的回调)或者当回调只是一次性的,我们还可以通过嵌入者( chrome )实现ContentClient 接口。ContentClient 在所有进程中都可以使用, 一些进程还可以拥有自己的回调API,比如 ContentBrowserClient, ContentRendererClient, ContentPluginClient.
当前状态和路线图
当前 content 没有依赖于 chrome。现在我们有一个基于 content 编译出来的基本的浏览器 content shell,它可以在所有平台上使用 content 来渲染页面。 这样就允许工作在 web 平台和核心代码的发人员只需要构建、测试 content 而不是 chrome 了。我们还有 content 的单元测试 content_unittests 和集成测试 content_browsertests。
content 是以一个动态链接库的形式构建的,所以可以加快构建的过程。
类似于 WebKit API,我们已经围绕 content 封装了一层 API。这样就隔离了嵌入者(chrome)和 content 的内部工作,并且使得实现那些嵌入者调用 content 内部方法的工作变得更加清晰。
Content API 的工作已经接近尾声了。
当这件事情做完之后,它也会对隔离 chrome 功能之间的依赖关系有所帮助。比如说,如果有人打算在 content 之上新增 拼写检查和翻译的功能,他们应该可以在不需要扩展的情况下完成构建。我还需要比较好的定义不同功能之间的API才有可能完成这个目标。