PluginView creation
How is the plugin initialized?
it's begin with the PluginView's creation
1.PluginView.create()
PassRefPtr<PluginView> PluginView::create(Frame* parentFrame, const IntSize& size,
Element* element, const KURL& url, const Vector<String>& paramNames,
const Vector<String>& paramValues,
const String& mimeType, bool loadManually)
{
....
PluginPackage* plugin = PluginDatabase::installedPlugins()->
findPlugin(url, mimeTypeCopy);
if (!plugin && PluginDatabase::installedPlugins()->refresh()) {
mimeTypeCopy = mimeType;
plugin = PluginDatabase::installedPlugins()->findPlugin(url, mimeTypeCopy);
}
return adoptRef(new PluginView(parentFrame, size, plugin, element, url, paramNames,
paramValues, mimeTypeCopy, loadManually));
}
find plugin and pass it to PluginView's constructor.
two vector, mpath and m_pluginDirectories
in "installedPlugins"
use default dir and set to "m_pluginDirectories"
in "refresh"
call "getPluginPathsInDirectories"
get path from "m_pluginDirectories" to "mpath"
and then use "mpath" to create "PluginPackage"
add "PinginPack" to "m_plugins"
1)first:
installedPlugins()->findPlugin()
a.installedPlugins()
find database from "m_pluginDirectories"
b.findPlugin()
find pluginpack from "PluginDatabase" using "pluginForMIMEType"
2)second
if can't refresh, and repeat
in refresh
HashSet<String> paths;
getPluginPathsInDirectories(paths);
a.get all PluginPath, and create PluginPack from proper path (PluginPackage::createPackage)
b.add PluginPack, to m_plugin.
2. PluginView()
PluginView::PluginView(Frame* parentFrame, const IntSize& size, PluginPackage* plugin,
Element* element,const KURL& url,const Vector<String>& paramNames,
const Vector<String>& paramValues, const String& mimeType, bool loadManually)
............
3.PluginView.init()
if (!m_plugin->load()) {
m_plugin = 0;
m_status = PluginStatusCanNotLoadPlugin;
return;
}
RefPtr<PluginPackage> m_plugin;
4.PluginPack.load()
// not defined in PluginPack.cpp, it's in PluginPackAndroid.cpp
// Open the library
void *handle = dlopen(m_path.utf8().data(), RTLD_NOW);
if(!handle) {
PLUGIN_LOG("Couldn't load plugin library \"%s\": %s\n",
m_path.utf8().data(), dlerror());
return false;
}
.....
NP_InitializeFuncPtr NP_Initialize;
if(!getEntryPoint(m_module, "NP_Initialize", (void **) &NP_Initialize) ||
!getEntryPoint(m_module, "NP_Shutdown", (void **) &m_NPP_Shutdown)) {
PLUGIN_LOG("Couldn't find Initialize function\n");
return false;
}
after that we got the function "NP_Initialize" and "NP_Shutdown" frome the .so file
and value it to "NP_Initialize" and "m_NPP_Shutdown"
5. initialize BrowserFunctions (also called in the PluginPack.load())
void PluginPackage::initializeBrowserFuncs()
{
memset(&m_browserFuncs, 0, sizeof(m_browserFuncs));
m_browserFuncs.size = sizeof(m_browserFuncs);
m_browserFuncs.version = NPVersion();
.......
m_browserFuncs.getvalueforurl = NPN_GetValueForURL;
m_browserFuncs.setvalueforurl = NPN_SetValueForURL;
m_browserFuncs.getauthenticationinfo = NPN_GetAuthenticationInfo;
}
give value to " NPNetscapeFuncs m_browserFuncs;" (
this variable will be passed into the plugin.)
6. NP_Initialize
if(NP_Initialize(&m_browserFuncs,
&m_pluginFuncs,
JSC::Bindings::getJNIEnv()) != NPERR_NO_ERROR) {
PLUGIN_LOG("Couldn't initialize plugin\n");
return false;
}
use plugin's initialize function to initialize the plugin ( pass the m_browserFunction in and get the m_pluginFuncs out)
7. Other
how is PluginPackage.fetchInfo called
a in PluginView(){} PluginDatabase::installedPlugins()->refresh()
b.RefPtr<PluginPackage> package = PluginPackage::createPackage(*it, lastModified)
c.package->fetchInfo()
How is PluginView called
how is pluginview.load called?
1.
void RenderFrameBase::layoutWithFlattening
void RenderFrame::layout()
void Document::updateLayout()
2.
FrameView.Layout()
performPostLayoutTasks();
3.
void FrameView::performPostLayoutTasks()
updateWidgets()
4.
bool FrameView::updateWidgets()
5.
void FrameView::updateWidget(RenderEmbeddedObject* object)
if (ownerElement->hasTagName(objectTag) || ownerElement->hasTagName(embedTag))
static_cast<HTMLPlugInImageElement*>(ownerElement)->updateWidget(false);
// FIXME: It is not clear that Media elements need or want this updateWidget() call.
#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
else if (ownerElement->hasTagName(videoTag) || ownerElement->hasTagName(audioTag))
static_cast<HTMLMediaElement*>(ownerElement)->updateWidget(false);
#endif
6.HTMLMediaElement.cpp
HTMLMediaElement.updateWidget()
7.HTMLMediaElement.cpp updateWidget()
loader->requestObject(this, m_url, getAttribute(nameAttr),
m_serviceType, paramNames, paramValues);
8.SubframeLoader.cpp
requestObject()
9.SubframeLoader.cpp
loadPlugin()
10.FrameLoaderClientAndroid.cpp
createPlugin().
11.PluginView.create()
.....
PluginView.setParent()
PluginView.init()
PluginPackage.load()//PluginPackageAndroid.cpp
for GingerBread
RenderEmbeddedObject::updateWidget
bool FrameLoader::requestObject
FrameLoaderClientAndroid::createPlugin
Plugin Display
1.SubframeLoader::loadPlugin(HTMLPlugInImageElement* pluginElement)
2.RenderEmbeddedObject.setWidget(PassRefPtr<Widget> widget)
RenderPart.setWidget(PassRefPtr<Widget> widget)
RenderWidget.setWidget(PassRefPtr<Widget> widget)
3.RenderWidget.moveWidgetToParentSoon(Widget* child, FrameView* parent)
4.FrameView(ScrollView)::addChild(PassRefPtr<Widget> prpChild(PluginView));
5.PluginView::setParent(ScrollView* parent)
6.PluginView::init()
7.PluginView::start()
pluginView
init()
start()
load()
example
take NPN_PluginThreadAsyncCall for example.
a.plugin call m_browserFunctions->pluginthreadasynccall
b.call PluginPackageAndroid.cpp,NPN_PluginThreadAsyncCall(instance,func,userData);
c.Npapi.cpp .void NPN_PluginThreadAsyncCall(NPP instance, void (*func) (void *), void *userData);
d.PluginMainThreadScheduler::scheduler().scheduleCall(instance, func, userData);
e.PluginMainThreadScheduler.scheduleCall((instance, func, userData);
f.PluginMainThreadScheduler.Call((MainThreadFunction* function, void* userData);