一、Chromium架构介绍

1、架构概览

Chromium采用是多进程架构,为什么采用多层架构呢?
因为构建一个从不会挂起或崩溃的渲染引擎几乎是不可能的。构建一个完全安全的渲染引擎也是几乎不可能的。web浏览器类似一个与过去的多任务操作系统合作的单独的用户,一个错误的web页面能让整个浏览器和所有正在运行的标签页停止运行。采用彼此隔离的独立进程,这样程序中的crash通常不会影响其他进程或整个浏览器,但是进程间数据的访问会受到一些限制。

架构概览

浏览器的标签页使用的是独立的进程,以此保护整个应用程序免受渲染引擎中的bug和故障的伤害。同时限制每个渲染引擎进程的相互访问,以及他们与系统其他部分的访问。某些程度上,这为web浏览提供了内存保护,为操作系统提供了访问控制。

Browser(浏览器进程或浏览器):运行UI 和管理 Tab/Plugin 的主进程。
Renderer(渲染进程或渲染器):标签页相关的进程,Renderer使用webkit开源引擎来实现中断与html的布局。

2、管理渲染进程

每个Renderer都有一个全局的RenderProcess对象,管理它与Browser之间的通信,维护全局的状态。Browser为每个Renderer维护一个对应的RenderViewHost,用来管理浏览器状态,并与渲染器交流。Browser与Renderer使用IPC进行交流。

3、管理view

每个渲染进程有一个以上的RenderView对象,由RenderProcess管理(它与标签页的内容相关)。对应的RenderProcessHost维护一个与渲染器中每个view相关的RenderViewHost。每个view被赋予一个view ID,以区分同一个渲染器中的不同view。这些ID在每个渲染器内是唯一的,但在浏览器中不是,所以区分一个view需要一个RenderProcessHost和一个view ID。
浏览器与一个包含内容的特定标签页之间的交流是通过这些RenderViewHost对象来完成的,它们知道如何通过他们的RenderProcessHost向RenderProcess和RenderView发送消息。

4、组件与接口

在渲染进程中:

RenderProcess处理与浏览器中对应的RenderProcessHost的通信。每个渲染进程就有唯一的一个RenderProcess对象。这就是所有浏览器-渲染器之间的交互发生的方式。
RenderView对象与它在浏览器进程中对应的RenderViewHost和webkit嵌入层通信(通过RenderProcess)。这个对象代表了一个网页在标签页或一个弹出窗口的内容。

在浏览器进程中:

Browser对象代表了顶级浏览器窗口
RenderProcessHost对象代表了浏览器端浏览器的与渲染器的IPC连接。 在浏览器进程里,每个渲染进程有一个RenderProcessHost对象。
RenderViewHost对象封装了与远端浏览器的交流,RenderWidgetHost处理输入并在浏览器中为RenderWidget进行绘制。

5、共享绘制器进程

通常每个新的window或标签页是在一个新进程里打开的。浏览器会生成一个新的进程,然后指导它去创建一个RenderView。有时候,希望在标签页或窗口间共享渲染进程。一个web应用程序会在期望同步交流时,打开一个新的窗口,比如,在javascript里使用window.open。这种情况下,创建一个新的window或标签页时,需要重用打开这个window的进程。

6、检测crash或者失误的渲染

每个到浏览器进程的IPC连接会观察进程句柄。如果这些句柄是signaled(有信号的),那么渲染进程已经挂了,标签页会得到一个通知。从这时开始,会展示一个“sad tab”画面来通知用户渲染器已经挂掉了。这个页面可以按刷新按钮或者通过打开一个新的导航来重新加载。这时,如果没有对应的进程,那么就创建一个新的进程。

7、渲染器中的沙箱

WebKit是运行在独立的进程中,可以限制它对系统资源的访问。例如:可以确保渲染器唯一的网络权限是通过它的父浏览器进程实现。也可以限制它对文件系统的访问权限来使用host操作系统内置的权限。除了限制渲染器对文件系统和网络的访问权限,还可以限制它对用户的显示器以及相关的东西的一些权限。

8、归还内存

让渲染器运行在独立的进程中,赋予隐藏的标签页更低的优先级会更加直接。通常,Windows平台上的最小化的进程会把它们的内存自动放到一个“可用内存”池里。在低内存的情况下,Windows会在交换这部分内存到更高优先级内存前,把它们交换到磁盘,以保证用户可见的程序更易响应。可以对隐藏的标签页使用相同的策略。当渲染器进程没有顶层标签页时,可以释放进程的“工作集”空间,作为一个给系统的信号,让它如果必要的话,优先把这些内存交换到磁盘。

