原文地址:http://blog.csdn.net/milado_nju/article/category/1060500
目录
WebKit, WebKit2, Chromium和Chrome介绍
WebKit, WebKit2, Chromium和Chrome介绍
概述
在介绍本系列各个专题之前,有必要先解释一下极其容易混淆的几个概念,它们是WebKit,WebKit2,Chromium和Chrome。
首先来了解WebKit。广义上来说,WebKit是一个开源的项目,其前身是来源于KDE的KHTML和KJS。该项目专注于网页内容的展示,开发出一流的网页渲染引擎。它不是浏览器,而且也不想成为浏览器。 该项目包含两个部分,第一是WebCore,其中包含了对HTML,CSS等很多W3C规范的实现;第二部分就是狭义上的WebKit,它主要是各个平台的的移植并提供相对应的Web接口,也就是WebView或者类似WebView,这些接口提供操作和显示网页的能力。目前使用WebKit的主流的浏览器或者WebView包括Chrome, Safari, QtWebKit, Android Browser以及众多的移动平台的浏览器。
WebKit2相对于狭义上的WebKit而言,它不是WebKit简单的第二个版本,它是一个新的API层,其最主要的变化在于将网页的渲染置于单独的进程,而接口层则在另外一个进程,它们之间通过IPC来通讯。对于接口的调用者来说,中间的IPC和底下的实现是透明的,这样做的好处有很多,一个很明显的好处是,当网页的渲染出现问题时,不会阻碍Web接口的调用者进程,这会在很大程度上解决或者帮助解决浏览器或者这些调用者的稳定性和安全性等问题。
Chromium是一个建立在WebKit之上的浏览器开源项目,由Google发起的。该项目被创建以来发展迅速,很多先进的技术被采用,如跨进程模型,沙箱模型等等。同时,很多新的规范被支持,例如WebGL,Canvas2D,CSS3以及其他很多的HTML5特性,基本上每天你都可以看到它的变化,它的版本升级很快。在性能方面,其也备受称赞,包括快速启动,网页加载迅速等。
Chrome是Google公司的浏览器产品,它基于chromium开源项目,一般选择稳定的版本作为它的基础,它和chromium的不同点在于chromium是开源试验场,会尝试很多新的东西,当这些东西稳定之后,chrome才会集成进来,这也就是说chrome的版本会落后于chromium。另外一个就是,chrome里面会加入一些私有的codec,这些仅在chrome中才会出现。再次,chrome还会整合Google的很多服务, 最后chrome还会有自动更新的功能,这也是chromium所没有的。
在“WebKit,WebKit2,Chromium和Chrome介绍”中,大致了解了WebKit是一个渲染引擎,Chromium是一个浏览器,它们那么分别包含哪些不同的功能模块?它们是如何划分地?本章节来为大家详细解读一下。
WebKit:
1. HTML解析::负责HTML语言的解析
2. CSS解析:负责CSS的解析工作
3. 图片解码:支持不同编码格式的图片
4. JavaScript引擎:JavaScript语言的解析引擎,缺省的是JavaScriptCore,但是目前Google 的V8 JavaScript被广泛使用
5. 正则表达式
6. 布局:负责布局(layout)的计算和更新工作
7. 文档对象模型(DOM):DOM是W3C定义的对象模型,该部分负责DOM树及其相应的接口
8. 渲染:与渲染相关的基础设施,例如渲染树,渲染层次树等等
9. SVG:对SVG的支持
10. XML解析:XML语言的解析
11. XSLT:XSLT语言的解析执行
12. URL解析器:URL规范的解析
13. Unicode编解码器:各种编码解码工作
14. 移植:WebKit中比较大的一部分,因为WebKit要工作需要不同平台上有具体的实现,因而不同的移植有不同的实现。chromium的移植很复杂,因为其支持跨平台,所以它的移植需要在windows,linux和mac上工作。
由上面的模块大致可以WebKit主要是跟网页的解析和渲染相关的工作,其不涉及浏览器的历史,书签,下载,cookie管理等等方面的工作。
Chromium:
1. Cookie管理器:cookie生命周期的管理
2. 历史管理器:历史记录的管理
3. 密码管理器:网页中密码登录信息管理
4. 窗口管理:多个Tab窗口的管理和切换
5. 地址栏:地址栏功能,智能地址填充与书签的协同工作
6. 安全浏览黑名单管理:安全浏览机制
7. 网络栈:与网络传输相关的工作,其有很多创新的东西
8. SSL/TLS:网络传输安全
9. 磁盘缓存:磁盘缓存页面及其替换策略等生命周期的管理
10. 下载管理器:管理下载相关
11. 粘帖板:clipboard的功能
12.书签管理:书签的组织和管理
13. URL解析器:同WebKit
14. Unicode编解码器:同WebKit
Chromium主要是实现浏览器相关的功能,如上面中的网络栈等等。其实以上只是一些浏览器基本功能,chromium实现的远不止这些,这其中包含沙箱模型,NaCl,扩展机制,硬件加速架构等等。这些我们将在之后的章节中逐一介绍它们。
URL解析器和Unicode编解码器在两者中都存在是因为它们都要使用到。
WebKit和Chromium的代码量很大(这两个项目都是几百万行代码的级别,不包括它们依赖的第三方库),读起来是相当的不容易。但是良好的代码组织结构很好的帮助了开发者和学习者们,下面大致介绍一下它们的目录结构及其用处,方便了解和学习,进而快速地理解整个项目。因为目录实在太多,所以这里介绍其中主要的部分。
先来看看WebKit。(WebKit项目在chromium中的目录是src/third_party/WebKit)
再来看看Chromium。
Chromium的界面相当简洁,这是她的设计理念。大体上可以把界面分成两个主要部分:网页内容和外边的修饰控件(例如,tab管理,工具栏,设置按钮等)。
整个chromium浏览器是个顶层窗口。每个tab都对应一个顶层窗口的子窗口,每个网页内容都会绘制在一个子窗口中。当然这个是现有的窗口结构,但在新的views框架中,窗口将会被移除,详细的后面有专门介绍。
Chromium界面另一个主要的控件是设置按钮,里面包含了所有有关chromium属性设置的部分。值得一提的是,里面有很多设置界面都是由HTML来撰写的,而不是传统的语言,例如c/c++。这很大程度上得益于chromium的扩展机制及其提供的API,这会在扩展章节详细介绍。
大家可能会觉得chromium界面简洁,用户或者能看到的浏览器信息有限,其实不然。尝试在地址栏里输入chrome://chrome-urls/,你会看到很多的chrome地址。这些地址提供给用户或者开发者关于浏览器的丰富的信息,可以说是包罗万象,你能想象的信息基本都能从这里看到。这些信息其实非常的有用,特别对于理解chromium的内部机制非常有帮助,很多细节我们会在后面的章节中逐一揭露。
概述
相信你一定有这样的经历:打开很多个页面,不幸的是其中某个页面不响应了或者崩溃了,随之而来的是更不幸的事,所有页面都不响应或者都崩溃了。最让人崩溃的是其中一些页面还有未保存或者未发送的信息!
这绝对是不堪回首的过去。但是,现在好了,现代浏览器很多都支持多进程模型,这个模型可以很好地避免上面的问题,虽然它很复杂而且也有自身的问题,例如更多的资源消耗,但是它的优势也是非常明显地。
chromium的多进程架构至少带来三点好处,其一是避免单个页面的不响应或者奔溃影响整个浏览器的稳定性;其二是当第三方插件奔溃时候不会影响页面或者浏览器的稳定性;其三是方便了安全模型的实施,也就是说沙箱模型是基于多进程架构的。其实,这很大程度上也是WebKit2产生的原因。那么,这是怎么做到的呢?
下图给出了缺省的chromium浏览器的进程模型。方框代表进程,连接线代表IPC进程间通信。
通常来讲,chromium浏览器包括以下主要进程类型:
- Browser进程:浏览器的主进程,负责浏览器界面的显示,各个页面的管理,其他各种进程的管理;
- Render进程:页面的渲染进程,负责页面的渲染工作,WebKit的工作主要在这个进程中完成;
- NPAPI插件进程:每种类型的插件只会有一个进程,每个插件进程可以被多个Render进程共享;
- GPU进程:最多只有一个,当且仅当GPU硬件加速打开的时候才会被创建,主要用于对3D加速调用的实现;
- Pepper插件进程:同NPAPI插件进程,不同的是为Pepper插件而创建的进程
Chromium浏览器的进程模型,包括以下特征:
- browser进程和页面是分开的,这保证了页面的奔溃不会导致浏览器主界面的奔溃;
- 每个页面是独立的进程,这保证了页面之间相互不影响;
- 插件进程也是独立的,插件的问题不会影响浏览器主界面和页面;
- GPU硬件加速进程也是独立的。
因为这么多的进程,开发者通常需要知道进程列表中的进程类别,这很简单,可以通过进程的命令行参数"--type"来识别。
有趣的是,就在我写下上面这段文字的时候,我的chrome浏览器的flash插件崩溃了,幸运的是其他一切都很好,感谢chrome的多进程模型!
模型的类型
其实介绍了进程模型,其实Chromium支持多种进程模型,特别是对页面而言,下面简单的介绍以下模型的类型:
Process-per-site-instance
该类型的含义是对同一个域的实例都会创建独立的进程。举个例子来讲,例如,用户访问了milado_nju的CSDN博客(我的博客),然后从个人主页打开多篇文章时,每篇文章的页面都是该域的一个实例,因而它们都共享同一个的进程。如果新打开CSDN博客的主页,那么就是另一个实例,会重新创建进程来渲染它。这带来的好处是每个页面互不影响,坏处自然是资源的巨大浪费。
Process-per-site
该类型的含义是不同一个域会创建独立的进程,同一域的不同实例共享同一个进程。好处是对于不同的域可以共享,相对较小的内存消耗,坏处是可能会有特别大的Renderer进程。可以在命令行加入参数--process-per-site来尝试它。
Process-per-tab
该类型的含义是为每个标签页创建一个独立的进程,这也是chrome/chromium的缺省行为
Single process
该类型的含义是不为页面创建任何独立的进程,所有渲染工作都在browser进程中。但是这个类型只是实验性质的,不稳定,因而不推荐使用,只有在比较单进程和多进程时候比较有用,可以在命令行加入参数--single-process来尝试它。
沙箱模型
在页面的多进程模型中,页面的渲染是运行在沙箱模型中的Render进程中实现的,这些渲染引擎没有访问本地资源的能力(例如文件系统,窗口系统,等等),这可以保护渲染引擎被入侵。
概述
本章节完整的描述一下从HTML及其资源(例如图片等)下载后到DOM树建立好这一段过程的细节及其WebKit所涉及的这一切的一切。大体地,本章内容主要包括网页结构描述,WebKit对网页结构的表示,WebKit解析HTML的基础设施,一般过程,DOM规范和DOM树。
按照惯例,这里给出一个例子。个人崇尚简单,只要能说明问题就行,如下所示,后面的解释和过程是基于此例子展开地。
网页结构
让我们首先了解网页的基本结构,这样便于后面理解WebKit的相关设施。其实,它并不复杂,如下图所示。
整个是一个网页,这里称之为Page。每个Page都有一个主框(Main Frame),该框通常包含一个HTML Document,主框也可能包含子框(sub frame),如图所示,这就是网页的多框结构,虽然这一结构饱受诟病,但现实还是这样。现在,更多的网页仅有主框,这样便于搜索引擎的检索和处理。本章的例子是一个仅有主框的最简单的网页结构。
这些框构成一个树型结构,以主框为根节点,每个框也可能包含自己的HTML Document,它是一颗DOM树。
WebKit设施
介绍了网页的基本结构,那么WebKit的设施也相对容易理解,下图是WebKit相对应的类,和网页的结构是一一对应的。这其中WebView是网页对外的接口。
在介绍WebKit中其他类之前,有必要先介绍一个WebKit普遍使用的设计模式。首先看一个例子。下图是Chrome和ChromeClient,这两个类非常重要。此Chrome非彼Chrome,这里的Chrome是WebKit的一个类,不是Google的浏览器产品Chrome。类Chrome后面会介绍,这里强调的是因为WebKit有很多种移植(port),所以不同移植中的Chrome需要有不同的实现,所以Chrome类需要满足两类要求:
- Chrome需要具备有获取各个平台资源的能力,例如WebKit可以调用Chrome来创建一个新窗口;
- Chrome需要把WebKit的状态和进度等信息分发给外部的调用者或者说是WebKit的使用者;
WebKit内部跟这两类要求相关的需求都是通过Chrome的接口来完成,这时候有个问题,那就是如何让WebKit和外部调用者既不紧密耦合,而能方便支持不同的平台?WebKit使用ChromeClient抽象类来实现。每个port实现类ChromeClient,一方面监听WebKit状态,一方面返回WebKit所需要的资源和信息。WebKit直接调用Chrome的接口,Chrome调用ChromeClient的接口,而ChromeClient的实现由各个移植来完成。
在这一部分中,很多都是该模式的类组合,例如FrameLoader和FrameLoaderClient,ImageLoader和ImageLoaderClient,ContextMenu和ContextMenuClient等等。这些类比较容易理解,不再阐述,这里简单介绍几组类的关系(很多其他的组类似):
- Frame和FrameLoader:Frame表示的是页面框和框的加载器,一个负责页面的表示,一个负责加载需要的接口及实现,还有很多类似的组合类,例如Document和DocumentLoader,CachedImage和ImageLoader等。
- WebView和Page:二者一一对应,Page是WebKit内部表示网页的类,WebView是WebKit对外表示网页的类,Page只有一个实现,WebView在不同的移植中有不同的实现。其他类似的组合类如WebFrame和Frame。
最后接上面介绍的类Chrome,它是一个非常重要的类,是WebKit与它的使用者之间的桥梁,主要负责UI和渲染相关的需要用到平台相关接口。以下是它的一些主要功能:
- 跟UI和渲染显示相关的需要移植实现的接口集合类;
- 继承自HostWindow(宿主窗口),其包含一系列接口,用来通知重绘或者更新相应整个窗口,滚动窗口等等;
- 窗口相关操作,例如显示,隐藏等;
- 显示/隐藏窗口中的toolbar,statusbar,scroolbar等;
- 显示JavaScript相关的窗口,例如JavaScript的Alert,confirm, prompt窗口等;
- 其他一些跟显示相关的,例如colorchooser等。
HTML解析的一般过程
首先介绍主要对象的创建顺序,如下图所示,简单明了。
下面是解析和创建DOM树的一般过程,依旧是用图说话,为简单起见,省略其中的若干类和步骤。
上述图中的顺序,简单来讲是,先接受服务器发送过来的数据,之后解析成一系列的Tokens,然后在加载结束后建立DOM树,这还是比较容易理解地,不再详细描述。下图是解析完例子后所创建的DOM树。简单吧?我也觉得:-)
DOM标准
DOM定义的是一组平台无关和语言无关的接口,该接口允许编程语言动态访问和更改结构化文档。本人( :-) )见的比较多的应用对象是XML和HTML。W3C标准化组织定义一系列DOM接口,随着时间的发展,目前包括DOM level 1, 2, 3。每个新版本是对以前版本的补充和新功能的加入。下面是对这三个版本的简单介绍:
DOM level 1:
1. Core:一组底层的接口,其接口可以表示任何结构化的文档,同时也允许对其进行扩展,典型的例子是支持XML文档。
2. HTML:一组基于Core定义的接口的上层接口,主要是为了方便HTML文档的访问。
DOM level 2:
1. Core:对DOM level1 中core部分的扩展,其中著名的就是getElementById(没用过的请举手),还有很多跟名空间(namespace)相关的接口;
2. Views:书上说views是“允许动态访问和修改文档内容的表示,主要是两个接口AbstractView和DocumentView”,没接触过加不懂,谁来救救我?
3. Events:这个很重要,引入了对时间的处理,个人觉得是个重要的变化,主要有EventTarget, Mouse events等接口,但不支持Keyboard,这个在DOM level3才被加入;
4. Style(CSS):加入接口可以修改样式属性;
5. Traversal and range:这个容易理解,就是遍历树(NodeIterator和TreeWalker)加上对制定范围的文档修改删除等操作;
6. HTML: 扩充DOM level1的HTML部分,允许动态访问和修改HTML文档。
DOM level 3:
1. Core:加入了新的adoptNode() 和 textContent支持;
2. Load and save:动态加载和序列化DOM表示;
3. Validation:根据scheme验证文档的有效性;
4. Events:主要扩展对keyboard的支持。HTML5和触屏技术如火如荼,所以对Touch的支持很快就会进入规范;
5. XPath: 使用XPath1.0来访问DOM树,XPath是一种简单直观的检索DOM树节点的方式,具体见W3CXPath标准。
DOM标准对具体的表示方法没有任何限制,只是定义了接口,因此它在现实中有很多种实现。DOM的树状表示是其中比较普遍的方式,还可以是二进制表示,其有很多的优点(例如binary xml),详情请google之。
好了,该结束本章了,但这不是全部,这部分还有很多的细节值得研究和探讨,例如个人比较关注的是DOM树上的事件(Event)分发机制。有兴趣的话,可以自行阅读以下目录中的WebKit代码,相信你会获益非浅。
源文件目录
third_party/WebKit/Source/WebCore/loader
加载相关的类,例如负责加载Document,Frame,image等
third_party/WebKit/Source/WebCore/page
表示页面的类,例如page, frame等, 及页面相关的设施,例如contextmenu,JavaScript内置的对象,例如,window,console, navigator, dom等。
third_party/WebKit/Source/WebCore/dom
DOM相关的类,包括节点定义类
third_party/WebKit/Source/WebCore/html
html标注的相应的DOM节点类定义
third_party/WebKit/Source/WebCore/html/parser
HTML解析器相关类
概述
Chromium中的NPAPI插件(plugin)来源于mozilla的插件机制。因为它被广泛的应用,很多插件厂商或者开发者基于它编写了数以万计的插件,因而chromium对它也提供了支持,不过chromium有自己独特的插件架构,后面我们会详细介绍。
NPAPI提供两组接口,一类以NPP打头,由插件来实现,被浏览器调用,主要包括一些插件创建,初始化,关闭,销毁,信息查询及事件处理,数据流,窗口设置,URL等;另一类以NPN打头,由浏览器来实现,被插件所调用,主要包括图形绘制,数据流处理,浏览器信息查询,内存分配和释放,浏览器的插件设置,URL等。
原始的NPAPI的接口使用起来不是很方便,因而有贡献者对其进行了封装以利于其使用。一个比较著名的开源项目是Firebreath。它将原始的C风格的NPAPI进行封装成C++风格的接口,非常方便用户使用,而且有针对Windows和X window的移植,用户无需对底层特别了解。特别的是,Firebreath也有对ActiveX的封装,因而对于现在主流的两种插件接口,你都可以基于Firebreath的接口进行编程,极大地方便了开发者。详情请参考Firebreath主页http://www.firebreath.org/display/documentation/FireBreath+Home
架构
因为chromium的安全模型,renderer进程没有访问除I/O读写等之外的权限,因而插件需要有自己的进程,这就是插件的out-of-process模型。下图给出chromium中插件的架构和进程模型。
每一种类型的plugin只有一个进程,这就是说,如果有两个或者多个renderer进程同时使用同一个插件,那么该插件会共享同一个进程。因为多个renderer进程共享同一种的plugin进程,那么plugin进程如何为它们服务呢?答案是为每个插件使用点在plugin进程中创建一个插件实例(PluginInstance).
值得注意的是,plugin进程是由browser进程来负责创建和销毁, 而不是renderer进程。 原因在于renderer进程没有创建的权限,而且plugin进程由browser进程来统一管理也更方便。 当plugin进程创建成功时,browser进程会返回IPCchannel handle用于创建和plugin进程通讯的PluginChannelHost. 那它什么时候被销毁呢?当没有任何插件实例并且空闲一段事件后,它才会被销毁,这样做的好处是避免频繁的创建和销毁plugin进程。
下图描述了browser和plugin进程间的通讯机制及其所涉及的相关的模块(类)。Browser进程通过PluginProcessHost发送消息调用Plugin进程的函数,响应动作由PluginThread完成。而Plugin进程则是通过WebPluginProxy发送消息调用browser的函数,响应动作有PluginProcessHost完成。
Browser和Plugin仅有较少的消息传递,用于创建等管理工作。主要的部分在renderer进程和plugin进程之间,机制也相对更复杂一些。HTMLPluginElement会包含一个WebPluginContainerImpl,而它包含一个WebPluginImpl,对plugin的调用有WebPluginDelegateProxy负责中转。在Plugin进程中,由WebPluginDelegateStub处理所有renderer过来的请求,并由WebPluginDelegateImpl调用创建好的PluginInstance对象。PluginInstance最终调用PluginLib读取的插件的函数入口地址,最终完成对插件实现的调用。而对插件实现中对NPN开头函数的调用,则是通过PluginHost来完成。
PluginHost主要负责实现NPN开头的函数,如前面所描述,这些函数被plugin进程所调用。可以在plugin和renderer进程被调用。当在plugin进程调用这些函数时,chromium会覆盖PluginHost的部分函数,而这些新的callback函数会调用NPObjectProxy来通过IPC发送请求到renderer进程。
PluginInstance实现了NPP开头的函数,被render所调用(webpluginImpl通过webplugindelegateImpl来调用),PluginInstance通过PluginLib获得了插件库的函数地址,从而把实际的调用桥接到具体的插件中。
具体的见下图所示,主要结构来源于chromium的官网,略有修改。
对于NPObject相关的函数调用, 有专门的类来处理。NPObject的调用或者访问是双向的(renderer进程<->plugin进程),他们的具体实现是通过NPObjectProxy和NPObjectStub来完成。 NPObjectProxy接受来自对方的访问请求,转发给NPObjectStub,最后NPObjectStub调用真正的NPObject并返回结果。见下图所示。
下面示例给出一个插件如何被renderer进程触发创建的过程。
当页面中包含一个“embed”或者“object”元素,renderer进程会创建一个HTMLEmbedElement元素,当该元素被访问是,会触发创建相应的插件。HTMLEmbedElement会请求创建自己对应的RenderWidget(WebPluginContainerImpl),进而创建WebPluginImpl和WebPluginDelegateProxy。WebPluginDelegateProxy会发送消息来创建Plugin进程。Plugin进程被browser进程创建后,会响应renderer的请求来创建PluginInstance并初始化它。这样它们之间的联系就建立好了。
Window和windowless插件
可以通过设置”embed”或者”object”元素的属性。两者的区别主要在于绘图的方式不同。Window插件由renderer进程提供一个窗口(window), 插件直接在该窗口上进行绘制;而windowless插件则不同,插件将绘制的结构(Pixmap),通过共享内存方式(Transport DIB)传递给renderer进程,renderer绘制该内容到自己内部的存储结构(backing store)上。好处是,可以把插件绘制的结构和网页上的其他内容做各种形式的合成。但是,从上面不能看出,一般来讲,window模式的性能是要高于windowless的。
相关目录和文件
third_party/WebKit/Source/WebKit/chromium/public/webplugin.h:
定义Webkit::WebPlugin接口,用于创建和销毁插件,及传送事件给插件
content/common/plugin_messages.h:
定义plugin进程与renderer进程和browser进程间的消息结构体,包括五类:
- PluginProcessMsg开头的消息- browser进程发给plugin进程
- PluginProcessHostMsg开头的消息- plugin进程发给browser进程
- PluginMsg开头的消息- renderer进程发给plugin进程
- PluginHostMsg开头的消息- plugin进程发给renderer进程
- NPObjectMsg开头的消息- plugin进程与render进程相互编码和解码NPObject
content/common/npobject_stub.(h&cc):
类NPObjectStub的定义和实现
content/common/npobject_Proxy.(h&cc):
类NPObjectProxy的定义和实现
content/plugin:
该目录用于存放Plugin进程使用的IPC和WebPlugin相关的函数和类
content/plugin/webplugin_proxy.(h&cc):
实现WebKit::npapi::WebPlugin接口,把插件的调用通过IPC发送给renderer进程
content/plugin/webplugin_delegate_stub.(h&cc):
把WebPluginDelegateProxy的消息转换为对WebPluginDelegateImpl的调用
content/plugin/plugin_channel.(h&cc):
定义Plugin进程与renderer进程通信的通道
webkit/plugins/npapi/:
该目录用于存放Plugin进程使用的对WebKit接口实现和插件库处理的相关的函数和类
webkit/plugins/npapi/webplugin.h:
定义WebPlugin接口,用于plugin端同web frame和webcore对象的交互
webkit/plugins/npapi/webplugin_impl.(h&cc):
实现WebKit::WebPlugin和WebPlugin接口,通过WebPluginPageDelegate来创建WebPluginDelegate
webkit/plugins/npapi/plugin_instance.(h&cc)
PluginInstance类的接口和实现,代表一个Plugin实例,对应于renderer进程的一个请求创建的plugin实例
webkit/plugins/npapi/webplugin_delegate.h:
定义WebPlugin代理,用来分离具体的插件的实现方式,例如可以使来实现进程内或者跨进程的插件架构,对WebPlugin来说,具体架构是透明的
webkit/plugins/npapi/webplugin_delegate_impl.(h&cc):
响应renderer进程实现对PluginInstance的调用请求,有gtk,win和aura三种不同的实现
webkit/plugins/npapi/plugin_host.(h&cc):
实现NPN开头的函数,在plugin进程和renderer进程有不同的实现
webkit/plugins/npapi/plugin_lib.(h&cc):
PluginLib用来管理实际插件库的生命周期
content/renderer/webplugin_delegate_proxy.(h&cc)
定义和实现WebPluginDelegateProxy类,桥接所有来自于WebPlugin的请求到WebPluginDelegateImpl
content/browser/plugin_process_host.(h&cc):
类PluginProcessHost的定义和实现,用于Browser进程与plugin进程的交互
content/browser/plugin_service_impl.(h&cc):
类PluginServiceImpl的定义和实现,用于响应Renderer进程创建插件请求及其他一些插件管理工作