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, |