9、插件

Firefox风格的NPAPI插件运行在他们自己的进程里,与渲染器隔离。

二、Chromium网页展示

1、了解应用概念层

如上图,每一层都做了高度的抽象,分离,进行了解耦。每个矩形代表了一个应用概念层,每一层都不了解上一层,也对上一层没有依赖。

1、WebKit:Safari,Chromium和其他所有基于WebKit的浏览器共享的渲染引擎。WebKit
Port是WebKit的一部分,用来集成平台独立的系统服务,比如资源加载与图像。

2、Glue:将WebKit的类型转为Chromium的类型。一般称为“WebKit嵌入层”。这是两个browser,Chromium,和test_shell(用来测试WebKit)的基础。

3、Renderer / Render host: 这是Chromium的“多进程嵌入层”。它代理通知,并执行跨过进程指令。

4、WebContents:一个可重用的组件,是内容模块的主类。易于嵌入,允许多进程将HTML绘制成View。

5、Browser: 代表浏览器窗口,包含多个WebContent。

6、Tab Helpers:可以被绑定到WebContent的独立对象(通过WebContentsUserData混杂)。浏览器将这些独立对象中的一种绑定到WebContent给它持有,一个给网站图标,一个给信息栏等等。

2、WebKit

Chromium使用WebKit开源工程来布局web页面。这部分代码是从Apple中pull过来的,存储在/third_party/WebKit目录。WebKit主要由“WebCore”+“JavaScriptCore”组成,WebCore代表了核心的布局功能,JavaScriptCore用来运行JavaScript。一般只在测试时运行JavaScriptCore,通常情况下,使用高性能的V8 Javascript引擎来代替它。The WebKit port在最低层,是平台相关功能的实现,它们与平台无关的WebCore代码交互。大部分与操作系统无关的,可以把它认为WebCore的“Chromium port”。但某些方面,比如字体渲染,必须在不同平台上做不同的处理。

3、Glue

Chromium应用程序使用不同的类型,编码风格,以及代码布局和第三方的WebKit代码。WebKitGlue使Google编码传统与类型为WebKit提供了一个更加方便的嵌入式API(例如,我们使用std::string而非WebCore::String,使用GURL而非KURL)。代码位于/webkit/glue。glue对象通常有与WebKit对象相似的命名,但在开头有Web前缀。例如, WebCore::Frame变成了WebFrame。WebKitGlue层将Chromium代码的其他部分与WebCore数据类型隔离开,以帮助减少WebCore的改变对Chromium代码基础的影响。因此,WebCore数据类型从不直接被Chromium使用。为了Chromium的便利,需要一些WebCore对象时,会把API加入WebKit的Glue层。

test shell应用程序是一个为测试我们的WebKit port和Glue代码的裸web浏览器。它在与WebKit交流时,像Chromium那样使用一样的Glue接口。它为开发者提供了简单的方式去测试新的代码,而不用理会许多复杂的浏览器特性,线程和进程。这个应用程序也被用于运行自动化WebKit测试。然而,test shell的缺点在于,它不像Chromium那样用多进程方式实践WebKit。内容模块嵌入在一个被称为“content shell”的应用程序,使测试工作更便利。

4、渲染器的进程与线程

Chromium的浏览器进程使用Glue接口嵌入在WebKit port中,它的工作主要是作为渲染器端到浏览器的IPC通道。渲染器中最重要的类是RenderView,位于/content/renderer/render_view_impl.cc。这个对象代表一个web页面。处理与浏览器之间所有导航相关的命令。驱动RenderWidget提供绘图和输入事件处理。RenderView与浏览器进程通过全局(每个渲染器进程)RenderProcess对象与浏览器进程交流。

每个渲染器有两个线程。渲染线程是主要的对象,比如RenderView和所有的WebKit代码运行的地方。当它与浏览器交流时,消息一开始发送到主线程,主线程轮流分发消息给浏览器进程。在其他情况里,允许从渲染器同步发送消息到浏览器。当一个来自浏览器的结果是用于后续操作时,这可以用于小量的操作。例如:JavaScript从网页请求cookie。渲染器线程会阻塞,主线程会让所有的接收到的消息排队,直到得到正确的响应。此时任何接收到的消息会突然发送给渲染器线程以执行普通的处理。

5、浏览器进程

