OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "chrome/browser/content_settings/content_settings_default_provider.h" | 5 #include "chrome/browser/content_settings/content_settings_default_provider.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/auto_reset.h" | 10 #include "base/auto_reset.h" |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
63 Rule Next() { | 63 Rule Next() { |
64 DCHECK(setting_ != CONTENT_SETTING_DEFAULT); | 64 DCHECK(setting_ != CONTENT_SETTING_DEFAULT); |
65 ContentSetting setting_to_return = setting_; | 65 ContentSetting setting_to_return = setting_; |
66 setting_ = CONTENT_SETTING_DEFAULT; | 66 setting_ = CONTENT_SETTING_DEFAULT; |
67 return Rule(ContentSettingsPattern::Wildcard(), | 67 return Rule(ContentSettingsPattern::Wildcard(), |
68 ContentSettingsPattern::Wildcard(), | 68 ContentSettingsPattern::Wildcard(), |
69 Value::CreateIntegerValue(setting_to_return)); | 69 Value::CreateIntegerValue(setting_to_return)); |
70 } | 70 } |
71 | 71 |
72 private: | 72 private: |
73 // TODO(markusheintz): |ContentSetting| should be replaced with a |Value|. | |
73 ContentSetting setting_; | 74 ContentSetting setting_; |
74 }; | 75 }; |
75 | 76 |
76 } // namespace | 77 } // namespace |
77 | 78 |
78 // static | 79 // static |
79 void DefaultProvider::RegisterUserPrefs(PrefService* prefs) { | 80 void DefaultProvider::RegisterUserPrefs(PrefService* prefs) { |
80 // The registration of the preference prefs::kDefaultContentSettings should | 81 // The registration of the preference prefs::kDefaultContentSettings should |
81 // also include the default values for default content settings. This allows | 82 // also include the default values for default content settings. This allows |
82 // functional tests to get default content settings by reading the preference | 83 // functional tests to get default content settings by reading the preference |
(...skipping 19 matching lines...) Expand all Loading... | |
102 DefaultProvider::DefaultProvider(PrefService* prefs, bool incognito) | 103 DefaultProvider::DefaultProvider(PrefService* prefs, bool incognito) |
103 : prefs_(prefs), | 104 : prefs_(prefs), |
104 is_incognito_(incognito), | 105 is_incognito_(incognito), |
105 updating_preferences_(false) { | 106 updating_preferences_(false) { |
106 DCHECK(prefs_); | 107 DCHECK(prefs_); |
107 MigrateObsoleteNotificationPref(); | 108 MigrateObsoleteNotificationPref(); |
108 MigrateObsoleteGeolocationPref(); | 109 MigrateObsoleteGeolocationPref(); |
109 | 110 |
110 // Read global defaults. | 111 // Read global defaults. |
111 ReadDefaultSettings(true); | 112 ReadDefaultSettings(true); |
112 if (default_content_settings_.settings[CONTENT_SETTINGS_TYPE_COOKIES] == | 113 |
113 CONTENT_SETTING_BLOCK) { | 114 ContentSetting cookie_setting = ValueToContentSetting( |
115 default_settings_[CONTENT_SETTINGS_TYPE_COOKIES].get()); | |
116 if (cookie_setting == CONTENT_SETTING_BLOCK) { | |
114 UserMetrics::RecordAction( | 117 UserMetrics::RecordAction( |
115 UserMetricsAction("CookieBlockingEnabledPerDefault")); | 118 UserMetricsAction("CookieBlockingEnabledPerDefault")); |
116 } else { | 119 } else { |
117 UserMetrics::RecordAction( | 120 UserMetrics::RecordAction( |
118 UserMetricsAction("CookieBlockingDisabledPerDefault")); | 121 UserMetricsAction("CookieBlockingDisabledPerDefault")); |
119 } | 122 } |
120 | 123 |
121 pref_change_registrar_.Init(prefs_); | 124 pref_change_registrar_.Init(prefs_); |
122 pref_change_registrar_.Add(prefs::kDefaultContentSettings, this); | 125 pref_change_registrar_.Add(prefs::kDefaultContentSettings, this); |
123 pref_change_registrar_.Add(prefs::kGeolocationDefaultContentSetting, this); | 126 pref_change_registrar_.Add(prefs::kGeolocationDefaultContentSetting, this); |
124 } | 127 } |
125 | 128 |
126 DefaultProvider::~DefaultProvider() { | 129 DefaultProvider::~DefaultProvider() { |
127 } | 130 } |
128 | 131 |
129 void DefaultProvider::SetContentSetting( | 132 bool DefaultProvider::SetWebsiteSetting( |
130 const ContentSettingsPattern& primary_pattern, | 133 const ContentSettingsPattern& primary_pattern, |
131 const ContentSettingsPattern& secondary_pattern, | 134 const ContentSettingsPattern& secondary_pattern, |
132 ContentSettingsType content_type, | 135 ContentSettingsType content_type, |
133 const ResourceIdentifier& resource_identifier, | 136 const ResourceIdentifier& resource_identifier, |
134 ContentSetting setting) { | 137 Value* value) { |
135 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 138 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
136 DCHECK(prefs_); | 139 DCHECK(prefs_); |
137 | 140 |
138 // Ignore non default settings | 141 // Ignore non default settings |
139 if (primary_pattern != ContentSettingsPattern::Wildcard() || | 142 if (primary_pattern != ContentSettingsPattern::Wildcard() || |
140 secondary_pattern != ContentSettingsPattern::Wildcard()) { | 143 secondary_pattern != ContentSettingsPattern::Wildcard()) { |
141 return; | 144 return false; |
142 } | 145 } |
143 | 146 |
144 // The default settings may not be directly modified for OTR sessions. | 147 // The default settings may not be directly modified for OTR sessions. |
145 // Instead, they are synced to the main profile's setting. | 148 // Instead, they are synced to the main profile's setting. |
146 if (is_incognito_) | 149 if (is_incognito_) |
147 return; | 150 return false; |
148 | 151 |
149 std::string dictionary_path = GetTypeName(content_type); | |
150 { | 152 { |
151 AutoReset<bool> auto_reset(&updating_preferences_, true); | 153 AutoReset<bool> auto_reset(&updating_preferences_, true); |
Bernhard Bauer
2011/11/15 17:45:53
I guess you don't need both of these scopes anymor
markusheintz_
2011/11/16 14:57:48
Done.
I thought it might be safer to first releas
| |
152 DictionaryPrefUpdate update(prefs_, prefs::kDefaultContentSettings); | 154 // Keep the obsolete pref in sync as long as backwards compatibility is |
153 DictionaryValue* default_settings_dictionary = update.Get(); | 155 // required. This is required to keep sync working correctly. |
156 if (content_type == CONTENT_SETTINGS_TYPE_GEOLOCATION) { | |
157 if (value) { | |
158 prefs_->Set(prefs::kGeolocationDefaultContentSetting, *value); | |
159 } else { | |
160 prefs_->ClearPref(prefs::kGeolocationDefaultContentSetting); | |
161 } | |
162 } | |
154 | 163 |
155 // |DefaultProvider| should not send any notifications when holding | 164 // |DefaultProvider| should not send any notifications when holding |
156 // |lock_|. |DictionaryPrefUpdate| destructor and | 165 // |lock_|. |DictionaryPrefUpdate| destructor and |
157 // |PrefService::SetInteger()| send out notifications. As a response, the | 166 // |PrefService::SetInteger()| send out notifications. As a response, the |
158 // upper layers may call |GetAllContentSettingRules| which acquires |lock_| | 167 // upper layers may call |GetAllContentSettingRules| which acquires |lock_| |
159 // again. | 168 // again. |
169 DictionaryPrefUpdate update(prefs_, prefs::kDefaultContentSettings); | |
170 DictionaryValue* default_settings_dictionary = update.Get(); | |
160 { | 171 { |
161 base::AutoLock lock(lock_); | 172 base::AutoLock lock(lock_); |
162 if (setting == CONTENT_SETTING_DEFAULT || | 173 if (value == NULL || |
163 setting == kDefaultSettings[content_type]) { | 174 ValueToContentSetting(value) == kDefaultSettings[content_type]) { |
164 default_content_settings_.settings[content_type] = | 175 // If |value| is NULL we need to reset the default setting the the |
165 kDefaultSettings[content_type]; | 176 // hardcoded default. |
166 default_settings_dictionary->RemoveWithoutPathExpansion(dictionary_path, | 177 default_settings_[content_type].reset( |
167 NULL); | 178 Value::CreateIntegerValue(kDefaultSettings[content_type])); |
179 | |
180 // Remove the corresponding pref entry since the hardcoded default value | |
181 // is used. | |
182 default_settings_dictionary->RemoveWithoutPathExpansion( | |
183 GetTypeName(content_type), NULL); | |
168 } else { | 184 } else { |
169 default_content_settings_.settings[content_type] = setting; | 185 default_settings_[content_type].reset(value->DeepCopy()); |
186 // Transfer ownership of |value| to the |default_settings_dictionary|. | |
170 default_settings_dictionary->SetWithoutPathExpansion( | 187 default_settings_dictionary->SetWithoutPathExpansion( |
171 dictionary_path, Value::CreateIntegerValue(setting)); | 188 GetTypeName(content_type), value); |
172 } | 189 } |
173 } | 190 } |
174 | |
175 // Keep the obsolete pref in sync as long as backwards compatibility is | |
176 // required. This is required to keep sync working correctly. | |
177 if (content_type == CONTENT_SETTINGS_TYPE_GEOLOCATION) { | |
178 prefs_->SetInteger(prefs::kGeolocationDefaultContentSetting, | |
179 setting == CONTENT_SETTING_DEFAULT ? | |
180 kDefaultSettings[content_type] : setting); | |
181 } | |
182 } | 191 } |
183 | 192 |
184 NotifyObservers(ContentSettingsPattern(), | 193 NotifyObservers(ContentSettingsPattern(), |
185 ContentSettingsPattern(), | 194 ContentSettingsPattern(), |
186 content_type, | 195 content_type, |
187 std::string()); | 196 std::string()); |
197 | |
198 return true; | |
188 } | 199 } |
189 | 200 |
190 RuleIterator* DefaultProvider::GetRuleIterator( | 201 RuleIterator* DefaultProvider::GetRuleIterator( |
191 ContentSettingsType content_type, | 202 ContentSettingsType content_type, |
192 const ResourceIdentifier& resource_identifier, | 203 const ResourceIdentifier& resource_identifier, |
193 bool incognito) const { | 204 bool incognito) const { |
194 base::AutoLock lock(lock_); | 205 base::AutoLock lock(lock_); |
195 if (resource_identifier.empty()) { | 206 if (resource_identifier.empty()) { |
196 return new DefaultRuleIterator( | 207 int int_value = 0; |
197 default_content_settings_.settings[content_type]); | 208 ValueMap::const_iterator it(default_settings_.find(content_type)); |
209 if (it != default_settings_.end()) { | |
210 it->second->GetAsInteger(&int_value); | |
211 } else { | |
212 NOTREACHED(); | |
213 } | |
214 return new DefaultRuleIterator(ContentSetting(int_value)); | |
198 } else { | 215 } else { |
199 return new EmptyRuleIterator(); | 216 return new EmptyRuleIterator(); |
200 } | 217 } |
201 } | 218 } |
202 | 219 |
203 void DefaultProvider::ClearAllContentSettingsRules( | 220 void DefaultProvider::ClearAllContentSettingsRules( |
204 ContentSettingsType content_type) { | 221 ContentSettingsType content_type) { |
205 // TODO(markusheintz): This method is only called when the | 222 // TODO(markusheintz): This method is only called when the |
206 // |DesktopNotificationService| calls |ClearAllSettingsForType| method on the | 223 // |DesktopNotificationService| calls |ClearAllSettingsForType| method on the |
207 // |HostContentSettingsMap|. Don't implement this method yet, otherwise the | 224 // |HostContentSettingsMap|. Don't implement this method yet, otherwise the |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
248 NOTREACHED() << "Unexpected notification"; | 265 NOTREACHED() << "Unexpected notification"; |
249 } | 266 } |
250 } | 267 } |
251 | 268 |
252 void DefaultProvider::ReadDefaultSettings(bool overwrite) { | 269 void DefaultProvider::ReadDefaultSettings(bool overwrite) { |
253 base::AutoLock lock(lock_); | 270 base::AutoLock lock(lock_); |
254 const DictionaryValue* default_settings_dictionary = | 271 const DictionaryValue* default_settings_dictionary = |
255 prefs_->GetDictionary(prefs::kDefaultContentSettings); | 272 prefs_->GetDictionary(prefs::kDefaultContentSettings); |
256 | 273 |
257 if (overwrite) | 274 if (overwrite) |
258 default_content_settings_ = ContentSettings(); | 275 default_settings_.clear(); |
259 | 276 |
260 // Careful: The returned value could be NULL if the pref has never been set. | 277 // Careful: The returned value could be NULL if the pref has never been set. |
261 if (default_settings_dictionary) { | 278 if (default_settings_dictionary) |
262 GetSettingsFromDictionary(default_settings_dictionary, | 279 GetSettingsFromDictionary(default_settings_dictionary); |
263 &default_content_settings_); | 280 |
264 } | |
265 ForceDefaultsToBeExplicit(); | 281 ForceDefaultsToBeExplicit(); |
266 } | 282 } |
267 | 283 |
268 void DefaultProvider::ForceDefaultsToBeExplicit() { | 284 void DefaultProvider::ForceDefaultsToBeExplicit() { |
269 for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) { | 285 for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) { |
270 if (default_content_settings_.settings[i] == CONTENT_SETTING_DEFAULT) | 286 ContentSettingsType type = ContentSettingsType(i); |
271 default_content_settings_.settings[i] = kDefaultSettings[i]; | 287 if (!default_settings_[type].get()) |
288 default_settings_[type].reset( | |
289 Value::CreateIntegerValue(kDefaultSettings[i])); | |
272 } | 290 } |
273 } | 291 } |
274 | 292 |
275 void DefaultProvider::GetSettingsFromDictionary( | 293 void DefaultProvider::GetSettingsFromDictionary( |
276 const DictionaryValue* dictionary, | 294 const DictionaryValue* dictionary) { |
277 ContentSettings* settings) { | |
278 for (DictionaryValue::key_iterator i(dictionary->begin_keys()); | 295 for (DictionaryValue::key_iterator i(dictionary->begin_keys()); |
279 i != dictionary->end_keys(); ++i) { | 296 i != dictionary->end_keys(); ++i) { |
280 const std::string& content_type(*i); | 297 const std::string& content_type(*i); |
281 for (size_t type = 0; type < CONTENT_SETTINGS_NUM_TYPES; ++type) { | 298 for (size_t type = 0; type < CONTENT_SETTINGS_NUM_TYPES; ++type) { |
282 if (content_type == GetTypeName(ContentSettingsType(type))) { | 299 if (content_type == GetTypeName(ContentSettingsType(type))) { |
283 int setting = CONTENT_SETTING_DEFAULT; | 300 int int_value = CONTENT_SETTING_DEFAULT; |
284 bool found = dictionary->GetIntegerWithoutPathExpansion(content_type, | 301 bool found = dictionary->GetIntegerWithoutPathExpansion(content_type, |
285 &setting); | 302 &int_value); |
286 DCHECK(found); | 303 DCHECK(found); |
287 settings->settings[type] = IntToContentSetting(setting); | 304 default_settings_[ContentSettingsType(type)].reset( |
305 Value::CreateIntegerValue(int_value)); | |
288 break; | 306 break; |
289 } | 307 } |
290 } | 308 } |
291 } | 309 } |
292 // Migrate obsolete cookie prompt mode/ | 310 // Migrate obsolete cookie prompt mode. |
293 if (settings->settings[CONTENT_SETTINGS_TYPE_COOKIES] == | 311 if (ValueToContentSetting( |
294 CONTENT_SETTING_ASK) | 312 default_settings_[CONTENT_SETTINGS_TYPE_COOKIES].get()) == |
295 settings->settings[CONTENT_SETTINGS_TYPE_COOKIES] = CONTENT_SETTING_BLOCK; | 313 CONTENT_SETTING_ASK) { |
314 default_settings_[CONTENT_SETTINGS_TYPE_COOKIES].reset( | |
315 Value::CreateIntegerValue(CONTENT_SETTING_BLOCK)); | |
316 } | |
296 | 317 |
297 settings->settings[CONTENT_SETTINGS_TYPE_PLUGINS] = | 318 if (default_settings_[CONTENT_SETTINGS_TYPE_PLUGINS].get()) { |
298 ClickToPlayFixup(CONTENT_SETTINGS_TYPE_PLUGINS, | 319 ContentSetting plugin_setting = ValueToContentSetting( |
299 settings->settings[CONTENT_SETTINGS_TYPE_PLUGINS]); | 320 default_settings_[CONTENT_SETTINGS_TYPE_PLUGINS].get()); |
321 plugin_setting = | |
322 ClickToPlayFixup(CONTENT_SETTINGS_TYPE_PLUGINS, plugin_setting); | |
323 default_settings_[CONTENT_SETTINGS_TYPE_PLUGINS].reset( | |
324 Value::CreateIntegerValue(plugin_setting)); | |
325 } | |
300 } | 326 } |
301 | 327 |
302 void DefaultProvider::MigrateObsoleteNotificationPref() { | 328 void DefaultProvider::MigrateObsoleteNotificationPref() { |
303 if (prefs_->HasPrefPath(prefs::kDesktopNotificationDefaultContentSetting)) { | 329 if (prefs_->HasPrefPath(prefs::kDesktopNotificationDefaultContentSetting)) { |
304 ContentSetting setting = IntToContentSetting( | 330 const base::Value* value = prefs_->FindPreference( |
305 prefs_->GetInteger(prefs::kDesktopNotificationDefaultContentSetting)); | 331 prefs::kDesktopNotificationDefaultContentSetting)->GetValue(); |
306 SetContentSetting( | 332 // Do not clear the old preference yet as long as we need to maintain |
333 // backward compatibility. | |
334 SetWebsiteSetting( | |
307 ContentSettingsPattern::Wildcard(), | 335 ContentSettingsPattern::Wildcard(), |
308 ContentSettingsPattern::Wildcard(), | 336 ContentSettingsPattern::Wildcard(), |
309 CONTENT_SETTINGS_TYPE_NOTIFICATIONS, | 337 CONTENT_SETTINGS_TYPE_NOTIFICATIONS, |
310 std::string(), | 338 std::string(), |
311 setting); | 339 value->DeepCopy()); |
312 prefs_->ClearPref(prefs::kDesktopNotificationDefaultContentSetting); | 340 prefs_->ClearPref(prefs::kDesktopNotificationDefaultContentSetting); |
313 } | 341 } |
314 } | 342 } |
315 | 343 |
316 void DefaultProvider::MigrateObsoleteGeolocationPref() { | 344 void DefaultProvider::MigrateObsoleteGeolocationPref() { |
317 if (prefs_->HasPrefPath(prefs::kGeolocationDefaultContentSetting)) { | 345 if (prefs_->HasPrefPath(prefs::kGeolocationDefaultContentSetting)) { |
318 ContentSetting setting = IntToContentSetting( | 346 const base::Value* value = prefs_->FindPreference( |
319 prefs_->GetInteger(prefs::kGeolocationDefaultContentSetting)); | 347 prefs::kGeolocationDefaultContentSetting)->GetValue(); |
320 // Do not clear the old preference yet as long as we need to maintain | 348 // Do not clear the old preference yet as long as we need to maintain |
321 // backward compatibility. | 349 // backward compatibility. |
322 SetContentSetting( | 350 SetWebsiteSetting( |
323 ContentSettingsPattern::Wildcard(), | 351 ContentSettingsPattern::Wildcard(), |
324 ContentSettingsPattern::Wildcard(), | 352 ContentSettingsPattern::Wildcard(), |
325 CONTENT_SETTINGS_TYPE_GEOLOCATION, | 353 CONTENT_SETTINGS_TYPE_GEOLOCATION, |
326 std::string(), | 354 std::string(), |
327 setting); | 355 value->DeepCopy()); |
328 } | 356 } |
329 } | 357 } |
330 | 358 |
331 } // namespace content_settings | 359 } // namespace content_settings |
OLD | NEW |