summaryrefslogtreecommitdiffstats
path: root/webkit/glue
diff options
context:
space:
mode:
Diffstat (limited to 'webkit/glue')
-rw-r--r--webkit/glue/chromium_bridge_impl.cc4
-rw-r--r--webkit/glue/plugins/plugin_host.cc2
-rw-r--r--webkit/glue/plugins/plugin_lib.cc197
-rw-r--r--webkit/glue/plugins/plugin_lib.h56
-rw-r--r--webkit/glue/plugins/plugin_list.cc232
-rw-r--r--webkit/glue/plugins/plugin_list.h71
-rw-r--r--webkit/glue/plugins/webplugin_delegate_impl.cc14
-rw-r--r--webkit/glue/webplugin.h7
8 files changed, 294 insertions, 289 deletions
diff --git a/webkit/glue/chromium_bridge_impl.cc b/webkit/glue/chromium_bridge_impl.cc
index 4e29dfc..fe18543 100644
--- a/webkit/glue/chromium_bridge_impl.cc
+++ b/webkit/glue/chromium_bridge_impl.cc
@@ -325,9 +325,9 @@ bool ChromiumBridge::plugins(bool refresh, Vector<PluginInfo*>* results) {
rv->desc = webkit_glue::StdWStringToString(plugin.desc);
rv->file =
#if defined(OS_WIN)
- webkit_glue::StdWStringToString(plugin.file.BaseName().value());
+ webkit_glue::StdWStringToString(plugin.path.BaseName().value());
#elif defined(OS_POSIX)
- webkit_glue::StdStringToString(plugin.file.BaseName().value());
+ webkit_glue::StdStringToString(plugin.path.BaseName().value());
#endif
for (size_t j = 0; j < plugin.mime_types.size(); ++ j) {
MimeClassInfo* new_mime = new MimeClassInfo();
diff --git a/webkit/glue/plugins/plugin_host.cc b/webkit/glue/plugins/plugin_host.cc
index 1181caa..8ef80da 100644
--- a/webkit/glue/plugins/plugin_host.cc
+++ b/webkit/glue/plugins/plugin_host.cc
@@ -759,7 +759,7 @@ NPError NPN_GetValue(NPP id, NPNVariable variable, void *value) {
// to worry about future standard change that may conflict with the
// variable definition.
scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id);
- if (plugin->plugin_lib()->plugin_info().file.value() ==
+ if (plugin->plugin_lib()->plugin_info().path.value() ==
kDefaultPluginLibraryName) {
plugin->webplugin()->OnMissingPluginStatus(
variable - default_plugin::kMissingPluginStatusStart);
diff --git a/webkit/glue/plugins/plugin_lib.cc b/webkit/glue/plugins/plugin_lib.cc
index e2c0f59..546c025 100644
--- a/webkit/glue/plugins/plugin_lib.cc
+++ b/webkit/glue/plugins/plugin_lib.cc
@@ -15,7 +15,6 @@
#include "base/string_util.h"
#include "base/sys_string_conversions.h"
#include "base/task.h"
-#include "net/base/mime_util.h"
#include "webkit/activex_shim/npp_impl.h"
#include "webkit/default_plugin/plugin_main.h"
#include "webkit/glue/glue_util.h"
@@ -32,29 +31,10 @@ namespace NPAPI
const char kPluginLibrariesLoadedCounter[] = "PluginLibrariesLoaded";
const char kPluginInstancesActiveCounter[] = "PluginInstancesActive";
-PluginLib::PluginMap* PluginLib::loaded_libs_;
-
-PluginLib* PluginLib::CreatePluginLib(const FilePath& filename) {
- // For Windows we have a bit of a problem in that we might have the same path
- // cased differently for two different plugin load paths. Therefore we do a
- // quick lowercase for canonicalization's sake. WARNING: If you clone this
- // file for other platforms, remove this lowercasing. This is *wrong* for
- // other platforms (and arguably the wrong way to do it for Windows too, but
- // let's not get into that here).
- FilePath filename_lc(StringToLowerASCII(filename.value()));
-
- // We can only have one PluginLib object per plugin as it controls the per
- // instance function calls (i.e. NP_Initialize and NP_Shutdown). So we keep
- // a (non-ref counted) map of PluginLib objects.
- if (!loaded_libs_)
- loaded_libs_ = new PluginMap();
-
- PluginMap::const_iterator iter = loaded_libs_->find(filename_lc);
- if (iter != loaded_libs_->end())
- return iter->second;
-
- static const InternalPluginInfo activex_shim_info_generic = {
+static const InternalPluginInfo g_internal_plugins[] = {
+ {
{kActiveXShimFileName,
+ kActiveXShimFileName,
L"ActiveX Plug-in",
L"ActiveX Plug-in provides a shim to support ActiveX controls",
L"1, 0, 0, 1",
@@ -65,11 +45,11 @@ PluginLib* PluginLib::CreatePluginLib(const FilePath& filename) {
activex_shim::ActiveX_Shim_NP_GetEntryPoints,
activex_shim::ActiveX_Shim_NP_Initialize,
activex_shim::ActiveX_Shim_NP_Shutdown
- };
-
- static const InternalPluginInfo activex_shim_wmplayer = {
+ },
+ {
{kActivexShimFileNameForMediaPlayer,
kActivexShimFileNameForMediaPlayer,
+ kActivexShimFileNameForMediaPlayer,
L"Windows Media Player",
L"1, 0, 0, 1",
L"application/x-ms-wmp|application/asx|video/x-ms-asf-plugin|"
@@ -81,10 +61,10 @@ PluginLib* PluginLib::CreatePluginLib(const FilePath& filename) {
activex_shim::ActiveX_Shim_NP_GetEntryPoints,
activex_shim::ActiveX_Shim_NP_Initialize,
activex_shim::ActiveX_Shim_NP_Shutdown
- };
-
- static const InternalPluginInfo default_plugin_info = {
+ },
+ {
{kDefaultPluginLibraryName,
+ kDefaultPluginLibraryName,
L"Default Plug-in",
L"Provides functionality for installing third-party plug-ins",
L"1, 0, 0, 1",
@@ -95,59 +75,50 @@ PluginLib* PluginLib::CreatePluginLib(const FilePath& filename) {
default_plugin::NP_GetEntryPoints,
default_plugin::NP_Initialize,
default_plugin::NP_Shutdown
- };
-
- WebPluginInfo* info = NULL;
- const InternalPluginInfo* internal_plugin_info = NULL;
- if (!_wcsicmp(filename.value().c_str(),
- activex_shim_info_generic.version_info.file_name.c_str())) {
- info = CreateWebPluginInfo(activex_shim_info_generic.version_info);
- internal_plugin_info = &activex_shim_info_generic;
- } else if (!_wcsicmp(filename.value().c_str(),
- activex_shim_wmplayer.version_info.file_name.c_str())) {
- info = CreateWebPluginInfo(activex_shim_wmplayer.version_info);
- internal_plugin_info = &activex_shim_wmplayer;
- } else if (!_wcsicmp(
- filename.value().c_str(),
- default_plugin_info.version_info.file_name.c_str())) {
- info = CreateWebPluginInfo(default_plugin_info.version_info);
- internal_plugin_info = &default_plugin_info;
- } else {
- info = ReadWebPluginInfo(filename_lc);
- if (!info) {
- DLOG(INFO) << "This file isn't a valid NPAPI plugin: "
- << filename.value();
- return NULL;
- }
+ },
+};
+
+
+// A list of all the instantiated plugins.
+static std::vector<scoped_refptr<PluginLib> >* g_loaded_libs;
+
+PluginLib* PluginLib::CreatePluginLib(const FilePath& filename) {
+ // We can only have one PluginLib object per plugin as it controls the per
+ // instance function calls (i.e. NP_Initialize and NP_Shutdown). So we keep
+ // a map of PluginLib objects.
+ if (!g_loaded_libs)
+ g_loaded_libs = new std::vector<scoped_refptr<PluginLib> >;
+
+ for (size_t i = 0; i < g_loaded_libs->size(); ++i) {
+ if ((*g_loaded_libs)[i]->plugin_info().path == filename)
+ return (*g_loaded_libs)[i];
}
- return new PluginLib(info, internal_plugin_info);
+ WebPluginInfo info;
+ if (!ReadWebPluginInfo(filename, &info))
+ return NULL;
+
+ return new PluginLib(info);
}
void PluginLib::UnloadAllPlugins() {
- if (loaded_libs_) {
- PluginMap::iterator lib_index;
- for (lib_index = loaded_libs_->begin(); lib_index != loaded_libs_->end();
- ++lib_index) {
- lib_index->second->Unload();
- }
- delete loaded_libs_;
- loaded_libs_ = NULL;
+ if (g_loaded_libs) {
+ for (size_t i = 0; i < g_loaded_libs->size(); ++i)
+ (*g_loaded_libs)[i]->Unload();
+
+ delete g_loaded_libs;
+ g_loaded_libs = NULL;
}
}
void PluginLib::ShutdownAllPlugins() {
- if (loaded_libs_) {
- PluginMap::iterator lib_index;
- for (lib_index = loaded_libs_->begin(); lib_index != loaded_libs_->end();
- ++lib_index) {
- lib_index->second->Shutdown();
- }
+ if (g_loaded_libs) {
+ for (size_t i = 0; i < g_loaded_libs->size(); ++i)
+ (*g_loaded_libs)[i]->Shutdown();
}
}
-PluginLib::PluginLib(WebPluginInfo* info,
- const InternalPluginInfo* internal_plugin_info)
+PluginLib::PluginLib(const WebPluginInfo& info)
: web_plugin_info_(info),
module_(0),
initialized_(false),
@@ -155,15 +126,18 @@ PluginLib::PluginLib(WebPluginInfo* info,
instance_count_(0) {
StatsCounter(kPluginLibrariesLoadedCounter).Increment();
memset((void*)&plugin_funcs_, 0, sizeof(plugin_funcs_));
-
- (*loaded_libs_)[info->file] = this;
- if (internal_plugin_info) {
- internal_ = true;
- NP_Initialize_ = internal_plugin_info->np_initialize;
- NP_GetEntryPoints_ = internal_plugin_info->np_getentrypoints;
- NP_Shutdown_ = internal_plugin_info->np_shutdown;
- } else {
- internal_ = false;
+ g_loaded_libs->push_back(this);
+
+ internal_ = false;
+ std::wstring wide_filename = UTF8ToWide(info.filename);
+ for (int i = 0; i < arraysize(g_internal_plugins); ++i) {
+ if (wide_filename == g_internal_plugins[i].version_info.filename) {
+ internal_ = true;
+ NP_Initialize_ = g_internal_plugins[i].np_initialize;
+ NP_GetEntryPoints_ = g_internal_plugins[i].np_getentrypoints;
+ NP_Shutdown_ = g_internal_plugins[i].np_shutdown;
+ break;
+ }
}
}
@@ -178,24 +152,6 @@ NPPluginFuncs *PluginLib::functions() {
return &plugin_funcs_;
}
-bool PluginLib::SupportsType(const std::string &mime_type,
- bool allow_wildcard) {
- // Webkit will ask for a plugin to handle empty mime types.
- if (mime_type.empty())
- return false;
-
- for (size_t i = 0; i < web_plugin_info_->mime_types.size(); ++i) {
- const WebPluginMimeType& mime_info = web_plugin_info_->mime_types[i];
- if (net::MatchesMimeType(mime_info.mime_type, mime_type)) {
- if (!allow_wildcard && (mime_info.mime_type == "*")) {
- continue;
- }
- return true;
- }
- }
- return false;
-}
-
NPError PluginLib::NP_Initialize() {
if (initialized_)
return NPERR_NO_ERROR;
@@ -233,10 +189,15 @@ void PluginLib::CloseInstance() {
if ((instance_count_ == 0) &&
webkit_glue::IsPluginRunningInRendererProcess()) {
Unload();
- loaded_libs_->erase(web_plugin_info_->file);
- if (loaded_libs_->empty()) {
- delete loaded_libs_;
- loaded_libs_ = NULL;
+ for (size_t i = 0; i < g_loaded_libs->size(); ++i) {
+ if ((*g_loaded_libs)[i].get() == this) {
+ g_loaded_libs->erase(g_loaded_libs->begin() + i);
+ break;
+ }
+ }
+ if (g_loaded_libs->empty()) {
+ delete g_loaded_libs;
+ g_loaded_libs = NULL;
}
}
}
@@ -249,7 +210,7 @@ bool PluginLib::Load() {
if (module_ != 0)
return rv;
- module = LoadPluginHelper(web_plugin_info_->file);
+ module = LoadPluginHelper(web_plugin_info_.path);
if (module == 0)
return rv;
@@ -370,7 +331,8 @@ void PluginLib::Shutdown() {
}
}
-WebPluginInfo* PluginLib::CreateWebPluginInfo(const PluginVersionInfo& pvi) {
+bool PluginLib::CreateWebPluginInfo(const PluginVersionInfo& pvi,
+ WebPluginInfo* info) {
std::vector<std::string> mime_types, file_extensions;
std::vector<std::wstring> descriptions;
SplitString(base::SysWideToNativeMB(pvi.mime_types), '|', &mime_types);
@@ -378,13 +340,13 @@ WebPluginInfo* PluginLib::CreateWebPluginInfo(const PluginVersionInfo& pvi) {
SplitString(pvi.file_open_names, '|', &descriptions);
if (mime_types.empty())
- return NULL;
+ return false;
- WebPluginInfo *info = new WebPluginInfo();
info->name = pvi.product_name;
info->desc = pvi.file_description;
info->version = pvi.file_version;
- info->file = FilePath(pvi.file_name);
+ info->filename = WideToUTF8(pvi.filename);
+ info->path = FilePath(pvi.path);
for (size_t i = 0; i < mime_types.size(); ++i) {
WebPluginMimeType mime_type;
@@ -408,10 +370,17 @@ WebPluginInfo* PluginLib::CreateWebPluginInfo(const PluginVersionInfo& pvi) {
info->mime_types.push_back(mime_type);
}
- return info;
+ return true;
}
-WebPluginInfo* PluginLib::ReadWebPluginInfo(const FilePath &filename) {
+
+ bool PluginLib::ReadWebPluginInfo(const FilePath &filename,
+ WebPluginInfo* info) {
+ for (int i = 0; i < arraysize(g_internal_plugins); ++i) {
+ if (filename.value() == g_internal_plugins[i].version_info.filename)
+ return CreateWebPluginInfo(g_internal_plugins[i].version_info, info);
+ }
+
// On windows, the way we get the mime types for the library is
// to check the version information in the DLL itself. This
// will be a string of the format: <type1>|<type2>|<type3>|...
@@ -420,7 +389,10 @@ WebPluginInfo* PluginLib::ReadWebPluginInfo(const FilePath &filename) {
scoped_ptr<FileVersionInfo> version_info(
FileVersionInfo::CreateFileVersionInfo(filename.value()));
if (!version_info.get())
- return NULL;
+ return false;
+
+ std::wstring original_filename = version_info->original_filename();
+ std::wstring file_version = version_info->file_version();
PluginVersionInfo pvi;
version_info->GetValue(L"MIMEType", &pvi.mime_types);
@@ -428,10 +400,11 @@ WebPluginInfo* PluginLib::ReadWebPluginInfo(const FilePath &filename) {
version_info->GetValue(L"FileOpenName", &pvi.file_open_names);
pvi.product_name = version_info->product_name();
pvi.file_description = version_info->file_description();
- pvi.file_version = version_info->file_version();
- pvi.file_name = filename.value();
+ pvi.file_version = file_version;
+ pvi.filename = original_filename;
+ pvi.path = filename.value();
- return CreateWebPluginInfo(pvi);
+ return CreateWebPluginInfo(pvi, info);
}
} // namespace NPAPI
diff --git a/webkit/glue/plugins/plugin_lib.h b/webkit/glue/plugins/plugin_lib.h
index cd3db97..884f235 100644
--- a/webkit/glue/plugins/plugin_lib.h
+++ b/webkit/glue/plugins/plugin_lib.h
@@ -8,13 +8,14 @@
#include "build/build_config.h"
#include <string>
+#include <vector>
#include "base/basictypes.h"
#include "base/file_path.h"
-#include "base/hash_tables.h"
#include "base/ref_counted.h"
#include "base/scoped_ptr.h"
#include "webkit/glue/plugins/nphostapi.h"
+#include "webkit/glue/webplugin.h"
#include "third_party/npapi/bindings/npapi.h"
struct WebPluginInfo;
@@ -27,7 +28,8 @@ class PluginInstance;
// This struct fully describes a plugin. For external plugins, it's read in from
// the version info of the dll; For internal plugins, it's predefined.
struct PluginVersionInfo {
- std::wstring file_name;
+ std::wstring filename;
+ std::wstring path;
std::wstring product_name;
std::wstring file_description;
std::wstring file_version;
@@ -49,8 +51,13 @@ struct InternalPluginInfo {
// manager for new PluginInstances.
class PluginLib : public base::RefCounted<PluginLib> {
public:
+ static PluginLib* PluginLib::CreatePluginLib(const FilePath& filename);
virtual ~PluginLib();
- static PluginLib* CreatePluginLib(const FilePath& filename);
+
+ // Creates a WebPluginInfo structure given a plugin's path. On success
+ // returns true, with the information being put into "info". Returns false if
+ // the library couldn't be found, or if it's not a plugin.
+ static bool ReadWebPluginInfo(const FilePath &filename, WebPluginInfo* info);
// Unloads all the loaded plugin libraries and cleans up the plugin map.
static void UnloadAllPlugins();
@@ -61,10 +68,6 @@ class PluginLib : public base::RefCounted<PluginLib> {
// Get the Plugin's function pointer table.
NPPluginFuncs *functions();
- // Returns true if this Plugin supports a given mime-type.
- // mime_type should be all lower case.
- bool SupportsType(const std::string &mime_type, bool allow_wildcard);
-
// Creates a new instance of this plugin.
PluginInstance *CreateInstance(const std::string &mime_type);
@@ -73,7 +76,7 @@ class PluginLib : public base::RefCounted<PluginLib> {
// Gets information about this plugin and the mime types that it
// supports.
- const WebPluginInfo& plugin_info() { return *web_plugin_info_; }
+ const WebPluginInfo& plugin_info() { return web_plugin_info_; }
//
// NPAPI functions
@@ -95,11 +98,8 @@ class PluginLib : public base::RefCounted<PluginLib> {
int instance_count() const { return instance_count_; }
private:
- // Creates a new PluginLib. The WebPluginInfo object is owned by this
- // object. If internal_plugin_info is not NULL, this Lib is an internal
- // plugin thus doesn't need to load a library.
- PluginLib(WebPluginInfo* info,
- const InternalPluginInfo* internal_plugin_info);
+ // Creates a new PluginLib
+ PluginLib(const WebPluginInfo& info);
// Attempts to load the plugin from the library.
// Returns true if it is a legitimate plugin, false otherwise
@@ -111,31 +111,25 @@ class PluginLib : public base::RefCounted<PluginLib> {
// Shutdown the plugin library.
void Shutdown();
- // Returns a WebPluginInfo structure given a plugin's path. Returns NULL if
- // the library couldn't be found, or if it's not a plugin.
- static WebPluginInfo* ReadWebPluginInfo(const FilePath &filename);
// Creates WebPluginInfo structure based on read in or built in
// PluginVersionInfo.
- static WebPluginInfo* CreateWebPluginInfo(const PluginVersionInfo& info);
+ static bool CreateWebPluginInfo(const PluginVersionInfo& pvi,
+ WebPluginInfo* info);
- bool internal_; // Whether this an internal plugin.
- scoped_ptr<WebPluginInfo> web_plugin_info_; // supported mime types, description
+ bool internal_; // Whether this an internal plugin.
+ WebPluginInfo web_plugin_info_; // supported mime types, description
#if defined(OS_WIN)
- HMODULE module_; // the opened DLL handle
+ HMODULE module_; // the opened DLL handle
#endif
- NPPluginFuncs plugin_funcs_; // the struct of plugin side functions
- bool initialized_; // is the plugin initialized
- NPSavedData *saved_data_; // persisted plugin info for NPAPI
- int instance_count_; // count of plugins in use
-
- // A map of all the instantiated plugins.
- typedef base::hash_map<FilePath, scoped_refptr<PluginLib> > PluginMap;
- static PluginMap* loaded_libs_;
+ NPPluginFuncs plugin_funcs_; // the struct of plugin side functions
+ bool initialized_; // is the plugin initialized
+ NPSavedData *saved_data_; // persisted plugin info for NPAPI
+ int instance_count_; // count of plugins in use
// C-style function pointers
- NP_InitializeFunc NP_Initialize_;
- NP_GetEntryPointsFunc NP_GetEntryPoints_;
- NP_ShutdownFunc NP_Shutdown_;
+ NP_InitializeFunc NP_Initialize_;
+ NP_GetEntryPointsFunc NP_GetEntryPoints_;
+ NP_ShutdownFunc NP_Shutdown_;
DISALLOW_EVIL_CONSTRUCTORS(PluginLib);
};
diff --git a/webkit/glue/plugins/plugin_list.cc b/webkit/glue/plugins/plugin_list.cc
index f969874..b4b3dcb 100644
--- a/webkit/glue/plugins/plugin_list.cc
+++ b/webkit/glue/plugins/plugin_list.cc
@@ -17,10 +17,11 @@
#include "base/string_util.h"
#include "base/sys_string_conversions.h"
#include "base/time.h"
+#include "net/base/mime_util.h"
#include "webkit/activex_shim/activex_shared.h"
+#include "webkit/glue/plugins/plugin_lib.h"
#include "webkit/glue/webkit_glue.h"
#include "webkit/glue/webplugin.h"
-#include "webkit/glue/plugins/plugin_lib.h"
#include "googleurl/src/gurl.h"
using base::TimeDelta;
@@ -42,10 +43,10 @@ static const TCHAR kRegistryPath[] = _T("Path");
static const TCHAR kRegistryMozillaPlugins[] = _T("SOFTWARE\\MozillaPlugins");
static const TCHAR kRegistryFirefoxInstalled[] =
_T("SOFTWARE\\Mozilla\\Mozilla Firefox");
-static const TCHAR kMozillaActiveXPlugin[] = _T("npmozax.dll");
-static const TCHAR kNewWMPPlugin[] = _T("np-mswmp.dll");
-static const TCHAR kOldWMPPlugin[] = _T("npdsplay.dll");
-static const TCHAR kYahooApplicationStatePlugin[] = _T("npystate.dll");
+static const char kMozillaActiveXPlugin[] = "npmozax.dll";
+static const char kNewWMPPlugin[] = "np-mswmp.dll";
+static const char kOldWMPPlugin[] = "npdsplay.dll";
+static const char kYahooApplicationStatePlugin[] = "npystate.dll";
static const TCHAR kRegistryJava[] =
_T("Software\\JavaSoft\\Java Runtime Environment");
static const TCHAR kRegistryBrowserJavaVersion[] = _T("BrowserJavaVersion");
@@ -80,10 +81,6 @@ PluginList::PluginList() :
!command_line.HasSwitch(kNoNativeActiveXShimSwitch);
}
-PluginList::~PluginList() {
- plugins_.clear();
-}
-
void PluginList::LoadPlugins(bool refresh) {
if (plugins_loaded_ && !refresh)
return;
@@ -122,9 +119,11 @@ void PluginList::LoadPlugins(bool refresh) {
LoadWindowsMediaPlugins();
if (webkit_glue::IsDefaultPluginEnabled()) {
- scoped_refptr<PluginLib> default_plugin = PluginLib::CreatePluginLib(
- FilePath(kDefaultPluginLibraryName));
- plugins_.push_back(default_plugin);
+ WebPluginInfo info;
+ if (PluginLib::ReadWebPluginInfo(FilePath(kDefaultPluginLibraryName),
+ &info)) {
+ plugins_[WideToUTF8(kDefaultPluginLibraryName)] = info;
+ }
}
TimeTicks end_time = TimeTicks::Now();
@@ -155,15 +154,42 @@ void PluginList::LoadPlugins(const FilePath &path) {
FindClose(find_handle);
}
+
+// Compares Windows style version strings (i.e. 1,2,3,4). Returns true if b's
+// version is newer than a's, or false if it's equal or older.
+bool IsNewerVersion(const std::wstring& a, const std::wstring& b) {
+ std::vector<std::wstring> a_ver, b_ver;
+ SplitString(a, ',', &a_ver);
+ SplitString(b, ',', &b_ver);
+ if (a_ver.size() != b_ver.size())
+ return false;
+ for (size_t i = 0; i < a_ver.size(); i++) {
+ int cur_a = StringToInt(a_ver[i]);
+ int cur_b = StringToInt(b_ver[i]);
+ if (cur_a > cur_b)
+ return false;
+ if (cur_a < cur_b)
+ return true;
+ }
+ return false;
+}
+
void PluginList::LoadPlugin(const FilePath &path) {
- if (!ShouldLoadPlugin(path.BaseName()))
+ WebPluginInfo plugin_info;
+ if (!PluginLib::ReadWebPluginInfo(path, &plugin_info))
return;
- scoped_refptr<PluginLib> new_plugin = PluginLib::CreatePluginLib(path);
- if (!new_plugin.get())
+ // Canonicalize names on Windows in case different versions of the plugin
+ // have different case in the version string.
+ std::string filename_lc = StringToLowerASCII(plugin_info.filename);
+ if (!ShouldLoadPlugin(filename_lc))
return;
- const WebPluginInfo& plugin_info = new_plugin->plugin_info();
+ PluginMap::const_iterator iter = plugins_.find(filename_lc);
+ if (iter != plugins_.end() &&
+ !IsNewerVersion(iter->second.version, plugin_info.version))
+ return; // The loaded version is newer.
+
for (size_t i = 0; i < plugin_info.mime_types.size(); ++i) {
// TODO: don't load global handlers for now.
// WebKit hands to the Plugin before it tries
@@ -172,50 +198,41 @@ void PluginList::LoadPlugin(const FilePath &path) {
if (mime_type == "*" ) {
#ifndef NDEBUG
// Make an exception for NPSPY.
- if (plugin_info.file.value().find(L"npspy.dll") != std::wstring::npos) {
- // Put it at the beginning so it's used before the real plugin.
- plugins_.insert(plugins_.begin(), new_plugin.get());
- }
+ if (filename_lc == "npspy.dll")
+ break;
#endif
- continue;
- }
-
- if (!SupportsType(mime_type)) {
- plugins_.push_back(new_plugin);
return;
}
}
+
+ plugins_[filename_lc] = plugin_info;
}
-bool PluginList::ShouldLoadPlugin(const FilePath& filename) {
- // Canonicalize names.
- std::wstring filename_lc = StringToLowerASCII(filename.value());
-
+bool PluginList::ShouldLoadPlugin(const std::string& filename) {
// Depends on XPCOM.
- if (filename_lc == kMozillaActiveXPlugin)
+ if (filename == kMozillaActiveXPlugin)
return false;
// Disable the yahoo application state plugin as it crashes the plugin
// process on return from NPObjectStub::OnInvoke. Please refer to
// http://b/issue?id=1372124 for more information.
- if (filename_lc == kYahooApplicationStatePlugin)
+ if (filename == kYahooApplicationStatePlugin)
return false;
// We will use activex shim to handle embeded wmp media.
if (use_internal_activex_shim_) {
- if (filename_lc == kNewWMPPlugin || filename_lc == kOldWMPPlugin)
+ if (filename == kNewWMPPlugin || filename == kOldWMPPlugin)
return false;
} else {
// If both the new and old WMP plugins exist, only load the new one.
- if (filename_lc == kNewWMPPlugin) {
+ if (filename == kNewWMPPlugin) {
if (dont_load_new_wmp_)
return false;
- int old_plugin = FindPluginFile(kOldWMPPlugin);
- if (old_plugin != -1)
- plugins_.erase(plugins_.begin() + old_plugin);
- } else if (filename_lc == kOldWMPPlugin) {
- if (FindPluginFile(kNewWMPPlugin) != -1)
+ if (plugins_.find(kOldWMPPlugin) != plugins_.end())
+ plugins_.erase(kOldWMPPlugin);
+ } else if (filename == kOldWMPPlugin) {
+ if (plugins_.find(kOldWMPPlugin) != plugins_.end())
return false;
}
}
@@ -224,73 +241,94 @@ bool PluginList::ShouldLoadPlugin(const FilePath& filename) {
}
void PluginList::LoadInternalPlugins() {
- if (use_internal_activex_shim_) {
- scoped_refptr<PluginLib> new_plugin = PluginLib::CreatePluginLib(
- FilePath(kActiveXShimFileName));
- plugins_.push_back(new_plugin);
-
- new_plugin = PluginLib::CreatePluginLib(
- FilePath(kActivexShimFileNameForMediaPlayer));
- plugins_.push_back(new_plugin);
- }
-}
+ if (!use_internal_activex_shim_)
+ return;
-int PluginList::FindPluginFile(const std::wstring& filename) {
- std::string filename_narrow = WideToASCII(filename);
- for (size_t i = 0; i < plugins_.size(); ++i) {
- if (LowerCaseEqualsASCII(
- plugins_[i]->plugin_info().file.BaseName().value(),
- filename_narrow.c_str())) {
- return static_cast<int>(i);
- }
+ WebPluginInfo info;
+ if (PluginLib::ReadWebPluginInfo(FilePath(kActiveXShimFileName),
+ &info)) {
+ plugins_[WideToUTF8(kActiveXShimFileName)] = info;
}
- return -1;
-}
+ if (PluginLib::ReadWebPluginInfo(FilePath(kActivexShimFileNameForMediaPlayer),
+ &info)) {
+ plugins_[WideToUTF8(kActivexShimFileNameForMediaPlayer)] = info;
+ }
+}
-PluginLib* PluginList::FindPlugin(const std::string& mime_type,
- const std::string& clsid,
- bool allow_wildcard) {
+bool PluginList::FindPlugin(const std::string& mime_type,
+ const std::string& clsid,
+ bool allow_wildcard,
+ WebPluginInfo* info) {
DCHECK(mime_type == StringToLowerASCII(mime_type));
- for (size_t idx = 0; idx < plugins_.size(); ++idx) {
- if (plugins_[idx]->SupportsType(mime_type, allow_wildcard)) {
- if (!clsid.empty() &&
- plugins_[idx]->plugin_info().file.value() == kActiveXShimFileName) {
+ PluginMap::const_iterator default_iter = plugins_.end();
+ for (PluginMap::const_iterator iter = plugins_.begin();
+ iter != plugins_.end(); ++iter) {
+ if (SupportsType(iter->second, mime_type, allow_wildcard)) {
+ if (iter->second.path.value() == kDefaultPluginLibraryName) {
+ // Only use the default plugin if it's the only one that's found.
+ default_iter = iter;
+ continue;
+ }
+
+ if (!clsid.empty() && iter->second.path.value() == kActiveXShimFileName) {
// Special handling for ActiveX shim. If ActiveX is not installed, we
// should use the default plugin to show the installation UI.
if (!activex_shim::IsActiveXInstalled(clsid))
continue;
}
- return plugins_[idx];
+ *info = iter->second;
+ return true;
}
}
- return NULL;
+ if (default_iter != plugins_.end()) {
+ *info = default_iter->second;
+ return true;
+ }
+
+ return false;
}
-PluginLib* PluginList::FindPlugin(const GURL &url, std::string* actual_mime_type) {
+bool PluginList::FindPlugin(const GURL &url, std::string* actual_mime_type,
+ WebPluginInfo* info) {
std::wstring path = base::SysNativeMBToWide(url.path());
std::wstring extension_wide = file_util::GetFileExtensionFromPath(path);
if (extension_wide.empty())
- return NULL;
+ return false;
std::string extension =
StringToLowerASCII(base::SysWideToNativeMB(extension_wide));
- for (size_t idx = 0; idx < plugins_.size(); ++idx) {
- if (SupportsExtension(plugins_[idx]->plugin_info(), extension, actual_mime_type)) {
- return plugins_[idx];
+ for (PluginMap::const_iterator iter = plugins_.begin();
+ iter != plugins_.end(); ++iter) {
+ if (SupportsExtension(iter->second, extension, actual_mime_type)) {
+ *info = iter->second;
+ return true;
}
}
- return NULL;
+ return false;
}
-bool PluginList::SupportsType(const std::string &mime_type) {
- DCHECK(mime_type == StringToLowerASCII(mime_type));
- bool allow_wildcard = true;
- return (FindPlugin(mime_type, "", allow_wildcard ) != 0);
+bool PluginList::SupportsType(const WebPluginInfo& info,
+ const std::string &mime_type,
+ bool allow_wildcard) {
+ // Webkit will ask for a plugin to handle empty mime types.
+ if (mime_type.empty())
+ return false;
+
+ for (size_t i = 0; i < info.mime_types.size(); ++i) {
+ const WebPluginMimeType& mime_info = info.mime_types[i];
+ if (net::MatchesMimeType(mime_info.mime_type, mime_type)) {
+ if (!allow_wildcard && mime_info.mime_type == "*") {
+ continue;
+ }
+ return true;
+ }
+ }
+ return false;
}
bool PluginList::SupportsExtension(const WebPluginInfo& info,
@@ -315,9 +353,12 @@ bool PluginList::GetPlugins(bool refresh, std::vector<WebPluginInfo>* plugins) {
if (refresh)
LoadPlugins(true);
+ int i = 0;
plugins->resize(plugins_.size());
- for (size_t i = 0; i < plugins->size(); ++i)
- (*plugins)[i] = plugins_[i]->plugin_info();
+ for (PluginMap::const_iterator iter = plugins_.begin();
+ iter != plugins_.end(); ++iter) {
+ (*plugins)[i++] = iter->second;
+ }
return true;
}
@@ -328,32 +369,25 @@ bool PluginList::GetPluginInfo(const GURL& url,
bool allow_wildcard,
WebPluginInfo* info,
std::string* actual_mime_type) {
- scoped_refptr<PluginLib> plugin = FindPlugin(mime_type, clsid,
- allow_wildcard);
-
- if (plugin.get() == NULL ||
- (plugin->plugin_info().file.value() == kDefaultPluginLibraryName
- && clsid.empty())) {
- scoped_refptr<PluginLib> default_plugin = plugin;
- plugin = FindPlugin(url, actual_mime_type);
- // url matches may not return the default plugin if no match is found.
- if (plugin.get() == NULL && default_plugin.get() != NULL)
- plugin = default_plugin;
+ bool found = FindPlugin(mime_type, clsid, allow_wildcard, info);
+ if (!found ||
+ (info->path.value() == kDefaultPluginLibraryName && clsid.empty())) {
+ WebPluginInfo info2;
+ if (FindPlugin(url, actual_mime_type, &info2)) {
+ found = true;
+ *info = info2;
+ }
}
- if (plugin.get() == NULL)
- return false;
-
- *info = plugin->plugin_info();
- return true;
+ return found;
}
bool PluginList::GetPluginInfoByPath(const FilePath& plugin_path,
WebPluginInfo* info) {
- for (size_t i = 0; i < plugins_.size(); ++i) {
- if (wcsicmp(plugins_[i]->plugin_info().file.value().c_str(),
- plugin_path.value().c_str()) == 0) {
- *info = plugins_[i]->plugin_info();
+ for (PluginMap::const_iterator iter = plugins_.begin();
+ iter != plugins_.end(); ++iter) {
+ if (iter->second.path == plugin_path) {
+ *info = iter->second;
return true;
}
}
diff --git a/webkit/glue/plugins/plugin_list.h b/webkit/glue/plugins/plugin_list.h
index ebdb687..6bb33aa 100644
--- a/webkit/glue/plugins/plugin_list.h
+++ b/webkit/glue/plugins/plugin_list.h
@@ -8,9 +8,9 @@
#define WEBKIT_GLUE_PLUGIN_PLUGIN_LIST_H__
#include <string>
-#include <vector>
#include "base/basictypes.h"
+#include "base/hash_tables.h"
#include "base/ref_counted.h"
#include "webkit/glue/webplugin.h"
@@ -33,7 +33,6 @@ namespace NPAPI
#define kDefaultPluginLibraryName L"default_plugin"
-class PluginLib;
class PluginInstance;
// The PluginList is responsible for loading our NPAPI based plugins. It does
@@ -58,35 +57,6 @@ class PluginList : public base::RefCounted<PluginList> {
// for plugins. Must be called before the plugins have been loaded.
static void AddExtraPluginPath(const FilePath& plugin_path);
- virtual ~PluginList();
-
- // Find a plugin to by mime type, and clsid.
- // If clsid is empty, we will just find the plugin that supports mime type.
- // Otherwise, if mime_type is application/x-oleobject etc that supported by
- // by our activex shim, we need to check if the specified ActiveX exists.
- // If not we will not return the activex shim, instead we will let the
- // default plugin handle activex installation.
- // The allow_wildcard parameter controls whether this function returns
- // plugins which support wildcard mime types (* as the mime type)
- PluginLib* FindPlugin(const std::string &mime_type, const std::string& clsid,
- bool allow_wildcard);
-
- // Find a plugin to by extension. Returns the corresponding mime type
- PluginLib* FindPlugin(const GURL &url, std::string* actual_mime_type);
-
- // Check if we have any plugin for a given type.
- // mime_type must be all lowercase.
- bool SupportsType(const std::string &mime_type);
-
- // Returns true if the given WebPluginInfo supports a given file extension.
- // extension should be all lower case.
- // If mime_type is not NULL, it will be set to the mime type if found.
- // The mime type which corresponds to the extension is optionally returned
- // back.
- static bool SupportsExtension(const WebPluginInfo& info,
- const std::string &extension,
- std::string* actual_mime_type);
-
// Shutdown all plugins. Should be called at process teardown.
void Shutdown();
@@ -123,14 +93,40 @@ class PluginList : public base::RefCounted<PluginList> {
void LoadPlugin(const FilePath& filename);
// Returns true if we should load the given plugin, or false otherwise.
- bool ShouldLoadPlugin(const FilePath& filename);
+ bool ShouldLoadPlugin(const std::string& filename);
// Load internal plugins. Right now there is only one: activex_shim.
void LoadInternalPlugins();
- // Find a plugin by filename. Returns -1 if it's not found, otherwise its
- // index in plugins_.
- int FindPluginFile(const std::wstring& filename);
+ // Find a plugin by mime type, and clsid.
+ // If clsid is empty, we will just find the plugin that supports mime type.
+ // Otherwise, if mime_type is application/x-oleobject etc that's supported by
+ // by our activex shim, we need to check if the specified ActiveX exists.
+ // If not we will not return the activex shim, instead we will let the
+ // default plugin handle activex installation.
+ // The allow_wildcard parameter controls whether this function returns
+ // plugins which support wildcard mime types (* as the mime type)
+ bool FindPlugin(const std::string &mime_type, const std::string& clsid,
+ bool allow_wildcard, WebPluginInfo* info);
+
+ // Find a plugin by extension. Returns the corresponding mime type.
+ bool FindPlugin(const GURL &url, std::string* actual_mime_type,
+ WebPluginInfo* info);
+
+ // Returns true if the given WebPluginInfo supports "mime-type".
+ // mime_type should be all lower case.
+ static bool SupportsType(const WebPluginInfo& info,
+ const std::string &mime_type,
+ bool allow_wildcard);
+
+ // Returns true if the given WebPluginInfo supports a given file extension.
+ // extension should be all lower case.
+ // If mime_type is not NULL, it will be set to the mime type if found.
+ // The mime type which corresponds to the extension is optionally returned
+ // back.
+ static bool SupportsExtension(const WebPluginInfo& info,
+ const std::string &extension,
+ std::string* actual_mime_type);
// The application path where we expect to find plugins.
static FilePath GetPluginAppDirectory();
@@ -169,7 +165,10 @@ class PluginList : public base::RefCounted<PluginList> {
static scoped_refptr<PluginList> singleton_;
bool plugins_loaded_;
- std::vector<scoped_refptr<PluginLib> > plugins_;
+
+ // Maps from the name of the plugin file (NOT path) to WebPluginInfo.
+ typedef base::hash_map<std::string, WebPluginInfo> PluginMap;
+ PluginMap plugins_;
DISALLOW_EVIL_CONSTRUCTORS(PluginList);
};
diff --git a/webkit/glue/plugins/webplugin_delegate_impl.cc b/webkit/glue/plugins/webplugin_delegate_impl.cc
index 364ae10..9819132 100644
--- a/webkit/glue/plugins/webplugin_delegate_impl.cc
+++ b/webkit/glue/plugins/webplugin_delegate_impl.cc
@@ -145,16 +145,16 @@ WebPluginDelegateImpl::WebPluginDelegateImpl(
memset(&window_, 0, sizeof(window_));
const WebPluginInfo& plugin_info = instance_->plugin_lib()->plugin_info();
- std::wstring filename = plugin_info.file.BaseName().value();
+ std::string filename = StringToLowerASCII(plugin_info.filename);
if (instance_->mime_type() == "application/x-shockwave-flash" ||
- filename == L"npswf32.dll") {
+ filename == "npswf32.dll") {
// Flash only requests windowless plugins if we return a Mozilla user
// agent.
instance_->set_use_mozilla_user_agent();
quirks_ |= PLUGIN_QUIRK_THROTTLE_WM_USER_PLUS_ONE;
quirks_ |= PLUGIN_QUIRK_PATCH_SETCURSOR;
- } else if (filename == L"nppdf32.dll") {
+ } else if (filename == "nppdf32.dll") {
// Check for the version number above or equal 9.
std::vector<std::wstring> version;
SplitString(plugin_info.version, L'.', &version);
@@ -169,7 +169,7 @@ WebPluginDelegateImpl::WebPluginDelegateImpl(
// Windows Media Player needs two NPP_SetWindow calls.
quirks_ |= PLUGIN_QUIRK_SETWINDOW_TWICE;
} else if (instance_->mime_type() == "audio/x-pn-realaudio-plugin" ||
- filename == L"nppl3260.dll") {
+ filename == "nppl3260.dll") {
quirks_ |= PLUGIN_QUIRK_DONT_CALL_WND_PROC_RECURSIVELY;
} else if (plugin_info.name.find(L"VLC Multimedia Plugin") !=
std::wstring::npos) {
@@ -178,14 +178,14 @@ WebPluginDelegateImpl::WebPluginDelegateImpl(
quirks_ |= PLUGIN_QUIRK_DONT_SET_NULL_WINDOW_HANDLE_ON_DESTROY;
// VLC 0.8.6d and 0.8.6e crash if multiple instances are created.
quirks_ |= PLUGIN_QUIRK_DONT_ALLOW_MULTIPLE_INSTANCES;
- } else if (filename == L"npctrl.dll") {
+ } else if (filename == "npctrl.dll") {
// Explanation for this quirk can be found in
// WebPluginDelegateImpl::Initialize.
quirks_ |= PLUGIN_QUIRK_PATCH_TRACKPOPUP_MENU;
quirks_ |= PLUGIN_QUIRK_PATCH_SETCURSOR;
}
- plugin_module_handle_ = ::GetModuleHandle(filename.c_str());
+ plugin_module_handle_ = ::GetModuleHandle(plugin_info.path.value().c_str());
}
WebPluginDelegateImpl::~WebPluginDelegateImpl() {
@@ -393,7 +393,7 @@ void WebPluginDelegateImpl::DidManualLoadFail() {
}
FilePath WebPluginDelegateImpl::GetPluginPath() {
- return instance()->plugin_lib()->plugin_info().file;
+ return instance()->plugin_lib()->plugin_info().path;
}
void WebPluginDelegateImpl::InstallMissingPlugin() {
diff --git a/webkit/glue/webplugin.h b/webkit/glue/webplugin.h
index 96807fb..a0ac200 100644
--- a/webkit/glue/webplugin.h
+++ b/webkit/glue/webplugin.h
@@ -39,8 +39,13 @@ struct WebPluginInfo {
// The name of the plugin (i.e. Flash).
std::wstring name;
+ // The UTF8 filename of the plugin, without the path. This may be in a
+ // different case than FilePath on some systems. On Windows this comes from
+ // the DLL's version information.
+ std::string filename;
+
// The path to the plugin file (DLL/bundle/library).
- FilePath file;
+ FilePath path;
// The version number of the plugin file (may be OS-specific)
std::wstring version;