WebKit插件机制分析 |
WebKit插件机制分析 |
1. 当页面解析到plugin节点时: #0 0x40400ac4 in WebCore::PluginPackage::createPackage () from /usr/lib/libwebkit-owb.so.2.0 #1 0x403ff1a8 in WebCore::PluginDatabase::refresh () from /usr/lib/libwebkit-owb.so.2.0 #2 0x403ff968 in WebCore::PluginDatabase::installedPlugins () from /usr/lib/libwebkit-owb.so.2.0 #3 0x4038c66c in WebCore::FrameLoader::defaultObjectContentType () from /usr/lib/libwebkit-owb.so.2.0 #4 0x4034b83c in WebCore::HTMLPlugInImageElement::isImageType () from /usr/lib/libwebkit-owb.so.2.0 #5 0x4034127c in WebCore::HTMLObjectElement::attach () from /usr/lib/libwebkit-owb.so.2.0 #6 0x40349c5c in WebCore::HTMLParser::insertNode () 说明: (1)PluginPackage::createPackage()中调用fetchInfo()函数: 会加载指定的lib*.so并调用NPP*函数:NP_GetMIMEDescription()、NP_GetValue() 由他们来确定制定库和页面中插件的类型匹配情况。 (2)PluginDatabase::installedPlugins () 到指定的目录去查找可能使用的插件库。 2. loadPlugin函数的调用过程:(目的为了创建PluginView对象) #0 0x4038d650 in WebCore::FrameLoader::loadPlugin () from /usr/lib/libwebkit-owb.so.2.0 #1 0x4039250c in WebCore::FrameLoader::requestObject () from /usr/lib/libwebkit-owb.so.2.0 #2 0x40453e0c in WebCore::RenderEmbeddedObject::updateWidget () from /usr/lib/libwebkit-owb.so.2.0 #3 0x403e38a8 in WebCore::FrameView::updateWidgets () from /usr/lib/libwebkit-owb.so.2.0 #4 0x403e39ec in WebCore::FrameView::performPostLayoutTasks () from /usr/lib/libwebkit-owb.so.2.0 #5 0x403e4198 in WebCore::FrameView::layout () from /usr/lib/libwebkit-owb.so.2.0 #6 0x40258aac in WebCore::Document::implicitClose () from /usr/lib/libwebkit-owb.so.2.0 说明:当页面FrameView需要layout时发现页面存在plugin,而这个Plugin所占显示区域由PluginView来呈现。 因此此时再去加载、创建Plugin对象. 3. PluginView::start()函数调用过程: #0 0x40403d80 in WebCore::PluginView::start () from /usr/lib/libwebkit-owb.so.2.0 #1 0x404043e8 in WebCore::PluginView::startOrAddToUnstartedList () from /usr/lib/libwebkit-owb.so.2.0 #2 0x40404484 in WebCore::PluginView::init () from /usr/lib/libwebkit-owb.so.2.0 #3 0x40227e34 in WebCore::ScrollView::addChild () from /usr/lib/libwebkit-owb.so.2.0 #4 0x404b9548 in WebCore::moveWidgetToParentSoon () from /usr/lib/libwebkit-owb.so.2.0 #5 0x404b96b0 in WebCore::RenderWidget::setWidget () from /usr/lib/libwebkit-owb.so.2.0 说明:这里的RenderWidget::setWidget()在FrameLoader的LoadPlugin()函数中创建了有效的pluginView对象之后 由L1251 renderer->setWidget(widget)来调用。 4. PluginView::init()所完成的工作: (1)PluginPackage::load() 定义在PluginPackageGeneric.cpp中 1)m_module = dlopen (m_path.utf8().data(), RTLD_LAZY); L157 调用dlopen()函数以指定模式打开指定的动态连接库文件,并返回一个句柄给调用进程。使用dlclose()来卸载打开的库。 从而加载插件库libmeld.so 2)NP_Initialize = (NP_InitializeFuncPtr)dlsym(m_module, "NP_Initialize"); m_NPP_Shutdown = (NPP_ShutdownProcPtr)dlsym(m_module, "NP_Shutdown"); 通过dlsym函数找到库中的NP_Initialize()和NP_Shutdown()函数符号用来调用。 3)调用NP_Initialize()初始化NPN*()和NPP*()函数指针。 (2)调用start()函数。 5. PluginView.start() 主要工作:npErr = m_plugin->pluginFuncs()->newp(...) 根据NP_Initialize()注册的pluginFuncs()调用newp(...),即NPP_New()函数来创建真正的Plugin对象。 6. 如下语句中PluginArray[i]的调用方式: var myPlugin=navigator.plugins[0]; var myMimeType=myPlugin[0]; #0 0x403f95b8 in WebCore::PluginArray::item () from /usr/lib/libwebkit-owb.so.2.0 #1 0x4054697c in WebCore::JSPluginArray::indexGetter () from /usr/lib/libwebkit-owb.so.2.0
7. MIMEType和Extension之间的关系: (1)在MIMETypeRegistry类中定义了一堆静态方法,如: getMIMETypeForExtension(), getExtensionsForMIMEType() 居于各种平台的实现中大都声明了一个结构体 ExtensionMap,如MIMETypeRegisteryGeneric.cpp文件中 可以看到extension表示文件的扩展名称,而MIMEType表示的是资源的媒体类型。 (附:媒体类型通常是通过 HTTP 协议,由 Web 服务器告知浏览器的,更准确地说,是通过 Content-Type 来表示的,例如: Content-Type: text/HTML表示内容是 text/HTML 类型,也就是超文本文件。MIME Type 不是个人指定的,是经过 ietf 组织协商,以 RFC的形式作 为建议的标准发布在网上的,大多数的 Web 服务器和用户代理都会支持这个规范 (顺便说一句,Email 附件的类型也是通过 MIME Type 指定的)。 通常只有一些在互联网上获得广泛应用的格式才会获得一个 MIME Type,如果是某个客户端自己定义的格式,一般只能以 application/x- 开头。) (2) PluginPackage类定义了mimeToDescriptions()和mimeToExtensions()方法。 后者是根据在头文件中定义的typedef HashMap 可以看到每个MIMEType类型可以对应一堆Extension。(两者是一对多的关系) 8. Plugin、PluginData、PluginArray、PluginPackage、PluginDatabase、MIMEType、MIMETypeArray之间的关系 (1) PluginArray -- 1:1 -- PluginData* PluginArray::item(...)和PluginArray::namedItem(...)可以得到对应的Plugin*指针。 Plugin类和MIMEType类都作为JS对象提供js脚本的访问。 具体的访问方式是通过Navigator.plugins返回对应的PluginArray、MIMETypeArray对象然后取item()或nameItem()得到。 Plugin类存储插件的name, filename, description,length信息。 MIMEType类存储相应的type, suffixs, description, enablePlugin信息。 他们都是通过PluginData相关联起来。 (2) PluginData类: 根据webkit中的注释:FIXME: merge with PluginDatabase in the future 说明该类和PluginDatabase有雷同的作用。 它的主要方法initPlugins()通过调用PluginDatabase中的installedPlugins()方法来初始化/记录当前浏览器所有支持的Plugin和MIMEType, 并且分别存放到Vector (3) PluginDatabase类与PluginPackage类是真正和实际的插件库打交道的类 前者根据缺省或自定义的插件库存放路径来加载库并记录相应的pluginInfo和MimeClassInfo信息 后者用于真正的初始化插件并创建和销毁对应的插件实例。 9. PluginQuirkSet是什么类,作用是什么? 10. NPP_SetWindow函数的调用过程: #0 0x42b2b99c in nsPluginInstance::SetWindow () from /usr/lib/plugins/libmidlet.so #1 0x42b299c4 in NPP_SetWindow () from /usr/lib/plugins/libmidlet.so #2 0x4040b55c in WebCore::PluginView::setNPWindowRect () from /usr/lib/libwebkit-owb.so.2.0 #3 0x40400e28 in WebCore::PluginView::setFrameRect () from /usr/lib/libwebkit-owb.so.2.0 #4 0x404b7818 in WebCore::RenderWidget::setWidgetGeometry () from /usr/lib/libwebkit-owb.so.2.0 #5 0x404b7b14 in WebCore::RenderWidget::updateWidgetPosition () from /usr/lib/libwebkit-owb.so.2.0 |