summaryrefslogtreecommitdiffstats
path: root/webkit
diff options
context:
space:
mode:
authorpastarmovj@chromium.org <pastarmovj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-01-24 17:37:12 +0000
committerpastarmovj@chromium.org <pastarmovj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-01-24 17:37:12 +0000
commitb83ff229cfe2c15a6dab2278acf7d328645470a5 (patch)
treea1b9183bbb3c9aaa91364b5e15c22115336b9786 /webkit
parent77d13338e12da7ac2c177f4da53b9293850ff357 (diff)
downloadchromium_src-b83ff229cfe2c15a6dab2278acf7d328645470a5.zip
chromium_src-b83ff229cfe2c15a6dab2278acf7d328645470a5.tar.gz
chromium_src-b83ff229cfe2c15a6dab2278acf7d328645470a5.tar.bz2
Refactor the plugin lists handling code.
Effects of this refactor: 1. The WebPluginInfo now keep information not only if a plugin is disabled but also the reason for that. It can either be user, policy or both. That way we can restore the right value after policies stop to control the feature. 2. Plugins can be correctly enabled and disabled either as a group or separately. 3. The code is cleaner and PluginGroup is not duplicating information from PluginList but stores all needed information and provides it through cleaner interface. BUG=54681,66505,69374,69148 TEST=Manual for the policy. DefaultPluginUITest.DefaultPluginLoadTest from ui_tests and Plugin* from test_shell_tests. Review URL: http://codereview.chromium.org/5699005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@72341 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit')
-rw-r--r--webkit/plugins/npapi/plugin_group.cc262
-rw-r--r--webkit/plugins/npapi/plugin_group.h70
-rw-r--r--webkit/plugins/npapi/plugin_group_unittest.cc41
-rw-r--r--webkit/plugins/npapi/plugin_lib_mac.mm4
-rw-r--r--webkit/plugins/npapi/plugin_lib_posix.cc2
-rw-r--r--webkit/plugins/npapi/plugin_lib_win.cc2
-rw-r--r--webkit/plugins/npapi/plugin_list.cc462
-rw-r--r--webkit/plugins/npapi/plugin_list.h102
-rw-r--r--webkit/plugins/npapi/plugin_list_mac.mm16
-rw-r--r--webkit/plugins/npapi/plugin_list_posix.cc28
-rw-r--r--webkit/plugins/npapi/plugin_list_unittest.cc211
-rw-r--r--webkit/plugins/npapi/plugin_list_win.cc62
-rw-r--r--webkit/plugins/npapi/webplugininfo.cc14
-rw-r--r--webkit/plugins/npapi/webplugininfo.h33
-rw-r--r--webkit/support/webkit_support.cc2
-rw-r--r--webkit/tools/test_shell/test_shell.gypi1
-rw-r--r--webkit/tools/test_shell/test_webview_delegate.cc2
17 files changed, 873 insertions, 441 deletions
diff --git a/webkit/plugins/npapi/plugin_group.cc b/webkit/plugins/npapi/plugin_group.cc
index dd80652..bbf5cdc 100644
--- a/webkit/plugins/npapi/plugin_group.cc
+++ b/webkit/plugins/npapi/plugin_group.cc
@@ -47,21 +47,6 @@ bool PluginGroup::IsPluginNameDisabledByPolicy(const string16& plugin_name) {
return false;
}
-/*static*/
-bool PluginGroup::IsPluginPathDisabledByPolicy(const FilePath& plugin_path) {
- std::vector<WebPluginInfo> plugins;
- PluginList::Singleton()->GetPlugins(false, &plugins);
- for (std::vector<WebPluginInfo>::const_iterator it = plugins.begin();
- it != plugins.end();
- ++it) {
- if (FilePath::CompareEqualIgnoreCase(it->path.value(),
- plugin_path.value()) && IsPluginNameDisabledByPolicy(it->name)) {
- return true;
- }
- }
- return false;
-}
-
VersionRange::VersionRange(VersionRangeDefinition definition)
: low_str(definition.version_matcher_low),
high_str(definition.version_matcher_high),
@@ -102,7 +87,7 @@ PluginGroup::PluginGroup(const string16& group_name,
group_name_(group_name),
name_matcher_(name_matcher),
update_url_(update_url),
- enabled_(false),
+ enabled_(true),
version_(Version::GetVersionFromString("0")) {
}
@@ -116,7 +101,6 @@ void PluginGroup::InitFrom(const PluginGroup& other) {
version_ranges_ = other.version_ranges_;
version_.reset(other.version_->Clone());
web_plugin_infos_ = other.web_plugin_infos_;
- web_plugin_positions_ = other.web_plugin_positions_;
}
PluginGroup::PluginGroup(const PluginGroup& other) {
@@ -214,12 +198,15 @@ Version* PluginGroup::CreateVersionFromString(const string16& version_string) {
void PluginGroup::UpdateActivePlugin(const WebPluginInfo& plugin) {
// A group is enabled if any of the files are enabled.
- if (plugin.enabled) {
- if (!enabled_) {
- // If this is the first enabled plugin, use its description.
- enabled_ = true;
+ if (IsPluginEnabled(plugin)) {
+ // The description of the group needs update either when it's state is
+ // about to change to enabled or if has never been set.
+ if (!enabled_ || description_.empty())
UpdateDescriptionAndVersion(plugin);
- }
+ // In case an enabled plugin has been added to a group that is currently
+ // disabled then we should enable the group.
+ if (!enabled_)
+ enabled_ = true;
} else {
// If this is the first plugin and it's disabled,
// use its description for now.
@@ -236,24 +223,61 @@ void PluginGroup::UpdateDescriptionAndVersion(const WebPluginInfo& plugin) {
version_.reset(Version::GetVersionFromString("0"));
}
-void PluginGroup::AddPlugin(const WebPluginInfo& plugin, int position) {
+void PluginGroup::AddPlugin(const WebPluginInfo& plugin) {
// Check if this group already contains this plugin.
for (size_t i = 0; i < web_plugin_infos_.size(); ++i) {
- if (web_plugin_infos_[i].name == plugin.name &&
- web_plugin_infos_[i].version == plugin.version &&
- FilePath::CompareEqualIgnoreCase(web_plugin_infos_[i].path.value(),
+ if (FilePath::CompareEqualIgnoreCase(web_plugin_infos_[i].path.value(),
plugin.path.value())) {
return;
}
}
web_plugin_infos_.push_back(plugin);
- // The position of this plugin relative to the global list of plugins.
- web_plugin_positions_.push_back(position);
- UpdateActivePlugin(plugin);
+ // If the group is disabled disable new plugins in it too. This should cover
+ // the case where a plugin has been upgraded that has been disabled and should
+ // stay disabled after the upgrade.
+ if (!enabled_)
+ DisablePlugin(web_plugin_infos_.back().path);
+ UpdateActivePlugin(web_plugin_infos_.back());
+ RefreshEnabledState();
}
-bool PluginGroup::IsEmpty() const {
- return web_plugin_infos_.empty();
+bool PluginGroup::RemovePlugin(const FilePath& filename) {
+ for (size_t i = 0; i < web_plugin_infos_.size(); ++i) {
+ if (web_plugin_infos_[i].path == filename) {
+ web_plugin_infos_.erase(web_plugin_infos_.begin() + i);
+ return true;
+ }
+ }
+ return false;
+}
+
+bool PluginGroup::EnablePlugin(const FilePath& filename) {
+ for (size_t i = 0; i < web_plugin_infos_.size(); ++i) {
+ if (web_plugin_infos_[i].path == filename) {
+ bool did_enable = Enable(&web_plugin_infos_[i],
+ WebPluginInfo::USER_ENABLED);
+ RefreshEnabledState();
+ return did_enable;
+ }
+ }
+ return false;
+}
+
+bool PluginGroup::DisablePlugin(const FilePath& filename) {
+ for (size_t i = 0; i < web_plugin_infos_.size(); ++i) {
+ if (web_plugin_infos_[i].path == filename) {
+ // We are only called for user intervention however we should respect a
+ // policy that might as well be active on this plugin.
+ bool did_disable = Disable(
+ &web_plugin_infos_[i],
+ IsPluginNameDisabledByPolicy(web_plugin_infos_[i].name) ?
+ WebPluginInfo::USER_DISABLED_POLICY_DISABLED :
+ WebPluginInfo::USER_DISABLED);
+ RefreshEnabledState();
+ return did_disable;
+ }
+ }
+ return false;
}
string16 PluginGroup::GetGroupName() const {
@@ -269,6 +293,15 @@ string16 PluginGroup::GetGroupName() const {
#endif
}
+bool PluginGroup::ContainsPlugin(const FilePath& path) const {
+ for (size_t i = 0; i < web_plugin_infos_.size(); ++i) {
+ if (web_plugin_infos_[i].path == path)
+ return true;
+ }
+ return false;
+}
+
+
DictionaryValue* PluginGroup::GetSummary() const {
DictionaryValue* result = new DictionaryValue();
result->SetString("name", GetGroupName());
@@ -289,40 +322,35 @@ DictionaryValue* PluginGroup::GetDataForUI() const {
ListValue* plugin_files = new ListValue();
bool all_plugins_disabled_by_policy = true;
for (size_t i = 0; i < web_plugin_infos_.size(); ++i) {
- const WebPluginInfo& web_plugin = web_plugin_infos_[i];
- int priority = web_plugin_positions_[i];
DictionaryValue* plugin_file = new DictionaryValue();
- plugin_file->SetString("name", web_plugin.name);
- plugin_file->SetString("description", web_plugin.desc);
- plugin_file->SetString("path", web_plugin.path.value());
- plugin_file->SetString("version", web_plugin.version);
+ plugin_file->SetString("name", web_plugin_infos_[i].name);
+ plugin_file->SetString("description", web_plugin_infos_[i].desc);
+ plugin_file->SetString("path", web_plugin_infos_[i].path.value());
+ plugin_file->SetString("version", web_plugin_infos_[i].version);
bool plugin_disabled_by_policy = group_disabled_by_policy ||
- IsPluginNameDisabledByPolicy(web_plugin.name);
+ ((web_plugin_infos_[i].enabled & WebPluginInfo::POLICY_DISABLED) != 0);
if (plugin_disabled_by_policy) {
plugin_file->SetString("enabledMode", "disabledByPolicy");
} else {
all_plugins_disabled_by_policy = false;
- plugin_file->SetString("enabledMode",
- web_plugin.enabled ? "enabled" : "disabledByUser");
+ plugin_file->SetString(
+ "enabledMode", IsPluginEnabled(web_plugin_infos_[i]) ?
+ "enabled" : "disabledByUser");
}
- plugin_file->SetInteger("priority", priority);
ListValue* mime_types = new ListValue();
- for (std::vector<WebPluginMimeType>::const_iterator type_it =
- web_plugin.mime_types.begin();
- type_it != web_plugin.mime_types.end();
- ++type_it) {
+ const std::vector<WebPluginMimeType>& plugin_mime_types =
+ web_plugin_infos_[i].mime_types;
+ for (size_t j = 0; j < plugin_mime_types.size(); ++j) {
DictionaryValue* mime_type = new DictionaryValue();
- mime_type->SetString("mimeType", type_it->mime_type);
- mime_type->SetString("description", type_it->description);
+ mime_type->SetString("mimeType", plugin_mime_types[j].mime_type);
+ mime_type->SetString("description", plugin_mime_types[j].description);
ListValue* file_extensions = new ListValue();
- for (std::vector<std::string>::const_iterator ext_it =
- type_it->file_extensions.begin();
- ext_it != type_it->file_extensions.end();
- ++ext_it) {
- file_extensions->Append(new StringValue(*ext_it));
- }
+ const std::vector<std::string>& mime_file_extensions =
+ plugin_mime_types[j].file_extensions;
+ for (size_t k = 0; k < mime_file_extensions.size(); ++k)
+ file_extensions->Append(new StringValue(mime_file_extensions[k]));
mime_type->Set("fileExtensions", file_extensions);
mime_types->Append(mime_type);
@@ -373,42 +401,130 @@ bool PluginGroup::IsVulnerable() const {
return false;
}
+bool PluginGroup::IsEmpty() const {
+ return web_plugin_infos_.size() == 0;
+}
+
void PluginGroup::DisableOutdatedPlugins() {
- description_ = string16();
- enabled_ = false;
+ bool first_enabled = true;
- for (std::vector<WebPluginInfo>::iterator it =
- web_plugin_infos_.begin();
- it != web_plugin_infos_.end(); ++it) {
- scoped_ptr<Version> version(CreateVersionFromString(it->version));
+ for (size_t i = 0; i < web_plugin_infos_.size(); ++i) {
+ scoped_ptr<Version> version(
+ CreateVersionFromString(web_plugin_infos_[i].version));
if (version.get()) {
- for (size_t i = 0; i < version_ranges_.size(); ++i) {
- if (IsPluginOutdated(*version, version_ranges_[i])) {
- it->enabled = false;
- PluginList::Singleton()->DisablePlugin(it->path);
+ bool plugin_is_outdated = false;
+ for (size_t j = 0; j < version_ranges_.size(); ++j) {
+ if (IsPluginOutdated(*version, version_ranges_[j])) {
+ Disable(&web_plugin_infos_[i], WebPluginInfo::USER_DISABLED);
+ plugin_is_outdated = true;
+ break;
}
}
+ if (!plugin_is_outdated && first_enabled) {
+ first_enabled = false;
+ UpdateDescriptionAndVersion(web_plugin_infos_[i]);
+ }
}
- UpdateActivePlugin(*it);
}
}
-void PluginGroup::Enable(bool enable) {
+bool PluginGroup::EnableGroup(bool enable) {
bool enabled_plugin_exists = false;
- for (std::vector<WebPluginInfo>::iterator it =
- web_plugin_infos_.begin();
- it != web_plugin_infos_.end(); ++it) {
- if (enable && !IsPluginNameDisabledByPolicy(it->name)) {
- PluginList::Singleton()->EnablePlugin(it->path);
- it->enabled = true;
+ bool group_disabled_by_policy = IsPluginNameDisabledByPolicy(group_name_);
+ // We can't enable groups disabled by policy
+ if (group_disabled_by_policy && enable)
+ return false;
+
+ for (size_t i = 0; i < web_plugin_infos_.size(); ++i) {
+ bool policy_disabled =
+ IsPluginNameDisabledByPolicy(web_plugin_infos_[i].name);
+ if (enable && !policy_disabled) {
+ Enable(&web_plugin_infos_[i], WebPluginInfo::USER_ENABLED);
enabled_plugin_exists = true;
} else {
- it->enabled = false;
- PluginList::Singleton()->DisablePlugin(it->path);
+ Disable(&web_plugin_infos_[i],
+ policy_disabled || group_disabled_by_policy ?
+ WebPluginInfo::POLICY_DISABLED :
+ WebPluginInfo::USER_DISABLED);
+ }
+ }
+ enabled_ = enabled_plugin_exists;
+ return enabled_ == enable;
+}
+
+void PluginGroup::EnforceGroupPolicy() {
+ bool enabled_plugin_exists = false;
+ bool group_disabled_by_policy = IsPluginNameDisabledByPolicy(group_name_);
+
+ for (size_t i = 0; i < web_plugin_infos_.size(); ++i) {
+ bool policy_disabled =
+ IsPluginNameDisabledByPolicy(web_plugin_infos_[i].name) |
+ group_disabled_by_policy;
+
+ // TODO(pastarmovj): Add the code for enforcing enabled by policy...
+ if (policy_disabled) {
+ Disable(&web_plugin_infos_[i], WebPluginInfo::POLICY_DISABLED);
+ // ...here would a else if (policy_enabled) { ... } be then.
+ } else {
+ Enable(&web_plugin_infos_[i], WebPluginInfo::POLICY_UNMANAGED);
+ if (IsPluginEnabled(web_plugin_infos_[i]))
+ enabled_plugin_exists = true;
+ }
+ }
+ enabled_ = enabled_plugin_exists;
+}
+
+void PluginGroup::RefreshEnabledState() {
+ bool enabled_plugin_exists = false;
+ for (size_t i = 0; i < web_plugin_infos_.size(); ++i) {
+ if (IsPluginEnabled(web_plugin_infos_[i])) {
+ enabled_plugin_exists = true;
+ break;
}
}
enabled_ = enabled_plugin_exists;
}
+bool PluginGroup::Enable(WebPluginInfo* plugin,
+ int new_reason) {
+ DCHECK(new_reason == WebPluginInfo::USER_ENABLED ||
+ new_reason == WebPluginInfo::POLICY_UNMANAGED ||
+ new_reason == WebPluginInfo::POLICY_ENABLED);
+ // If we are only stripping the policy then mask the policy bits.
+ if (new_reason == WebPluginInfo::POLICY_UNMANAGED) {
+ plugin->enabled &= WebPluginInfo::USER_MASK;
+ return true;
+ }
+ // If already enabled just upgrade the reason.
+ if (IsPluginEnabled(*plugin)) {
+ plugin->enabled |= new_reason;
+ return true;
+ } else {
+ // Only changeable if not managed.
+ if (plugin->enabled & WebPluginInfo::MANAGED_MASK)
+ return false;
+ plugin->enabled = new_reason;
+ }
+ return true;
+}
+
+bool PluginGroup::Disable(WebPluginInfo* plugin,
+ int new_reason) {
+ DCHECK(new_reason == WebPluginInfo::USER_DISABLED ||
+ new_reason == WebPluginInfo::POLICY_DISABLED ||
+ new_reason == WebPluginInfo::USER_DISABLED_POLICY_DISABLED);
+ // If already disabled just upgrade the reason.
+ if (!IsPluginEnabled(*plugin)) {
+ plugin->enabled |= new_reason;
+ return true;
+ } else {
+ // Only changeable if not managed.
+ if (plugin->enabled & WebPluginInfo::MANAGED_MASK)
+ return false;
+ plugin->enabled = new_reason;
+ }
+ return true;
+}
+
} // namespace npapi
} // namespace webkit
diff --git a/webkit/plugins/npapi/plugin_group.h b/webkit/plugins/npapi/plugin_group.h
index d6a2157..cc5ff7c 100644
--- a/webkit/plugins/npapi/plugin_group.h
+++ b/webkit/plugins/npapi/plugin_group.h
@@ -14,6 +14,7 @@
#include "base/gtest_prod_util.h"
#include "base/scoped_ptr.h"
#include "base/string16.h"
+#include "webkit/plugins/npapi/webplugininfo.h"
class DictionaryValue;
class FilePath;
@@ -25,8 +26,9 @@ namespace webkit {
namespace npapi {
class PluginList;
-struct WebPluginInfo;
-
+namespace plugin_test_internal {
+class PluginListWithoutFileIO;
+}
// Hard-coded version ranges for plugin groups.
struct VersionRangeDefinition {
// Matcher for lowest version matched by this range (inclusive). May be empty
@@ -94,22 +96,29 @@ class PluginGroup {
// the lookup key.
static bool IsPluginNameDisabledByPolicy(const string16& plugin_name);
- // Tests to see if a plugin is on the blacklist using its path as
- // the lookup key.
- static bool IsPluginPathDisabledByPolicy(const FilePath& plugin_path);
-
// Returns true if the given plugin matches this group.
bool Match(const WebPluginInfo& plugin) const;
- // Adds the given plugin to this group. Provide the position of the
- // plugin as given by PluginList so we can display its priority.
- void AddPlugin(const WebPluginInfo& plugin, int position);
+ // Adds the given plugin to this group.
+ void AddPlugin(const WebPluginInfo& plugin);
- bool IsEmpty() const;
+ // Removes a plugin from the group by its path.
+ bool RemovePlugin(const FilePath& filename);
+
+ // The two following functions enable/disable a plugin given its filename. The
+ // function returns true if the plugin could be enabled/disabled. Plugins
+ // might not get enabled/disabled if they are controlled by policy or are
+ // already in the wanted state.
+ bool EnablePlugin(const FilePath& filename);
+ bool DisablePlugin(const FilePath& filename);
// Enables/disables this group. This enables/disables all plugins in the
// group.
- void Enable(bool enable);
+ bool EnableGroup(bool enable);
+
+ // Checks whether the group should be disabled/enabled by a policy and puts
+ // it in the needed state. Updates all contained plugins too.
+ void EnforceGroupPolicy();
// Returns whether the plugin group is enabled or not.
bool Enabled() const { return enabled_; }
@@ -118,10 +127,23 @@ class PluginGroup {
// string otherwise.
const std::string& identifier() const { return identifier_; }
+ // Sets a unique identifier for this group or if none is set an empty string.
+ void set_identifier(const std::string& identifier) {
+ identifier_ = identifier;
+ }
+
// Returns this group's name, or the filename without extension if the name
// is empty.
string16 GetGroupName() const;
+ // Returns all plugins added to the group.
+ const std::vector<WebPluginInfo>& web_plugins_info() const {
+ return web_plugin_infos_;
+ }
+
+ // Checks whether a plugin exists in the group with the given path.
+ bool ContainsPlugin(const FilePath& path) const;
+
// Returns the description of the highest-priority plug-in in the group.
const string16& description() const { return description_; }
@@ -138,6 +160,10 @@ class PluginGroup {
// security problems.
bool IsVulnerable() const;
+ // Check if the group has no plugins. Could happen after a reload if the plug-
+ // in has disappeared from the pc (or in the process of updating).
+ bool IsEmpty() const;
+
// Disables all plugins in this group that are older than the
// minimum version.
void DisableOutdatedPlugins();
@@ -149,12 +175,12 @@ class PluginGroup {
std::vector<WebPluginInfo> web_plugin_infos() { return web_plugin_infos_; }
private:
- typedef std::map<std::string, PluginGroup*> PluginMap;
-
friend class PluginList;
+ friend class plugin_test_internal::PluginListWithoutFileIO;
friend class PluginGroupTest;
friend class ::TableModelArrayControllerTest;
friend class ::PluginExceptionsTableModelTest;
+ FRIEND_TEST_ALL_PREFIXES(PluginListTest, DisableOutdated);
// Generates the (short) identifier string for the given plugin.
static std::string GetIdentifier(const WebPluginInfo& wpi);
@@ -196,6 +222,23 @@ class PluginGroup {
// enabled one, or if all plugins are disabled, simply the first one.
void UpdateActivePlugin(const WebPluginInfo& plugin);
+ // Refreshes the enabled flag based on the state of its plugins.
+ void RefreshEnabledState();
+
+ // Enables the plugin if not already enabled and if policy allows it to.
+ // Returns true on success.
+ static bool Enable(WebPluginInfo* plugin, int reason);
+
+ // Disables the plugin if not already disabled and if policy allows it to.
+ // Returns true on success.
+ static bool Disable(WebPluginInfo* plugin, int reason);
+
+ // Returns a non-const vector of all plugins in the group. This is only used
+ // by PluginList.
+ std::vector<WebPluginInfo>& GetPluginsContainer() {
+ return web_plugin_infos_;
+ }
+
static std::set<string16>* policy_disabled_plugin_patterns_;
std::string identifier_;
@@ -207,7 +250,6 @@ class PluginGroup {
std::vector<VersionRange> version_ranges_;
scoped_ptr<Version> version_;
std::vector<WebPluginInfo> web_plugin_infos_;
- std::vector<int> web_plugin_positions_;
};
} // namespace npapi
diff --git a/webkit/plugins/npapi/plugin_group_unittest.cc b/webkit/plugins/npapi/plugin_group_unittest.cc
index 6fc3db2..a4ea89b 100644
--- a/webkit/plugins/npapi/plugin_group_unittest.cc
+++ b/webkit/plugins/npapi/plugin_group_unittest.cc
@@ -92,7 +92,7 @@ TEST(PluginGroupTest, PluginGroupMatch) {
EXPECT_TRUE(group->Match(kPlugin3045));
EXPECT_TRUE(group->Match(kPlugin3045r));
EXPECT_FALSE(group->Match(kPluginNoVersion));
- group->AddPlugin(kPlugin3045, 0);
+ group->AddPlugin(kPlugin3045);
EXPECT_FALSE(group->IsVulnerable());
group.reset(PluginGroupTest::CreatePluginGroup(kPluginDef));
@@ -130,42 +130,26 @@ TEST(PluginGroupTest, PluginGroupDescription) {
scoped_ptr<PluginGroup> group(PluginGroupTest::CreatePluginGroup(
plugindefs[i]));
EXPECT_TRUE(group->Match(plugin3043));
- group->AddPlugin(plugin3043, 0);
+ group->AddPlugin(plugin3043);
EXPECT_EQ(desc3043, group->description());
EXPECT_TRUE(group->IsVulnerable());
EXPECT_TRUE(group->Match(plugin3045));
- group->AddPlugin(plugin3045, 1);
+ group->AddPlugin(plugin3045);
EXPECT_EQ(desc3043, group->description());
EXPECT_TRUE(group->IsVulnerable());
}
-
- {
- // Disable the first plugin.
- plugin3043.enabled = false;
- scoped_ptr<PluginGroup> group(PluginGroupTest::CreatePluginGroup(
- plugindefs[i]));
- EXPECT_TRUE(group->Match(plugin3043));
- group->AddPlugin(plugin3043, 0);
- EXPECT_EQ(desc3043, group->description());
- EXPECT_TRUE(group->IsVulnerable());
- EXPECT_FALSE(group->Enabled());
- EXPECT_TRUE(group->Match(plugin3045));
- group->AddPlugin(plugin3045, 1);
- EXPECT_EQ(desc3045, group->description());
- EXPECT_FALSE(group->IsVulnerable());
- }
-
{
// Disable the second plugin.
- plugin3045.enabled = false;
+ plugin3045.enabled =
+ webkit::npapi::WebPluginInfo::USER_DISABLED_POLICY_UNMANAGED;
scoped_ptr<PluginGroup> group(PluginGroupTest::CreatePluginGroup(
plugindefs[i]));
EXPECT_TRUE(group->Match(plugin3043));
- group->AddPlugin(plugin3043, 1);
+ group->AddPlugin(plugin3043);
EXPECT_EQ(desc3043, group->description());
EXPECT_TRUE(group->IsVulnerable());
EXPECT_TRUE(group->Match(plugin3045));
- group->AddPlugin(plugin3045, 0);
+ group->AddPlugin(plugin3045);
EXPECT_EQ(desc3043, group->description());
EXPECT_TRUE(group->IsVulnerable());
}
@@ -188,8 +172,9 @@ TEST(PluginGroupTest, DisableOutdated) {
for (size_t i = 0; i < 2; ++i) {
scoped_ptr<PluginGroup> group(PluginGroupTest::CreatePluginGroup(
plugindefs[i]));
- group->AddPlugin(kPlugin3043, 0);
- group->AddPlugin(kPlugin3045, 1);
+ group->AddPlugin(kPlugin3043);
+ group->AddPlugin(kPlugin3045);
+
EXPECT_EQ(ASCIIToUTF16("MyPlugin version 3.0.43"), group->description());
EXPECT_TRUE(group->IsVulnerable());
@@ -218,7 +203,7 @@ TEST(PluginGroupTest, VersionExtraction) {
ASCIIToUTF16(versions[i][0]), string16());
scoped_ptr<PluginGroup> group(PluginGroupTest::CreatePluginGroup(plugin));
EXPECT_TRUE(group->Match(plugin));
- group->AddPlugin(plugin, 0);
+ group->AddPlugin(plugin);
scoped_ptr<DictionaryValue> data(group->GetDataForUI());
std::string version;
data->GetString("version", &version);
@@ -256,7 +241,7 @@ TEST(PluginGroupTest, IsVulnerable) {
ASCIIToUTF16("adobe reader 10"));
scoped_ptr<PluginGroup> group(PluginGroupTest::CreatePluginGroup(
adobe_reader_plugin_def));
- group->AddPlugin(adobe_reader_plugin, 0);
+ group->AddPlugin(adobe_reader_plugin);
PluginGroup group_copy(*group); // Exercise the copy constructor.
EXPECT_FALSE(group_copy.IsVulnerable());
@@ -274,7 +259,7 @@ TEST(PluginGroupTest, IsVulnerable) {
ASCIIToUTF16("4.0.50917.0"),
ASCIIToUTF16("silverlight 4"));
group.reset(PluginGroupTest::CreatePluginGroup(silverlight_plugin_def));
- group->AddPlugin(silverlight_plugin, 0);
+ group->AddPlugin(silverlight_plugin);
EXPECT_FALSE(PluginGroup(*group).IsVulnerable());
}
} // namespace npapi
diff --git a/webkit/plugins/npapi/plugin_lib_mac.mm b/webkit/plugins/npapi/plugin_lib_mac.mm
index 6e3a22a..f80e8f2 100644
--- a/webkit/plugins/npapi/plugin_lib_mac.mm
+++ b/webkit/plugins/npapi/plugin_lib_mac.mm
@@ -129,7 +129,7 @@ bool ReadPlistPluginInfo(const FilePath& filename, CFBundleRef bundle,
info->desc = base::SysNSStringToUTF16(plugin_desc);
else
info->desc = UTF8ToUTF16(filename.BaseName().value());
- info->enabled = true;
+ info->enabled = WebPluginInfo::USER_ENABLED;
return true;
}
@@ -223,7 +223,7 @@ bool ReadSTRPluginInfo(const FilePath& filename, CFBundleRef bundle,
info->desc = UTF8ToUTF16(plugin_descs[0]);
else
info->desc = UTF8ToUTF16(filename.BaseName().value());
- info->enabled = true;
+ info->enabled = WebPluginInfo::USER_ENABLED;
return true;
}
diff --git a/webkit/plugins/npapi/plugin_lib_posix.cc b/webkit/plugins/npapi/plugin_lib_posix.cc
index 27f87de..debd457 100644
--- a/webkit/plugins/npapi/plugin_lib_posix.cc
+++ b/webkit/plugins/npapi/plugin_lib_posix.cc
@@ -159,7 +159,7 @@ bool PluginLib::ReadWebPluginInfo(const FilePath& filename,
}
info->path = filename;
- info->enabled = true;
+ info->enabled = WebPluginInfo::USER_ENABLED;
// Attempt to swap in the wrapped plugin if this is nspluginwrapper.
UnwrapNSPluginWrapper(&dl, &info->path);
diff --git a/webkit/plugins/npapi/plugin_lib_win.cc b/webkit/plugins/npapi/plugin_lib_win.cc
index 4b6e361..ccdb4b6 100644
--- a/webkit/plugins/npapi/plugin_lib_win.cc
+++ b/webkit/plugins/npapi/plugin_lib_win.cc
@@ -38,7 +38,7 @@ bool PluginLib::ReadWebPluginInfo(const FilePath &filename,
info->desc = version_info->file_description();
info->version = version_info->file_version();
info->path = filename;
- info->enabled = true;
+ info->enabled = WebPluginInfo::USER_ENABLED_POLICY_UNMANAGED;
// TODO(evan): Move the ParseMimeTypes code inline once Pepper is updated.
if (!PluginList::ParseMimeTypes(
diff --git a/webkit/plugins/npapi/plugin_list.cc b/webkit/plugins/npapi/plugin_list.cc
index 96912d9..ab1b9dc 100644
--- a/webkit/plugins/npapi/plugin_list.cc
+++ b/webkit/plugins/npapi/plugin_list.cc
@@ -9,7 +9,6 @@
#include "base/command_line.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
-#include "base/stl_util-inl.h"
#include "base/string_split.h"
#include "base/string_util.h"
#include "base/sys_string_conversions.h"
@@ -234,7 +233,7 @@ void PluginList::RegisterInternalPlugin(const FilePath& filename,
plugin.info.name = ASCIIToUTF16(name);
plugin.info.version = ASCIIToUTF16("1");
plugin.info.desc = ASCIIToUTF16(description);
- plugin.info.enabled = true;
+ plugin.info.enabled = WebPluginInfo::USER_ENABLED_POLICY_UNMANAGED;
WebPluginMimeType mime_type;
mime_type.mime_type = mime_type_str;
@@ -324,22 +323,12 @@ bool PluginList::ParseMimeTypes(
PluginList::PluginList()
: plugins_loaded_(false),
plugins_need_refresh_(false),
- disable_outdated_plugins_(false),
- next_priority_(0) {
+ disable_outdated_plugins_(false) {
PlatformInit();
AddHardcodedPluginGroups();
}
-bool PluginList::ShouldDisableGroup(const string16& group_name) {
- base::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) {
+void PluginList::LoadPluginsInternal(ScopedVector<PluginGroup>* plugin_groups) {
// 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.
std::vector<FilePath> extra_plugin_paths;
@@ -347,9 +336,6 @@ void PluginList::LoadPlugins(bool refresh) {
std::vector<InternalPlugin> internal_plugins;
{
base::AutoLock lock(lock_);
- if (plugins_loaded_ && !refresh && !plugins_need_refresh_)
- return;
-
// Clear the refresh bit now, because it might get set again before we
// reach the end of the method.
plugins_need_refresh_ = false;
@@ -358,7 +344,6 @@ void PluginList::LoadPlugins(bool refresh) {
internal_plugins = internal_plugins_;
}
- std::vector<WebPluginInfo> new_plugins;
std::set<FilePath> visited_plugins;
std::vector<FilePath> directories_to_scan;
@@ -370,74 +355,110 @@ void PluginList::LoadPlugins(bool refresh) {
for (size_t i = 0; i < internal_plugins.size(); ++i) {
if (internal_plugins[i].info.path.value() == kDefaultPluginLibraryName)
continue;
- LoadPlugin(internal_plugins[i].info.path, &new_plugins);
+ LoadPlugin(internal_plugins[i].info.path, plugin_groups);
}
for (size_t i = 0; i < extra_plugin_paths.size(); ++i) {
const FilePath& path = extra_plugin_paths[i];
if (visited_plugins.find(path) != visited_plugins.end())
continue;
- LoadPlugin(path, &new_plugins);
+ LoadPlugin(path, plugin_groups);
visited_plugins.insert(path);
}
for (size_t i = 0; i < extra_plugin_dirs.size(); ++i) {
- LoadPluginsFromDir(extra_plugin_dirs[i], &new_plugins, &visited_plugins);
+ LoadPluginsFromDir(
+ extra_plugin_dirs[i], plugin_groups, &visited_plugins);
}
for (size_t i = 0; i < directories_to_scan.size(); ++i) {
- LoadPluginsFromDir(directories_to_scan[i], &new_plugins, &visited_plugins);
+ LoadPluginsFromDir(
+ directories_to_scan[i], plugin_groups, &visited_plugins);
}
#if defined(OS_WIN)
- LoadPluginsFromRegistry(&new_plugins, &visited_plugins);
+ LoadPluginsFromRegistry(plugin_groups, &visited_plugins);
#endif
// Load the default plugin last.
if (webkit_glue::IsDefaultPluginEnabled())
- LoadPlugin(FilePath(kDefaultPluginLibraryName), &new_plugins);
+ LoadPlugin(FilePath(kDefaultPluginLibraryName), plugin_groups);
+}
+void PluginList::LoadPlugins(bool refresh) {
+ {
+ base::AutoLock lock(lock_);
+ if (plugins_loaded_ && !refresh && !plugins_need_refresh_)
+ return;
+ }
+
+ ScopedVector<PluginGroup> new_plugin_groups;
+ // Do the actual loading of the plugins.
+ LoadPluginsInternal(&new_plugin_groups);
+
+ base::AutoLock lock(lock_);
+ // Grab all plugins that were found before to copy enabled statuses.
+ std::vector<WebPluginInfo> old_plugins;
+ for (size_t i = 0; i < plugin_groups_.size(); ++i) {
+ const std::vector<WebPluginInfo>& gr_plugins =
+ plugin_groups_[i]->web_plugins_info();
+ old_plugins.insert(old_plugins.end(), gr_plugins.begin(), gr_plugins.end());
+ }
// 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.
- for (PluginGroup::PluginMap::iterator it = plugin_groups_.begin();
- it != plugin_groups_.end(); ++it) {
- PluginGroup* group = it->second;
+ for (size_t i = 0; i < new_plugin_groups.size(); ++i) {
+ PluginGroup* group = new_plugin_groups[i];
string16 group_name = group->GetGroupName();
- if (ShouldDisableGroup(group_name)) {
- group->Enable(false);
- }
- if (disable_outdated_plugins_) {
- group->DisableOutdatedPlugins();
+ std::vector<WebPluginInfo>& gr_plugins = group->GetPluginsContainer();
+ for (size_t j = 0; j < gr_plugins.size(); ++j) {
+ int plugin_found = -1;
+ for (size_t k = 0; k < old_plugins.size(); ++k) {
+ if (gr_plugins[j].path == old_plugins[k].path) {
+ plugin_found = k;
+ break;
+ }
+ }
+ if (plugin_found >= 0)
+ gr_plugins[j].enabled = old_plugins[plugin_found].enabled;
+ // Set the disabled flag of all plugins scheduled for disabling.
+ if (plugins_to_disable_.find(gr_plugins[j].path) !=
+ plugins_to_disable_.end()) {
+ group->DisablePlugin(gr_plugins[j].path);
+ }
}
- if (!group->Enabled()) {
- base::AutoLock lock(lock_);
- disabled_groups_.insert(group_name);
+ if (group->IsEmpty()) {
+ if (!group->Enabled())
+ groups_to_disable_.insert(group->GetGroupName());
+ new_plugin_groups.erase(new_plugin_groups.begin() + i);
+ --i;
+ continue;
}
- }
- // Only update the data now since loading plugins can take a while.
- base::AutoLock lock(lock_);
+ group->EnforceGroupPolicy();
+ if (disable_outdated_plugins_)
+ group->DisableOutdatedPlugins();
+ }
+ // We flush the list of prematurely disabled plugins after the load has
+ // finished. If for some reason a plugin reappears on a second load it is
+ // going to be loaded normally. This is only true for non-policy controlled
+ // plugins though.
+ plugins_to_disable_.clear();
- plugins_ = new_plugins;
+ plugin_groups_.swap(new_plugin_groups);
plugins_loaded_ = true;
}
void PluginList::LoadPlugin(const FilePath& path,
- std::vector<WebPluginInfo>* plugins) {
+ ScopedVector<PluginGroup>* plugin_groups) {
LOG_IF(ERROR, PluginList::DebugPluginLoading())
<< "Loading plugin " << path.value();
-
WebPluginInfo plugin_info;
const PluginEntryPoints* entry_points;
if (!ReadPluginInfo(path, &plugin_info, &entry_points))
return;
- if (!ShouldLoadPlugin(plugin_info, plugins))
+ if (!ShouldLoadPlugin(plugin_info, plugin_groups))
return;
if (path.value() != kDefaultPluginLibraryName
@@ -455,61 +476,18 @@ void PluginList::LoadPlugin(const FilePath& path,
}
}
- // Mark disabled plugins as such. (This has to happen before calling
- // |AddToPluginGroups(plugin_info)|.)
- if (disabled_plugins_.count(plugin_info.path)) {
- plugin_info.enabled = false;
- } else {
- plugin_info.enabled = true;
- }
-
- base::AutoLock lock(lock_);
- plugins->push_back(plugin_info);
- AddToPluginGroups(plugin_info);
+ AddToPluginGroups(plugin_info, plugin_groups);
}
-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,
- const std::string &extension,
- std::string* actual_mime_type) {
- for (size_t i = 0; i < info.mime_types.size(); ++i) {
- const WebPluginMimeType& mime_type = info.mime_types[i];
- for (size_t j = 0; j < mime_type.file_extensions.size(); ++j) {
- if (mime_type.file_extensions[j] == extension) {
- if (actual_mime_type)
- *actual_mime_type = mime_type.mime_type;
- return true;
- }
- }
- }
-
- return false;
-}
-
-
void PluginList::GetPlugins(bool refresh, std::vector<WebPluginInfo>* plugins) {
LoadPlugins(refresh);
base::AutoLock lock(lock_);
- *plugins = plugins_;
+ for (size_t i = 0; i < plugin_groups_.size(); ++i) {
+ const std::vector<WebPluginInfo>& gr_plugins =
+ plugin_groups_[i]->web_plugins_info();
+ plugins->insert(plugins->end(), gr_plugins.begin(), gr_plugins.end());
+ }
}
void PluginList::GetEnabledPlugins(bool refresh,
@@ -518,11 +496,13 @@ void PluginList::GetEnabledPlugins(bool refresh,
plugins->clear();
base::AutoLock lock(lock_);
- for (std::vector<WebPluginInfo>::const_iterator it = plugins_.begin();
- it != plugins_.end();
- ++it) {
- if (it->enabled)
- plugins->push_back(*it);
+ for (size_t i = 0; i < plugin_groups_.size(); ++i) {
+ const std::vector<WebPluginInfo>& gr_plugins =
+ plugin_groups_[i]->web_plugins_info();
+ for (size_t i = 0; i < gr_plugins.size(); ++i) {
+ if (IsPluginEnabled(gr_plugins[i]))
+ plugins->push_back(gr_plugins[i]);
+ }
}
}
@@ -545,15 +525,19 @@ void PluginList::GetPluginInfoArray(
// 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);
+ for (size_t i = 0; i < plugin_groups_.size(); ++i) {
+ const std::vector<WebPluginInfo>& plugins =
+ plugin_groups_[i]->web_plugins_info();
+ for (size_t i = 0; i < plugins.size(); ++i) {
+ if (IsPluginEnabled(plugins[i]) && 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);
+ }
}
}
}
@@ -564,42 +548,60 @@ void PluginList::GetPluginInfoArray(
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);
+ for (size_t i = 0; i < plugin_groups_.size(); ++i) {
+ const std::vector<WebPluginInfo>& plugins =
+ plugin_groups_[i]->web_plugins_info();
+ for (size_t i = 0; i < plugins.size(); ++i) {
+ if (IsPluginEnabled(plugins[i]) &&
+ 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);
+ for (size_t i = 0; i < plugin_groups_.size(); ++i) {
+ const std::vector<WebPluginInfo>& plugins =
+ plugin_groups_[i]->web_plugins_info();
+ for (size_t i = 0; i < plugins.size(); ++i) {
+ if (!IsPluginEnabled(plugins[i]) &&
+ 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);
+ for (size_t i = 0; i < plugin_groups_.size(); ++i) {
+#if defined(OS_WIN)
+ if (plugin_groups_[i]->identifier().compare(
+ WideToUTF8(kDefaultPluginLibraryName)) == 0) {
+#else
+ if (plugin_groups_[i]->identifier().compare(
+ kDefaultPluginLibraryName) == 0) {
+#endif
+ DCHECK_NE(0U, plugin_groups_[i]->web_plugins_info().size());
+ const WebPluginInfo& default_info =
+ plugin_groups_[i]->web_plugins_info()[0];
+ if (SupportsType(default_info, mime_type, allow_wildcard)) {
+ info->push_back(default_info);
+ if (actual_mime_types)
+ actual_mime_types->push_back(mime_type);
+ }
}
}
}
@@ -637,10 +639,14 @@ bool PluginList::GetPluginInfoByPath(const FilePath& plugin_path,
WebPluginInfo* info) {
LoadPlugins(false);
base::AutoLock lock(lock_);
- for (size_t i = 0; i < plugins_.size(); ++i) {
- if (plugins_[i].path == plugin_path) {
- *info = plugins_[i];
- return true;
+ for (size_t i = 0; i < plugin_groups_.size(); ++i) {
+ const std::vector<WebPluginInfo>& plugins =
+ plugin_groups_[i]->web_plugins_info();
+ for (size_t i = 0; i < plugins.size(); ++i) {
+ if (plugins[i].path == plugin_path) {
+ *info = plugins[i];
+ return true;
+ }
}
}
@@ -652,32 +658,34 @@ void PluginList::GetPluginGroups(
std::vector<PluginGroup>* plugin_groups) {
if (load_if_necessary)
LoadPlugins(false);
+ base::AutoLock lock(lock_);
plugin_groups->clear();
- for (PluginGroup::PluginMap::const_iterator it = plugin_groups_.begin();
- it != plugin_groups_.end(); ++it) {
- if (!it->second->IsEmpty())
- plugin_groups->push_back(*it->second);
+ for (size_t i = 0; i < plugin_groups_.size(); ++i) {
+ // In some unit tests we can get confronted with empty groups but in real
+ // world code this if should never be false here.
+ if (!plugin_groups_[i]->IsEmpty())
+ plugin_groups->push_back(*plugin_groups_[i]);
}
}
const PluginGroup* PluginList::GetPluginGroup(
const WebPluginInfo& web_plugin_info) {
base::AutoLock lock(lock_);
- return AddToPluginGroups(web_plugin_info);
+ return AddToPluginGroups(web_plugin_info, &plugin_groups_);
}
-string16 PluginList::GetPluginGroupName(std::string identifier) {
- PluginGroup::PluginMap::iterator it = plugin_groups_.find(identifier);
- if (it == plugin_groups_.end()) {
- return string16();
+string16 PluginList::GetPluginGroupName(const std::string& identifier) {
+ for (size_t i = 0; i < plugin_groups_.size(); ++i) {
+ if (plugin_groups_[i]->identifier() == identifier)
+ return plugin_groups_[i]->GetGroupName();
}
- return it->second->GetGroupName();
+ return string16();
}
std::string PluginList::GetPluginGroupIdentifier(
const WebPluginInfo& web_plugin_info) {
base::AutoLock lock(lock_);
- PluginGroup* group = AddToPluginGroups(web_plugin_info);
+ PluginGroup* group = AddToPluginGroups(web_plugin_info, &plugin_groups_);
return group->identifier();
}
@@ -687,22 +695,29 @@ void PluginList::AddHardcodedPluginGroups() {
for (size_t i = 0; i < GetPluginGroupDefinitionsSize(); ++i) {
PluginGroup* definition_group = PluginGroup::FromPluginGroupDefinition(
definitions[i]);
- std::string identifier = definition_group->identifier();
- DCHECK(plugin_groups_.find(identifier) == plugin_groups_.end());
- plugin_groups_.insert(std::make_pair(identifier, definition_group));
+ plugin_groups_.push_back(definition_group);
}
}
PluginGroup* PluginList::AddToPluginGroups(
- const WebPluginInfo& web_plugin_info) {
+ const WebPluginInfo& web_plugin_info,
+ ScopedVector<PluginGroup>* plugin_groups) {
PluginGroup* group = NULL;
- for (PluginGroup::PluginMap::iterator it = plugin_groups_.begin();
- it != plugin_groups_.end(); ++it) {
- if (it->second->Match(web_plugin_info))
- group = it->second;
+ for (size_t i = 0; i < plugin_groups->size(); ++i) {
+ if ((*plugin_groups)[i]->Match(web_plugin_info)) {
+ group = (*plugin_groups)[i];
+ break;
+ }
}
if (!group) {
group = PluginGroup::FromWebPluginInfo(web_plugin_info);
+ // If group is scheduled for disabling do that now and remove it from the
+ // list.
+ if (groups_to_disable_.find(group->GetGroupName()) !=
+ groups_to_disable_.end()) {
+ group->EnableGroup(false);
+ groups_to_disable_.erase(group->GetGroupName());
+ }
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
@@ -710,93 +725,97 @@ PluginGroup* PluginList::AddToPluginGroups(
// 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())
- identifier = PluginGroup::GetLongIdentifier(web_plugin_info);
- DCHECK(plugin_groups_.find(identifier) == plugin_groups_.end());
- plugin_groups_.insert(std::make_pair(identifier, group));
+ for (size_t i = 0; i < plugin_groups->size(); ++i) {
+ if ((*plugin_groups)[i]->identifier() == identifier) {
+ group->set_identifier(PluginGroup::GetLongIdentifier(web_plugin_info));
+ break;
+ }
+ }
+ plugin_groups->push_back(group);
}
- group->AddPlugin(web_plugin_info, next_priority_++);
+ group->AddPlugin(web_plugin_info);
return group;
}
bool PluginList::EnablePlugin(const FilePath& filename) {
base::AutoLock lock(lock_);
-
- bool did_enable = false;
-
- std::set<FilePath>::iterator entry = disabled_plugins_.find(filename);
- if (entry == disabled_plugins_.end())
- return did_enable; // Early exit if plugin not in disabled list.
-
- disabled_plugins_.erase(entry); // Remove from disabled list.
-
- // Set enabled flags if necessary.
- for (std::vector<WebPluginInfo>::iterator it = plugins_.begin();
- it != plugins_.end();
- ++it) {
- if (it->path == filename) {
- DCHECK(!it->enabled); // Should have been disabled.
- it->enabled = true;
- did_enable = true;
- }
+ for (size_t i = 0; i < plugin_groups_.size(); ++i) {
+ if (plugin_groups_[i]->ContainsPlugin(filename))
+ return plugin_groups_[i]->EnablePlugin(filename);
}
-
- return did_enable;
+ // Non existing plugin is being enabled. Check if it has been disabled before
+ // and remove it.
+ return (plugins_to_disable_.erase(filename) != 0);
}
bool PluginList::DisablePlugin(const FilePath& filename) {
base::AutoLock lock(lock_);
+ for (size_t i = 0; i < plugin_groups_.size(); ++i) {
+ if (plugin_groups_[i]->ContainsPlugin(filename))
+ return plugin_groups_[i]->DisablePlugin(filename);
+ }
+ // Non existing plugin is being disabled. Queue the plugin so that on the next
+ // load plugins call they will be disabled.
+ // Check if we already have this one to avoid double inclusion.
+ plugins_to_disable_.insert(filename);
+ return true;
+}
- bool did_disable = false;
-
- if (disabled_plugins_.find(filename) != disabled_plugins_.end())
- return did_disable; // Early exit if plugin already in disabled list.
-
- disabled_plugins_.insert(filename); // Add to disabled list.
-
- // Unset enabled flags if necessary.
- for (std::vector<WebPluginInfo>::iterator it = plugins_.begin();
- it != plugins_.end();
- ++it) {
- if (it->path == filename) {
- DCHECK(it->enabled); // Should have been enabled.
- it->enabled = false;
- did_disable = true;
+bool PluginList::EnableGroup(bool enable, const string16& group_name) {
+ base::AutoLock lock(lock_);
+ PluginGroup* group = NULL;
+ for (size_t i = 0; i < plugin_groups_.size(); ++i) {
+ if (plugin_groups_[i]->GetGroupName().find(group_name) != string16::npos) {
+ group = plugin_groups_[i];
+ break;
+ }
+ }
+ if (!group) {
+ // Non existing group is being enabled. Queue the group so that on the next
+ // load plugins call they will be disabled.
+ if (!enable) {
+ groups_to_disable_.insert(group_name);
+ return true;
+ } else {
+ return (groups_to_disable_.erase(group_name) != 0);
}
}
- return did_disable;
+ return group->EnableGroup(enable);
}
-bool PluginList::EnableGroup(bool enable, const string16& group_name) {
- bool did_change = false;
- {
- base::AutoLock lock(lock_);
+bool PluginList::SupportsType(const WebPluginInfo& plugin,
+ 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;
- 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);
+ for (size_t i = 0; i < plugin.mime_types.size(); ++i) {
+ const WebPluginMimeType& mime_info = plugin.mime_types[i];
+ if (net::MatchesMimeType(mime_info.mime_type, mime_type)) {
+ if (!allow_wildcard && mime_info.mime_type == "*")
+ continue;
+ return true;
}
}
+ return false;
+}
- for (PluginGroup::PluginMap::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;
+bool PluginList::SupportsExtension(const WebPluginInfo& plugin,
+ const std::string& extension,
+ std::string* actual_mime_type) {
+ for (size_t i = 0; i < plugin.mime_types.size(); ++i) {
+ const WebPluginMimeType& mime_type = plugin.mime_types[i];
+ for (size_t j = 0; j < mime_type.file_extensions.size(); ++j) {
+ if (mime_type.file_extensions[j] == extension) {
+ if (actual_mime_type)
+ *actual_mime_type = mime_type.mime_type;
+ return true;
}
}
}
-
- return did_change;
+ return false;
}
void PluginList::DisableOutdatedPluginGroups() {
@@ -804,13 +823,8 @@ void PluginList::DisableOutdatedPluginGroups() {
}
PluginList::~PluginList() {
- Shutdown();
}
-void PluginList::Shutdown() {
- STLDeleteContainerPairSecondPointers(plugin_groups_.begin(),
- plugin_groups_.end());
-}
} // namespace npapi
} // namespace webkit
diff --git a/webkit/plugins/npapi/plugin_list.h b/webkit/plugins/npapi/plugin_list.h
index f0c269b..f7708aa 100644
--- a/webkit/plugins/npapi/plugin_list.h
+++ b/webkit/plugins/npapi/plugin_list.h
@@ -7,12 +7,14 @@
#include <set>
#include <string>
+#include <utility>
#include <vector>
#include "base/basictypes.h"
#include "base/file_path.h"
#include "base/linked_ptr.h"
#include "base/synchronization/lock.h"
+#include "base/scoped_vector.h"
#include "third_party/npapi/bindings/nphostapi.h"
#include "webkit/plugins/npapi/plugin_group.h"
#include "webkit/plugins/npapi/webplugininfo.h"
@@ -122,9 +124,6 @@ class PluginList {
const string16& mime_type_descriptions,
std::vector<WebPluginMimeType>* parsed_mime_types);
- // Shutdown all plugins. Should be called at process teardown.
- void Shutdown();
-
// Get all the plugins.
void GetPlugins(bool refresh, std::vector<WebPluginInfo>* plugins);
@@ -176,7 +175,7 @@ class PluginList {
// Returns the name of the PluginGroup with the given identifier.
// If no such group exists, an empty string is returned.
- string16 GetPluginGroupName(std::string identifier);
+ string16 GetPluginGroupName(const std::string& identifier);
// Returns the identifier string of the PluginGroup corresponding to the given
// WebPluginInfo. If no such group exists, it is created and added to the
@@ -185,13 +184,12 @@ class PluginList {
// Load a specific plugin with full path.
void LoadPlugin(const FilePath& filename,
- std::vector<WebPluginInfo>* plugins);
+ ScopedVector<PluginGroup>* plugin_groups);
// Enable a specific plugin, specified by path. Returns |true| iff a plugin
// currently in the plugin list was actually enabled as a result; regardless
// of return value, if a plugin is found in the future with the given name, it
- // will be enabled. Note that plugins are enabled by default as far as
- // |PluginList| is concerned.
+ // will be enabled.
bool EnablePlugin(const FilePath& filename);
// Disable a specific plugin, specified by path. Returns |true| iff a plugin
@@ -203,8 +201,7 @@ class PluginList {
// Enable/disable a plugin group, specified by group_name. Returns |true| iff
// a plugin currently in the plugin list was actually enabled/disabled as a
// result; regardless of return value, if a plugin is found in the future with
- // the given name, it will be enabled/disabled. Note that plugins are enabled
- // by default as far as |PluginList| is concerned.
+ // the given name, it will be enabled/disabled.
bool EnableGroup(bool enable, const string16& name);
// Disable all plugins groups that are known to be outdated, according to
@@ -213,22 +210,33 @@ class PluginList {
// version.
void DisableOutdatedPluginGroups();
- ~PluginList();
-
- private:
- FRIEND_TEST_ALL_PREFIXES(PluginGroupTest, PluginGroupDefinition);
+ virtual ~PluginList();
+ protected:
// Constructors are private for singletons
PluginList();
+ // Adds the given WebPluginInfo to its corresponding group, creating it if
+ // necessary, and returns the group.
+ // Callers need to protect calls to this method by a lock themselves.
+ PluginGroup* AddToPluginGroups(const WebPluginInfo& web_plugin_info,
+ ScopedVector<PluginGroup>* plugin_groups);
+
+// Holds the currently available plugin groups.
+ ScopedVector<PluginGroup> plugin_groups_;
+
+ private:
+ friend class PluginListTest;
+ FRIEND_TEST_ALL_PREFIXES(PluginGroupTest, PluginGroupDefinition);
+
// Creates PluginGroups for the static group definitions, and adds them to
// the PluginGroup cache of this PluginList.
void AddHardcodedPluginGroups();
- // Adds the given WebPluginInfo to its corresponding group, creating it if
- // necessary, and returns the group.
- // Callers need to protect calls to this method by a lock themselves.
- PluginGroup* AddToPluginGroups(const WebPluginInfo& web_plugin_info);
+ // Implements all IO dependant operations of the LoadPlugins method so that
+ // test classes can mock these out. Return value false means LoadPlugins
+ // should not go on with the loading.
+ virtual void LoadPluginsInternal(ScopedVector<PluginGroup>* plugin_groups);
// Load all plugins from the default plugins directory
void LoadPlugins(bool refresh);
@@ -238,14 +246,14 @@ class PluginList {
// |visited_plugins| is updated with paths to all plugins that were considered
// (including those we didn't load)
void LoadPluginsFromDir(const FilePath& path,
- std::vector<WebPluginInfo>* plugins,
+ ScopedVector<PluginGroup>* plugin_groups,
std::set<FilePath>* visited_plugins);
// Returns true if we should load the given plugin, or false otherwise.
// plugins is the list of plugins we have crawled in the current plugin
// loading run.
bool ShouldLoadPlugin(const WebPluginInfo& info,
- std::vector<WebPluginInfo>* plugins);
+ ScopedVector<PluginGroup>* plugins);
// Return whether a plug-in group with the given name should be disabled,
// either because it already is on the list of disabled groups, or because it
@@ -253,20 +261,19 @@ class PluginList {
// list of disabled groups as well.
bool ShouldDisableGroup(const string16& group_name);
- // 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);
+ // Returns true if the plugin supports |mime_type|. |mime_type| should be all
+ // lower case.
+ bool SupportsType(const WebPluginInfo& plugin,
+ const std::string& mime_type,
+ bool allow_wildcard);
+
+ // Returns true if the given plugin 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.
+ bool SupportsExtension(const WebPluginInfo& plugin,
+ const std::string& extension,
+ std::string* actual_mime_type);
//
// Platform functions
@@ -285,22 +292,19 @@ class PluginList {
// Loads plugins registered under HKCU\Software\MozillaPlugins and
// HKLM\Software\MozillaPlugins.
- void LoadPluginsFromRegistry(std::vector<WebPluginInfo>* plugins,
+ void LoadPluginsFromRegistry(ScopedVector<PluginGroup>* plugins,
std::set<FilePath>* visited_plugins);
#endif
//
// Internals
//
-
+ // Set to true when the LoadPlugins method has finished.
bool plugins_loaded_;
// If true, we reload plugins even if they've been loaded already.
bool plugins_need_refresh_;
- // Contains information about the available plugins.
- std::vector<WebPluginInfo> plugins_;
-
// Extra plugin paths that we want to search when loading.
std::vector<FilePath> extra_plugin_paths_;
@@ -314,18 +318,20 @@ class PluginList {
// Holds information about internal plugins.
std::vector<InternalPlugin> internal_plugins_;
- // Path names of plugins to disable (the default is to enable them all).
- std::set<FilePath> disabled_plugins_;
-
- // Group names to disable (the default is to enable them all).
- std::set<string16> disabled_groups_;
-
+ // If set to true outdated plugins are disabled in the end of LoadPlugins.
bool disable_outdated_plugins_;
- // Holds the currently available plugin groups.
- PluginGroup::PluginMap plugin_groups_;
-
- int next_priority_;
+ // The set of plugins that have been scheduled for disabling once they get
+ // loaded. This list is used in LoadPlugins and pruned after it. Contains
+ // plugins that were either disabled by the user (prefs are loaded before
+ // plugins) or disabled by a policy.
+ std::set<FilePath> plugins_to_disable_;
+ // Equivalent to the |plugins_to_disable_| this is the set of groups
+ // scheduled for disabling once they appear. This list is never completely
+ // pruned but all groups that do get created are removed from it. New groups
+ // might get added if they should be pruned because of plugins getting removed
+ // for example.
+ std::set<string16> groups_to_disable_;
// Need synchronization for the above members since this object can be
// accessed on multiple threads.
diff --git a/webkit/plugins/npapi/plugin_list_mac.mm b/webkit/plugins/npapi/plugin_list_mac.mm
index 62e682b..802ea3e 100644
--- a/webkit/plugins/npapi/plugin_list_mac.mm
+++ b/webkit/plugins/npapi/plugin_list_mac.mm
@@ -77,29 +77,33 @@ void PluginList::GetPluginDirectories(std::vector<FilePath>* plugin_dirs) {
}
void PluginList::LoadPluginsFromDir(const FilePath &path,
- std::vector<WebPluginInfo>* plugins,
+ ScopedVector<PluginGroup>* plugin_groups,
std::set<FilePath>* visited_plugins) {
file_util::FileEnumerator enumerator(path,
false, // not recursive
file_util::FileEnumerator::DIRECTORIES);
for (FilePath path = enumerator.Next(); !path.value().empty();
path = enumerator.Next()) {
- LoadPlugin(path, plugins);
+ LoadPlugin(path, plugin_groups);
visited_plugins->insert(path);
}
}
bool PluginList::ShouldLoadPlugin(const WebPluginInfo& info,
- std::vector<WebPluginInfo>* plugins) {
+ ScopedVector<PluginGroup>* plugin_groups) {
if (IsBlacklistedPlugin(info))
return false;
// Hierarchy check
// (we're loading plugins hierarchically from Library folders, so plugins we
// encounter earlier must override plugins we encounter later)
- for (size_t i = 0; i < plugins->size(); ++i) {
- if ((*plugins)[i].path.BaseName() == info.path.BaseName()) {
- return false; // We already have a loaded plugin higher in the hierarchy.
+ for (size_t i = 0; i < plugin_groups->size(); ++i) {
+ const std::vector<WebPluginInfo>& plugins =
+ (*plugin_groups)[i]->web_plugins_info();
+ for (size_t j = 0; j < plugins.size(); ++j) {
+ if (plugins[j].path.BaseName() == info.path.BaseName()) {
+ return false; // Already have a loaded plugin higher in the hierarchy.
+ }
}
}
diff --git a/webkit/plugins/npapi/plugin_list_posix.cc b/webkit/plugins/npapi/plugin_list_posix.cc
index fd5e5b7..f861fc5 100644
--- a/webkit/plugins/npapi/plugin_list_posix.cc
+++ b/webkit/plugins/npapi/plugin_list_posix.cc
@@ -165,7 +165,7 @@ void PluginList::GetPluginDirectories(std::vector<FilePath>* plugin_dirs) {
}
void PluginList::LoadPluginsFromDir(const FilePath& dir_path,
- std::vector<WebPluginInfo>* plugins,
+ ScopedVector<PluginGroup>* plugin_groups,
std::set<FilePath>* visited_plugins) {
// See ScanPluginsDirectory near
// http://mxr.mozilla.org/firefox/source/modules/plugin/base/src/nsPluginHostImpl.cpp#5052
@@ -234,12 +234,12 @@ void PluginList::LoadPluginsFromDir(const FilePath& dir_path,
// Load the files in order.
for (FileTimeList::const_iterator i = files.begin(); i != files.end(); ++i) {
- LoadPlugin(i->first, plugins);
+ LoadPlugin(i->first, plugin_groups);
}
}
bool PluginList::ShouldLoadPlugin(const WebPluginInfo& info,
- std::vector<WebPluginInfo>* plugins) {
+ ScopedVector<PluginGroup>* plugin_groups) {
LOG_IF(ERROR, PluginList::DebugPluginLoading())
<< "Considering " << info.path.value() << " (" << info.name << ")";
@@ -248,15 +248,19 @@ bool PluginList::ShouldLoadPlugin(const WebPluginInfo& info,
<< info.path.value() << " is undesirable.";
// See if we have a better version of this plugin.
- for (size_t i = 0; i < plugins->size(); ++i) {
- if (plugins->at(i).name == info.name &&
- !IsUndesirablePlugin(plugins->at(i))) {
- // Skip the current undesirable one so we can use the better one
- // we just found.
- LOG_IF(ERROR, PluginList::DebugPluginLoading())
- << "Skipping " << info.path.value() << ", preferring "
- << plugins->at(i).path.value();
- return false;
+ for (size_t i = 0; i < plugin_groups->size(); ++i) {
+ const std::vector<WebPluginInfo>& plugins =
+ (*plugin_groups)[i]->web_plugins_info();
+ for (size_t j = 0; j < plugins.size(); ++j) {
+ if (plugins[j].name == info.name &&
+ !IsUndesirablePlugin(plugins[j])) {
+ // Skip the current undesirable one so we can use the better one
+ // we just found.
+ LOG_IF(ERROR, PluginList::DebugPluginLoading())
+ << "Skipping " << info.path.value() << ", preferring "
+ << plugins[j].path.value();
+ return false;
+ }
}
}
}
diff --git a/webkit/plugins/npapi/plugin_list_unittest.cc b/webkit/plugins/npapi/plugin_list_unittest.cc
new file mode 100644
index 0000000..3e0fb47
--- /dev/null
+++ b/webkit/plugins/npapi/plugin_list_unittest.cc
@@ -0,0 +1,211 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "webkit/plugins/npapi/plugin_list.h"
+
+#include "base/utf_string_conversions.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace webkit {
+namespace npapi {
+
+namespace plugin_test_internal {
+
+// A PluginList for tests that avoids file system IO. There is also no reason
+// to use |lock_| (but it doesn't hurt either).
+class PluginListWithoutFileIO : public PluginList {
+ public:
+ std::vector<WebPluginInfo> plugins_to_load_;
+
+ private:
+ // NPAPI::PluginList methods:
+ virtual void LoadPluginsInternal(ScopedVector<PluginGroup>* plugin_groups) {
+ for (size_t i = 0; i < plugins_to_load_.size(); ++i)
+ AddToPluginGroups(plugins_to_load_[i], plugin_groups);
+
+ return;
+ }
+};
+
+} // namespace plugin_test_internal
+
+namespace {
+
+bool Equals(const WebPluginInfo& a, const WebPluginInfo& b,
+ bool care_about_enabled_status) {
+ return (a.name == b.name &&
+ a.path == b.path &&
+ a.version == b.version &&
+ a.desc == b.desc &&
+ (!care_about_enabled_status || a.enabled == b.enabled));
+}
+
+bool Contains(const std::vector<WebPluginInfo>& list,
+ const WebPluginInfo& plugin,
+ bool care_about_enabled_status) {
+ for (std::vector<WebPluginInfo>::const_iterator it = list.begin();
+ it != list.end(); ++it) {
+ if (Equals(*it, plugin, care_about_enabled_status))
+ return true;
+ }
+ return false;
+}
+
+} // namespace
+
+class PluginListTest : public testing::Test {
+ public:
+ PluginListTest()
+ : foo_plugin_(ASCIIToUTF16("Foo Plugin"),
+ FilePath(FILE_PATH_LITERAL("/plugins/foo.plugin")),
+ ASCIIToUTF16("1.2.3"),
+ ASCIIToUTF16("foo")),
+ bar_plugin_(ASCIIToUTF16("Bar Plugin"),
+ FilePath(FILE_PATH_LITERAL("/plugins/bar.plugin")),
+ ASCIIToUTF16("2.3.4"),
+ ASCIIToUTF16("bar")) {
+ }
+
+ virtual void SetUp() {
+ bar_plugin_.enabled = WebPluginInfo::USER_DISABLED_POLICY_UNMANAGED;
+ plugin_list_.DisablePlugin(bar_plugin_.path);
+ plugin_list_.plugins_to_load_.push_back(foo_plugin_);
+ plugin_list_.plugins_to_load_.push_back(bar_plugin_);
+ plugin_list_.LoadPlugins(true);
+ }
+
+ protected:
+ plugin_test_internal::PluginListWithoutFileIO plugin_list_;
+ WebPluginInfo foo_plugin_;
+ WebPluginInfo bar_plugin_;
+};
+
+TEST_F(PluginListTest, GetPlugins) {
+ std::vector<WebPluginInfo> plugins;
+ plugin_list_.GetPlugins(false, &plugins);
+ EXPECT_EQ(2u, plugins.size());
+ EXPECT_TRUE(Contains(plugins, foo_plugin_, true));
+ EXPECT_TRUE(Contains(plugins, bar_plugin_, true));
+}
+
+TEST_F(PluginListTest, GetEnabledPlugins) {
+ std::vector<WebPluginInfo> plugins;
+ plugin_list_.GetEnabledPlugins(false, &plugins);
+ EXPECT_EQ(1u, plugins.size());
+ EXPECT_TRUE(Contains(plugins, foo_plugin_, true));
+}
+
+TEST_F(PluginListTest, GetPluginGroup) {
+ const PluginGroup* foo_group = plugin_list_.GetPluginGroup(foo_plugin_);
+ EXPECT_EQ(foo_group->GetGroupName(), foo_plugin_.name);
+ EXPECT_TRUE(foo_group->Enabled());
+ // The second request should return a pointer to the same instance.
+ const PluginGroup* foo_group2 = plugin_list_.GetPluginGroup(foo_plugin_);
+ EXPECT_EQ(foo_group, foo_group2);
+ const PluginGroup* bar_group = plugin_list_.GetPluginGroup(bar_plugin_);
+ EXPECT_FALSE(bar_group->Enabled());
+}
+
+TEST_F(PluginListTest, EnableDisablePlugin) {
+ // Disable "foo" plugin.
+ plugin_list_.DisablePlugin(foo_plugin_.path);
+ std::vector<WebPluginInfo> plugins;
+ plugin_list_.GetEnabledPlugins(false, &plugins);
+ EXPECT_FALSE(Contains(plugins, foo_plugin_, false));
+ const PluginGroup* foo_group = plugin_list_.GetPluginGroup(foo_plugin_);
+ EXPECT_FALSE(foo_group->Enabled());
+ // Enable "bar" plugin.
+ plugin_list_.EnablePlugin(bar_plugin_.path);
+ plugin_list_.GetEnabledPlugins(false, &plugins);
+ EXPECT_TRUE(Contains(plugins, bar_plugin_, false));
+ const PluginGroup* bar_group = plugin_list_.GetPluginGroup(bar_plugin_);
+ EXPECT_TRUE(bar_group->Enabled());
+}
+
+TEST_F(PluginListTest, EnableGroup) {
+ // Disable "foo" plugin group.
+ const PluginGroup* foo_group = plugin_list_.GetPluginGroup(foo_plugin_);
+ EXPECT_TRUE(foo_group->Enabled());
+ EXPECT_TRUE(plugin_list_.EnableGroup(false, foo_group->GetGroupName()));
+ EXPECT_FALSE(foo_group->Enabled());
+ std::vector<WebPluginInfo> plugins;
+ plugin_list_.GetEnabledPlugins(false, &plugins);
+ EXPECT_EQ(0u, plugins.size());
+ EXPECT_FALSE(Contains(plugins, foo_plugin_, false));
+ // Enable "bar" plugin group.
+ const PluginGroup* bar_group = plugin_list_.GetPluginGroup(bar_plugin_);
+ EXPECT_FALSE(bar_group->Enabled());
+ plugin_list_.EnableGroup(true, bar_group->GetGroupName());
+ EXPECT_TRUE(bar_group->Enabled());
+ plugin_list_.GetEnabledPlugins(false, &plugins);
+ EXPECT_TRUE(Contains(plugins, bar_plugin_, false));
+}
+
+TEST_F(PluginListTest, EmptyGroup) {
+ std::vector<PluginGroup> groups;
+ plugin_list_.GetPluginGroups(false, &groups);
+ for (size_t i = 0; i < groups.size(); ++i) {
+ EXPECT_GE(1U, groups[i].web_plugins_info().size());
+ }
+}
+
+TEST_F(PluginListTest, DisableOutdated) {
+ VersionRangeDefinition version_range[] = {
+ { "0", "4", "3.0.44" },
+ { "4", "5", "" }
+ };
+ WebPluginInfo plugin_3043(ASCIIToUTF16("MyPlugin"),
+ FilePath(FILE_PATH_LITERAL("/myplugin.3.0.43")),
+ ASCIIToUTF16("3.0.43"),
+ ASCIIToUTF16("MyPlugin version 3.0.43"));
+ WebPluginInfo plugin_3045(ASCIIToUTF16("MyPlugin"),
+ FilePath(FILE_PATH_LITERAL("/myplugin.3.0.45")),
+ ASCIIToUTF16("3.0.45"),
+ ASCIIToUTF16("MyPlugin version 3.0.45"));
+ plugin_list_.plugins_to_load_.clear();
+ plugin_list_.plugins_to_load_.push_back(plugin_3043);
+ plugin_list_.plugins_to_load_.push_back(plugin_3045);
+ // Enfore the load to run.
+ std::vector<WebPluginInfo> plugins;
+ plugin_list_.GetPlugins(true, &plugins);
+ PluginGroup* group_3043 =
+ const_cast<PluginGroup*>(plugin_list_.GetPluginGroup(plugin_3043));
+ const PluginGroup* group_3045 = plugin_list_.GetPluginGroup(plugin_3045);
+ EXPECT_EQ(group_3043, group_3045);
+ group_3043->version_ranges_.push_back(VersionRange(version_range[0]));
+ group_3043->version_ranges_.push_back(VersionRange(version_range[1]));
+ EXPECT_EQ(plugin_3043.desc, group_3043->description());
+ EXPECT_TRUE(group_3043->IsVulnerable());
+ group_3043->DisableOutdatedPlugins();
+ EXPECT_EQ(plugin_3045.desc, group_3043->description());
+ EXPECT_FALSE(group_3043->IsVulnerable());
+}
+
+TEST_F(PluginListTest, DisableAndEnableBeforeLoad) {
+ WebPluginInfo plugin_3043(ASCIIToUTF16("MyPlugin"),
+ FilePath(FILE_PATH_LITERAL("/myplugin.3.0.43")),
+ ASCIIToUTF16("3.0.43"),
+ ASCIIToUTF16("MyPlugin version 3.0.43"));
+ WebPluginInfo plugin_3045(ASCIIToUTF16("MyPlugin"),
+ FilePath(FILE_PATH_LITERAL("/myplugin.3.0.45")),
+ ASCIIToUTF16("3.0.45"),
+ ASCIIToUTF16("MyPlugin version 3.0.45"));
+ // Disable the first one and disable and then enable the second one.
+ EXPECT_TRUE(plugin_list_.DisablePlugin(plugin_3043.path));
+ EXPECT_TRUE(plugin_list_.DisablePlugin(plugin_3045.path));
+ EXPECT_TRUE(plugin_list_.EnablePlugin(plugin_3045.path));
+ // Simulate loading of the plugins.
+ plugin_list_.plugins_to_load_.clear();
+ plugin_list_.plugins_to_load_.push_back(plugin_3043);
+ plugin_list_.plugins_to_load_.push_back(plugin_3045);
+ // Now we should have them in the state we specified above.
+ std::vector<WebPluginInfo> plugins;
+ plugin_list_.GetPlugins(true, &plugins);
+ plugin_3043.enabled = WebPluginInfo::USER_DISABLED_POLICY_UNMANAGED;
+ ASSERT_TRUE(Contains(plugins, plugin_3043, true));
+ ASSERT_TRUE(Contains(plugins, plugin_3045, true));
+}
+
+} // namespace npapi
+} // namespace webkit
diff --git a/webkit/plugins/npapi/plugin_list_win.cc b/webkit/plugins/npapi/plugin_list_win.cc
index 324dffb..eaa64a7 100644
--- a/webkit/plugins/npapi/plugin_list_win.cc
+++ b/webkit/plugins/npapi/plugin_list_win.cc
@@ -250,7 +250,7 @@ void PluginList::GetPluginDirectories(std::vector<FilePath>* plugin_dirs) {
}
void PluginList::LoadPluginsFromDir(const FilePath &path,
- std::vector<WebPluginInfo>* plugins,
+ ScopedVector<PluginGroup>* plugin_groups,
std::set<FilePath>* visited_plugins) {
WIN32_FIND_DATA find_file_data;
HANDLE find_handle;
@@ -266,7 +266,7 @@ void PluginList::LoadPluginsFromDir(const FilePath &path,
do {
if (!(find_file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
FilePath filename = path.Append(find_file_data.cFileName);
- LoadPlugin(filename, plugins);
+ LoadPlugin(filename, plugin_groups);
visited_plugins->insert(filename);
}
} while (FindNextFile(find_handle, &find_file_data) != 0);
@@ -276,7 +276,7 @@ void PluginList::LoadPluginsFromDir(const FilePath &path,
}
void PluginList::LoadPluginsFromRegistry(
- std::vector<WebPluginInfo>* plugins,
+ ScopedVector<PluginGroup>* plugin_groups,
std::set<FilePath>* visited_plugins) {
std::set<FilePath> plugin_dirs;
@@ -287,7 +287,7 @@ void PluginList::LoadPluginsFromRegistry(
for (std::set<FilePath>::iterator i = plugin_dirs.begin();
i != plugin_dirs.end(); ++i) {
- LoadPlugin(*i, plugins);
+ LoadPlugin(*i, plugin_groups);
visited_plugins->insert(*i);
}
}
@@ -335,22 +335,26 @@ bool IsNewerVersion(const std::wstring& a, const std::wstring& b) {
}
bool PluginList::ShouldLoadPlugin(const WebPluginInfo& info,
- std::vector<WebPluginInfo>* plugins) {
+ ScopedVector<PluginGroup>* plugin_groups) {
// Version check
- for (size_t i = 0; i < plugins->size(); ++i) {
- std::wstring plugin1 =
- StringToLowerASCII((*plugins)[i].path.BaseName().ToWStringHack());
- std::wstring plugin2 =
- StringToLowerASCII(info.path.BaseName().ToWStringHack());
- if ((plugin1 == plugin2 && HaveSharedMimeType((*plugins)[i], info)) ||
- (plugin1 == kJavaDeploy1 && plugin2 == kJavaDeploy2) ||
- (plugin1 == kJavaDeploy2 && plugin2 == kJavaDeploy1)) {
- if (!IsNewerVersion((*plugins)[i].version, info.version))
- return false; // We have loaded a plugin whose version is newer.
-
- plugins->erase(plugins->begin() + i);
- break;
+ for (size_t i = 0; i < plugin_groups->size(); ++i) {
+ const std::vector<WebPluginInfo>& plugins =
+ (*plugin_groups)[i]->web_plugins_info();
+ for (size_t j = 0; j < plugins.size(); ++j) {
+ std::wstring plugin1 =
+ StringToLowerASCII(plugins[j].path.BaseName().ToWStringHack());
+ std::wstring plugin2 =
+ StringToLowerASCII(info.path.BaseName().ToWStringHack());
+ if ((plugin1 == plugin2 && HaveSharedMimeType(plugins[j], info)) ||
+ (plugin1 == kJavaDeploy1 && plugin2 == kJavaDeploy2) ||
+ (plugin1 == kJavaDeploy2 && plugin2 == kJavaDeploy1)) {
+ if (!IsNewerVersion(plugins[j].version, info.version))
+ return false; // We have loaded a plugin whose version is newer.
+
+ (*plugin_groups)[i]->RemovePlugin(plugins[j].path);
+ break;
+ }
}
}
@@ -396,16 +400,24 @@ bool PluginList::ShouldLoadPlugin(const WebPluginInfo& info,
if (dont_load_new_wmp_)
return false;
- for (size_t i = 0; i < plugins->size(); ++i) {
- if ((*plugins)[i].path.BaseName().value() == kOldWMPPlugin) {
- plugins->erase(plugins->begin() + i);
- break;
+ for (size_t i = 0; i < plugin_groups->size(); ++i) {
+ const std::vector<WebPluginInfo>& plugins =
+ (*plugin_groups)[i]->web_plugins_info();
+ for (size_t j = 0; j < plugins.size(); ++j) {
+ if (plugins[j].path.BaseName().value() == kOldWMPPlugin) {
+ (*plugin_groups)[i]->RemovePlugin(plugins[j].path);
+ break;
+ }
}
}
} else if (filename == kOldWMPPlugin) {
- for (size_t i = 0; i < plugins->size(); ++i) {
- if ((*plugins)[i].path.BaseName().value() == kNewWMPPlugin)
- return false;
+ for (size_t i = 0; i < plugin_groups->size(); ++i) {
+ const std::vector<WebPluginInfo>& plugins =
+ (*plugin_groups)[i]->web_plugins_info();
+ for (size_t j = 0; j < plugins.size(); ++j) {
+ if (plugins[j].path.BaseName().value() == kNewWMPPlugin)
+ return false;
+ }
}
}
diff --git a/webkit/plugins/npapi/webplugininfo.cc b/webkit/plugins/npapi/webplugininfo.cc
index cd5a19f..772a7d0 100644
--- a/webkit/plugins/npapi/webplugininfo.cc
+++ b/webkit/plugins/npapi/webplugininfo.cc
@@ -4,6 +4,8 @@
#include "webkit/plugins/npapi/webplugininfo.h"
+#include "base/logging.h"
+
namespace webkit {
namespace npapi {
@@ -11,7 +13,9 @@ WebPluginMimeType::WebPluginMimeType() {}
WebPluginMimeType::~WebPluginMimeType() {}
-WebPluginInfo::WebPluginInfo() : enabled(false) {}
+WebPluginInfo::WebPluginInfo()
+ : enabled(USER_DISABLED_POLICY_UNMANAGED) {
+}
WebPluginInfo::WebPluginInfo(const WebPluginInfo& rhs)
: name(rhs.name),
@@ -43,9 +47,13 @@ WebPluginInfo::WebPluginInfo(const string16& fake_name,
version(fake_version),
desc(fake_desc),
mime_types(),
- enabled(true) {
+ enabled(USER_ENABLED_POLICY_UNMANAGED) {
+}
+
+bool IsPluginEnabled(const WebPluginInfo& plugin) {
+ return ((plugin.enabled & WebPluginInfo::POLICY_ENABLED) ||
+ plugin.enabled == WebPluginInfo::USER_ENABLED_POLICY_UNMANAGED);
}
} // namespace npapi
} // namespace webkit
-
diff --git a/webkit/plugins/npapi/webplugininfo.h b/webkit/plugins/npapi/webplugininfo.h
index 859665c..c4e58ed 100644
--- a/webkit/plugins/npapi/webplugininfo.h
+++ b/webkit/plugins/npapi/webplugininfo.h
@@ -31,6 +31,32 @@ struct WebPluginMimeType {
// Describes an available NPAPI plugin.
struct WebPluginInfo {
+ // Defines the possible enabled state a plugin can have.
+ // The enum values actually represent a 3-bit bitfield :
+ // |PE|PD|U| - where |PE|PD| is policy state and U is user state.
+ // PE == 1 means the plugin is forced to enabled state by policy
+ // PD == 1 means the plugin is forced to disabled by policy
+ // PE and PD CAN'T be both 1 but can be both 0 which mean no policy is set.
+ // U == 1 means the user has disabled the plugin.
+ // Because the plugin user state might have been changed before a policy was
+ // introduced the user state might contradict the policy state in which case
+ // the policy has precedence.
+ enum EnabledStates {
+ USER_ENABLED = 0,
+ USER_DISABLED = 1 << 0,
+ POLICY_DISABLED = 1 << 1,
+ POLICY_ENABLED = 1 << 2,
+ USER_ENABLED_POLICY_UNMANAGED = USER_ENABLED,
+ USER_ENABLED_POLICY_DISABLED = USER_ENABLED| POLICY_DISABLED,
+ USER_ENABLED_POLICY_ENABLED = USER_ENABLED | POLICY_ENABLED,
+ USER_DISABLED_POLICY_UNMANAGED = USER_DISABLED,
+ USER_DISABLED_POLICY_DISABLED = USER_DISABLED | POLICY_DISABLED,
+ USER_DISABLED_POLICY_ENABLED = USER_DISABLED | POLICY_ENABLED,
+ USER_MASK = USER_DISABLED,
+ MANAGED_MASK = POLICY_DISABLED | POLICY_ENABLED,
+ POLICY_UNMANAGED = -1
+ };
+
WebPluginInfo();
WebPluginInfo(const WebPluginInfo& rhs);
~WebPluginInfo();
@@ -57,10 +83,13 @@ struct WebPluginInfo {
// A list of all the mime types that this plugin supports.
std::vector<WebPluginMimeType> mime_types;
- // Whether the plugin is enabled.
- bool enabled;
+ // Enabled state of the plugin. See the EnabledStates enum.
+ int enabled;
};
+// Checks whether a plugin is enabled either by the user or by policy.
+bool IsPluginEnabled(const WebPluginInfo& plugin);
+
} // namespace npapi
} // namespace webkit
diff --git a/webkit/support/webkit_support.cc b/webkit/support/webkit_support.cc
index db23097..195257b 100644
--- a/webkit/support/webkit_support.cc
+++ b/webkit/support/webkit_support.cc
@@ -253,7 +253,7 @@ WebPlugin* CreateWebPlugin(WebFrame* frame,
std::string actual_mime_type;
if (!webkit::npapi::PluginList::Singleton()->GetPluginInfo(
params.url, params.mimeType.utf8(), kAllowWildcard, &info,
- &actual_mime_type) || !info.enabled) {
+ &actual_mime_type) || !webkit::npapi::IsPluginEnabled(info)) {
return NULL;
}
diff --git a/webkit/tools/test_shell/test_shell.gypi b/webkit/tools/test_shell/test_shell.gypi
index c50ca5b..0dc2c8d 100644
--- a/webkit/tools/test_shell/test_shell.gypi
+++ b/webkit/tools/test_shell/test_shell.gypi
@@ -413,6 +413,7 @@
'../../mocks/mock_weburlloader.h',
'../../plugins/npapi/plugin_group_unittest.cc',
'../../plugins/npapi/plugin_lib_unittest.cc',
+ '../../plugins/npapi/plugin_list_unittest.cc',
'../../plugins/npapi/webplugin_impl_unittest.cc',
'../../plugins/ppapi/callbacks_unittest.cc',
'../../plugins/ppapi/mock_plugin_delegate.cc',
diff --git a/webkit/tools/test_shell/test_webview_delegate.cc b/webkit/tools/test_shell/test_webview_delegate.cc
index 9ca127a..ce2485e 100644
--- a/webkit/tools/test_shell/test_webview_delegate.cc
+++ b/webkit/tools/test_shell/test_webview_delegate.cc
@@ -716,7 +716,7 @@ WebPlugin* TestWebViewDelegate::createPlugin(WebFrame* frame,
std::string actual_mime_type;
if (!webkit::npapi::PluginList::Singleton()->GetPluginInfo(
params.url, params.mimeType.utf8(), allow_wildcard, &info,
- &actual_mime_type) || !info.enabled)
+ &actual_mime_type) || !webkit::npapi::IsPluginEnabled(info))
return NULL;
return new webkit::npapi::WebPluginImpl(