Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4592)

Unified Diff: chrome/browser/content_settings/pref_content_settings_provider.cc

Issue 6410022: Add content_settings::PrefProvider to HostContentSettingsMap. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Worked on comments Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/content_settings/pref_content_settings_provider.cc
diff --git a/chrome/browser/content_settings/pref_content_settings_provider.cc b/chrome/browser/content_settings/pref_content_settings_provider.cc
index a7cf5e06fc84483d5e07e1122e5ce0d417052c36..aaa6125bfb2fcb08d68282cf53a468f59ae65c3b 100644
--- a/chrome/browser/content_settings/pref_content_settings_provider.cc
+++ b/chrome/browser/content_settings/pref_content_settings_provider.cc
@@ -5,6 +5,8 @@
#include "chrome/browser/content_settings/pref_content_settings_provider.h"
#include <string>
+#include <vector>
+#include <utility>
#include "base/command_line.h"
#include "chrome/browser/browser_thread.h"
@@ -14,13 +16,28 @@
#include "chrome/browser/prefs/scoped_pref_update.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/chrome_switches.h"
+#include "chrome/common/content_settings.h"
#include "chrome/common/notification_details.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/notification_source.h"
#include "chrome/common/pref_names.h"
+#include "googleurl/src/gurl.h"
+#include "net/base/net_util.h"
namespace {
+// The preference keys where resource identifiers are stored for
+// ContentSettingsType values that support resource identifiers.
+const char* kResourceTypeNames[CONTENT_SETTINGS_NUM_TYPES] = {
+ NULL,
+ NULL,
+ NULL,
+ "per_plugin",
+ NULL,
+ NULL, // Not used for Geolocation
+ NULL, // Not used for Notifications
+};
+
// The default setting for each content type.
const ContentSetting kDefaultSettings[CONTENT_SETTINGS_NUM_TYPES] = {
CONTENT_SETTING_ALLOW, // CONTENT_SETTINGS_TYPE_COOKIES
@@ -43,6 +60,17 @@ const char* kTypeNames[CONTENT_SETTINGS_NUM_TYPES] = {
NULL, // Not used for Notifications
};
+// True if a given content settings type requires additional resource
+// identifiers.
+const bool kRequiresResourceIdentifier[CONTENT_SETTINGS_NUM_TYPES] = {
+ false, // CONTENT_SETTINGS_TYPE_COOKIES
+ false, // CONTENT_SETTINGS_TYPE_IMAGES
+ false, // CONTET_SETTINGS_TYPE_JAVASCRIPT
+ true, // CONTENT_SETTINGS_TYPE_PLUGINS
+ false, // CONTENT_SETTINGS_TYPE_POPUPS
+ false, // Not used for Geolocation
+ false, // Not used for Notifications
+};
// Map ASK for the plugins content type to BLOCK if click-to-play is
// not enabled.
@@ -261,4 +289,675 @@ void PrefDefaultProvider::RegisterUserPrefs(PrefService* prefs) {
prefs->RegisterDictionaryPref(prefs::kDefaultContentSettings);
}
+// ////////////////////////////////////////////////////////////////////////////
+// PrefProvider::
+//
+
+// static
+void PrefProvider::RegisterUserPrefs(PrefService* prefs) {
+ prefs->RegisterIntegerPref(prefs::kContentSettingsVersion,
+ ContentSettingsPattern::kContentSettingsPatternVersion);
+ prefs->RegisterDictionaryPref(prefs::kContentSettingsPatterns);
+
+ // Obsolete prefs, for migration:
+ prefs->RegisterListPref(prefs::kPopupWhitelistedHosts);
+ prefs->RegisterDictionaryPref(prefs::kPerHostContentSettings);
+}
+
+PrefProvider::PrefProvider(Profile* profile)
+ : profile_(profile),
+ is_off_the_record_(profile_->IsOffTheRecord()),
+ updating_preferences_(false) {
+ initializing_ = true;
+ PrefService* prefs = profile_->GetPrefs();
+
+ // Migrate obsolete preferences.
+ MigrateObsoletePerhostPref(prefs);
+ MigrateObsoletePopupsPref(prefs);
+
+ // Verify preferences version.
+ if (!prefs->HasPrefPath(prefs::kContentSettingsVersion)) {
+ prefs->SetInteger(prefs::kContentSettingsVersion,
+ ContentSettingsPattern::kContentSettingsPatternVersion);
+ }
+ if (prefs->GetInteger(prefs::kContentSettingsVersion) >
+ ContentSettingsPattern::kContentSettingsPatternVersion) {
+ LOG(ERROR) << "Unknown content settings version in preferences.";
+ return;
+ }
+
+ // Read exceptions.
+ ReadExceptions(false);
+
+ pref_change_registrar_.Init(prefs);
+ pref_change_registrar_.Add(prefs::kContentSettingsPatterns, this);
+
+ notification_registrar_.Add(this, NotificationType::PROFILE_DESTROYED,
+ Source<Profile>(profile_));
+ initializing_ = false;
+}
+
+bool PrefProvider::ContentSettingsTypeIsManaged(
+ ContentSettingsType content_type) {
+ return false;
+}
+
+ContentSetting PrefProvider::GetContentSetting(
+ const GURL& requesting_url,
+ const GURL& embedding_url,
+ ContentSettingsType content_type,
+ const ResourceIdentifier& resource_identifier) const {
+ // Support for embedding_patterns is not implemented yet.
+ DCHECK(requesting_url == embedding_url);
+
+ if (!RequiresResourceIdentifier(content_type))
+ return GetNonDefaultContentSettings(requesting_url).settings[content_type];
+
+ if (RequiresResourceIdentifier(content_type) && resource_identifier.empty())
+ return CONTENT_SETTING_DEFAULT;
+
+ if (CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableResourceContentSettings)) {
+ DCHECK(!resource_identifier.empty());
+ }
+
+ base::AutoLock auto_lock(lock_);
+
+ const std::string host(net::GetHostOrSpecFromURL(requesting_url));
+ ContentSettingsTypeResourceIdentifierPair
+ requested_setting(content_type, resource_identifier);
+
+ // Check for exact matches first.
+ HostContentSettings::const_iterator i(host_content_settings_.find(host));
+ if (i != host_content_settings_.end() &&
+ i->second.content_settings_for_resources.find(requested_setting) !=
+ i->second.content_settings_for_resources.end()) {
+ return i->second.content_settings_for_resources.find(
+ requested_setting)->second;
+ }
+
+ // If this map is not for an off-the-record profile, these searches will never
+ // match. The additional off-the-record exceptions always overwrite the
+ // regular ones.
+ i = off_the_record_settings_.find(host);
+ if (i != off_the_record_settings_.end() &&
+ i->second.content_settings_for_resources.find(requested_setting) !=
+ i->second.content_settings_for_resources.end()) {
+ return i->second.content_settings_for_resources.find(
+ requested_setting)->second;
+ }
+
+ // Match patterns starting with the most concrete pattern match.
+ for (std::string key =
+ std::string(ContentSettingsPattern::kDomainWildcard) + host; ; ) {
+ HostContentSettings::const_iterator i(off_the_record_settings_.find(key));
+ if (i != off_the_record_settings_.end() &&
+ i->second.content_settings_for_resources.find(requested_setting) !=
+ i->second.content_settings_for_resources.end()) {
+ return i->second.content_settings_for_resources.find(
+ requested_setting)->second;
+ }
+
+ i = host_content_settings_.find(key);
+ if (i != host_content_settings_.end() &&
+ i->second.content_settings_for_resources.find(requested_setting) !=
+ i->second.content_settings_for_resources.end()) {
+ return i->second.content_settings_for_resources.find(
+ requested_setting)->second;
+ }
+
+ const size_t next_dot =
+ key.find('.', ContentSettingsPattern::kDomainWildcardLength);
+ if (next_dot == std::string::npos)
+ break;
+ key.erase(ContentSettingsPattern::kDomainWildcardLength,
+ next_dot - ContentSettingsPattern::kDomainWildcardLength + 1);
+ }
+
+ return CONTENT_SETTING_DEFAULT;
+}
+
+void PrefProvider::SetContentSetting(
+ const ContentSettingsPattern& requesting_pattern,
+ const ContentSettingsPattern& embedding_pattern,
+ ContentSettingsType content_type,
+ const ResourceIdentifier& resource_identifier,
+ ContentSetting setting) {
+ // Support for embedding_patterns is not implemented yet.
+ DCHECK(requesting_pattern == embedding_pattern);
+
+ DCHECK(kTypeNames[content_type] != NULL); // Don't call this for Geolocation.
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK_NE(RequiresResourceIdentifier(content_type),
+ resource_identifier.empty());
+ DCHECK(content_type != CONTENT_SETTINGS_TYPE_PLUGINS ||
+ setting != CONTENT_SETTING_ASK ||
+ CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableClickToPlay));
+
+ const ContentSettingsPattern pattern(
+ requesting_pattern.CanonicalizePattern());
+
+ bool early_exit = false;
+ std::string pattern_str(pattern.AsString());
+ PrefService* prefs = NULL;
+ DictionaryValue* all_settings_dictionary = NULL;
+ HostContentSettings* map_to_modify = &off_the_record_settings_;
+ if (!is_off_the_record_) {
+ prefs = profile_->GetPrefs();
+ all_settings_dictionary =
+ prefs->GetMutableDictionary(prefs::kContentSettingsPatterns);
Bernhard Bauer 2011/02/07 09:46:46 Nit: indent two more spaces.
markusheintz_ 2011/02/07 15:57:10 Done.
+ map_to_modify = &host_content_settings_;
+ }
+
+ {
+ base::AutoLock auto_lock(lock_);
+ if (!map_to_modify->count(pattern_str))
+ (*map_to_modify)[pattern_str].content_settings = ContentSettings();
+ HostContentSettings::iterator
+ i(map_to_modify->find(pattern_str));
Bernhard Bauer 2011/02/07 09:46:46 Nit: break after `i(' ?
markusheintz_ 2011/02/07 15:57:10 Done.
+ ContentSettings& settings = i->second.content_settings;
+ if (RequiresResourceIdentifier(content_type)) {
+ settings.settings[content_type] = CONTENT_SETTING_DEFAULT;
+ if (setting != CONTENT_SETTING_DEFAULT) {
+ i->second.content_settings_for_resources[
+ ContentSettingsTypeResourceIdentifierPair(content_type,
+ resource_identifier)] = setting;
+ } else {
+ i->second.content_settings_for_resources.erase(
+ ContentSettingsTypeResourceIdentifierPair(content_type,
+ resource_identifier));
+ }
+ } else {
+ settings.settings[content_type] = setting;
+ }
+ if (AllDefault(i->second)) {
+ map_to_modify->erase(i);
+ if (all_settings_dictionary)
+ all_settings_dictionary->RemoveWithoutPathExpansion(pattern_str, NULL);
+
+ // We can't just return because |NotifyObservers()| needs to be called,
+ // without |lock_| being held.
+ early_exit = true;
+ }
+ }
+
+ if (!early_exit && all_settings_dictionary) {
+ DictionaryValue* host_settings_dictionary = NULL;
+ bool found = all_settings_dictionary->GetDictionaryWithoutPathExpansion(
+ pattern_str, &host_settings_dictionary);
+ if (!found) {
+ host_settings_dictionary = new DictionaryValue;
+ all_settings_dictionary->SetWithoutPathExpansion(
+ pattern_str, host_settings_dictionary);
+ DCHECK_NE(setting, CONTENT_SETTING_DEFAULT);
+ }
+ if (RequiresResourceIdentifier(content_type)) {
+ std::string dictionary_path(kResourceTypeNames[content_type]);
+ DictionaryValue* resource_dictionary = NULL;
+ found = host_settings_dictionary->GetDictionary(
+ dictionary_path, &resource_dictionary);
+ if (!found) {
+ resource_dictionary = new DictionaryValue;
+ host_settings_dictionary->Set(dictionary_path, resource_dictionary);
+ }
+ if (setting == CONTENT_SETTING_DEFAULT) {
+ resource_dictionary->RemoveWithoutPathExpansion(resource_identifier,
+ NULL);
+ } else {
+ resource_dictionary->SetWithoutPathExpansion(
+ resource_identifier, Value::CreateIntegerValue(setting));
+ }
+ } else {
+ std::string dictionary_path(kTypeNames[content_type]);
+ if (setting == CONTENT_SETTING_DEFAULT) {
+ host_settings_dictionary->RemoveWithoutPathExpansion(dictionary_path,
+ NULL);
+ } else {
+ host_settings_dictionary->SetWithoutPathExpansion(
+ dictionary_path, Value::CreateIntegerValue(setting));
+ }
+ }
+ }
+
+ updating_preferences_ = true;
+ if (!is_off_the_record_)
+ ScopedPrefUpdate update(prefs, prefs::kContentSettingsPatterns);
+ updating_preferences_ = false;
+
+ NotifyObservers(ContentSettingsDetails(pattern, content_type, ""));
+}
+
+void PrefProvider::GetAllContentSettingsRules(
+ ContentSettingsType content_type,
+ const ResourceIdentifier& resource_identifier,
+ Rules* content_setting_rules) const {
+ DCHECK(RequiresResourceIdentifier(content_type) !=
+ resource_identifier.empty());
+ DCHECK(content_setting_rules);
+ content_setting_rules->clear();
+
+ const HostContentSettings* map_to_return =
+ is_off_the_record_ ? &off_the_record_settings_ : &host_content_settings_;
+ ContentSettingsTypeResourceIdentifierPair
+ requested_setting(content_type, resource_identifier);
Bernhard Bauer 2011/02/07 09:46:46 Nit: break after `requested_setting(' if it fits.
markusheintz_ 2011/02/07 15:57:10 Done.
+
+ base::AutoLock auto_lock(lock_);
+ for (HostContentSettings::const_iterator i(map_to_return->begin());
+ i != map_to_return->end(); ++i) {
+ ContentSetting setting;
+ if (RequiresResourceIdentifier(content_type)) {
+ if (i->second.content_settings_for_resources.find(requested_setting) !=
+ i->second.content_settings_for_resources.end())
+ setting = i->second.content_settings_for_resources.find(
Bernhard Bauer 2011/02/07 09:46:46 Nit: Please add braces for the two branches.
markusheintz_ 2011/02/07 15:57:10 Done.
+ requested_setting)->second;
+ else
+ setting = CONTENT_SETTING_DEFAULT;
+ } else {
+ setting = i->second.content_settings.settings[content_type];
+ }
+ if (setting != CONTENT_SETTING_DEFAULT) {
+ // Use of push_back() relies on the map iterator traversing in order of
+ // ascending keys.
+ content_setting_rules->push_back(Rule(ContentSettingsPattern(i->first),
+ ContentSettingsPattern(i->first),
+ setting));
+ }
+ }
+}
+
+void PrefProvider::ResetToDefaults() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ {
+ base::AutoLock auto_lock(lock_);
+ host_content_settings_.clear();
+ off_the_record_settings_.clear();
+ }
+
+ if (!is_off_the_record_) {
+ PrefService* prefs = profile_->GetPrefs();
+ updating_preferences_ = true;
+ prefs->ClearPref(prefs::kContentSettingsPatterns);
+ updating_preferences_ = false;
+ }
+}
+
+void PrefProvider::ClearAllContentSettingsRules(
+ ContentSettingsType content_type) {
+ DCHECK(kTypeNames[content_type] != NULL); // Don't call this for Geolocation.
+
+ PrefService* prefs = NULL;
+ DictionaryValue* all_settings_dictionary = NULL;
+ HostContentSettings* map_to_modify = &off_the_record_settings_;
+
+ if (!is_off_the_record_) {
+ prefs = profile_->GetPrefs();
+ all_settings_dictionary =
+ prefs->GetMutableDictionary(prefs::kContentSettingsPatterns);
Bernhard Bauer 2011/02/07 09:46:46 Nit: indent two more spaces.
markusheintz_ 2011/02/07 15:57:10 Done.
+ map_to_modify = &host_content_settings_;
+ }
+
+ {
+ base::AutoLock auto_lock(lock_);
+ for (HostContentSettings::iterator i(map_to_modify->begin());
+ i != map_to_modify->end(); ) {
+ if (RequiresResourceIdentifier(content_type) ||
+ i->second.content_settings.settings[content_type] !=
+ CONTENT_SETTING_DEFAULT) {
+ if (RequiresResourceIdentifier(content_type))
+ i->second.content_settings_for_resources.clear();
+ i->second.content_settings.settings[content_type] =
+ CONTENT_SETTING_DEFAULT;
+ std::string host(i->first);
+ if (AllDefault(i->second)) {
+ if (all_settings_dictionary)
+ all_settings_dictionary->
Bernhard Bauer 2011/02/07 09:46:46 Nit: braces.
markusheintz_ 2011/02/07 15:57:10 Put everything in one line.
+ RemoveWithoutPathExpansion(host, NULL);
+ map_to_modify->erase(i++);
+ } else if (all_settings_dictionary) {
+ DictionaryValue* host_settings_dictionary;
+ bool found =
+ all_settings_dictionary->GetDictionaryWithoutPathExpansion(
+ host, &host_settings_dictionary);
+ DCHECK(found);
+ host_settings_dictionary->RemoveWithoutPathExpansion(
+ kTypeNames[content_type], NULL);
+ ++i;
+ }
+ } else {
+ ++i;
+ }
+ }
+ }
+
+ updating_preferences_ = true;
+ if (!is_off_the_record_)
+ ScopedPrefUpdate update(prefs, prefs::kContentSettingsPatterns);
+ updating_preferences_ = false;
+
+ NotifyObservers(
+ ContentSettingsDetails(ContentSettingsPattern(), content_type, ""));
+}
+
+void PrefProvider::Observe(
+ NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ if (type == NotificationType::PREF_CHANGED) {
+ DCHECK_EQ(profile_->GetPrefs(), Source<PrefService>(source).ptr());
+ if (updating_preferences_)
+ return;
+
+ std::string* name = Details<std::string>(details).ptr();
+ if (*name == prefs::kContentSettingsPatterns) {
+ ReadExceptions(true);
+ } else {
+ NOTREACHED() << "Unexpected preference observed";
+ return;
+ }
+
+ if (!is_off_the_record_) {
+ NotifyObservers(ContentSettingsDetails(ContentSettingsPattern(),
+ CONTENT_SETTINGS_TYPE_DEFAULT,
+ ""));
+ }
+ } else if (type == NotificationType::PROFILE_DESTROYED) {
+ DCHECK_EQ(profile_, Source<Profile>(source).ptr());
+ UnregisterObservers();
+ } else {
+ NOTREACHED() << "Unexpected notification";
+ }
+}
+
+PrefProvider::~PrefProvider() {
+ UnregisterObservers();
+}
+
+// ////////////////////////////////////////////////////////////////////////////
+// Private
+
+bool PrefProvider::RequiresResourceIdentifier(
+ ContentSettingsType content_type) const {
+ if (CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableResourceContentSettings)) {
+ return kRequiresResourceIdentifier[content_type];
+ } else {
+ return false;
+ }
+}
+
+bool PrefProvider::AllDefault(
+ const ExtendedContentSettings& settings) const {
+ for (size_t i = 0; i < arraysize(settings.content_settings.settings); ++i) {
+ if (settings.content_settings.settings[i] != CONTENT_SETTING_DEFAULT)
+ return false;
+ }
+ return settings.content_settings_for_resources.empty();
+}
+
+void PrefProvider::ReadExceptions(bool overwrite) {
+ base::AutoLock lock(lock_);
+
+ PrefService* prefs = profile_->GetPrefs();
+ DictionaryValue* all_settings_dictionary =
+ prefs->GetMutableDictionary(prefs::kContentSettingsPatterns);
+
+ if (overwrite)
+ host_content_settings_.clear();
+
+ // Careful: The returned value could be NULL if the pref has never been set.
+ if (all_settings_dictionary != NULL) {
+ // Convert all Unicode patterns into punycode form, then read.
+ CanonicalizeContentSettingsExceptions(all_settings_dictionary);
+
+ for (DictionaryValue::key_iterator i(all_settings_dictionary->begin_keys());
+ i != all_settings_dictionary->end_keys(); ++i) {
+ const std::string& pattern(*i);
+ if (!ContentSettingsPattern(pattern).IsValid())
+ LOG(WARNING) << "Invalid pattern stored in content settings";
+ DictionaryValue* pattern_settings_dictionary = NULL;
+ bool found = all_settings_dictionary->GetDictionaryWithoutPathExpansion(
+ pattern, &pattern_settings_dictionary);
+ DCHECK(found);
+ ContentSettings settings;
+ GetSettingsFromDictionary(pattern_settings_dictionary, &settings);
+ host_content_settings_[pattern].content_settings = settings;
+ GetResourceSettingsFromDictionary(
+ pattern_settings_dictionary,
+ &host_content_settings_[pattern].content_settings_for_resources);
+ }
+ }
+}
+
+void PrefProvider::CanonicalizeContentSettingsExceptions(
+ DictionaryValue* all_settings_dictionary) {
+ DCHECK(all_settings_dictionary);
+
+ std::vector<std::string> remove_items;
+ std::vector<std::pair<std::string, std::string> > move_items;
+ for (DictionaryValue::key_iterator i(all_settings_dictionary->begin_keys());
+ i != all_settings_dictionary->end_keys(); ++i) {
+ const std::string& pattern(*i);
+ const std::string canonicalized_pattern =
+ ContentSettingsPattern(pattern).CanonicalizePattern();
+
+ if (canonicalized_pattern.empty() || canonicalized_pattern == pattern)
+ continue;
+
+ // Clear old pattern if prefs already have canonicalized pattern.
+ DictionaryValue* new_pattern_settings_dictionary = NULL;
+ if (all_settings_dictionary->GetDictionaryWithoutPathExpansion(
+ canonicalized_pattern, &new_pattern_settings_dictionary)) {
+ remove_items.push_back(pattern);
+ continue;
+ }
+
+ // Move old pattern to canonicalized pattern.
+ DictionaryValue* old_pattern_settings_dictionary = NULL;
+ if (all_settings_dictionary->GetDictionaryWithoutPathExpansion(
+ pattern, &old_pattern_settings_dictionary)) {
+ move_items.push_back(std::make_pair(pattern, canonicalized_pattern));
+ }
+ }
+
+ for (size_t i = 0; i < remove_items.size(); ++i) {
+ all_settings_dictionary->RemoveWithoutPathExpansion(remove_items[i], NULL);
+ }
+
+ for (size_t i = 0; i < move_items.size(); ++i) {
+ Value* pattern_settings_dictionary = NULL;
+ all_settings_dictionary->RemoveWithoutPathExpansion(
+ move_items[i].first, &pattern_settings_dictionary);
+ all_settings_dictionary->SetWithoutPathExpansion(
+ move_items[i].second, pattern_settings_dictionary);
+ }
+}
+
+void PrefProvider::GetSettingsFromDictionary(
+ const DictionaryValue* dictionary,
+ ContentSettings* settings) {
+ for (DictionaryValue::key_iterator i(dictionary->begin_keys());
+ i != dictionary->end_keys(); ++i) {
+ const std::string& content_type(*i);
+ for (size_t type = 0; type < arraysize(kTypeNames); ++type) {
+ if ((kTypeNames[type] != NULL) && (kTypeNames[type] == content_type)) {
+ int setting = CONTENT_SETTING_DEFAULT;
+ bool found = dictionary->GetIntegerWithoutPathExpansion(content_type,
+ &setting);
+ DCHECK(found);
+ settings->settings[type] = IntToContentSetting(setting);
+ break;
+ }
+ }
+ }
+ // Migrate obsolete cookie prompt mode.
+ if (settings->settings[CONTENT_SETTINGS_TYPE_COOKIES] ==
+ CONTENT_SETTING_ASK)
+ settings->settings[CONTENT_SETTINGS_TYPE_COOKIES] = CONTENT_SETTING_BLOCK;
+
+ settings->settings[CONTENT_SETTINGS_TYPE_PLUGINS] =
+ ClickToPlayFixup(CONTENT_SETTINGS_TYPE_PLUGINS,
+ settings->settings[CONTENT_SETTINGS_TYPE_PLUGINS]);
+}
+
+void PrefProvider::GetResourceSettingsFromDictionary(
+ const DictionaryValue* dictionary,
+ ResourceContentSettings* settings) {
+ for (DictionaryValue::key_iterator i(dictionary->begin_keys());
+ i != dictionary->end_keys(); ++i) {
+ const std::string& content_type(*i);
+ for (size_t type = 0; type < arraysize(kResourceTypeNames); ++type) {
+ if ((kResourceTypeNames[type] != NULL) &&
+ (kResourceTypeNames[type] == content_type)) {
+ DictionaryValue* resource_dictionary = NULL;
+ bool found = dictionary->GetDictionary(content_type,
+ &resource_dictionary);
+ DCHECK(found);
+ for (DictionaryValue::key_iterator j(resource_dictionary->begin_keys());
+ j != resource_dictionary->end_keys(); ++j) {
+ const std::string& resource_identifier(*j);
+ int setting = CONTENT_SETTING_DEFAULT;
+ bool found = resource_dictionary->GetIntegerWithoutPathExpansion(
+ resource_identifier, &setting);
+ DCHECK(found);
+ (*settings)[ContentSettingsTypeResourceIdentifierPair(
+ ContentSettingsType(type), resource_identifier)] =
+ ClickToPlayFixup(ContentSettingsType(type),
+ ContentSetting(setting));
+ }
+
+ break;
+ }
+ }
+ }
+}
+
+void PrefProvider::NotifyObservers(
+ const ContentSettingsDetails& details) {
+ if (initializing_)
+ return;
+ NotificationService::current()->Notify(
+ NotificationType::CONTENT_SETTINGS_CHANGED,
+ Source<HostContentSettingsMap>(
+ profile_->GetHostContentSettingsMap()),
+ Details<const ContentSettingsDetails>(&details));
+}
+
+void PrefProvider::UnregisterObservers() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ if (!profile_)
+ return;
+ pref_change_registrar_.RemoveAll();
+ notification_registrar_.Remove(this, NotificationType::PROFILE_DESTROYED,
+ Source<Profile>(profile_));
+ profile_ = NULL;
+}
+
+void PrefProvider::MigrateObsoletePerhostPref(PrefService* prefs) {
+ if (prefs->HasPrefPath(prefs::kPerHostContentSettings)) {
+ const DictionaryValue* all_settings_dictionary =
+ prefs->GetDictionary(prefs::kPerHostContentSettings);
+ for (DictionaryValue::key_iterator i(all_settings_dictionary->begin_keys());
+ i != all_settings_dictionary->end_keys(); ++i) {
+ const std::string& host(*i);
+ ContentSettingsPattern pattern(
+ std::string(ContentSettingsPattern::kDomainWildcard) + host);
+ DictionaryValue* host_settings_dictionary = NULL;
+ bool found = all_settings_dictionary->GetDictionaryWithoutPathExpansion(
+ host, &host_settings_dictionary);
+ DCHECK(found);
+ ContentSettings settings;
+ GetSettingsFromDictionary(host_settings_dictionary, &settings);
+ for (int j = 0; j < CONTENT_SETTINGS_NUM_TYPES; ++j) {
+ if (settings.settings[j] != CONTENT_SETTING_DEFAULT &&
+ !RequiresResourceIdentifier(ContentSettingsType(j)))
Bernhard Bauer 2011/02/07 09:46:46 Nit: Braces.
markusheintz_ 2011/02/07 15:57:10 Done.
+ SetContentSetting(
+ pattern,
+ pattern,
+ ContentSettingsType(j),
+ "",
+ settings.settings[j]);
+ }
+ }
+ prefs->ClearPref(prefs::kPerHostContentSettings);
+ }
+}
+
+void PrefProvider::MigrateObsoletePopupsPref(PrefService* prefs) {
+ if (prefs->HasPrefPath(prefs::kPopupWhitelistedHosts)) {
+ const ListValue* whitelist_pref =
+ prefs->GetList(prefs::kPopupWhitelistedHosts);
+ for (ListValue::const_iterator i(whitelist_pref->begin());
+ i != whitelist_pref->end(); ++i) {
+ std::string host;
+ (*i)->GetAsString(&host);
+ SetContentSetting(ContentSettingsPattern(host),
+ ContentSettingsPattern(host),
+ CONTENT_SETTINGS_TYPE_POPUPS,
+ "",
+ CONTENT_SETTING_ALLOW);
+ }
+ prefs->ClearPref(prefs::kPopupWhitelistedHosts);
+ }
+}
+
+// ////////////////////////////////////////////////////////////////////////////
+// LEGACY TBR
+//
+
+ContentSettings PrefProvider::GetNonDefaultContentSettings(
+ const GURL& url) const {
+ base::AutoLock auto_lock(lock_);
+
+ const std::string host(net::GetHostOrSpecFromURL(url));
+ ContentSettings output;
+ for (int j = 0; j < CONTENT_SETTINGS_NUM_TYPES; ++j)
+ output.settings[j] = CONTENT_SETTING_DEFAULT;
+
+ // Check for exact matches first.
+ HostContentSettings::const_iterator i(host_content_settings_.find(host));
+ if (i != host_content_settings_.end())
+ output = i->second.content_settings;
+
+ // If this map is not for an off-the-record profile, these searches will never
+ // match. The additional off-the-record exceptions always overwrite the
+ // regular ones.
+ i = off_the_record_settings_.find(host);
+ if (i != off_the_record_settings_.end()) {
+ for (int j = 0; j < CONTENT_SETTINGS_NUM_TYPES; ++j)
+ if (i->second.content_settings.settings[j] != CONTENT_SETTING_DEFAULT)
+ output.settings[j] = i->second.content_settings.settings[j];
+ }
+
+ // Match patterns starting with the most concrete pattern match.
+ for (std::string key =
+ std::string(ContentSettingsPattern::kDomainWildcard) + host; ; ) {
+ HostContentSettings::const_iterator i(off_the_record_settings_.find(key));
+ if (i != off_the_record_settings_.end()) {
+ for (int j = 0; j < CONTENT_SETTINGS_NUM_TYPES; ++j) {
+ if (output.settings[j] == CONTENT_SETTING_DEFAULT)
+ output.settings[j] = i->second.content_settings.settings[j];
+ }
+ }
+ i = host_content_settings_.find(key);
+ if (i != host_content_settings_.end()) {
+ for (int j = 0; j < CONTENT_SETTINGS_NUM_TYPES; ++j) {
+ if (output.settings[j] == CONTENT_SETTING_DEFAULT)
+ output.settings[j] = i->second.content_settings.settings[j];
+ }
+ }
+ const size_t next_dot =
+ key.find('.', ContentSettingsPattern::kDomainWildcardLength);
+ if (next_dot == std::string::npos)
+ break;
+ key.erase(ContentSettingsPattern::kDomainWildcardLength,
+ next_dot - ContentSettingsPattern::kDomainWildcardLength + 1);
+ }
+
+ return output;
+}
+
} // namespace content_settings

Powered by Google App Engine
This is Rietveld 408576698