summaryrefslogtreecommitdiffstats
path: root/chrome/browser/plugin_prefs.cc
diff options
context:
space:
mode:
authorbauerb@chromium.org <bauerb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-09-15 09:30:28 +0000
committerbauerb@chromium.org <bauerb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-09-15 09:30:28 +0000
commit682ef685be471686d07513f4e44e59c9a71cf356 (patch)
tree283cf7eda62b47bc86aa50782d1497b618d2b869 /chrome/browser/plugin_prefs.cc
parentbb035bc522fb7e7162ea6f5e12a80d86b5aa6a8d (diff)
downloadchromium_src-682ef685be471686d07513f4e44e59c9a71cf356.zip
chromium_src-682ef685be471686d07513f4e44e59c9a71cf356.tar.gz
chromium_src-682ef685be471686d07513f4e44e59c9a71cf356.tar.bz2
Store plug-in enabled/disabled state in PluginPrefs instead of WebPluginInfo, to allow different sets of enabled/disabled plug-ins to be specified per profile.
BUG=80794 TEST=Open two profiles, disable different plugins in them. Review URL: http://codereview.chromium.org/7848025 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@101269 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/plugin_prefs.cc')
-rw-r--r--chrome/browser/plugin_prefs.cc354
1 files changed, 247 insertions, 107 deletions
diff --git a/chrome/browser/plugin_prefs.cc b/chrome/browser/plugin_prefs.cc
index 50d1d42..a60a28b 100644
--- a/chrome/browser/plugin_prefs.cc
+++ b/chrome/browser/plugin_prefs.cc
@@ -7,19 +7,23 @@
#include <string>
#include "base/command_line.h"
+#include "base/lazy_instance.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/singleton.h"
#include "base/message_loop.h"
#include "base/path_service.h"
+#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "base/version.h"
+#include "chrome/browser/browser_process.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/prefs/scoped_user_pref_update.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_dependency_manager.h"
#include "chrome/browser/profiles/profile_keyed_service.h"
#include "chrome/browser/profiles/profile_keyed_service_factory.h"
+#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/common/chrome_content_client.h"
#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/chrome_paths.h"
@@ -27,6 +31,7 @@
#include "chrome/common/pref_names.h"
#include "content/browser/browser_thread.h"
#include "content/common/notification_service.h"
+#include "webkit/plugins/npapi/plugin_group.h"
#include "webkit/plugins/npapi/plugin_list.h"
#include "webkit/plugins/webplugininfo.h"
@@ -49,6 +54,11 @@ class PluginPrefsWrapper : public ProfileKeyedService {
scoped_refptr<PluginPrefs> plugin_prefs_;
};
+// Default state for a plug-in (not state of the default plug-in!).
+// Accessed only on the UI thread.
+base::LazyInstance<std::map<FilePath, bool> > g_default_plugin_state(
+ base::LINKER_INITIALIZED);
+
}
// How long to wait to save the plugin enabled information, which might need to
@@ -61,6 +71,10 @@ class PluginPrefs::Factory : public ProfileKeyedServiceFactory {
PluginPrefsWrapper* GetWrapperForProfile(Profile* profile);
+ // Factory function for use with
+ // ProfileKeyedServiceFactory::SetTestingFactory.
+ static ProfileKeyedService* CreateWrapperForProfile(Profile* profile);
+
private:
friend struct DefaultSingletonTraits<Factory>;
@@ -89,31 +103,138 @@ PluginPrefs* PluginPrefs::GetForProfile(Profile* profile) {
return wrapper->plugin_prefs();
}
-DictionaryValue* PluginPrefs::CreatePluginFileSummary(
- const webkit::WebPluginInfo& plugin) {
- DictionaryValue* data = new DictionaryValue();
- data->SetString("path", plugin.path.value());
- data->SetString("name", plugin.name);
- data->SetString("version", plugin.version);
- data->SetBoolean("enabled", IsPluginEnabled(plugin));
- return data;
+// static
+PluginPrefs* PluginPrefs::GetForTestingProfile(Profile* profile) {
+ ProfileKeyedService* wrapper =
+ Factory::GetInstance()->SetTestingFactoryAndUse(
+ profile, &Factory::CreateWrapperForProfile);
+ return static_cast<PluginPrefsWrapper*>(wrapper)->plugin_prefs();
}
-void PluginPrefs::EnablePluginGroup(bool enable, const string16& group_name) {
- webkit::npapi::PluginList::Singleton()->EnableGroup(enable, group_name);
- NotifyPluginStatusChanged();
+void PluginPrefs::EnablePluginGroup(bool enabled, const string16& group_name) {
+ if (!BrowserThread::CurrentlyOn(BrowserThread::FILE)) {
+ BrowserThread::PostTask(
+ BrowserThread::FILE, FROM_HERE,
+ NewRunnableMethod(this, &PluginPrefs::EnablePluginGroup,
+ enabled, group_name));
+ return;
+ }
+
+ webkit::npapi::PluginList* plugin_list =
+ webkit::npapi::PluginList::Singleton();
+ std::vector<webkit::npapi::PluginGroup> groups;
+ plugin_list->GetPluginGroups(true, &groups);
+
+ base::AutoLock auto_lock(lock_);
+
+ // Set the desired state for the group.
+ plugin_group_state_[group_name] = enabled;
+
+ // Update the state for all plug-ins in the group.
+ for (size_t i = 0; i < groups.size(); ++i) {
+ if (groups[i].GetGroupName() != group_name)
+ continue;
+ const std::vector<webkit::WebPluginInfo>& plugins =
+ groups[i].web_plugin_infos();
+ for (size_t j = 0; j < plugins.size(); ++j)
+ plugin_state_[plugins[j].path] = enabled;
+ break;
+ }
+
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ NewRunnableMethod(this, &PluginPrefs::OnUpdatePreferences, groups));
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ NewRunnableMethod(this, &PluginPrefs::NotifyPluginStatusChanged));
}
-void PluginPrefs::EnablePlugin(bool enable, const FilePath& path) {
- if (enable)
- webkit::npapi::PluginList::Singleton()->EnablePlugin(path);
- else
- webkit::npapi::PluginList::Singleton()->DisablePlugin(path);
+void PluginPrefs::EnablePlugin(bool enabled, const FilePath& path) {
+ if (!BrowserThread::CurrentlyOn(BrowserThread::FILE)) {
+ BrowserThread::PostTask(
+ BrowserThread::FILE, FROM_HERE,
+ NewRunnableMethod(this, &PluginPrefs::EnablePlugin, enabled, path));
+ return;
+ }
- NotifyPluginStatusChanged();
+ {
+ // Set the desired state for the plug-in.
+ base::AutoLock auto_lock(lock_);
+ plugin_state_[path] = enabled;
+ }
+
+ webkit::npapi::PluginList* plugin_list =
+ webkit::npapi::PluginList::Singleton();
+ std::vector<webkit::npapi::PluginGroup> groups;
+ plugin_list->GetPluginGroups(true, &groups);
+
+ bool found_group = false;
+ for (size_t i = 0; i < groups.size(); ++i) {
+ bool all_disabled = true;
+ const std::vector<webkit::WebPluginInfo>& plugins =
+ groups[i].web_plugin_infos();
+ for (size_t j = 0; j < plugins.size(); ++j) {
+ all_disabled = all_disabled && !IsPluginEnabled(plugins[j]);
+ if (plugins[j].path == path) {
+ found_group = true;
+ DCHECK_EQ(enabled, IsPluginEnabled(plugins[j]));
+ }
+ }
+ if (found_group) {
+ // Update the state for the corresponding plug-in group.
+ base::AutoLock auto_lock(lock_);
+ plugin_group_state_[groups[i].GetGroupName()] = !all_disabled;
+ break;
+ }
+ }
+
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ NewRunnableMethod(this, &PluginPrefs::OnUpdatePreferences, groups));
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ NewRunnableMethod(this, &PluginPrefs::NotifyPluginStatusChanged));
+}
+
+// static
+void PluginPrefs::EnablePluginGlobally(bool enable, const FilePath& file_path) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ g_default_plugin_state.Get()[file_path] = enable;
+ std::vector<Profile*> profiles =
+ g_browser_process->profile_manager()->GetLoadedProfiles();
+ for (std::vector<Profile*>::iterator it = profiles.begin();
+ it != profiles.end(); ++it) {
+ PluginPrefs* plugin_prefs = PluginPrefs::GetForProfile(*it);
+ DCHECK(plugin_prefs);
+ plugin_prefs->EnablePlugin(enable, file_path);
+ }
+}
+
+PluginPrefs::PolicyStatus PluginPrefs::PolicyStatusForPlugin(
+ const string16& name) {
+ base::AutoLock auto_lock(lock_);
+ if (IsStringMatchedInSet(name, policy_enabled_plugin_patterns_)) {
+ return POLICY_ENABLED;
+ } else if (IsStringMatchedInSet(name, policy_disabled_plugin_patterns_) &&
+ !IsStringMatchedInSet(
+ name, policy_disabled_plugin_exception_patterns_)) {
+ return POLICY_DISABLED;
+ } else {
+ return NO_POLICY;
+ }
}
bool PluginPrefs::IsPluginEnabled(const webkit::WebPluginInfo& plugin) {
+ scoped_ptr<webkit::npapi::PluginGroup> group(
+ webkit::npapi::PluginList::Singleton()->GetPluginGroup(plugin));
+ string16 group_name = group->GetGroupName();
+
+ // Check if the plug-in or its group is enabled by policy.
+ PolicyStatus plugin_status = PolicyStatusForPlugin(plugin.name);
+ PolicyStatus group_status = PolicyStatusForPlugin(group_name);
+ if (plugin_status == POLICY_ENABLED || group_status == POLICY_ENABLED)
+ return true;
+
+ // Check if the plug-in or its group is disabled by policy.
+ if (plugin_status == POLICY_DISABLED || group_status == POLICY_DISABLED)
+ return false;
+
// If enabling NaCl, make sure the plugin is also enabled. See bug
// http://code.google.com/p/chromium/issues/detail?id=81010 for more
// information.
@@ -123,12 +244,27 @@ bool PluginPrefs::IsPluginEnabled(const webkit::WebPluginInfo& plugin) {
CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableNaCl)) {
return true;
}
- return webkit::IsPluginEnabled(plugin);
+
+ base::AutoLock auto_lock(lock_);
+ // Check user preferences for the plug-in.
+ std::map<FilePath, bool>::iterator plugin_it =
+ plugin_state_.find(plugin.path);
+ if (plugin_it != plugin_state_.end())
+ return plugin_it->second;
+
+ // Check user preferences for the plug-in group.
+ std::map<string16, bool>::iterator group_it(
+ plugin_group_state_.find(plugin.name));
+ if (group_it != plugin_group_state_.end())
+ return group_it->second;
+
+ // Default to enabled.
+ return true;
}
void PluginPrefs::Observe(int type,
- const NotificationSource& source,
- const NotificationDetails& details) {
+ const NotificationSource& source,
+ const NotificationDetails& details) {
DCHECK_EQ(chrome::NOTIFICATION_PREF_CHANGED, type);
const std::string* pref_name = Details<std::string>(details).ptr();
if (!pref_name) {
@@ -136,39 +272,39 @@ void PluginPrefs::Observe(int type,
return;
}
DCHECK_EQ(prefs_, Source<PrefService>(source).ptr());
- if (*pref_name == prefs::kPluginsDisabledPlugins ||
- *pref_name == prefs::kPluginsDisabledPluginsExceptions ||
- *pref_name == prefs::kPluginsEnabledPlugins) {
- const ListValue* disabled_list =
- prefs_->GetList(prefs::kPluginsDisabledPlugins);
- const ListValue* exceptions_list =
- prefs_->GetList(prefs::kPluginsDisabledPluginsExceptions);
- const ListValue* enabled_list =
- prefs_->GetList(prefs::kPluginsEnabledPlugins);
- UpdatePluginsStateFromPolicy(disabled_list, exceptions_list, enabled_list);
+ if (*pref_name == prefs::kPluginsDisabledPlugins) {
+ base::AutoLock auto_lock(lock_);
+ ListValueToStringSet(prefs_->GetList(prefs::kPluginsDisabledPlugins),
+ &policy_disabled_plugin_patterns_);
+ } else if (*pref_name == prefs::kPluginsDisabledPluginsExceptions) {
+ base::AutoLock auto_lock(lock_);
+ ListValueToStringSet(
+ prefs_->GetList(prefs::kPluginsDisabledPluginsExceptions),
+ &policy_disabled_plugin_exception_patterns_);
+ } else if (*pref_name == prefs::kPluginsEnabledPlugins) {
+ base::AutoLock auto_lock(lock_);
+ ListValueToStringSet(prefs_->GetList(prefs::kPluginsEnabledPlugins),
+ &policy_enabled_plugin_patterns_);
+ } else {
+ NOTREACHED();
}
+ NotifyPluginStatusChanged();
}
-void PluginPrefs::UpdatePluginsStateFromPolicy(
- const ListValue* disabled_list,
- const ListValue* exceptions_list,
- const ListValue* enabled_list) {
- std::set<string16> disabled_plugin_patterns;
- std::set<string16> disabled_plugin_exception_patterns;
- std::set<string16> enabled_plugin_patterns;
-
- ListValueToStringSet(disabled_list, &disabled_plugin_patterns);
- ListValueToStringSet(exceptions_list, &disabled_plugin_exception_patterns);
- ListValueToStringSet(enabled_list, &enabled_plugin_patterns);
-
- webkit::npapi::PluginGroup::SetPolicyEnforcedPluginPatterns(
- disabled_plugin_patterns,
- disabled_plugin_exception_patterns,
- enabled_plugin_patterns);
+/*static*/
+bool PluginPrefs::IsStringMatchedInSet(const string16& name,
+ const std::set<string16>& pattern_set) {
+ std::set<string16>::const_iterator pattern(pattern_set.begin());
+ while (pattern != pattern_set.end()) {
+ if (MatchPattern(name, *pattern))
+ return true;
+ ++pattern;
+ }
- NotifyPluginStatusChanged();
+ return false;
}
+/* static */
void PluginPrefs::ListValueToStringSet(const ListValue* src,
std::set<string16>* dest) {
DCHECK(src);
@@ -277,8 +413,7 @@ void PluginPrefs::SetPrefs(PrefService* prefs) {
}
}
- if (!enabled)
- webkit::npapi::PluginList::Singleton()->DisablePlugin(plugin_path);
+ plugin_state_[plugin_path] = enabled;
} else if (!enabled && plugin->GetString("name", &group_name)) {
// Don't disable this group if it's for the pdf or nacl plugins and
// we just forced it on.
@@ -289,7 +424,7 @@ void PluginPrefs::SetPrefs(PrefService* prefs) {
continue;
// Otherwise this is a list of groups.
- EnablePluginGroup(false, group_name);
+ plugin_group_state_[group_name] = false;
}
}
} else {
@@ -304,17 +439,14 @@ void PluginPrefs::SetPrefs(PrefService* prefs) {
// Build the set of policy enabled/disabled plugin patterns once and cache it.
// Don't do this in the constructor, there's no profile available there.
- const ListValue* disabled_plugins =
- prefs_->GetList(prefs::kPluginsDisabledPlugins);
- const ListValue* disabled_exception_plugins =
- prefs_->GetList(prefs::kPluginsDisabledPluginsExceptions);
- const ListValue* enabled_plugins =
- prefs_->GetList(prefs::kPluginsEnabledPlugins);
- UpdatePluginsStateFromPolicy(disabled_plugins,
- disabled_exception_plugins,
- enabled_plugins);
+ ListValueToStringSet(prefs_->GetList(prefs::kPluginsDisabledPlugins),
+ &policy_disabled_plugin_patterns_);
+ ListValueToStringSet(
+ prefs_->GetList(prefs::kPluginsDisabledPluginsExceptions),
+ &policy_disabled_plugin_exception_patterns_);
+ ListValueToStringSet(prefs_->GetList(prefs::kPluginsEnabledPlugins),
+ &policy_enabled_plugin_patterns_);
- registrar_.RemoveAll();
registrar_.Init(prefs_);
registrar_.Add(prefs::kPluginsDisabledPlugins, this);
registrar_.Add(prefs::kPluginsDisabledPluginsExceptions, this);
@@ -322,16 +454,22 @@ void PluginPrefs::SetPrefs(PrefService* prefs) {
if (force_enable_internal_pdf || internal_pdf_enabled) {
// See http://crbug.com/50105 for background.
- EnablePluginGroup(false, ASCIIToUTF16(
- webkit::npapi::PluginGroup::kAdobeReaderGroupName));
+ plugin_group_state_[ASCIIToUTF16(
+ webkit::npapi::PluginGroup::kAdobeReaderGroupName)] = false;
}
if (force_enable_internal_pdf || force_enable_nacl) {
// We want to save this, but doing so requires loading the list of plugins,
// so do it after a minute as to not impact startup performance. Note that
// plugins are loaded after 30s by the metrics service.
- UpdatePreferences(kPluginUpdateDelayMs);
+ BrowserThread::PostDelayedTask(
+ BrowserThread::FILE,
+ FROM_HERE,
+ NewRunnableMethod(this, &PluginPrefs::GetPreferencesDataOnFileThread),
+ kPluginUpdateDelayMs);
}
+
+ NotifyPluginStatusChanged();
}
void PluginPrefs::ShutdownOnUIThread() {
@@ -349,47 +487,51 @@ PluginPrefsWrapper* PluginPrefs::Factory::GetWrapperForProfile(
return static_cast<PluginPrefsWrapper*>(GetServiceForProfile(profile, true));
}
+// static
+ProfileKeyedService* PluginPrefs::Factory::CreateWrapperForProfile(
+ Profile* profile) {
+ return GetInstance()->BuildServiceInstanceFor(profile);
+}
+
PluginPrefs::Factory::Factory()
: ProfileKeyedServiceFactory(ProfileDependencyManager::GetInstance()) {
}
ProfileKeyedService* PluginPrefs::Factory::BuildServiceInstanceFor(
- Profile* profile) const {
+ Profile* profile) const {
scoped_refptr<PluginPrefs> plugin_prefs(new PluginPrefs());
plugin_prefs->SetPrefs(profile->GetPrefs());
return new PluginPrefsWrapper(plugin_prefs);
}
-PluginPrefs::PluginPrefs() : prefs_(NULL), notify_pending_(false) {
+PluginPrefs::PluginPrefs() : plugin_state_(g_default_plugin_state.Get()),
+ prefs_(NULL) {
}
PluginPrefs::~PluginPrefs() {
}
-void PluginPrefs::UpdatePreferences(int delay_ms) {
- BrowserThread::PostDelayedTask(
- BrowserThread::FILE,
- FROM_HERE,
- NewRunnableMethod(this, &PluginPrefs::GetPreferencesDataOnFileThread),
- delay_ms);
+void PluginPrefs::SetPolicyEnforcedPluginPatterns(
+ const std::set<string16>& disabled_patterns,
+ const std::set<string16>& disabled_exception_patterns,
+ const std::set<string16>& enabled_patterns) {
+ policy_disabled_plugin_patterns_ = disabled_patterns;
+ policy_disabled_plugin_exception_patterns_ = disabled_exception_patterns;
+ policy_enabled_plugin_patterns_ = enabled_patterns;
}
void PluginPrefs::GetPreferencesDataOnFileThread() {
- std::vector<webkit::WebPluginInfo> plugins;
std::vector<webkit::npapi::PluginGroup> groups;
webkit::npapi::PluginList* plugin_list =
webkit::npapi::PluginList::Singleton();
- plugin_list->GetPlugins(&plugins);
plugin_list->GetPluginGroups(false, &groups);
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- NewRunnableMethod(this, &PluginPrefs::OnUpdatePreferences,
- plugins, groups));
+ NewRunnableMethod(this, &PluginPrefs::OnUpdatePreferences, groups));
}
void PluginPrefs::OnUpdatePreferences(
- std::vector<webkit::WebPluginInfo> plugins,
std::vector<webkit::npapi::PluginGroup> groups) {
if (!prefs_)
return;
@@ -402,44 +544,42 @@ void PluginPrefs::OnUpdatePreferences(
if (PathService::Get(chrome::DIR_INTERNAL_PLUGINS, &internal_dir))
prefs_->SetFilePath(prefs::kPluginsLastInternalDirectory, internal_dir);
- // Add the plugin files.
- for (size_t i = 0; i < plugins.size(); ++i) {
- DictionaryValue* summary = CreatePluginFileSummary(plugins[i]);
- // If the plugin is managed by policy, store the user preferred state
- // instead.
- if (plugins[i].enabled & webkit::WebPluginInfo::MANAGED_MASK) {
- bool user_enabled =
- (plugins[i].enabled & webkit::WebPluginInfo::USER_MASK) ==
- webkit::WebPluginInfo::USER_ENABLED;
- summary->SetBoolean("enabled", user_enabled);
- }
- plugins_list->Append(summary);
- }
+ base::AutoLock auto_lock(lock_);
- // Add the groups as well.
+ // Add the plug-in groups.
for (size_t i = 0; i < groups.size(); ++i) {
- DictionaryValue* summary = groups[i].GetSummary();
- // If the plugin is disabled only by policy don't store this state in the
- // user pref store.
- if (!groups[i].Enabled() &&
- webkit::npapi::PluginGroup::IsPluginNameDisabledByPolicy(
- groups[i].GetGroupName()))
- summary->SetBoolean("enabled", true);
+ // Add the plugin files to the same list.
+ const std::vector<webkit::WebPluginInfo>& plugins =
+ groups[i].web_plugin_infos();
+ for (size_t j = 0; j < plugins.size(); ++j) {
+ DictionaryValue* summary = new DictionaryValue();
+ summary->SetString("path", plugins[j].path.value());
+ summary->SetString("name", plugins[j].name);
+ summary->SetString("version", plugins[j].version);
+ bool enabled = true;
+ std::map<FilePath, bool>::iterator it =
+ plugin_state_.find(plugins[j].path);
+ if (it != plugin_state_.end())
+ enabled = it->second;
+ summary->SetBoolean("enabled", enabled);
plugins_list->Append(summary);
+ }
+
+ DictionaryValue* summary = new DictionaryValue();
+ string16 name = groups[i].GetGroupName();
+ summary->SetString("name", name);
+ bool enabled = true;
+ std::map<string16, bool>::iterator it =
+ plugin_group_state_.find(name);
+ if (it != plugin_group_state_.end())
+ enabled = it->second;
+ summary->SetBoolean("enabled", enabled);
+ plugins_list->Append(summary);
}
}
void PluginPrefs::NotifyPluginStatusChanged() {
- if (notify_pending_)
- return;
- notify_pending_ = true;
- MessageLoop::current()->PostTask(
- FROM_HERE,
- NewRunnableMethod(this, &PluginPrefs::OnNotifyPluginStatusChanged));
-}
-
-void PluginPrefs::OnNotifyPluginStatusChanged() {
- notify_pending_ = false;
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
NotificationService::current()->Notify(
chrome::NOTIFICATION_PLUGIN_ENABLE_STATUS_CHANGED,
Source<PluginPrefs>(this),