底层浏览器进程对象
所有的与渲染器进程交流的IPC是在浏览器的I/O线程完成的。这个线程也处理所有的网络交流,使得它不受用户界面的干扰。当一个RenderProcessHost对象在主线程完成初始化(当用户界面运行时),它会创造新的渲染器进程和一个通道代理IPC对象(有一个命名了的管道通向渲染器),自动转发所有的消息回给UI线程的RenderProcessHost。一个ResourceMessageFilter会安装在这个通道,它会过滤指定的消息,以直接在I/O线程处理(比如网络请求)。这个过滤器发生在ResourceMessageFilter::OnMessageReceived里。UI线程中的RenderProcessHost负责分发所有view相关消息给合适的RenderViewHost(它自己处理有限数量的与View相关的消息)。这种分发发生在RenderProcessHost::OnMessageReceived中。

上层浏览器进程对象
View相关消息出现在RenderViewHost::OnMessageReceived。这里处理的大部分消息,剩下的部分转发给RenderWidgetHost基类。这两个对象在渲染器里里映射到RenderView和RenderWidget。每个平台有一个view类(RenderWidgetHostView[Aura|Gtk|Mac|Win])以集成到native view系统。

在RenderView/Widget上面是WebContents对象,大部分的消息事实上结束于这个对象的函数调用。一个WebContent代表网页的内容。它是内容模块的顶层对象,并且负责在一个矩形的view中展示网页。WebContents对象包含在一个TabContentsWrapper中,它位于chrome/。负责标签页。

三、Chromium插件结构

1、概述

插件是浏览器不稳定的主要来源。插件也会在渲染器没有实际运行时,让进程沙箱化。因为进程是第三方编写的,所有无法控制他们对操作系统的访问。解决方案是:让插件在各自独立的进程中运行。

2、进程内插件

Chromium有着在进程内运行插件的能力(对测试来讲非常方便),也可以在进程外运行插件。它们都始于非多进程WebKit嵌入层,嵌入层实现WebKit::WebPlugin接口。这实际由WebPluginImpl实现。WebPluginImpl在图中的虚线以上,与WebPluginDelegate接口交流,对进程内插件而言,这个接口由WebPluginDelegateImpl实现,它会与NPAPI包装层通信。

在还没有WebKit嵌入层的时候,WebPluginImpl是对应的嵌入层。它会与“嵌入应用程序”通过WebPluginDelegate抽象接口交流,通过切换这个接口的实现,服务与进程内插件与进程外插件,在有了额外的Chromium WebKit API之后,增加了新的WebKit::WebPlugin抽象接口,它与旧的WebPluginDelegate接口有着相同的功能。这个接口合并WebPluginImpl和WebPluginDelegateImpl,在WebKit::WebPlugin层做进程划分。

3、进程外插件

Chromium通过切换上面的图中,虚线以上几层的实现来支持跨进程插件。这干预了WebPluginImpl层和WebPluginDelegateImpl之间的IPC层,让每个模式之间共享所有的NPAPI代码。所有旧的WebPluginDelegateImpl代码,以及与它通信的NPAPI层,现在是在独立的插件进程中执行了。

渲染器/插件通信通道的两端分别由PluginChannel和PluginChannelHost代表。对于每种它所使用的插件都持有一个PluginChannelHost对象(例如,Adobe Flash和Windows Media Player)。在每个插件进程中,每个渲染器进程会有一个PluginChannel,它们各自持有一个那种插件的实例。接着,channel的每个端点,对应许多不同的插件实例。例如,如果网页中嵌有两个Adobe Flash视频,渲染器端就会有两个WebPluginDelegateProxies对象,插件端就会有两个WebPluginDelegateStubs。channel用一个IPC连接管理这些对象直接复数的通信。在下图中,可以看到上面的进程内图表的类(用灰色表示),以及中间彩色的新的进程外代码层。

使用一个stub(存根)/proxy(代理)模型进行通信,每个IPC通道的端点有一个stub和一个proxy,分别接收和发送消息给对应的插件。这会导致许多类变得迷乱。因此,WebPluginStub被合并到WebPluginDelegateProxy,现在它处理渲染器端与一个插件实例的所有IPC通信。插件端还没有合并,还剩两个类WebPluginDelegateStub和WebPluginProxy,概念上他们是相同的对象,只是代表了通信的不同方向。

4、系统全貌

下图展示了整个系统,有浏览器和两个渲染进程,它们都与一个共享的进程外Flash进程交流。总共有三个插件实例。WebPluginStub已经合并到WebPluginDelegateProxy中了。

