WebKit之NPAPI插件

2023-10-31 22:08
文章标签 插件 webkit npapi

本文主要是介绍WebKit之NPAPI插件,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

转载请注明原文地址:http://blog.csdn.net/milado_nju/article/details/7216136

# 插件机制(NPAPI plugin)

## 概述

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进程创建插件请求及其他一些插件管理工作

这篇关于WebKit之NPAPI插件的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/318445

相关文章

IDEA常用插件之代码扫描SonarLint详解

《IDEA常用插件之代码扫描SonarLint详解》SonarLint是一款用于代码扫描的插件,可以帮助查找隐藏的bug,下载并安装插件后,右键点击项目并选择“Analyze”、“Analyzewit... 目录SonajavascriptrLint 查找隐藏的bug下载安装插件扫描代码查看结果总结Sona

Maven(插件配置和生命周期的绑定)

1.这篇文章很好,介绍的maven插件的。 2.maven的source插件为例,可以把源代码打成包。 Goals Overview就可以查看该插件下面所有的目标。 这里我们要使用的是source:jar-no-fork。 3.查看source插件的example,然后配置到riil-collect.xml中。  <build>   <plugins>    <pl

jenkins 插件执行shell命令时,提示“Command not found”处理方法

首先提示找不到“Command not found,可能我们第一反应是查看目标机器是否已支持该命令,不过如果相信能找到这里来的朋友估计遇到的跟我一样,其实目标机器是没有问题的通过一些远程工具执行shell命令是可以执行。奇怪的就是通过jenkinsSSH插件无法执行,经一番折腾各种搜索发现是jenkins没有加载/etc/profile导致。 【解决办法】: 需要在jenkins调用shell脚

Jenkins 插件 地址证书报错问题解决思路

问题提示摘要: SunCertPathBuilderException: unable to find valid certification path to requested target...... 网上很多的解决方式是更新站点的地址,我这里修改了一个日本的地址(清华镜像也好),其实发现是解决不了上述的报错问题的,其实,最终拉去插件的时候,会提示证书的问题,几经周折找到了其中一遍博文

Apple quietly slips WebRTC audio, video into Safari's WebKit spec

转自:http://www.zdnet.com/article/apple-quietly-slips-webrtc-audio-video-into-safaris-webkit-spec/?from=timeline&isappinstalled=0 http://www.zdnet.com/article/apple-quietly-slips-webrtc-audio-video-

eclipse安装subversion(SVN)版本控制插件

陈科肇 查看插件更新站点 网址:http://subclipse.tigris.org/servlets/ProjectProcess?pageID=p4wYuA 网站截图: 根据自己的eclipse版本,选择需要的更新站点. 使用eclipse集成subservion插件 Help > Install New Software…> 等待下载安装插件…

Weex入门教程之2,Android Studio安装Weex插件

插件位置及描述 https://plugins.jetbrains.com/idea/plugin/8460-weex 貌似对windows还不是很支持,先放着吧。 安装 插件功能 先预览下都有什么功能 安装完成Weex插件后,如果在main toolbar找不到这些功能图标,那么就需要手动添加到main toolbar 添加到main toolbar 红框内就是

mybatis框架基础以及自定义插件开发

文章目录 框架概览框架预览MyBatis框架的核心组件MyBatis框架的工作原理MyBatis框架的配置MyBatis框架的最佳实践 自定义插件开发1. 添加依赖2. 创建插件类3. 配置插件4. 启动类中注册插件5. 测试插件 参考文献 框架概览 MyBatis是一个优秀的持久层框架,它支持自定义SQL、存储过程以及高级映射,为开发者提供了极大的灵活性和便利性。以下是关于M

PrestaShop免费模块/插件/扩展/工具下载

PrestaShop免费模块/插件/扩展/工具下载 PrestaShop免费模块 适用于您的电子商务网站的PrestaShop模块 现有超过3,000个PrestaShop模块可帮助您自定义在线商店,增加流量,提高转化率并建立客户忠诚度。 使您的电子商务网站成功! 下载(超过142+之多的PrestaShop官网认证的免费模块) 标签PrestaShop免费, PrestaShop免费工

zblog自定义关键词和描述,zblog做seo优化必备插件

zblog自定义关键词和描述,zblog做seo优化必备插件     首先说下用到的一款插件:CustomMeta自定义数据字段 ,我们这里用到的版本是1.1,1.1+版增加了列表页标签支持!     插件介绍:文章,分类等添加自定义数据字段。1.1+版适用于 Z-Blog 2.0 B2以上版本。     在zblog2.0beta1里面,这个插件是集成到了程序里面,beta2里面默认没有了