Chromium Code Reviews| Index: chrome/browser/content_settings/content_settings_pref_provider.cc |
| diff --git a/chrome/browser/content_settings/content_settings_pref_provider.cc b/chrome/browser/content_settings/content_settings_pref_provider.cc |
| index 0d26a262621813aaa3044506a6763415870d6837..f74c73022227c206129e5abd5439190c2aca7c97 100644 |
| --- a/chrome/browser/content_settings/content_settings_pref_provider.cc |
| +++ b/chrome/browser/content_settings/content_settings_pref_provider.cc |
| @@ -83,6 +83,20 @@ void SetDefaultContentSettings(DictionaryValue* default_settings) { |
| } |
| } |
| +std::string CreatePatternString( |
| + const ContentSettingsPattern& requesting_pattern, |
| + const ContentSettingsPattern& embedding_pattern) { |
| + DCHECK(requesting_pattern == embedding_pattern); |
| + return requesting_pattern.ToString(); |
| +} |
| + |
| +ContentSetting ValueToContentSetting(Value * value) { |
|
Bernhard Bauer
2011/05/24 14:21:29
Nit: no space between |Value| and |*|
markusheintz_
2011/05/26 13:22:13
Done.
|
| + DCHECK(value); |
|
Bernhard Bauer
2011/05/24 14:21:29
Nit: I think that DCHECK is kind of unnecessary (G
markusheintz_
2011/05/26 13:22:13
Done.
|
| + int int_value; |
| + value->GetAsInteger(&int_value); |
| + return IntToContentSetting(int_value); |
| +} |
| + |
| } // namespace |
| namespace content_settings { |
| @@ -344,8 +358,8 @@ void PrefProvider::RegisterUserPrefs(PrefService* prefs) { |
| } |
| PrefProvider::PrefProvider(Profile* profile) |
| - : BaseProvider(profile->IsOffTheRecord()), |
| - profile_(profile), |
| + : profile_(profile), |
| + is_incognito_(profile_->IsOffTheRecord()), |
| updating_preferences_(false) { |
| Init(); |
| } |
| @@ -380,6 +394,58 @@ void PrefProvider::Init() { |
| initializing_ = false; |
| } |
| +ContentSetting PrefProvider::GetContentSetting( |
| + const GURL& requesting_url, |
| + const GURL& embedding_url, |
| + ContentSettingsType content_type, |
| + const ResourceIdentifier& resource_identifier) const { |
| + // Support for item, top-level-frame URLs are not enabled yet. |
| + DCHECK(requesting_url == embedding_url); |
| + |
| + // For a non incognito provider this will alwasy return NULL. |
|
Bernhard Bauer
2011/05/24 14:21:29
Nit: "always"
Bernhard Bauer
2011/05/24 14:21:29
How does this work? Do we have separate providers
markusheintz_
2011/05/26 13:22:13
Done.
markusheintz_
2011/05/26 13:22:13
Sorry that comment was garbage. Fixed
|
| + Value* incognito_value = incognito_value_map_.GetValue( |
| + requesting_url, |
| + embedding_url, |
| + content_type, |
| + resource_identifier); |
| + if (incognito_value != NULL) |
|
Bernhard Bauer
2011/05/24 14:21:29
Nit: just |if (incognito_value)|?
markusheintz_
2011/05/26 13:22:13
Done. Also for the if (value ... below
|
| + return ValueToContentSetting(incognito_value); |
| + |
| + Value* value = value_map_.GetValue( |
| + requesting_url, |
| + embedding_url, |
| + content_type, |
| + resource_identifier); |
| + if (value != NULL) |
| + return ValueToContentSetting(value); |
| + |
| + return CONTENT_SETTING_DEFAULT; |
| +} |
| + |
| +void PrefProvider::GetAllContentSettingsRules( |
| + ContentSettingsType content_type, |
| + const ResourceIdentifier& resource_identifier, |
| + Rules* content_setting_rules) const { |
| + DCHECK_NE(BaseProvider::RequiresResourceIdentifier(content_type), |
| + resource_identifier.empty()); |
| + DCHECK(content_setting_rules); |
| + content_setting_rules->clear(); |
| + |
| + const OriginIdentifierValueMap* map_to_return = |
| + is_incognito_ ? &incognito_value_map_ : &value_map_; |
| + |
| + base::AutoLock auto_lock(lock_); |
| + for (OriginIdentifierValueMap::ConstIterator entry = map_to_return->Begin(); |
| + entry != map_to_return->End(); |
| + ++entry) { |
| + if (entry->c == content_type && entry->d == resource_identifier) { |
| + ContentSetting setting = ValueToContentSetting(entry->e); |
| + DCHECK(setting != CONTENT_SETTING_DEFAULT); |
| + content_setting_rules->push_back(Rule(entry->a, entry->b, setting)); |
| + } |
| + } |
| +} |
| + |
| void PrefProvider::SetContentSetting( |
| const ContentSettingsPattern& requesting_pattern, |
| const ContentSettingsPattern& embedding_pattern, |
| @@ -391,104 +457,103 @@ void PrefProvider::SetContentSetting( |
| DCHECK(kTypeNames[content_type] != NULL); // Don't call this for Geolocation. |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| - DCHECK_NE(RequiresResourceIdentifier(content_type), |
| + DCHECK_NE(BaseProvider::RequiresResourceIdentifier(content_type), |
| resource_identifier.empty()); |
| DCHECK(content_type != CONTENT_SETTINGS_TYPE_PLUGINS || |
| setting != CONTENT_SETTING_ASK || |
| CommandLine::ForCurrentProcess()->HasSwitch( |
| switches::kEnableClickToPlay)); |
| - bool early_exit = false; |
| - std::string pattern_str(requesting_pattern.ToString()); |
| - DictionaryValue* all_settings_dictionary = NULL; |
| - |
| updating_preferences_ = true; |
| { |
| - // Begin scope of update. |
| - // profile_ may be NULL in unit tests. |
| DictionaryPrefUpdate update(profile_ ? profile_->GetPrefs() : NULL, |
| prefs::kContentSettingsPatterns); |
| + DictionaryValue* all_settings_dictionary = NULL; |
| - // Select content-settings-map to write to. |
| - HostContentSettings* map_to_modify = incognito_settings(); |
| - if (!is_incognito()) { |
| + OriginIdentifierValueMap* map_to_modify = &incognito_value_map_; |
| + if (!is_incognito_) { |
| + map_to_modify = &value_map_; |
| all_settings_dictionary = update.Get(); |
| - |
| - map_to_modify = host_content_settings(); |
| } |
| - // Update content-settings-map. |
| + // Update in memory value map. |
| { |
| - 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)); |
| - } |
| + base::AutoLock auto_lock(lock_); |
| + if (setting == CONTENT_SETTING_DEFAULT) { |
| + map_to_modify->DeleteValue( |
| + requesting_pattern, |
| + embedding_pattern, |
| + 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; |
| + map_to_modify->SetValue( |
| + requesting_pattern, |
| + embedding_pattern, |
| + content_type, |
| + resource_identifier, |
| + Value::CreateIntegerValue(setting)); |
| } |
| } |
| - // Update the content_settings preference. |
| - if (!early_exit && all_settings_dictionary) { |
| - DictionaryValue* host_settings_dictionary = NULL; |
| + // Update the content settings preference. |
| + std::string pattern_str(CreatePatternString(requesting_pattern, |
| + embedding_pattern)); |
| + if (all_settings_dictionary) { |
| + // Get settings dictionary for the pattern string (key). |
| + DictionaryValue* settings_dictionary = NULL; |
| bool found = all_settings_dictionary->GetDictionaryWithoutPathExpansion( |
| - pattern_str, &host_settings_dictionary); |
| + pattern_str, &settings_dictionary); |
| + |
| if (!found) { |
| - host_settings_dictionary = new DictionaryValue; |
| + if (setting == CONTENT_SETTING_DEFAULT) |
| + return; // Nothing to remove. Exit early. |
| + settings_dictionary = new DictionaryValue; |
| all_settings_dictionary->SetWithoutPathExpansion( |
| - pattern_str, host_settings_dictionary); |
| - DCHECK_NE(setting, CONTENT_SETTING_DEFAULT); |
| + pattern_str, settings_dictionary); |
| } |
| - if (RequiresResourceIdentifier(content_type)) { |
| - std::string dictionary_path(kResourceTypeNames[content_type]); |
| + |
| + if (BaseProvider::RequiresResourceIdentifier(content_type)) { |
| + // Get resource dictionary. |
| + std::string res_dictionary_path(kResourceTypeNames[content_type]); |
| DictionaryValue* resource_dictionary = NULL; |
| - found = host_settings_dictionary->GetDictionary( |
| - dictionary_path, &resource_dictionary); |
| + found = settings_dictionary->GetDictionary( |
| + res_dictionary_path, &resource_dictionary); |
| if (!found) { |
| + if (setting == CONTENT_SETTING_DEFAULT) |
| + return; // Nothing to remove. Exit early. |
| resource_dictionary = new DictionaryValue; |
| - host_settings_dictionary->Set(dictionary_path, resource_dictionary); |
| + settings_dictionary->Set(res_dictionary_path, resource_dictionary); |
| } |
| + // Update resource dictionary. |
| if (setting == CONTENT_SETTING_DEFAULT) { |
| resource_dictionary->RemoveWithoutPathExpansion(resource_identifier, |
| NULL); |
| + if (resource_dictionary->empty()) { |
| + settings_dictionary->RemoveWithoutPathExpansion( |
| + res_dictionary_path, NULL); |
| + } |
| } else { |
| resource_dictionary->SetWithoutPathExpansion( |
| resource_identifier, Value::CreateIntegerValue(setting)); |
| } |
| } else { |
| - std::string dictionary_path(kTypeNames[content_type]); |
| + // Update settings dictionary. |
| + std::string setting_path(kTypeNames[content_type]); |
| if (setting == CONTENT_SETTING_DEFAULT) { |
| - host_settings_dictionary->RemoveWithoutPathExpansion(dictionary_path, |
| - NULL); |
| + settings_dictionary->RemoveWithoutPathExpansion(setting_path, |
| + NULL); |
| } else { |
| - host_settings_dictionary->SetWithoutPathExpansion( |
| - dictionary_path, Value::CreateIntegerValue(setting)); |
| + settings_dictionary->SetWithoutPathExpansion( |
| + setting_path, Value::CreateIntegerValue(setting)); |
| } |
| } |
| + // Remove the settings dictionary if it is empty. |
| + if (settings_dictionary->empty()) { |
| + all_settings_dictionary->RemoveWithoutPathExpansion( |
| + pattern_str, NULL); |
| + } |
| } |
| - } // End scope of update. |
| + } |
| updating_preferences_ = false; |
| NotifyObservers(ContentSettingsDetails(requesting_pattern, content_type, "")); |
| @@ -498,12 +563,12 @@ void PrefProvider::ResetToDefaults() { |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| { |
| - base::AutoLock auto_lock(lock()); |
| - host_content_settings()->clear(); |
| - incognito_settings()->clear(); |
| + base::AutoLock auto_lock(lock_); |
| + value_map_.Clear(); |
| + incognito_value_map_.Clear(); |
| } |
| - if (!is_incognito()) { |
| + if (!is_incognito_) { |
| PrefService* prefs = profile_->GetPrefs(); |
| updating_preferences_ = true; |
| prefs->ClearPref(prefs::kContentSettingsPatterns); |
| @@ -515,47 +580,47 @@ void PrefProvider::ClearAllContentSettingsRules( |
| ContentSettingsType content_type) { |
| DCHECK(kTypeNames[content_type] != NULL); // Don't call this for Geolocation. |
| - DictionaryValue* all_settings_dictionary = NULL; |
| - HostContentSettings* map_to_modify = incognito_settings(); |
| - |
| updating_preferences_ = true; |
| { // Begin scope of update. |
| DictionaryPrefUpdate update(profile_->GetPrefs(), |
| prefs::kContentSettingsPatterns); |
| - if (!is_incognito()) { |
| + DictionaryValue* all_settings_dictionary = NULL; |
| + OriginIdentifierValueMap* map_to_modify = &incognito_value_map_; |
| + if (!is_incognito_) { |
| all_settings_dictionary = update.Get(); |
| - map_to_modify = host_content_settings(); |
| + map_to_modify = &value_map_; |
| } |
| { |
| - 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; |
| + base::AutoLock auto_lock(lock_); |
| + |
| + OriginIdentifierValueMap::Iterator entry(map_to_modify->Begin()); |
| + while (entry != map_to_modify->End()) { |
| + // TODO: What happens if no resource identifier is required? |
|
Bernhard Bauer
2011/05/24 14:21:29
Nit: TODO(markusheintz) ;-)
markusheintz_
2011/05/26 13:22:13
Removed.
|
| + if (entry->c == content_type) { |
| + std::string pattern_str = CreatePatternString(entry->a, entry->b); |
| + // Delete current |entry| and set |entry| to the next value map entry. |
| + entry = map_to_modify->DeleteValue(entry); |
| + |
| + // Update the content settings preference. |
| + if (all_settings_dictionary) { |
| + // Update the settings dictionary. |
| + DictionaryValue* settings_dictionary; |
| bool found = |
| all_settings_dictionary->GetDictionaryWithoutPathExpansion( |
| - host, &host_settings_dictionary); |
| + pattern_str, &settings_dictionary); |
| DCHECK(found); |
| - host_settings_dictionary->RemoveWithoutPathExpansion( |
| + settings_dictionary->RemoveWithoutPathExpansion( |
| kTypeNames[content_type], NULL); |
| - ++i; |
| + // Remove empty dictionaries. |
| + if (settings_dictionary->empty()) |
| + all_settings_dictionary->RemoveWithoutPathExpansion(pattern_str, |
| + NULL); |
| } |
| } else { |
| - ++i; |
| + // No action required move to next value map entry. |
|
Bernhard Bauer
2011/05/24 14:21:29
Nit: semicolon between "No action required" and "m
markusheintz_
2011/05/26 13:22:13
Done.
|
| + ++entry; |
| } |
| } |
| } |
| @@ -585,7 +650,7 @@ void PrefProvider::Observe( |
| return; |
| } |
| - if (!is_incognito()) { |
| + if (!is_incognito_) { |
| NotifyObservers(ContentSettingsDetails(ContentSettingsPattern(), |
| CONTENT_SETTINGS_TYPE_DEFAULT, |
| "")); |
| @@ -606,31 +671,29 @@ PrefProvider::~PrefProvider() { |
| // Private |
| void PrefProvider::ReadExceptions(bool overwrite) { |
| - base::AutoLock auto_lock(lock()); |
| + base::AutoLock auto_lock(lock_); |
| PrefService* prefs = profile_->GetPrefs(); |
| const DictionaryValue* all_settings_dictionary = |
| prefs->GetDictionary(prefs::kContentSettingsPatterns); |
| if (overwrite) |
| - host_content_settings()->clear(); |
| + value_map_.Clear(); |
| updating_preferences_ = true; |
| - |
| // Careful: The returned value could be NULL if the pref has never been set. |
| if (all_settings_dictionary != NULL) { |
| DictionaryPrefUpdate update(prefs, prefs::kContentSettingsPatterns); |
| DictionaryValue* mutable_settings; |
| scoped_ptr<DictionaryValue> mutable_settings_scope; |
| - if (!is_incognito()) { |
| + if (!is_incognito_) { |
| mutable_settings = update.Get(); |
| } else { |
| // Create copy as we do not want to persist anything in OTR prefs. |
| mutable_settings = all_settings_dictionary->DeepCopy(); |
| mutable_settings_scope.reset(mutable_settings); |
| } |
| - |
| // Convert all Unicode patterns into punycode form, then read. |
| CanonicalizeContentSettingsExceptions(mutable_settings); |
| @@ -639,11 +702,15 @@ void PrefProvider::ReadExceptions(bool overwrite) { |
| const std::string& pattern(*i); |
| if (!ContentSettingsPattern::FromString(pattern).IsValid()) |
| LOG(WARNING) << "Invalid pattern stored in content settings"; |
| + // Get settings dictionary for the current pattern string. |
| DictionaryValue* pattern_settings_dictionary = NULL; |
| bool found = mutable_settings->GetDictionaryWithoutPathExpansion( |
| pattern, &pattern_settings_dictionary); |
| DCHECK(found); |
| + // TODO(markusheintz): It is not necessary to read the preferences to an |
| + // ExtendedContentSettings struct first. Read the settings from the |
| + // directory an write them directly to the value_map. |
| ExtendedContentSettings extended_settings; |
| GetSettingsFromDictionary(pattern_settings_dictionary, |
| &extended_settings.content_settings); |
| @@ -651,7 +718,36 @@ void PrefProvider::ReadExceptions(bool overwrite) { |
| pattern_settings_dictionary, |
| &extended_settings.content_settings_for_resources); |
| - (*host_content_settings())[pattern] = extended_settings; |
| + for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) { |
| + ContentSettingsType content_type = ContentSettingsType(i); |
| + if (BaseProvider::RequiresResourceIdentifier(content_type)) { |
| + ResourceContentSettings* res_settings = |
| + &extended_settings.content_settings_for_resources; |
| + for (ResourceContentSettings::iterator entry = res_settings->begin(); |
| + entry != res_settings->end(); |
| + ++entry) { |
| + ContentSettingsType content_type = entry->first.first; |
| + ResourceIdentifier identifier = entry->first.second; |
| + ContentSetting setting = entry->second; |
| + value_map_.SetValue(ContentSettingsPattern::FromString(pattern), |
| + ContentSettingsPattern::FromString(pattern), |
| + content_type, |
| + identifier, |
| + Value::CreateIntegerValue(setting)); |
| + } |
| + |
| + } else { |
| + ContentSetting setting = |
| + extended_settings.content_settings.settings[i]; |
| + if (setting == CONTENT_SETTING_DEFAULT) |
| + continue; |
| + value_map_.SetValue(ContentSettingsPattern::FromString(pattern), |
| + ContentSettingsPattern::FromString(pattern), |
| + content_type, |
| + ResourceIdentifier(""), |
| + Value::CreateIntegerValue(setting)); |
| + } |
| + } |
| } |
| } |
| updating_preferences_ = false; |
| @@ -724,8 +820,9 @@ void PrefProvider::GetSettingsFromDictionary( |
| 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]); |
| + BaseProvider::ClickToPlayFixup( |
| + CONTENT_SETTINGS_TYPE_PLUGINS, |
| + settings->settings[CONTENT_SETTINGS_TYPE_PLUGINS]); |
| } |
| void PrefProvider::GetResourceSettingsFromDictionary( |
| @@ -750,8 +847,8 @@ void PrefProvider::GetResourceSettingsFromDictionary( |
| DCHECK(found); |
| (*settings)[ContentSettingsTypeResourceIdentifierPair( |
| ContentSettingsType(type), resource_identifier)] = |
| - ClickToPlayFixup(ContentSettingsType(type), |
| - ContentSetting(setting)); |
| + BaseProvider::ClickToPlayFixup(ContentSettingsType(type), |
| + ContentSetting(setting)); |
| } |
| break; |
| @@ -801,7 +898,7 @@ void PrefProvider::MigrateObsoletePerhostPref(PrefService* prefs) { |
| 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))) { |
| + !BaseProvider::RequiresResourceIdentifier(ContentSettingsType(j))) { |
| SetContentSetting( |
| pattern, |
| pattern, |