2018-03-21

我的笔记

关于Chromium


源文章地址

源代码语言

结构

Chromium分为三个主要部分(不包括其他库):浏览器,渲染器和Webkit。
浏览器:主流程,代表所有UI和I/O.
渲染器:是由浏览器驱动的(通常)每个选项卡子流程.
webkit:一个开源的浏览器引擎,它拥有清晰的结构、极快的渲染速度.(好像现在还有一个基于webkit的Blink引擎)

解决方案文件

  • 解决方案文件是chrome/chrome.sln
    • 启动代码在App/chrome_dllApp/chrome项目中。
    • 共同的共享库代码在Libraries/base项目中。(他应该尽量小)
    • 通用的浏览器特定的代码在Browser/common项目中,这是浏览器和渲染器共享的。
    • 胶水与Browser/renderer项目交谈,该项目代表我们运行每个选项卡的子流程
    • Browser/browser项目提供用户界面,存储,网络请求等。
    • Webkit代码位于中的项目中Webkit(readonly)。最重要的是Google WebKit(ours)/port与Windows 的接口,然后WebKit(ours)/glue是我们的嵌入层
结构图
  • android_webview: 提供一个适用于整合到android平台的src /内容的外观。不打算在个人Android应用程序(APK)中使用。有关 Android WebView源代码组织的更多信息。
  • apps:Chrome打包的应用。
  • base: 所有子项目之间共享的通用代码。这包含诸如字符串操作,通用实用程序等内容。只有当它必须在多个其他顶级项目之间共享时才在此处添加内容。
  • breakpad: Google的开源碰撞报告项目。这直接从Google Code的Subversion存储库中提取。
  • build: 所有项目共享的与构建相关的配置
  • cc: Chromium合成器的实现。
  • chrome:Chromium浏览器(见下文)。
  • chrome/test/data: 用于运行某些测试的数据文件。
  • components: 组件的目录,它们将内容模块作为它们所依赖的最上层。
  • content: 多进程沙盒浏览器所需的核心代码(见下文)。 关于为什么我们分离出这些代码的更多信息。
  • device:通用低级硬件API的跨平台抽象。
  • net: 为Chromium开发的网络库。在存储库中运行我们简单的test_shell时,这可以与Chromium分开使用webkit。另见chrome/common/net。
  • sandbox:试图阻止黑客渲染器修改系统的沙箱项目。
  • skia:Google为Android开发的Skia图形库。这是Android树的副本。我们在ui / gfx中的其他课程包装Skia。
  • **sql: **我们围绕sqlite。
  • testing: 包含我们用于单元测试的Google的开源GTest代码。
  • third_party: 一堆外部库,例如图像解码器和压缩库。还有一些Chrome特定的第三方库chrome/third_party。添加新的软件包。
  • tools
  • ui/gfx: 共享图形类。这些构成了Chromium UI图形的基础。
  • ui/views: 用于UI开发的简单框架,提供渲染,布局和事件处理。大多数的浏览器UI都是在这个系统中实现的。该目录包含基础对象。一些浏览器特定的对象位于chrome / browser / ui / views中。
  • url: Google的开源网址解析和规范化库。
  • v8: V8 Javascript库。这直接从Google Code的Subversion存储库中提取。
  • webkit: 所有Chromium的与Webkit相关的东西:
    appcache:
    基地:
    blob:
    构建:其余项目的项目文件和配置。
    数据:大多数目录包含我们的移植层单元测试使用的数据。该layout_tests目录是WebKit的布局测试套件,我们直接拉苹果。
    胶水:胶水层是嵌入层。它在Webcore类型和我们应用程序的类型(主要是STL)之间进行转换,并提供了更多方便的方法来镜像我们需要访问的大量Webcore对象。
    工具
    layout_tests:用于运行WebCore布局测试的脚本。
    merge:用于帮助合并到WebKit树的脚本。
    npapi_layout_test_plugin:我们的一些测试用来锻炼插件层的特殊插件。
    test_shell:一个非常简单的独立浏览器。这允许测试我们的胶水和端口代码,而无需编译和运行非常大的Chromium应用程序。

“content /”下目录树的快速参考

