summaryrefslogtreecommitdiffstats
path: root/webkit/glue/plugins/plugin_list.cc
diff options
context:
space:
mode:
Diffstat (limited to 'webkit/glue/plugins/plugin_list.cc')
-rw-r--r--webkit/glue/plugins/plugin_list.cc311
1 files changed, 234 insertions, 77 deletions
diff --git a/webkit/glue/plugins/plugin_list.cc b/webkit/glue/plugins/plugin_list.cc
index b2a7634..4b3ce27 100644
--- a/webkit/glue/plugins/plugin_list.cc
+++ b/webkit/glue/plugins/plugin_list.cc
@@ -11,6 +11,7 @@
#include "base/logging.h"
#include "base/string_split.h"
#include "base/string_util.h"
+#include "base/sys_string_conversions.h"
#include "base/utf_string_conversions.h"
#include "googleurl/src/gurl.h"
#include "net/base/mime_util.h"
@@ -23,12 +24,19 @@ namespace NPAPI {
base::LazyInstance<PluginList> g_singleton(base::LINKER_INITIALIZED);
+static LoadPluginsFromDiskHookFunc g_load_plugins_hook;
+
// static
PluginList* PluginList::Singleton() {
return g_singleton.Pointer();
}
// static
+void PluginList::SetPluginLoadHook(LoadPluginsFromDiskHookFunc hook) {
+ g_load_plugins_hook = hook;
+}
+
+// static
bool PluginList::DebugPluginLoading() {
return CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDebugPluginLoading);
@@ -108,9 +116,9 @@ bool PluginList::CreateWebPluginInfo(const PluginVersionInfo& pvi,
WebPluginInfo* info) {
std::vector<std::string> mime_types, file_extensions;
std::vector<string16> descriptions;
- SplitString(WideToUTF8(pvi.mime_types), '|', &mime_types);
- SplitString(WideToUTF8(pvi.file_extensions), '|', &file_extensions);
- SplitString(WideToUTF16(pvi.type_descriptions), '|', &descriptions);
+ base::SplitString(WideToUTF8(pvi.mime_types), '|', &mime_types);
+ base::SplitString(WideToUTF8(pvi.file_extensions), '|', &file_extensions);
+ base::SplitString(WideToUTF16(pvi.type_descriptions), '|', &descriptions);
info->mime_types.clear();
@@ -130,7 +138,7 @@ bool PluginList::CreateWebPluginInfo(const PluginVersionInfo& pvi,
WebPluginMimeType mime_type;
mime_type.mime_type = StringToLowerASCII(mime_types[i]);
if (file_extensions.size() > i)
- SplitString(file_extensions[i], ',', &mime_type.file_extensions);
+ base::SplitString(file_extensions[i], ',', &mime_type.file_extensions);
if (descriptions.size() > i) {
mime_type.description = descriptions[i];
@@ -154,10 +162,21 @@ bool PluginList::CreateWebPluginInfo(const PluginVersionInfo& pvi,
}
PluginList::PluginList()
- : plugins_loaded_(false), plugins_need_refresh_(false) {
+ : plugins_loaded_(false),
+ plugins_need_refresh_(false),
+ disable_outdated_plugins_(false) {
PlatformInit();
}
+bool PluginList::ShouldDisableGroup(const string16& group_name) {
+ AutoLock lock(lock_);
+ if (PluginGroup::IsPluginNameDisabledByPolicy(group_name)) {
+ disabled_groups_.insert(group_name);
+ return true;
+ }
+ return disabled_groups_.count(group_name) > 0;
+}
+
void PluginList::LoadPlugins(bool refresh) {
// Don't want to hold the lock while loading new plugins, so we don't block
// other methods if they're called on other threads.
@@ -177,6 +196,9 @@ void PluginList::LoadPlugins(bool refresh) {
internal_plugins = internal_plugins_;
}
+ if (g_load_plugins_hook)
+ g_load_plugins_hook();
+
std::vector<WebPluginInfo> new_plugins;
std::set<FilePath> visited_plugins;
@@ -216,15 +238,37 @@ void PluginList::LoadPlugins(bool refresh) {
if (webkit_glue::IsDefaultPluginEnabled())
LoadPlugin(FilePath(kDefaultPluginLibraryName), &new_plugins);
+ // Disable all of the plugins and plugin groups that are disabled by policy.
+ // There's currenly a bug that makes it impossible to correctly re-enable
+ // plugins or plugin-groups to their original, "pre-policy" state, so
+ // plugins and groups are only changed to a more "safe" state after a policy
+ // change, i.e. from enabled to disabled. See bug 54681.
+ PluginMap plugin_groups;
+ GetPluginGroups(&new_plugins, &plugin_groups);
+ for (PluginMap::const_iterator it = plugin_groups.begin();
+ it != plugin_groups.end(); ++it) {
+ PluginGroup* group = it->second.get();
+ string16 group_name = group->GetGroupName();
+ if (ShouldDisableGroup(group_name)) {
+ it->second->Enable(false);
+ }
+
+ if (disable_outdated_plugins_) {
+ group->DisableOutdatedPlugins();
+ if (!group->Enabled()) {
+ AutoLock lock(lock_);
+ disabled_groups_.insert(group_name);
+ }
+ }
+ }
+
// Only update the data now since loading plugins can take a while.
AutoLock lock(lock_);
- // Go through and mark new plugins in the disabled list as, well, disabled.
- for (std::vector<WebPluginInfo>::iterator it = new_plugins.begin();
- it != new_plugins.end();
- ++it) {
- if (disabled_plugins_.find(it->path) != disabled_plugins_.end())
- it->enabled = false;
+ // Mark disabled plugins as such.
+ for (size_t i = 0; i < new_plugins.size(); ++i) {
+ if (disabled_plugins_.count(new_plugins[i].path))
+ new_plugins[i].enabled = false;
}
plugins_ = new_plugins;
@@ -263,65 +307,6 @@ void PluginList::LoadPlugin(const FilePath& path,
plugins->push_back(plugin_info);
}
-bool PluginList::FindPlugin(const std::string& mime_type,
- bool allow_wildcard,
- WebPluginInfo* info) {
- DCHECK(mime_type == StringToLowerASCII(mime_type));
-
- LoadPlugins(false);
- AutoLock lock(lock_);
- for (size_t i = 0; i < plugins_.size(); ++i) {
- if (plugins_[i].enabled &&
- SupportsType(plugins_[i], mime_type, allow_wildcard)) {
- *info = plugins_[i];
- return true;
- }
- }
-
- return false;
-}
-
-bool PluginList::FindDisabledPlugin(const std::string& mime_type,
- bool allow_wildcard,
- WebPluginInfo* info) {
- DCHECK(mime_type == StringToLowerASCII(mime_type));
-
- LoadPlugins(false);
- AutoLock lock(lock_);
- for (size_t i = 0; i < plugins_.size(); ++i) {
- if (!plugins_[i].enabled &&
- SupportsType(plugins_[i], mime_type, allow_wildcard)) {
- *info = plugins_[i];
- return true;
- }
- }
-
- return false;
-}
-
-bool PluginList::FindPlugin(const GURL &url,
- std::string* actual_mime_type,
- WebPluginInfo* info) {
- LoadPlugins(false);
- AutoLock lock(lock_);
- std::string path = url.path();
- std::string::size_type last_dot = path.rfind('.');
- if (last_dot == std::string::npos)
- return false;
-
- std::string extension = StringToLowerASCII(std::string(path, last_dot+1));
-
- for (size_t i = 0; i < plugins_.size(); ++i) {
- if (plugins_[i].enabled &&
- SupportsExtension(plugins_[i], extension, actual_mime_type)) {
- *info = plugins_[i];
- return true;
- }
- }
-
- return false;
-}
-
bool PluginList::SupportsType(const WebPluginInfo& info,
const std::string &mime_type,
bool allow_wildcard) {
@@ -380,20 +365,111 @@ void PluginList::GetEnabledPlugins(bool refresh,
}
}
+void PluginList::GetPluginInfoArray(const GURL& url,
+ const std::string& mime_type,
+ bool allow_wildcard,
+ std::vector<WebPluginInfo>* info,
+ std::vector<std::string>* actual_mime_types)
+{
+ DCHECK(mime_type == StringToLowerASCII(mime_type));
+ DCHECK(info);
+
+ LoadPlugins(false);
+ AutoLock lock(lock_);
+ info->clear();
+ if (actual_mime_types)
+ actual_mime_types->clear();
+
+ std::set<FilePath> visited_plugins;
+
+ // Add in enabled plugins by mime type.
+ WebPluginInfo default_plugin;
+ for (size_t i = 0; i < plugins_.size(); ++i) {
+ if (plugins_[i].enabled &&
+ SupportsType(plugins_[i], mime_type, allow_wildcard)) {
+ FilePath path = plugins_[i].path;
+ if (path.value() != kDefaultPluginLibraryName &&
+ visited_plugins.insert(path).second) {
+ info->push_back(plugins_[i]);
+ if (actual_mime_types)
+ actual_mime_types->push_back(mime_type);
+ }
+ }
+ }
+
+ // Add in enabled plugins by url.
+ std::string path = url.path();
+ std::string::size_type last_dot = path.rfind('.');
+ if (last_dot != std::string::npos) {
+ std::string extension = StringToLowerASCII(std::string(path, last_dot+1));
+ std::string actual_mime_type;
+ for (size_t i = 0; i < plugins_.size(); ++i) {
+ if (plugins_[i].enabled &&
+ SupportsExtension(plugins_[i], extension, &actual_mime_type)) {
+ FilePath path = plugins_[i].path;
+ if (path.value() != kDefaultPluginLibraryName &&
+ visited_plugins.insert(path).second) {
+ info->push_back(plugins_[i]);
+ if (actual_mime_types)
+ actual_mime_types->push_back(actual_mime_type);
+ }
+ }
+ }
+ }
+
+ // Add in disabled plugins by mime type.
+ for (size_t i = 0; i < plugins_.size(); ++i) {
+ if (!plugins_[i].enabled &&
+ SupportsType(plugins_[i], mime_type, allow_wildcard)) {
+ FilePath path = plugins_[i].path;
+ if (path.value() != kDefaultPluginLibraryName &&
+ visited_plugins.insert(path).second) {
+ info->push_back(plugins_[i]);
+ if (actual_mime_types)
+ actual_mime_types->push_back(mime_type);
+ }
+ }
+ }
+
+ // Add the default plugin at the end if it supports the mime type given,
+ // and the default plugin is enabled.
+ if (!plugins_.empty() && webkit_glue::IsDefaultPluginEnabled()) {
+ const WebPluginInfo& default_info = plugins_.back();
+ if (SupportsType(default_info, mime_type, allow_wildcard)) {
+ info->push_back(default_info);
+ if (actual_mime_types)
+ actual_mime_types->push_back(mime_type);
+ }
+ }
+}
+
bool PluginList::GetPluginInfo(const GURL& url,
const std::string& mime_type,
bool allow_wildcard,
WebPluginInfo* info,
std::string* actual_mime_type) {
- bool found = FindPlugin(mime_type, allow_wildcard, info);
- if (!found || (info->path.value() == kDefaultPluginLibraryName)) {
- if (FindPlugin(url, actual_mime_type, info) ||
- FindDisabledPlugin(mime_type, allow_wildcard, info)) {
- found = true;
+ DCHECK(info);
+ std::vector<WebPluginInfo> info_list;
+
+ // GetPluginInfoArray has slightly less work to do if we can pass
+ // NULL for the mime type list...
+ if (actual_mime_type) {
+ std::vector<std::string> mime_type_list;
+ GetPluginInfoArray(
+ url, mime_type, allow_wildcard, &info_list, &mime_type_list);
+ if (!info_list.empty()) {
+ *info = info_list[0];
+ *actual_mime_type = mime_type_list[0];
+ return true;
+ }
+ } else {
+ GetPluginInfoArray(url, mime_type, allow_wildcard, &info_list, NULL);
+ if (!info_list.empty()) {
+ *info = info_list[0];
+ return true;
}
}
-
- return found;
+ return false;
}
bool PluginList::GetPluginInfoByPath(const FilePath& plugin_path,
@@ -410,6 +486,47 @@ bool PluginList::GetPluginInfoByPath(const FilePath& plugin_path,
return false;
}
+void PluginList::GetPluginGroups(bool load_if_necessary,
+ PluginMap* plugin_groups) {
+ if (load_if_necessary)
+ LoadPlugins(false);
+
+ AutoLock lock(lock_);
+ GetPluginGroups(&plugins_, plugin_groups);
+}
+
+// static
+void PluginList::GetPluginGroups(const std::vector<WebPluginInfo>* plugins,
+ PluginMap* plugin_groups) {
+ plugin_groups->clear();
+ // We first search for an existing group that matches our name,
+ // and only create a new group if we can't find any.
+ for (size_t i = 0; i < plugins->size(); ++i) {
+ const WebPluginInfo& web_plugin = (*plugins)[i];
+ PluginGroup* group = PluginGroup::FindGroupMatchingPlugin(
+ *plugin_groups, web_plugin);
+ if (!group) {
+ group = PluginGroup::CopyOrCreatePluginGroup(web_plugin);
+ std::string identifier = group->identifier();
+ // If the identifier is not unique, use the full path. This means that we
+ // probably won't be able to search for this group by identifier, but at
+ // least it's going to be in the set of plugin groups, and if there
+ // is already a plug-in with the same filename, it's probably going to
+ // handle the same MIME types (and it has a higher priority), so this one
+ // is not going to run anyway.
+ if (plugin_groups->find(identifier) != plugin_groups->end())
+#if defined(OS_POSIX)
+ identifier = web_plugin.path.value();
+#elif defined(OS_WIN)
+ identifier = base::SysWideToUTF8(web_plugin.path.value());
+#endif
+ DCHECK(plugin_groups->find(identifier) == plugin_groups->end());
+ (*plugin_groups)[identifier] = linked_ptr<PluginGroup>(group);
+ }
+ group->AddPlugin(web_plugin, i);
+ }
+}
+
bool PluginList::EnablePlugin(const FilePath& filename) {
AutoLock lock(lock_);
@@ -459,6 +576,46 @@ bool PluginList::DisablePlugin(const FilePath& filename) {
return did_disable;
}
+bool PluginList::EnableGroup(bool enable, const string16& group_name) {
+ bool did_change = false;
+ {
+ AutoLock lock(lock_);
+
+ std::set<string16>::iterator entry = disabled_groups_.find(group_name);
+ if (enable) {
+ if (entry == disabled_groups_.end())
+ return did_change; // Early exit if group not in disabled list.
+ disabled_groups_.erase(entry); // Remove from disabled list.
+ } else {
+ if (entry != disabled_groups_.end())
+ return did_change; // Early exit if group already in disabled list.
+ disabled_groups_.insert(group_name);
+ }
+ }
+
+ PluginMap plugin_groups;
+ GetPluginGroups(false, &plugin_groups);
+ for (PluginMap::const_iterator it = plugin_groups.begin();
+ it != plugin_groups.end(); ++it) {
+ if (it->second->GetGroupName() == group_name) {
+ if (it->second->Enabled() != enable) {
+ it->second->Enable(enable);
+ did_change = true;
+ break;
+ }
+ }
+ }
+
+ return did_change;
+}
+
+void PluginList::DisableOutdatedPluginGroups() {
+ disable_outdated_plugins_ = true;
+}
+
+PluginList::~PluginList() {
+}
+
void PluginList::Shutdown() {
// TODO
}