Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/content_settings/core/browser/content_settings_pref.h" | 5 #include "components/content_settings/core/browser/content_settings_pref.h" |
| 6 | 6 |
| 7 #include "base/auto_reset.h" | 7 #include "base/auto_reset.h" |
| 8 #include "base/bind.h" | 8 #include "base/bind.h" |
| 9 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
| 10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
| 11 #include "base/prefs/scoped_user_pref_update.h" | 11 #include "base/prefs/scoped_user_pref_update.h" |
| 12 #include "base/strings/string_split.h" | 12 #include "base/strings/string_split.h" |
| 13 #include "base/time/clock.h" | 13 #include "base/time/clock.h" |
| 14 #include "components/content_settings/core/browser/content_settings_rule.h" | 14 #include "components/content_settings/core/browser/content_settings_rule.h" |
| 15 #include "components/content_settings/core/browser/content_settings_utils.h" | 15 #include "components/content_settings/core/browser/content_settings_utils.h" |
| 16 #include "components/content_settings/core/browser/host_content_settings_map.h" | 16 #include "components/content_settings/core/browser/host_content_settings_map.h" |
| 17 #include "components/content_settings/core/common/content_settings.h" | 17 #include "components/content_settings/core/common/content_settings.h" |
| 18 #include "components/content_settings/core/common/content_settings_pattern.h" | 18 #include "components/content_settings/core/common/content_settings_pattern.h" |
| 19 #include "components/content_settings/core/common/pref_names.h" | 19 #include "components/content_settings/core/common/pref_names.h" |
| 20 #include "url/gurl.h" | 20 #include "url/gurl.h" |
| 21 | 21 |
| 22 namespace { | 22 namespace { |
| 23 | 23 |
| 24 typedef std::pair<std::string, std::string> StringPair; | 24 const char kSettingPath[] = "setting"; |
| 25 | 25 const char kPerResourceIdentifierPrefName[] = "per_resource"; |
| 26 const char kPerPluginPrefName[] = "per_plugin"; | 26 const char kPerPluginPrefName[] = "per_plugin"; |
| 27 const char kLastUsed[] = "last_used"; | 27 const char kLastUsed[] = "last_used"; |
| 28 | 28 |
| 29 ContentSetting FixObsoleteCookiePromptMode(ContentSettingsType content_type, | 29 ContentSetting FixObsoleteCookiePromptMode(ContentSettingsType content_type, |
| 30 ContentSetting setting) { | 30 ContentSetting setting) { |
| 31 if (content_type == CONTENT_SETTINGS_TYPE_COOKIES && | 31 if (content_type == CONTENT_SETTINGS_TYPE_COOKIES && |
| 32 setting == CONTENT_SETTING_ASK) { | 32 setting == CONTENT_SETTING_ASK) { |
| 33 return CONTENT_SETTING_BLOCK; | 33 return CONTENT_SETTING_BLOCK; |
| 34 } | 34 } |
| 35 return setting; | 35 return setting; |
| 36 } | 36 } |
| 37 | 37 |
| 38 // If the given content type supports resource identifiers in user preferences, | 38 // If the given content type supports resource identifiers in user preferences, |
| 39 // returns true and sets |pref_key| to the key in the content settings | 39 // returns true and sets |pref_key| to the key in the content settings |
| 40 // dictionary under which per-resource content settings are stored. | 40 // dictionary under which per-resource content settings are stored. |
| 41 // Otherwise, returns false. | 41 // Otherwise, returns false. |
| 42 bool GetResourceTypeName(ContentSettingsType content_type, | 42 bool SupportsResourceIdentifiers(ContentSettingsType content_type) { |
| 43 std::string* pref_key) { | 43 return content_type == CONTENT_SETTINGS_TYPE_PLUGINS; |
| 44 if (content_type == CONTENT_SETTINGS_TYPE_PLUGINS) { | |
| 45 *pref_key = kPerPluginPrefName; | |
| 46 return true; | |
| 47 } | |
| 48 return false; | |
| 49 } | 44 } |
| 50 | 45 |
| 51 } // namespace | 46 } // namespace |
| 52 | 47 |
| 53 namespace content_settings { | 48 namespace content_settings { |
| 54 | 49 |
| 55 ContentSettingsPref::ContentSettingsPref( | 50 ContentSettingsPref::ContentSettingsPref( |
| 51 ContentSettingsType content_type, | |
| 56 PrefService* prefs, | 52 PrefService* prefs, |
| 57 PrefChangeRegistrar* registrar, | 53 PrefChangeRegistrar* registrar, |
| 58 base::Clock* clock, | 54 const char* pref_name, |
| 59 bool incognito, | 55 bool incognito, |
| 56 bool* updating_old_preferences_flag, | |
| 60 NotifyObserversCallback notify_callback) | 57 NotifyObserversCallback notify_callback) |
| 61 : prefs_(prefs), | 58 : content_type_(content_type), |
| 62 clock_(clock), | 59 prefs_(prefs), |
| 63 registrar_(registrar), | 60 registrar_(registrar), |
| 61 pref_name_(pref_name), | |
| 64 is_incognito_(incognito), | 62 is_incognito_(incognito), |
| 65 updating_preferences_(false), | 63 updating_preferences_(false), |
| 64 updating_old_preferences_(updating_old_preferences_flag), | |
| 66 notify_callback_(notify_callback) { | 65 notify_callback_(notify_callback) { |
| 67 DCHECK(prefs_); | 66 DCHECK(prefs_); |
| 68 | 67 |
| 69 // Read content settings exceptions. | |
| 70 ReadContentSettingsFromPref(); | 68 ReadContentSettingsFromPref(); |
| 71 | 69 |
| 72 registrar->Add( | 70 registrar_->Add( |
| 73 prefs::kContentSettingsPatternPairs, | 71 pref_name_, |
| 74 base::Bind(&ContentSettingsPref::OnContentSettingsPatternPairsChanged, | 72 base::Bind(&ContentSettingsPref::OnPrefChanged, base::Unretained(this))); |
| 75 base::Unretained(this))); | |
| 76 } | 73 } |
| 77 | 74 |
| 78 ContentSettingsPref::~ContentSettingsPref() { | 75 ContentSettingsPref::~ContentSettingsPref() { |
| 79 } | 76 } |
| 80 | 77 |
| 81 RuleIterator* ContentSettingsPref::GetRuleIterator( | 78 RuleIterator* ContentSettingsPref::GetRuleIterator( |
| 82 ContentSettingsType content_type, | |
| 83 const ResourceIdentifier& resource_identifier, | 79 const ResourceIdentifier& resource_identifier, |
| 84 bool incognito) const { | 80 bool incognito) const { |
| 85 if (incognito) | 81 if (incognito) |
| 86 return incognito_value_map_.GetRuleIterator(content_type, | 82 return incognito_value_map_.GetRuleIterator(content_type_, |
| 87 resource_identifier, | 83 resource_identifier, |
| 88 &lock_); | 84 &lock_); |
| 89 return value_map_.GetRuleIterator(content_type, resource_identifier, &lock_); | 85 return value_map_.GetRuleIterator(content_type_, resource_identifier, &lock_); |
| 90 } | 86 } |
| 91 | 87 |
| 92 bool ContentSettingsPref::SetWebsiteSetting( | 88 bool ContentSettingsPref::SetWebsiteSetting( |
| 93 const ContentSettingsPattern& primary_pattern, | 89 const ContentSettingsPattern& primary_pattern, |
| 94 const ContentSettingsPattern& secondary_pattern, | 90 const ContentSettingsPattern& secondary_pattern, |
| 95 ContentSettingsType content_type, | |
| 96 const ResourceIdentifier& resource_identifier, | 91 const ResourceIdentifier& resource_identifier, |
| 97 base::Value* in_value) { | 92 base::Value* in_value) { |
| 98 DCHECK(thread_checker_.CalledOnValidThread()); | 93 DCHECK(thread_checker_.CalledOnValidThread()); |
| 99 DCHECK(prefs_); | 94 DCHECK(prefs_); |
| 100 | 95 DCHECK(primary_pattern != ContentSettingsPattern::Wildcard() || |
| 101 // Default settings are set using a wildcard pattern for both | 96 secondary_pattern != ContentSettingsPattern::Wildcard() || |
| 102 // |primary_pattern| and |secondary_pattern|. Don't store default settings in | 97 !resource_identifier.empty()); |
| 103 // the |PrefProvider|. The |PrefProvider| handles settings for specific | |
| 104 // sites/origins defined by the |primary_pattern| and the |secondary_pattern|. | |
| 105 // Default settings are handled by the |DefaultProvider|. | |
| 106 if (primary_pattern == ContentSettingsPattern::Wildcard() && | |
| 107 secondary_pattern == ContentSettingsPattern::Wildcard() && | |
| 108 resource_identifier.empty()) { | |
| 109 return false; | |
| 110 } | |
| 111 | 98 |
| 112 // At this point take the ownership of the |in_value|. | 99 // At this point take the ownership of the |in_value|. |
| 113 scoped_ptr<base::Value> value(in_value); | 100 scoped_ptr<base::Value> value(in_value); |
| 101 | |
| 114 // Update in memory value map. | 102 // Update in memory value map. |
| 115 OriginIdentifierValueMap* map_to_modify = &incognito_value_map_; | 103 OriginIdentifierValueMap* map_to_modify = &incognito_value_map_; |
| 116 if (!is_incognito_) | 104 if (!is_incognito_) |
| 117 map_to_modify = &value_map_; | 105 map_to_modify = &value_map_; |
| 118 | 106 |
| 119 { | 107 { |
| 120 base::AutoLock auto_lock(lock_); | 108 base::AutoLock auto_lock(lock_); |
| 121 if (value.get()) { | 109 if (value.get()) { |
| 122 map_to_modify->SetValue( | 110 map_to_modify->SetValue( |
| 123 primary_pattern, | 111 primary_pattern, |
| 124 secondary_pattern, | 112 secondary_pattern, |
| 125 content_type, | 113 content_type_, |
| 126 resource_identifier, | 114 resource_identifier, |
| 127 value->DeepCopy()); | 115 value->DeepCopy()); |
| 128 } else { | 116 } else { |
| 129 map_to_modify->DeleteValue( | 117 map_to_modify->DeleteValue( |
| 130 primary_pattern, | 118 primary_pattern, |
| 131 secondary_pattern, | 119 secondary_pattern, |
| 132 content_type, | 120 content_type_, |
| 133 resource_identifier); | 121 resource_identifier); |
| 134 } | 122 } |
| 135 } | 123 } |
| 136 // Update the content settings preference. | 124 // Update the content settings preference. |
| 137 if (!is_incognito_) { | 125 if (!is_incognito_) { |
| 138 UpdatePref(primary_pattern, | 126 UpdatePref(primary_pattern, |
| 139 secondary_pattern, | 127 secondary_pattern, |
| 140 content_type, | |
| 141 resource_identifier, | 128 resource_identifier, |
| 142 value.get()); | 129 value.get()); |
| 130 if (IsContentSettingsTypeSyncable(content_type_)) | |
| 131 UpdateOldPref(primary_pattern, | |
| 132 secondary_pattern, | |
| 133 resource_identifier, | |
| 134 value.get()); | |
| 143 } | 135 } |
| 144 | 136 |
| 145 notify_callback_.Run( | 137 notify_callback_.Run( |
| 146 primary_pattern, secondary_pattern, content_type, resource_identifier); | 138 primary_pattern, secondary_pattern, content_type_, resource_identifier); |
| 147 | 139 |
| 148 return true; | 140 return true; |
| 149 } | 141 } |
| 150 | 142 |
| 151 void ContentSettingsPref::ClearAllContentSettingsRules( | 143 void ContentSettingsPref::ClearAllContentSettingsRules() { |
| 152 ContentSettingsType content_type) { | |
| 153 DCHECK(thread_checker_.CalledOnValidThread()); | 144 DCHECK(thread_checker_.CalledOnValidThread()); |
| 154 DCHECK(prefs_); | 145 DCHECK(prefs_); |
| 155 | 146 |
| 156 OriginIdentifierValueMap* map_to_modify = &incognito_value_map_; | 147 OriginIdentifierValueMap* map_to_modify = &incognito_value_map_; |
| 157 if (!is_incognito_) | 148 if (!is_incognito_) |
| 158 map_to_modify = &value_map_; | 149 map_to_modify = &value_map_; |
| 159 | 150 |
| 160 std::vector<Rule> rules_to_delete; | 151 std::vector<Rule> rules_to_delete; |
| 161 { | 152 { |
| 162 base::AutoLock auto_lock(lock_); | 153 base::AutoLock auto_lock(lock_); |
| 163 scoped_ptr<RuleIterator> rule_iterator( | 154 scoped_ptr<RuleIterator> rule_iterator( |
| 164 map_to_modify->GetRuleIterator(content_type, std::string(), NULL)); | 155 map_to_modify->GetRuleIterator(content_type_, std::string(), NULL)); |
| 165 // Copy the rules; we cannot call |UpdatePref| while holding |lock_|. | 156 // Copy the rules; we cannot call |UpdatePref| while holding |lock_|. |
| 166 while (rule_iterator->HasNext()) | 157 while (rule_iterator->HasNext()) |
| 167 rules_to_delete.push_back(rule_iterator->Next()); | 158 rules_to_delete.push_back(rule_iterator->Next()); |
| 168 | 159 |
| 169 map_to_modify->DeleteValues(content_type, std::string()); | 160 map_to_modify->DeleteValues(content_type_, std::string()); |
| 170 } | 161 } |
| 171 | 162 |
| 172 for (std::vector<Rule>::const_iterator it = rules_to_delete.begin(); | 163 for (std::vector<Rule>::const_iterator it = rules_to_delete.begin(); |
| 173 it != rules_to_delete.end(); ++it) { | 164 it != rules_to_delete.end(); ++it) { |
| 174 UpdatePref(it->primary_pattern, | 165 UpdatePref(it->primary_pattern, |
| 175 it->secondary_pattern, | 166 it->secondary_pattern, |
| 176 content_type, | |
| 177 std::string(), | 167 std::string(), |
| 178 NULL); | 168 NULL); |
| 169 if (IsContentSettingsTypeSyncable(content_type_)) | |
|
markusheintz_
2015/04/01 10:02:51
Please add { }
msramek
2015/04/01 10:53:35
Done.
| |
| 170 UpdateOldPref(it->primary_pattern, | |
| 171 it->secondary_pattern, | |
| 172 std::string(), | |
| 173 NULL); | |
| 179 } | 174 } |
| 180 notify_callback_.Run(ContentSettingsPattern(), | 175 notify_callback_.Run(ContentSettingsPattern(), |
| 181 ContentSettingsPattern(), | 176 ContentSettingsPattern(), |
| 182 content_type, | 177 content_type_, |
| 183 std::string()); | 178 std::string()); |
| 184 } | 179 } |
| 185 | 180 |
| 186 void ContentSettingsPref::UpdateLastUsage( | 181 void ContentSettingsPref::UpdateLastUsage( |
| 187 const ContentSettingsPattern& primary_pattern, | 182 const ContentSettingsPattern& primary_pattern, |
| 188 const ContentSettingsPattern& secondary_pattern, | 183 const ContentSettingsPattern& secondary_pattern, |
| 189 ContentSettingsType content_type) { | 184 base::Clock* clock) { |
| 190 // Don't write if in incognito. | 185 // Don't write if in incognito. |
| 191 if (is_incognito_) { | 186 if (is_incognito_) { |
| 192 return; | 187 return; |
| 193 } | 188 } |
| 194 | 189 |
| 195 // Ensure that |lock_| is not held by this thread, since this function will | 190 // Ensure that |lock_| is not held by this thread, since this function will |
| 196 // send out notifications (by |~DictionaryPrefUpdate|). | 191 // send out notifications (by |~DictionaryPrefUpdate|). |
| 197 AssertLockNotHeld(); | 192 AssertLockNotHeld(); |
| 198 | 193 |
| 199 base::AutoReset<bool> auto_reset(&updating_preferences_, true); | 194 base::AutoReset<bool> auto_reset(&updating_preferences_, true); |
| 200 { | 195 { |
| 201 DictionaryPrefUpdate update(prefs_, prefs::kContentSettingsPatternPairs); | 196 DictionaryPrefUpdate update(prefs_, pref_name_); |
| 202 base::DictionaryValue* pattern_pairs_settings = update.Get(); | 197 base::DictionaryValue* pattern_pairs_settings = update.Get(); |
| 203 | 198 |
| 204 std::string pattern_str( | 199 std::string pattern_str( |
| 205 CreatePatternString(primary_pattern, secondary_pattern)); | 200 CreatePatternString(primary_pattern, secondary_pattern)); |
| 206 base::DictionaryValue* settings_dictionary = NULL; | 201 base::DictionaryValue* settings_dictionary = NULL; |
| 207 bool found = pattern_pairs_settings->GetDictionaryWithoutPathExpansion( | 202 bool found = pattern_pairs_settings->GetDictionaryWithoutPathExpansion( |
| 208 pattern_str, &settings_dictionary); | 203 pattern_str, &settings_dictionary); |
| 209 | 204 |
| 210 if (!found) { | 205 if (!found) { |
| 211 settings_dictionary = new base::DictionaryValue; | 206 settings_dictionary = new base::DictionaryValue; |
| 212 pattern_pairs_settings->SetWithoutPathExpansion(pattern_str, | 207 pattern_pairs_settings->SetWithoutPathExpansion(pattern_str, |
| 213 settings_dictionary); | 208 settings_dictionary); |
| 214 } | 209 } |
| 215 | 210 |
| 216 base::DictionaryValue* last_used_dictionary = NULL; | 211 settings_dictionary->SetWithoutPathExpansion( |
| 217 found = settings_dictionary->GetDictionaryWithoutPathExpansion( | 212 kLastUsed, new base::FundamentalValue(clock->Now().ToDoubleT())); |
| 218 kLastUsed, &last_used_dictionary); | |
| 219 | |
| 220 if (!found) { | |
| 221 last_used_dictionary = new base::DictionaryValue; | |
| 222 settings_dictionary->SetWithoutPathExpansion(kLastUsed, | |
| 223 last_used_dictionary); | |
| 224 } | |
| 225 | |
| 226 std::string settings_path = GetTypeName(content_type); | |
| 227 last_used_dictionary->Set( | |
| 228 settings_path, new base::FundamentalValue(clock_->Now().ToDoubleT())); | |
| 229 } | 213 } |
| 230 } | 214 } |
| 231 | 215 |
| 232 base::Time ContentSettingsPref::GetLastUsage( | 216 base::Time ContentSettingsPref::GetLastUsage( |
| 233 const ContentSettingsPattern& primary_pattern, | 217 const ContentSettingsPattern& primary_pattern, |
| 234 const ContentSettingsPattern& secondary_pattern, | 218 const ContentSettingsPattern& secondary_pattern) { |
| 235 ContentSettingsType content_type) { | |
| 236 const base::DictionaryValue* pattern_pairs_settings = | 219 const base::DictionaryValue* pattern_pairs_settings = |
| 237 prefs_->GetDictionary(prefs::kContentSettingsPatternPairs); | 220 prefs_->GetDictionary(pref_name_); |
| 238 std::string pattern_str( | 221 std::string pattern_str( |
| 239 CreatePatternString(primary_pattern, secondary_pattern)); | 222 CreatePatternString(primary_pattern, secondary_pattern)); |
| 240 | 223 |
| 241 const base::DictionaryValue* settings_dictionary = NULL; | 224 const base::DictionaryValue* settings_dictionary = NULL; |
| 242 bool found = pattern_pairs_settings->GetDictionaryWithoutPathExpansion( | 225 bool found = pattern_pairs_settings->GetDictionaryWithoutPathExpansion( |
| 243 pattern_str, &settings_dictionary); | 226 pattern_str, &settings_dictionary); |
| 244 | 227 |
| 245 if (!found) | 228 if (!found) |
| 246 return base::Time(); | 229 return base::Time(); |
| 247 | 230 |
| 248 const base::DictionaryValue* last_used_dictionary = NULL; | |
| 249 found = settings_dictionary->GetDictionaryWithoutPathExpansion( | |
| 250 kLastUsed, &last_used_dictionary); | |
| 251 | |
| 252 if (!found) | |
| 253 return base::Time(); | |
| 254 | |
| 255 double last_used_time; | 231 double last_used_time; |
| 256 found = last_used_dictionary->GetDoubleWithoutPathExpansion( | 232 found = settings_dictionary->GetDoubleWithoutPathExpansion( |
| 257 GetTypeName(content_type), &last_used_time); | 233 kLastUsed, &last_used_time); |
| 258 | 234 |
| 259 if (!found) | 235 if (!found) |
| 260 return base::Time(); | 236 return base::Time(); |
| 261 | 237 |
| 262 return base::Time::FromDoubleT(last_used_time); | 238 return base::Time::FromDoubleT(last_used_time); |
| 263 } | 239 } |
| 264 | 240 |
| 265 size_t ContentSettingsPref::GetNumExceptions() { | 241 size_t ContentSettingsPref::GetNumExceptions() { |
| 266 return value_map_.size(); | 242 return value_map_.size(); |
| 267 } | 243 } |
| 268 | 244 |
| 269 void ContentSettingsPref::SetClockForTesting(base::Clock* clock) { | |
| 270 clock_ = clock; | |
| 271 } | |
| 272 | |
| 273 void ContentSettingsPref::ReadContentSettingsFromPref() { | 245 void ContentSettingsPref::ReadContentSettingsFromPref() { |
| 274 // |DictionaryPrefUpdate| sends out notifications when destructed. This | 246 // |DictionaryPrefUpdate| sends out notifications when destructed. This |
| 275 // construction order ensures |AutoLock| gets destroyed first and |lock_| is | 247 // construction order ensures |AutoLock| gets destroyed first and |lock_| is |
| 276 // not held when the notifications are sent. Also, |auto_reset| must be still | 248 // not held when the notifications are sent. Also, |auto_reset| must be still |
| 277 // valid when the notifications are sent, so that |Observe| skips the | 249 // valid when the notifications are sent, so that |Observe| skips the |
| 278 // notification. | 250 // notification. |
| 279 base::AutoReset<bool> auto_reset(&updating_preferences_, true); | 251 base::AutoReset<bool> auto_reset(&updating_preferences_, true); |
| 280 DictionaryPrefUpdate update(prefs_, prefs::kContentSettingsPatternPairs); | 252 DictionaryPrefUpdate update(prefs_, pref_name_); |
| 281 base::AutoLock auto_lock(lock_); | 253 base::AutoLock auto_lock(lock_); |
| 282 | 254 |
| 283 const base::DictionaryValue* all_settings_dictionary = | 255 const base::DictionaryValue* all_settings_dictionary = |
| 284 prefs_->GetDictionary(prefs::kContentSettingsPatternPairs); | 256 prefs_->GetDictionary(pref_name_); |
| 285 | 257 |
| 286 value_map_.clear(); | 258 value_map_.clear(); |
| 259 if (IsContentSettingsTypeSyncable(content_type_)) | |
| 260 ClearOldPreference(); | |
| 287 | 261 |
| 288 // Careful: The returned value could be NULL if the pref has never been set. | 262 // Careful: The returned value could be NULL if the pref has never been set. |
| 289 if (!all_settings_dictionary) | 263 if (!all_settings_dictionary) |
| 290 return; | 264 return; |
| 291 | 265 |
| 292 base::DictionaryValue* mutable_settings; | 266 base::DictionaryValue* mutable_settings; |
| 293 scoped_ptr<base::DictionaryValue> mutable_settings_scope; | 267 scoped_ptr<base::DictionaryValue> mutable_settings_scope; |
| 294 | 268 |
| 295 if (!is_incognito_) { | 269 if (!is_incognito_) { |
| 296 mutable_settings = update.Get(); | 270 mutable_settings = update.Get(); |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 316 LOG(ERROR) << "Invalid pattern strings: " << pattern_str; | 290 LOG(ERROR) << "Invalid pattern strings: " << pattern_str; |
| 317 continue; | 291 continue; |
| 318 } | 292 } |
| 319 | 293 |
| 320 // Get settings dictionary for the current pattern string, and read | 294 // Get settings dictionary for the current pattern string, and read |
| 321 // settings from the dictionary. | 295 // settings from the dictionary. |
| 322 const base::DictionaryValue* settings_dictionary = NULL; | 296 const base::DictionaryValue* settings_dictionary = NULL; |
| 323 bool is_dictionary = i.value().GetAsDictionary(&settings_dictionary); | 297 bool is_dictionary = i.value().GetAsDictionary(&settings_dictionary); |
| 324 DCHECK(is_dictionary); | 298 DCHECK(is_dictionary); |
| 325 | 299 |
| 326 for (size_t i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) { | 300 if (SupportsResourceIdentifiers(content_type_)) { |
| 327 ContentSettingsType content_type = static_cast<ContentSettingsType>(i); | 301 const base::DictionaryValue* resource_dictionary = NULL; |
| 328 | 302 if (settings_dictionary->GetDictionary( |
| 329 std::string res_dictionary_path; | 303 kPerResourceIdentifierPrefName, &resource_dictionary)) { |
| 330 if (GetResourceTypeName(content_type, &res_dictionary_path)) { | 304 for (base::DictionaryValue::Iterator j(*resource_dictionary); |
| 331 const base::DictionaryValue* resource_dictionary = NULL; | 305 !j.IsAtEnd(); |
| 332 if (settings_dictionary->GetDictionary( | 306 j.Advance()) { |
| 333 res_dictionary_path, &resource_dictionary)) { | 307 const std::string& resource_identifier(j.key()); |
| 334 for (base::DictionaryValue::Iterator j(*resource_dictionary); | 308 int setting = CONTENT_SETTING_DEFAULT; |
| 335 !j.IsAtEnd(); | 309 bool is_integer = j.value().GetAsInteger(&setting); |
| 336 j.Advance()) { | 310 DCHECK(is_integer); |
| 337 const std::string& resource_identifier(j.key()); | |
| 338 int setting = CONTENT_SETTING_DEFAULT; | |
| 339 bool is_integer = j.value().GetAsInteger(&setting); | |
| 340 DCHECK(is_integer); | |
| 341 DCHECK_NE(CONTENT_SETTING_DEFAULT, setting); | |
| 342 value_map_.SetValue(pattern_pair.first, | |
| 343 pattern_pair.second, | |
| 344 content_type, | |
| 345 resource_identifier, | |
| 346 new base::FundamentalValue(setting)); | |
| 347 } | |
| 348 } | |
| 349 } | |
| 350 base::Value* value = NULL; | |
| 351 if (HostContentSettingsMap::ContentTypeHasCompoundValue(content_type)) { | |
| 352 const base::DictionaryValue* setting = NULL; | |
| 353 // TODO(xians): Handle the non-dictionary types. | |
| 354 if (settings_dictionary->GetDictionaryWithoutPathExpansion( | |
| 355 GetTypeName(ContentSettingsType(i)), &setting)) { | |
| 356 DCHECK(!setting->empty()); | |
| 357 value = setting->DeepCopy(); | |
| 358 } | |
| 359 } else { | |
| 360 int setting = CONTENT_SETTING_DEFAULT; | |
| 361 if (settings_dictionary->GetIntegerWithoutPathExpansion( | |
| 362 GetTypeName(ContentSettingsType(i)), &setting)) { | |
| 363 DCHECK_NE(CONTENT_SETTING_DEFAULT, setting); | 311 DCHECK_NE(CONTENT_SETTING_DEFAULT, setting); |
| 364 setting = FixObsoleteCookiePromptMode(content_type, | 312 scoped_ptr<base::Value> setting_ptr = make_scoped_ptr( |
| 365 ContentSetting(setting)); | 313 new base::FundamentalValue(setting)); |
| 366 value = new base::FundamentalValue(setting); | 314 value_map_.SetValue(pattern_pair.first, |
| 367 } | 315 pattern_pair.second, |
| 368 } | 316 content_type_, |
| 369 | 317 resource_identifier, |
| 370 // |value_map_| will take the ownership of |value|. | 318 setting_ptr.get()); |
| 371 if (value != NULL) { | 319 if (IsContentSettingsTypeSyncable(content_type_)) { |
| 372 value_map_.SetValue(pattern_pair.first, | 320 UpdateOldPref(pattern_pair.first, |
| 373 pattern_pair.second, | 321 pattern_pair.second, |
| 374 content_type, | 322 resource_identifier, |
| 375 ResourceIdentifier(), | 323 setting_ptr.get()); |
| 376 value); | |
| 377 if (content_type == CONTENT_SETTINGS_TYPE_COOKIES) { | |
| 378 ContentSetting s = ValueToContentSetting(value); | |
| 379 switch (s) { | |
| 380 case CONTENT_SETTING_ALLOW : | |
| 381 ++cookies_allow_exception_count; | |
| 382 break; | |
| 383 case CONTENT_SETTING_BLOCK : | |
| 384 ++cookies_block_exception_count; | |
| 385 break; | |
| 386 case CONTENT_SETTING_SESSION_ONLY : | |
| 387 ++cookies_session_only_exception_count; | |
| 388 break; | |
| 389 default: | |
| 390 NOTREACHED(); | |
| 391 break; | |
| 392 } | 324 } |
| 393 } | 325 } |
| 394 } | 326 } |
| 395 } | 327 } |
| 328 base::Value* value = NULL; | |
| 329 if (HostContentSettingsMap::ContentTypeHasCompoundValue(content_type_)) { | |
| 330 const base::DictionaryValue* setting = NULL; | |
| 331 // TODO(xians): Handle the non-dictionary types. | |
| 332 if (settings_dictionary->GetDictionaryWithoutPathExpansion( | |
| 333 kSettingPath, &setting)) { | |
| 334 DCHECK(!setting->empty()); | |
| 335 value = setting->DeepCopy(); | |
| 336 } | |
| 337 } else { | |
| 338 int setting = CONTENT_SETTING_DEFAULT; | |
| 339 if (settings_dictionary->GetIntegerWithoutPathExpansion( | |
| 340 kSettingPath, &setting)) { | |
| 341 DCHECK_NE(CONTENT_SETTING_DEFAULT, setting); | |
| 342 setting = FixObsoleteCookiePromptMode(content_type_, | |
| 343 ContentSetting(setting)); | |
| 344 value = new base::FundamentalValue(setting); | |
| 345 } | |
| 346 } | |
| 347 | |
| 348 // |map_to_modify| will take the ownership of |value|. | |
| 349 if (value != NULL) { | |
| 350 value_map_.SetValue(pattern_pair.first, | |
| 351 pattern_pair.second, | |
| 352 content_type_, | |
| 353 ResourceIdentifier(), | |
| 354 value); | |
| 355 if (IsContentSettingsTypeSyncable(content_type_)) { | |
| 356 UpdateOldPref(pattern_pair.first, | |
| 357 pattern_pair.second, | |
| 358 ResourceIdentifier(), | |
| 359 value); | |
| 360 } | |
| 361 if (content_type_ == CONTENT_SETTINGS_TYPE_COOKIES) { | |
| 362 ContentSetting s = ValueToContentSetting(value); | |
| 363 switch (s) { | |
| 364 case CONTENT_SETTING_ALLOW : | |
| 365 ++cookies_allow_exception_count; | |
| 366 break; | |
| 367 case CONTENT_SETTING_BLOCK : | |
| 368 ++cookies_block_exception_count; | |
| 369 break; | |
| 370 case CONTENT_SETTING_SESSION_ONLY : | |
| 371 ++cookies_session_only_exception_count; | |
| 372 break; | |
| 373 default: | |
| 374 NOTREACHED(); | |
| 375 break; | |
| 376 } | |
| 377 } | |
| 378 } | |
| 379 | |
| 396 } | 380 } |
| 397 UMA_HISTOGRAM_COUNTS("ContentSettings.NumberOfBlockCookiesExceptions", | 381 |
| 398 cookies_block_exception_count); | 382 if (content_type_ == CONTENT_SETTINGS_TYPE_COOKIES) { |
| 399 UMA_HISTOGRAM_COUNTS("ContentSettings.NumberOfAllowCookiesExceptions", | 383 UMA_HISTOGRAM_COUNTS("ContentSettings.NumberOfBlockCookiesExceptions", |
| 400 cookies_allow_exception_count); | 384 cookies_block_exception_count); |
| 401 UMA_HISTOGRAM_COUNTS("ContentSettings.NumberOfSessionOnlyCookiesExceptions", | 385 UMA_HISTOGRAM_COUNTS("ContentSettings.NumberOfAllowCookiesExceptions", |
| 402 cookies_session_only_exception_count); | 386 cookies_allow_exception_count); |
| 387 UMA_HISTOGRAM_COUNTS("ContentSettings.NumberOfSessionOnlyCookiesExceptions", | |
| 388 cookies_session_only_exception_count); | |
| 389 } | |
| 403 } | 390 } |
| 404 | 391 |
| 405 void ContentSettingsPref::OnContentSettingsPatternPairsChanged() { | 392 void ContentSettingsPref::OnPrefChanged() { |
| 406 DCHECK(thread_checker_.CalledOnValidThread()); | 393 DCHECK(thread_checker_.CalledOnValidThread()); |
| 407 | 394 |
| 408 if (updating_preferences_) | 395 if (updating_preferences_) |
| 409 return; | 396 return; |
| 410 | 397 |
| 411 ReadContentSettingsFromPref(); | 398 ReadContentSettingsFromPref(); |
| 412 | 399 |
| 413 notify_callback_.Run(ContentSettingsPattern(), | 400 notify_callback_.Run(ContentSettingsPattern(), |
| 414 ContentSettingsPattern(), | 401 ContentSettingsPattern(), |
| 415 CONTENT_SETTINGS_TYPE_DEFAULT, | 402 content_type_, |
| 416 std::string()); | 403 std::string()); |
| 417 } | 404 } |
| 418 | 405 |
| 419 void ContentSettingsPref::UpdatePref( | 406 void ContentSettingsPref::UpdatePref( |
| 420 const ContentSettingsPattern& primary_pattern, | 407 const ContentSettingsPattern& primary_pattern, |
| 421 const ContentSettingsPattern& secondary_pattern, | 408 const ContentSettingsPattern& secondary_pattern, |
| 422 ContentSettingsType content_type, | |
| 423 const ResourceIdentifier& resource_identifier, | 409 const ResourceIdentifier& resource_identifier, |
| 424 const base::Value* value) { | 410 const base::Value* value) { |
| 425 // Ensure that |lock_| is not held by this thread, since this function will | 411 // Ensure that |lock_| is not held by this thread, since this function will |
| 426 // send out notifications (by |~DictionaryPrefUpdate|). | 412 // send out notifications (by |~DictionaryPrefUpdate|). |
| 427 AssertLockNotHeld(); | 413 AssertLockNotHeld(); |
| 428 | 414 |
| 429 base::AutoReset<bool> auto_reset(&updating_preferences_, true); | 415 base::AutoReset<bool> auto_reset(&updating_preferences_, true); |
| 430 { | 416 { |
| 417 DictionaryPrefUpdate update(prefs_, pref_name_); | |
| 418 base::DictionaryValue* pattern_pairs_settings = update.Get(); | |
| 419 | |
| 420 // Get settings dictionary for the given patterns. | |
| 421 std::string pattern_str(CreatePatternString(primary_pattern, | |
| 422 secondary_pattern)); | |
| 423 base::DictionaryValue* settings_dictionary = NULL; | |
| 424 bool found = pattern_pairs_settings->GetDictionaryWithoutPathExpansion( | |
| 425 pattern_str, &settings_dictionary); | |
| 426 | |
| 427 if (!found && value) { | |
| 428 settings_dictionary = new base::DictionaryValue; | |
| 429 pattern_pairs_settings->SetWithoutPathExpansion( | |
| 430 pattern_str, settings_dictionary); | |
| 431 } | |
| 432 | |
| 433 if (settings_dictionary) { | |
| 434 if (SupportsResourceIdentifiers(content_type_) && | |
| 435 !resource_identifier.empty()) { | |
| 436 base::DictionaryValue* resource_dictionary = NULL; | |
| 437 found = settings_dictionary->GetDictionary( | |
| 438 kPerResourceIdentifierPrefName, &resource_dictionary); | |
| 439 if (!found) { | |
| 440 if (value == NULL) | |
| 441 return; // Nothing to remove. Exit early. | |
| 442 resource_dictionary = new base::DictionaryValue; | |
| 443 settings_dictionary->Set( | |
| 444 kPerResourceIdentifierPrefName, resource_dictionary); | |
| 445 } | |
| 446 // Update resource dictionary. | |
| 447 if (value == NULL) { | |
| 448 resource_dictionary->RemoveWithoutPathExpansion(resource_identifier, | |
| 449 NULL); | |
| 450 if (resource_dictionary->empty()) { | |
| 451 settings_dictionary->RemoveWithoutPathExpansion( | |
| 452 kPerResourceIdentifierPrefName, NULL); | |
| 453 } | |
| 454 } else { | |
| 455 resource_dictionary->SetWithoutPathExpansion( | |
| 456 resource_identifier, value->DeepCopy()); | |
| 457 } | |
| 458 } else { | |
| 459 // Update settings dictionary. | |
| 460 if (value == NULL) { | |
| 461 settings_dictionary->RemoveWithoutPathExpansion(kSettingPath, NULL); | |
| 462 settings_dictionary->RemoveWithoutPathExpansion(kLastUsed, NULL); | |
| 463 } else { | |
| 464 settings_dictionary->SetWithoutPathExpansion( | |
| 465 kSettingPath, value->DeepCopy()); | |
| 466 } | |
| 467 } | |
| 468 // Remove the settings dictionary if it is empty. | |
| 469 if (settings_dictionary->empty()) { | |
| 470 pattern_pairs_settings->RemoveWithoutPathExpansion( | |
| 471 pattern_str, NULL); | |
| 472 } | |
| 473 } | |
| 474 } | |
| 475 } | |
| 476 | |
| 477 void ContentSettingsPref::UpdateOldPref( | |
| 478 const ContentSettingsPattern& primary_pattern, | |
| 479 const ContentSettingsPattern& secondary_pattern, | |
| 480 const ResourceIdentifier& resource_identifier, | |
| 481 const base::Value* value) { | |
| 482 DCHECK(IsContentSettingsTypeSyncable(content_type_)); | |
| 483 | |
| 484 if (*updating_old_preferences_) | |
| 485 return; | |
| 486 | |
| 487 base::AutoReset<bool> auto_reset(updating_old_preferences_, true); | |
| 488 { | |
| 431 DictionaryPrefUpdate update(prefs_, | 489 DictionaryPrefUpdate update(prefs_, |
| 432 prefs::kContentSettingsPatternPairs); | 490 prefs::kContentSettingsPatternPairs); |
| 433 base::DictionaryValue* pattern_pairs_settings = update.Get(); | 491 base::DictionaryValue* pattern_pairs_settings = update.Get(); |
| 434 | 492 |
| 435 // Get settings dictionary for the given patterns. | 493 // Get settings dictionary for the given patterns. |
| 436 std::string pattern_str(CreatePatternString(primary_pattern, | 494 std::string pattern_str(CreatePatternString(primary_pattern, |
| 437 secondary_pattern)); | 495 secondary_pattern)); |
| 438 base::DictionaryValue* settings_dictionary = NULL; | 496 base::DictionaryValue* settings_dictionary = NULL; |
| 439 bool found = pattern_pairs_settings->GetDictionaryWithoutPathExpansion( | 497 bool found = pattern_pairs_settings->GetDictionaryWithoutPathExpansion( |
| 440 pattern_str, &settings_dictionary); | 498 pattern_str, &settings_dictionary); |
| 441 | 499 |
| 442 if (!found && value) { | 500 if (!found && value) { |
| 443 settings_dictionary = new base::DictionaryValue; | 501 settings_dictionary = new base::DictionaryValue; |
| 444 pattern_pairs_settings->SetWithoutPathExpansion( | 502 pattern_pairs_settings->SetWithoutPathExpansion( |
| 445 pattern_str, settings_dictionary); | 503 pattern_str, settings_dictionary); |
| 446 } | 504 } |
| 447 | 505 |
| 448 if (settings_dictionary) { | 506 if (settings_dictionary) { |
| 449 std::string res_dictionary_path; | 507 if (content_type_ == CONTENT_SETTINGS_TYPE_PLUGINS && |
| 450 if (GetResourceTypeName(content_type, &res_dictionary_path) && | |
| 451 !resource_identifier.empty()) { | 508 !resource_identifier.empty()) { |
| 452 base::DictionaryValue* resource_dictionary = NULL; | 509 base::DictionaryValue* resource_dictionary = NULL; |
| 453 found = settings_dictionary->GetDictionary( | 510 found = settings_dictionary->GetDictionary( |
| 454 res_dictionary_path, &resource_dictionary); | 511 kPerPluginPrefName, &resource_dictionary); |
| 455 if (!found) { | 512 if (!found) { |
| 456 if (value == NULL) | 513 if (value == NULL) |
| 457 return; // Nothing to remove. Exit early. | 514 return; // Nothing to remove. Exit early. |
| 458 resource_dictionary = new base::DictionaryValue; | 515 resource_dictionary = new base::DictionaryValue; |
| 459 settings_dictionary->Set(res_dictionary_path, resource_dictionary); | 516 settings_dictionary->Set(kPerPluginPrefName, resource_dictionary); |
| 460 } | 517 } |
| 461 // Update resource dictionary. | 518 // Update resource dictionary. |
| 462 if (value == NULL) { | 519 if (value == NULL) { |
| 463 resource_dictionary->RemoveWithoutPathExpansion(resource_identifier, | 520 resource_dictionary->RemoveWithoutPathExpansion(resource_identifier, |
| 464 NULL); | 521 NULL); |
| 465 if (resource_dictionary->empty()) { | 522 if (resource_dictionary->empty()) { |
| 466 settings_dictionary->RemoveWithoutPathExpansion( | 523 settings_dictionary->RemoveWithoutPathExpansion( |
| 467 res_dictionary_path, NULL); | 524 kPerPluginPrefName, NULL); |
| 468 } | 525 } |
| 469 } else { | 526 } else { |
| 470 resource_dictionary->SetWithoutPathExpansion( | 527 resource_dictionary->SetWithoutPathExpansion( |
| 471 resource_identifier, value->DeepCopy()); | 528 resource_identifier, value->DeepCopy()); |
| 472 } | 529 } |
| 473 } else { | 530 } else { |
| 474 // Update settings dictionary. | 531 // Update settings dictionary. |
| 475 std::string setting_path = GetTypeName(content_type); | 532 std::string setting_path = GetTypeName(content_type_); |
| 476 if (value == NULL) { | 533 if (value == NULL) { |
| 477 settings_dictionary->RemoveWithoutPathExpansion(setting_path, | 534 settings_dictionary->RemoveWithoutPathExpansion(setting_path, |
| 478 NULL); | 535 NULL); |
| 479 settings_dictionary->RemoveWithoutPathExpansion(kLastUsed, NULL); | 536 settings_dictionary->RemoveWithoutPathExpansion(kLastUsed, NULL); |
| 480 } else { | 537 } else { |
| 481 settings_dictionary->SetWithoutPathExpansion( | 538 settings_dictionary->SetWithoutPathExpansion( |
| 482 setting_path, value->DeepCopy()); | 539 setting_path, value->DeepCopy()); |
| 483 } | 540 } |
| 484 } | 541 } |
| 485 // Remove the settings dictionary if it is empty. | 542 // Remove the settings dictionary if it is empty. |
| 486 if (settings_dictionary->empty()) { | 543 if (settings_dictionary->empty()) { |
| 487 pattern_pairs_settings->RemoveWithoutPathExpansion( | 544 pattern_pairs_settings->RemoveWithoutPathExpansion( |
| 488 pattern_str, NULL); | 545 pattern_str, NULL); |
| 489 } | 546 } |
| 490 } | 547 } |
| 491 } | 548 } |
| 492 } | 549 } |
| 493 | 550 |
| 551 void ContentSettingsPref::ClearOldPreference() { | |
| 552 DCHECK(IsContentSettingsTypeSyncable(content_type_)); | |
| 553 | |
| 554 if (*updating_old_preferences_) | |
| 555 return; | |
| 556 | |
| 557 std::vector<std::string> keys; | |
| 558 | |
| 559 base::AutoReset<bool> auto_reset(updating_old_preferences_, true); | |
| 560 DictionaryPrefUpdate update(prefs_, prefs::kContentSettingsPatternPairs); | |
| 561 base::DictionaryValue* old_dictionary = update.Get(); | |
| 562 | |
| 563 for (base::DictionaryValue::Iterator it(*old_dictionary); | |
| 564 !it.IsAtEnd(); it.Advance()) { | |
| 565 keys.push_back(it.key()); | |
| 566 } | |
| 567 | |
| 568 for (const std::string key : keys) { | |
| 569 base::DictionaryValue* exception; | |
| 570 bool is_dictionary = | |
| 571 old_dictionary->GetDictionaryWithoutPathExpansion(key, &exception); | |
| 572 DCHECK(is_dictionary); | |
| 573 | |
| 574 exception->RemoveWithoutPathExpansion(GetTypeName(content_type_), NULL); | |
| 575 | |
| 576 base::DictionaryValue* last_used; | |
| 577 if (exception->GetDictionaryWithoutPathExpansion(kLastUsed, &last_used)) { | |
| 578 last_used->RemoveWithoutPathExpansion(GetTypeName(content_type_), NULL); | |
| 579 | |
| 580 if (last_used->empty()) | |
| 581 exception->RemoveWithoutPathExpansion(kLastUsed, NULL); | |
| 582 } | |
| 583 | |
| 584 if (content_type_ == CONTENT_SETTINGS_TYPE_PLUGINS) | |
| 585 exception->RemoveWithoutPathExpansion(kPerPluginPrefName, NULL); | |
| 586 | |
| 587 if (exception->empty()) | |
| 588 old_dictionary->RemoveWithoutPathExpansion(key, NULL); | |
| 589 } | |
| 590 | |
| 591 } | |
| 592 | |
| 494 // static | 593 // static |
| 495 void ContentSettingsPref::CanonicalizeContentSettingsExceptions( | 594 void ContentSettingsPref::CanonicalizeContentSettingsExceptions( |
| 496 base::DictionaryValue* all_settings_dictionary) { | 595 base::DictionaryValue* all_settings_dictionary) { |
| 497 DCHECK(all_settings_dictionary); | 596 DCHECK(all_settings_dictionary); |
| 498 | 597 |
| 499 std::vector<std::string> remove_items; | 598 std::vector<std::string> remove_items; |
| 500 base::StringPairs move_items; | 599 base::StringPairs move_items; |
| 501 for (base::DictionaryValue::Iterator i(*all_settings_dictionary); | 600 for (base::DictionaryValue::Iterator i(*all_settings_dictionary); |
| 502 !i.IsAtEnd(); | 601 !i.IsAtEnd(); |
| 503 i.Advance()) { | 602 i.Advance()) { |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 549 | 648 |
| 550 void ContentSettingsPref::AssertLockNotHeld() const { | 649 void ContentSettingsPref::AssertLockNotHeld() const { |
| 551 #if !defined(NDEBUG) | 650 #if !defined(NDEBUG) |
| 552 // |Lock::Acquire()| will assert if the lock is held by this thread. | 651 // |Lock::Acquire()| will assert if the lock is held by this thread. |
| 553 lock_.Acquire(); | 652 lock_.Acquire(); |
| 554 lock_.Release(); | 653 lock_.Release(); |
| 555 #endif | 654 #endif |
| 556 } | 655 } |
| 557 | 656 |
| 558 } // namespace content_settings | 657 } // namespace content_settings |
| OLD | NEW |