目录 功能
浏览器 处理所有I / O和与子进程通信的应用程序的后端。这涉及 renderer 到管理网页
common 在多个进程(即浏览器和渲染器,渲染器和插件等)之间共享的文件
gpu GPU进程的代码,用于3D合成和3D API
plugin 用于在其他进程中运行浏览器插件的代码
ppapi_plugin Pepper插件进程的代码
renderer 每个选项卡中的子流程代码。这嵌入WebKit并谈判 browser 为I / O
utility 用于在沙盒进程中运行随机操作的代码。浏览器进程在想要对不可信数据运行操作时使用它
worker 运行HTML5 Web Workers的代码

“chrome /”下目录树的快速参考

  • 应用程序:“应用程序”是该程序的最基本的级别。它在启动时运行,并根据当前进程所处的功能分派到浏览器或渲染器代码。它包含用于chrome.exe和的项目chrome.dll。除了图像和字符串之类的资源之外,您通常不需要更改这些内容。

    • locales:用于构建本地化DLL的项目。
    • 资源:图标和游标。
    • 主题:以窗口为主题的图像。
  • 浏览器:该前端包括主窗口中,用户界面,以及用于它处理所有I / O和存储的应用程序的后端。这涉及renderer到管理网页。

  • UI特性和功能的UI模型,视图和控制器代码

  • 常见:浏览器和特定于Chrome模块的渲染器之间共享的文件。

    • netnet顶层模块顶部的一些Chromium特定的东西。这应该与浏览器/网络合并。
  • 安装程序:用于制作安装程序的源文件和项目(MSI软件包)。

  • ****渲染器:在渲染器进程中运行的Chrome特定代码。这增加了诸如自动填充,翻译等Chrome功能到内容模块。

  • 测试

    • 自动化:通过试验来驱动浏览器的用户界面,例如test/uitest/startup等,这与通信browser/automation的浏览器。
    • page_cycler:运行页面循环测试的代码(用于性能测量)。看tools/perf/dashboard
    • 可靠性:可靠性测试,用于可靠性度量和崩溃查找的页面加载分布式测试。
    • selenium:运行硒测试的代码,这是针对Ajaxy和JavaScript的第三方测试套件。看test/third_party/selenium_core
    • 启动:测试启动性能。见tools/perf/dashboardtools/test/reference_build
    • 用户界面:在浏览器的UI戳,打开标签等,使用的UI测试test/automation做的大部分操作。
    • 单位:单元测试的基本代码。单个测试的测试代码通常与其在*_unittest.cc文件中测试的代码一起。
  • third_party:特定于Chromium的第三方库。其他一些第三方库位于顶层third_party库中。

  • 工具

  • 构建:与建筑相关的工具和随机材料。

    • buildbot:Buildbot配置。Buildbot管理我们的自动化构建系统。看third_pary/buildbot
    • win:Windows构建的东西,包括.vsprops用于项目属性和脚本的一些 文件。
  • 记忆:记忆东西的工具。目前包括gflags用于设置页面堆选项。

  • perf / dashboard:将性能日志(例如test/startup_test)转换为数据和图形的代码。

  • 配置文件:随机历史数据的生成器。用于制作测试配置文件。

一些代码路径:

启动:

Winmain: 在chrome/app/main.cc中,它可以启动谷歌更新客户端.就是说,它具有自动更新的能力,从chrome.dll那里加载。
ChromeMain:

Tab启动和初始导航

  1. Browser::AddTabchrome/browser/ui/browser.cc调用中添加一个新选项卡。
  2. 它将TabContents从中创建一个新对象browser/tab_contents/tab_contents.cc
  3. TabContents通过中的Init函数创建一个RenderViewHostchrome/browser/renderer_host/render_view_host.cc))。根据不同,产生新的渲染器进程或重新使用现有的渲染器进程。是浏览器中代表单个渲染器子进程的对象。RenderViewHostManager``'s``chrome/browser/tab_contents/render_view_host_manager.cc``SiteInstance``RenderViewHost``RenderProcessHost``RenderProcessHost
  4. NavigationControllerchrome/browser/tab_contents/navigation_controller.cc其通过的标签内容拥有,指示导航到URL在新标签NavigationController::LoadURL。从步骤3开始的“从URL栏导航”描述了从这一点发生的事情。

