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..a0ada341b6a8d2bd7ef1fa74f6ef2f6158d6ed3f 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,677 @@ 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); |
+ 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)); |
+ 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); |
+ |
+ 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( |
+ 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); |
+ 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->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) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ if (initializing_ || profile_ == NULL) |
+ 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))) { |
+ 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 |