【Android】Chromium架构简介相关推荐

  1. Android平台架构简介

    Android系统介绍 Linux内核层 系统运行库层 提供Android系统特性的函数库 Android运行时库 Android虚拟机与Java虚拟机 应用框架层 应用层 Android系统介绍 A ...

  2. 移动互联网应用技术架构简介-Android

    Android历史 Android是一款基于Linux的操作系统,面向触摸屏移动设备如智能手机和平板电脑. 最早是由位于加州的Android公司所开发, 2003年创立,2005年被Google收购. ...

  3. 谈谈 Android MVP 架构 | 掘金技术征文

    前言:本文所写的是博主的个人见解,如有错误或者不恰当之处,欢迎私信博主,加以改正!原文链接,demo链接 MVP 架构简介 说起 MVP 架构,相信很多朋友都看过,网上也有很多这方面的资料.博主使用 ...

  4. Android Jetpack架构组件之 Room(使用、源码篇)

    2019独角兽企业重金招聘Python工程师标准>>> 1.前言 最近简单看了下google推出的框架Jetpack,感觉此框架的内容可以对平时的开发有很大的帮助,也可以解决很多开发 ...

  5. Android Treble架构解析

    本文主要介绍Treble架构下的HAL&HIDL&Binder相关技术原理.Treble的详细资料文档,请参考Treble 官方文档. 1. Treble 简介 Android 8.0 ...

  6. Android MediaRecorder架构详解

    1. 简介 在android中录制音频有两种方式,MediaRecorder和AudioRecord.两者的区别如下: (1) MediaRecorder 简单方便,不需要理会中间录制过程,结束录制后 ...

  7. Android项目架构设计深入浅出

    简介:本文结合个人在架构设计上的思考和理解,介绍如何从0到1设计一个大型Android项目架构. 作者 | 璞珂 来源 | 阿里技术公众号 前言:本文结合个人在架构设计上的思考和理解,介绍如何从0到1 ...

  8. android mvp框架基类,Android MVP架构项目搭建封装,基类封装

    综述 对于MVP (Model View Presenter)架构是从著名的MVC(Model View Controller)架构演变而来的.而对于Android应用的开发中本身可视为一种MVC架构 ...

  9. android 使用4大组件的源码,Android Jetpack架构组件之 Paging(使用、源码篇)

    1.前言 最近简单看了下google推出的框架Jetpack,感觉此框架的内容可以对平时的开发有很大的帮助,也可以解决很多开发中的问题,对代码的逻辑和UI界面实现深层解耦,打造数据驱动型UI界面. A ...

最新文章

  1. Execution failed for task ':app:mergeDebugResources'.
  2. Linux CNTOS7 修改网络配置
  3. bzoj1089: [SCOI2003]严格n元树
  4. ACM 配置中心实战:Spring + MyBatis + Druid + ACM
  5. nginx实现防止ddos攻击
  6. 基于单样本单统计推断-假设检验
  7. Angularjs 设置全局变量的3种方法
  8. python发布_python网站发布
  9. iPhone 九、十月份在中国销量曝光:真的卖疯了!
  10. SQL Server里的闩锁介绍
  11. PHP:错误控制运算符
  12. 脸大脖子短,适合什么发型?
  13. yum 下载并切换到本地源(银河麒麟V10,中标麒麟V5)
  14. Python调用cmd
  15. 主角叫张四的Java游戏_第一卷 :仙剑世界中的黑化张四 123 贝爷附体
  16. Python每日一练-----整数转罗马数字
  17. iphone照片恢复至android,将照片从Android传输到iPhone的8种方法很容易
  18. 斯诺登评苹果Face ID:我更担心隐私安全
  19. 美国国家学术出版社所有PDF图书开放免费下载
  20. C语言写一个函数,可以逆序一个字符串的内容。

热门文章

  1. Java后端解密微信小程序手机号数据
  2. 计算机及其应用本课程,北京08自考计算机及应用(独本)课程设置
  3. Nwafu-OJ-1410 Problem I C语言实习题二——4.判断是否能构成一个三角形
  4. 5-3 凸多边形面积
  5. node安装与环境搭建 + VUE项目搭建
  6. DOSBOX与DEBUG的使用方法及命令
  7. 《炒股的智慧》第6节文摘
  8. JDK更换IDEA如何修改
  9. E/WindowManager: android.view.WindowLeaked: Activity com.xxx.xxx.xxx has leaked window com.android.i
  10. 科学家即将揭示人类大脑神经网络结构的奥秘