从URL栏导航

  1. 当用户输入或接受URL栏中的条目时,自动填充编辑框确定最终目标URL并将其传递给AutocompleteEdit::OpenURL。(这可能不是用户输入的内容 - 例如,在搜索查询的情况下生成URL。)
  2. 指示导航控制器导航到中的URL NavigationController::LoadURL
  3. NavigationController呼叫TabContents::NavigateNavigationEntry它创建的代表这个特定页面过渡。它将创建一个新的RenderViewHost如果必要的,这将导致RenderView 在渲染过程中创建一个。RenderView如果这是第一次导航,或者如果渲染器已经崩溃,则A 将不存在,所以这也将从崩溃中恢复。
  4. Navigate转发给RenderViewHost::NavigateToEntry。在NavigationController此导航条目,但它被标记为“待定”,因为它不知道是否过渡将于专卖店(也许主机无法解析)。
  5. RenderViewHost::NavigateToEntry 在渲染器进程中发送一个ViewMsg_NavigateRenderView的。
  6. 当被告知导航,RenderView可能导航,它可能会失败,或者它可能导航到其他地方(例如,如果用户点击链接)。RenderViewHost等待一个ViewHostMsg_FrameNavigateRenderView
  7. 当负载由WebKit“提交”(服务器响应并向我们发送数据)时,RenderView发送此消息,该消息在中处理RenderViewHost::OnMsgNavigate
  8. NavigationEntry与负载上的信息进行更新。在点击链接的情况下,浏览器从未见过此URL。如果导航是由浏览器启动的,就像在启动情况下那样,可能有重定向改变了URL。
  9. NavigationController更新其导航列表来解释这种新的信息。

导航和会话历史

每个NavigationEntry存储一个页面ID和一个历史状态数据块。页面ID用于唯一标识页面加载,因此我们知道NavigationEntry它与哪个页面相对应。它在页面提交时被分配提交,因此一个待处理NavigationEntry页面的页面ID为-1。历史状态数据只是一个WebCore::HistoryItem串行化的字符串。此项目包含的内容包括页面URL,子帧URL和表单数据。

  1. 当浏览器启动请求时(输入URL栏,或者点击后退/转发/重新加载)
    1. A WebRequest代表导航,以及额外的信息,如簿记的页面ID。新导航的ID为-1。导航到旧条目时,ID会分配给NavigationEntry页面首次访问时的位置。稍后当负载提交时会查询这些额外的信息。
    2. 主要WebFrame被告知加载新的请求。
  2. 渲染器发起请求时(用户单击链接,javascript更改位置等):
    1. WebCore::FrameLoader 被告知通过其中一种bajillion不同的加载方法加载请求。
  3. 在任何一种情况下,当收到来自服务器的第一个数据包时,都会提交负载(不再是“挂起”或“临时”)。
  4. 如果这是一个新的导航,WebCore将创建一个新的HistoryItem并将其添加到BackForwardList一个WebCore类。通过这种方式,我们可以区分哪些导航是新的,哪些是会话历史导航。
  5. RenderView::DidCommitLoadForFrame处理负载的提交。这里,上一页的状态通过ViewHostMsg_UpdateState消息存储在会话历史中。这将告诉浏览器用新的历史状态更新相应的NavigationEntry(由RenderView's当前标识的page ID)。
  6. RenderView's当前page ID更新以反映已提交的页面。对于新的导航,page ID会生成一个新的唯一。对于会话历史记录导航,它将page ID是最初访问时初始分配的,这是我们WebRequest在启动导航时存储的。
  7. 一条ViewHostMsg_FrameNavigate消息被发送到浏览器,用新的URL和其他信息更新相应的NavigationEntry(由RenderView's新更新确定的page ID)。
相关参考文献:

多进程的体系结构

显示-A-网页,在铬

进程间的通信

穿线

重要的抽象和数据结构

智能指针指引

铬字符串使用

推荐一篇CSDN文章 这儿有一些代码,可以看着玩玩

给个总结吧:这篇文章原文是英文,以我的四级水平看得一言难尽,借助了谷歌翻译,翻译版本也是让人一言难尽。
而我个人觉得这篇文章专业术语特别多(谷歌翻译刚好不太擅长这个),没有什么口水话 ,几乎都是干货。所以如果做个PPT来讲述它,总结它,我觉得没什么意义,因为他本来就是一个总结,我就做了个这个方便大家一起来看,以后接触到具体代码时,如果有疑惑便可以来查阅一下,当然,有误的地方将来也慢慢更正。
原文主要是对chromium的大致架构做了介绍。说白了,就是告诉我们,执行什么功能的代码大致在哪里。我想它的作用之一便是可以作为我们这样的初学者的一个速查手册。

你可能感兴趣的:(2018-03-21)