Chromium 命名规范

2021年09月15日 阅读数:1
这篇文章主要向大家介绍Chromium 命名规范,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

Chromium 代码中的文件数不胜数,读懂文件名能够帮咱们快速定位某个文件的用途。好的文件命名方式应该是自解释的,可以实现 “望文生义” 的效果。不过 Chromium 只对代码风格作了指引,并未对名称的遣词作统一规定,因此文件的命名更可能是所在目录的约定俗成,受 Owner 的文化背景影响,好比有 Mac 或 iOS 开发背景的 Owner 更有可能将一个类的回调对象命名为 Delegate,而非此背景下的开发者则有可能命名为 Client。linux

*_{platform}.{ext}

Chromium 代码支持多个平台,因为各个平台有不一样的系统 API ,一般须要将这些 API 进行封装,并只在对应的平台上进行编译。 Chromium 在文件名层面区分不一样的平台的方式是命名为 *_{platform}.{ext} ,例如 ,该文件就只在 android 平台进行编译。Chromium 的两个编译系统, gyp 原生支持在编译时过滤非对应平台的源文件, gn 则须要手动声明 sources_assignment_filter 才能过滤。android

目前 Chromium 经常使用的的平台标识符以下:ios

  • android
  • chromeos
  • freebsd
  • fuchsia
  • ios
  • linux
  • mac
  • openbsd
  • posix
  • win

其中 fuchsia 是 Google 最新开发的操做系统,可以同时支持 PC 和嵌入式设备。web

*_impl.{ext}

Chromium 代码中随处可见 *_impl.{ext} 文件,涵义并不彻底相同。chrome

cc/ 目录下的部分 *_impl.{ext} 文件表示该类运行在 impl-side painting 的 impl 线程,好比 cc/trees/layer_tree_host_impl.h。数据结构

除此以外的 {clazz}_impl.{ext} 文件基本上都是抽象接口 Clazz 类的具体实现类。架构

web_*_impl.{ext} 一般表示该类是 WebKit 的平台实现(PlatformImpl),好比 content/child/web_url_loader_impl.h 即为 WebKit 的 WebURLLoader 在 Chromium 平台下的实现。socket

定义抽象接口类与具体实现 Impl 类的方法作到了接口与实现的分离,保证了接口类的相对稳定,也对上层模块隐藏了实现细节;同时抽象接口类容许咱们实现 Mock 类,方便进行单元测试,特别是考虑到 content/ 目录下不少类都须要进行 IPC 通讯,初始化、创建管道等操做相对于单元测试来讲太过于繁琐。ide

*_host.{ext}

Host 在 Chromium 代码中的语义也不尽相同,在 Chromium 代码中有一类 *_host.{ext} 文件标识了多进程架构下的通讯关系,一般老是有一个 {clazz}.{ext} 文件与 {clazz}_host.{ext} 对应,好比 content/public/browser/render_view_host.h 与 content/public/renderer/render_view.h 。单元测试

RenderViewHost 与 RenderView 经过 IPC 消息进行通讯,很大程度上能够认为 RenderViewHost 是 RenderView 在 Browser 端的代理(Proxy),几乎全部 Browser 端对 RenderViewHost 的操做都须要经过 IPC 消息传给 RenderView 进行实际操做,而 RenderView 也须要经过 IPC 消息传递到 RenderViewHost 回调和通知 Browser 端的上层。

如下列出了几个使用 Host 这种用法的重要的文件:

  • content/browser/frame_host/render_frame_host_impl.h 与 content/renderer/render_frame_impl.h
  • content/browser/renderer_host/render_view_host_impl.h 与 content/renderer/render_view_impl.h
  • content/browser/loader/resource_dispatcher_host_impl.h 与 content/child/resource_dispatcher.h
  • gpu/ipc/client/gpu_channel_host.h 与 gpu/ipc/service/gpu_channel.h

IPC 消息三剑客

IPC 是 Chromium 多进程架构下进程间通讯的机制,经过命名管道(Linux 和 OS X 下是 socketpair)在进程间传递二进制数据,该二进制数据是由用于进程间通讯的数据结构序列化而来,因此在 IPC 消息的接收端还要反序列化回来。

  • *_messages.{ext}

*_messages.{ext} 经过 Chromium 提供的一套 IPC 消息生成宏(参见 ipc_message_macros.h)定义 IPC 消息及其参数。咱们只须要声明 IPC 消息的类型以及参数列表,对复合型的参数声明其数据结构中须要序列化的字段,上述消息宏会自动帮咱们生成 IPC 消息序列化和反序列化的实现。

  • *_traits.{ext}

有些复合型参数,不能简单的经过序列化和反序列化数据结构中的字段来传递数据,而须要作一些额外的操做。 *_traits.{ext} 文件就是用于自定义这类参数的序列化和反序列化实现。

  • *_message_filter.{ext}

IPC 消息的实际 I/O 操做在当前进程的 IO 线程上,监听处理逻辑(IPC::Listener)运行在当前进程的主线程(Browser 端是 UI 线程,Renderer 端是 Renderer 线程)上, MessageFilter 提供了一个机会能够在 IO 线程上直接拦截 IPC 消息,一般用于将拦截到的 IPC 消息转发到非主线程。

*.mojom

mojom 是 mojo 的模板文件,在前一篇 《Chromium代码文化系列之二:目录结构》中咱们提到, mojo 相似于 Android 的 AIDL ,提供了跨语言(C++ / Java / JavaScript)的进程间对象(Object)通讯机制, mojom 文件也相似于 aidl 文件,会生成进程间通讯对象的抽象接口以及其底层的 IPC 实现。