Revert 168224 - Update V8 to version 3.15.4.
[chromium-blink-merge.git] / chrome / browser / content_settings / content_settings_pref_provider.cc
blobeb6135f7c507a3e8c30773537de33828f7f7f499
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/content_settings/content_settings_pref_provider.h"
7 #include <map>
8 #include <string>
9 #include <utility>
11 #include "base/auto_reset.h"
12 #include "base/command_line.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/metrics/histogram.h"
15 #include "chrome/browser/content_settings/content_settings_rule.h"
16 #include "chrome/browser/content_settings/content_settings_utils.h"
17 #include "chrome/browser/content_settings/host_content_settings_map.h"
18 #include "chrome/browser/prefs/pref_service.h"
19 #include "chrome/browser/prefs/scoped_user_pref_update.h"
20 #include "chrome/common/chrome_notification_types.h"
21 #include "chrome/common/chrome_switches.h"
22 #include "chrome/common/content_settings.h"
23 #include "chrome/common/content_settings_pattern.h"
24 #include "chrome/common/pref_names.h"
25 #include "content/public/browser/browser_thread.h"
26 #include "content/public/browser/notification_details.h"
27 #include "content/public/browser/notification_source.h"
28 #include "content/public/browser/user_metrics.h"
29 #include "googleurl/src/gurl.h"
31 using content::BrowserThread;
32 using content::UserMetricsAction;
34 namespace {
36 typedef std::pair<std::string, std::string> StringPair;
37 typedef std::map<std::string, std::string> StringMap;
39 const char kPerPluginPrefName[] = "per_plugin";
41 ContentSetting FixObsoleteCookiePromptMode(ContentSettingsType content_type,
42 ContentSetting setting) {
43 if (content_type == CONTENT_SETTINGS_TYPE_COOKIES &&
44 setting == CONTENT_SETTING_ASK) {
45 return CONTENT_SETTING_BLOCK;
47 return setting;
50 // If the given content type supports resource identifiers in user preferences,
51 // returns true and sets |pref_key| to the key in the content settings
52 // dictionary under which per-resource content settings are stored.
53 // Otherwise, returns false.
54 bool GetResourceTypeName(ContentSettingsType content_type,
55 std::string* pref_key) {
56 if (content_type == CONTENT_SETTINGS_TYPE_PLUGINS) {
57 *pref_key = kPerPluginPrefName;
58 return true;
60 return false;
63 } // namespace
65 namespace content_settings {
67 // ////////////////////////////////////////////////////////////////////////////
68 // PrefProvider:
71 // static
72 void PrefProvider::RegisterUserPrefs(PrefService* prefs) {
73 prefs->RegisterIntegerPref(
74 prefs::kContentSettingsVersion,
75 ContentSettingsPattern::kContentSettingsPatternVersion,
76 PrefService::UNSYNCABLE_PREF);
77 prefs->RegisterDictionaryPref(prefs::kContentSettingsPatternPairs,
78 PrefService::SYNCABLE_PREF);
80 // Obsolete prefs, for migration:
81 prefs->RegisterDictionaryPref(prefs::kGeolocationContentSettings,
82 PrefService::UNSYNCABLE_PREF);
83 prefs->RegisterDictionaryPref(prefs::kContentSettingsPatterns,
84 PrefService::UNSYNCABLE_PREF);
85 prefs->RegisterListPref(prefs::kDesktopNotificationAllowedOrigins,
86 PrefService::UNSYNCABLE_PREF);
87 prefs->RegisterListPref(prefs::kDesktopNotificationDeniedOrigins,
88 PrefService::UNSYNCABLE_PREF);
91 PrefProvider::PrefProvider(PrefService* prefs,
92 bool incognito)
93 : prefs_(prefs),
94 is_incognito_(incognito),
95 updating_preferences_(false) {
96 DCHECK(prefs_);
97 if (!is_incognito_) {
98 // Migrate obsolete preferences.
99 MigrateObsoleteContentSettingsPatternPref();
100 MigrateObsoleteGeolocationPref();
101 MigrateObsoleteNotificationsPrefs();
104 // Verify preferences version.
105 if (!prefs_->HasPrefPath(prefs::kContentSettingsVersion)) {
106 prefs_->SetInteger(prefs::kContentSettingsVersion,
107 ContentSettingsPattern::kContentSettingsPatternVersion);
109 if (prefs_->GetInteger(prefs::kContentSettingsVersion) >
110 ContentSettingsPattern::kContentSettingsPatternVersion) {
111 return;
114 // Read content settings exceptions.
115 ReadContentSettingsFromPref(false);
117 if (!is_incognito_) {
118 UMA_HISTOGRAM_COUNTS("ContentSettings.NumberOfExceptions",
119 value_map_.size());
122 pref_change_registrar_.Init(prefs_);
123 pref_change_registrar_.Add(
124 prefs::kContentSettingsPatternPairs,
125 base::Bind(&PrefProvider::OnContentSettingsPatternPairsChanged,
126 base::Unretained(this)));
129 bool PrefProvider::SetWebsiteSetting(
130 const ContentSettingsPattern& primary_pattern,
131 const ContentSettingsPattern& secondary_pattern,
132 ContentSettingsType content_type,
133 const ResourceIdentifier& resource_identifier,
134 Value* in_value) {
135 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
136 DCHECK(prefs_);
137 // Default settings are set using a wildcard pattern for both
138 // |primary_pattern| and |secondary_pattern|. Don't store default settings in
139 // the |PrefProvider|. The |PrefProvider| handles settings for specific
140 // sites/origins defined by the |primary_pattern| and the |secondary_pattern|.
141 // Default settings are handled by the |DefaultProvider|.
142 if (primary_pattern == ContentSettingsPattern::Wildcard() &&
143 secondary_pattern == ContentSettingsPattern::Wildcard() &&
144 resource_identifier.empty()) {
145 return false;
148 // At this point take the ownership of the |in_value|.
149 scoped_ptr<base::Value> value(in_value);
150 // Update in memory value map.
151 OriginIdentifierValueMap* map_to_modify = &incognito_value_map_;
152 if (!is_incognito_)
153 map_to_modify = &value_map_;
156 base::AutoLock auto_lock(lock_);
157 if (value.get()) {
158 map_to_modify->SetValue(
159 primary_pattern,
160 secondary_pattern,
161 content_type,
162 resource_identifier,
163 value->DeepCopy());
164 } else {
165 map_to_modify->DeleteValue(
166 primary_pattern,
167 secondary_pattern,
168 content_type,
169 resource_identifier);
172 // Update the content settings preference.
173 if (!is_incognito_) {
174 UpdatePref(primary_pattern,
175 secondary_pattern,
176 content_type,
177 resource_identifier,
178 value.get());
181 NotifyObservers(
182 primary_pattern, secondary_pattern, content_type, resource_identifier);
184 return true;
187 void PrefProvider::ClearAllContentSettingsRules(
188 ContentSettingsType content_type) {
189 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
190 DCHECK(prefs_);
192 OriginIdentifierValueMap* map_to_modify = &incognito_value_map_;
193 if (!is_incognito_)
194 map_to_modify = &value_map_;
196 std::vector<Rule> rules_to_delete;
198 base::AutoLock auto_lock(lock_);
199 scoped_ptr<RuleIterator> rule_iterator(
200 map_to_modify->GetRuleIterator(content_type, "", NULL));
201 // Copy the rules; we cannot call |UpdatePref| while holding |lock_|.
202 while (rule_iterator->HasNext())
203 rules_to_delete.push_back(rule_iterator->Next());
205 map_to_modify->DeleteValues(content_type, "");
208 for (std::vector<Rule>::const_iterator it = rules_to_delete.begin();
209 it != rules_to_delete.end(); ++it) {
210 UpdatePref(
211 it->primary_pattern,
212 it->secondary_pattern,
213 content_type,
215 NULL);
217 NotifyObservers(ContentSettingsPattern(),
218 ContentSettingsPattern(),
219 content_type,
220 std::string());
223 PrefProvider::~PrefProvider() {
224 DCHECK(!prefs_);
227 RuleIterator* PrefProvider::GetRuleIterator(
228 ContentSettingsType content_type,
229 const ResourceIdentifier& resource_identifier,
230 bool incognito) const {
231 if (incognito)
232 return incognito_value_map_.GetRuleIterator(content_type,
233 resource_identifier,
234 &lock_);
235 return value_map_.GetRuleIterator(content_type, resource_identifier, &lock_);
238 // ////////////////////////////////////////////////////////////////////////////
239 // Private
241 void PrefProvider::UpdatePref(
242 const ContentSettingsPattern& primary_pattern,
243 const ContentSettingsPattern& secondary_pattern,
244 ContentSettingsType content_type,
245 const ResourceIdentifier& resource_identifier,
246 const base::Value* value) {
247 // Ensure that |lock_| is not held by this thread, since this function will
248 // send out notifications (by |~DictionaryPrefUpdate|).
249 AssertLockNotHeld();
251 AutoReset<bool> auto_reset(&updating_preferences_, true);
253 DictionaryPrefUpdate update(prefs_,
254 prefs::kContentSettingsPatternPairs);
255 DictionaryValue* pattern_pairs_settings = update.Get();
256 UpdatePatternPairsSettings(primary_pattern,
257 secondary_pattern,
258 content_type,
259 resource_identifier,
260 value,
261 pattern_pairs_settings);
265 void PrefProvider::ReadContentSettingsFromPref(bool overwrite) {
266 // |DictionaryPrefUpdate| sends out notifications when destructed. This
267 // construction order ensures |AutoLock| gets destroyed first and |lock_| is
268 // not held when the notifications are sent. Also, |auto_reset| must be still
269 // valid when the notifications are sent, so that |Observe| skips the
270 // notification.
271 AutoReset<bool> auto_reset(&updating_preferences_, true);
272 DictionaryPrefUpdate update(prefs_, prefs::kContentSettingsPatternPairs);
273 base::AutoLock auto_lock(lock_);
275 const DictionaryValue* all_settings_dictionary =
276 prefs_->GetDictionary(prefs::kContentSettingsPatternPairs);
278 if (overwrite)
279 value_map_.clear();
281 // Careful: The returned value could be NULL if the pref has never been set.
282 if (!all_settings_dictionary)
283 return;
285 DictionaryValue* mutable_settings;
286 scoped_ptr<DictionaryValue> mutable_settings_scope;
288 if (!is_incognito_) {
289 mutable_settings = update.Get();
290 } else {
291 // Create copy as we do not want to persist anything in OTR prefs.
292 mutable_settings = all_settings_dictionary->DeepCopy();
293 mutable_settings_scope.reset(mutable_settings);
295 // Convert all Unicode patterns into punycode form, then read.
296 CanonicalizeContentSettingsExceptions(mutable_settings);
298 for (DictionaryValue::key_iterator i(mutable_settings->begin_keys());
299 i != mutable_settings->end_keys(); ++i) {
300 const std::string& pattern_str(*i);
301 std::pair<ContentSettingsPattern, ContentSettingsPattern> pattern_pair =
302 ParsePatternString(pattern_str);
303 if (!pattern_pair.first.IsValid() ||
304 !pattern_pair.second.IsValid()) {
305 LOG(DFATAL) << "Invalid pattern strings: " << pattern_str;
306 continue;
309 // Get settings dictionary for the current pattern string, and read
310 // settings from the dictionary.
311 DictionaryValue* settings_dictionary = NULL;
312 bool found = mutable_settings->GetDictionaryWithoutPathExpansion(
313 pattern_str, &settings_dictionary);
314 DCHECK(found);
316 for (size_t i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) {
317 ContentSettingsType content_type = static_cast<ContentSettingsType>(i);
319 std::string res_dictionary_path;
320 if (GetResourceTypeName(content_type, &res_dictionary_path)) {
321 DictionaryValue* resource_dictionary = NULL;
322 if (settings_dictionary->GetDictionary(
323 res_dictionary_path, &resource_dictionary)) {
324 for (DictionaryValue::key_iterator j(
325 resource_dictionary->begin_keys());
326 j != resource_dictionary->end_keys();
327 ++j) {
328 const std::string& resource_identifier(*j);
329 int setting = CONTENT_SETTING_DEFAULT;
330 found = resource_dictionary->GetIntegerWithoutPathExpansion(
331 resource_identifier, &setting);
332 DCHECK_NE(CONTENT_SETTING_DEFAULT, setting);
333 value_map_.SetValue(pattern_pair.first,
334 pattern_pair.second,
335 content_type,
336 resource_identifier,
337 Value::CreateIntegerValue(setting));
341 Value* value = NULL;
342 if (HostContentSettingsMap::ContentTypeHasCompoundValue(content_type)) {
343 DictionaryValue* setting = NULL;
344 // TODO(xians): Handle the non-dictionary types.
345 if (settings_dictionary->GetDictionaryWithoutPathExpansion(
346 GetTypeName(ContentSettingsType(i)), &setting)) {
347 DCHECK(!setting->empty());
348 value = setting->DeepCopy();
350 } else {
351 int setting = CONTENT_SETTING_DEFAULT;
352 if (settings_dictionary->GetIntegerWithoutPathExpansion(
353 GetTypeName(ContentSettingsType(i)), &setting)) {
354 DCHECK_NE(CONTENT_SETTING_DEFAULT, setting);
355 setting = FixObsoleteCookiePromptMode(content_type,
356 ContentSetting(setting));
357 value = Value::CreateIntegerValue(setting);
361 // |value_map_| will take the ownership of |value|.
362 if (value != NULL) {
363 value_map_.SetValue(pattern_pair.first,
364 pattern_pair.second,
365 content_type,
366 ResourceIdentifier(""),
367 value);
373 void PrefProvider::OnContentSettingsPatternPairsChanged() {
374 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
376 if (updating_preferences_)
377 return;
379 ReadContentSettingsFromPref(true);
381 NotifyObservers(ContentSettingsPattern(),
382 ContentSettingsPattern(),
383 CONTENT_SETTINGS_TYPE_DEFAULT,
384 std::string());
387 void PrefProvider::UpdatePatternPairsSettings(
388 const ContentSettingsPattern& primary_pattern,
389 const ContentSettingsPattern& secondary_pattern,
390 ContentSettingsType content_type,
391 const ResourceIdentifier& resource_identifier,
392 const base::Value* value,
393 DictionaryValue* pattern_pairs_settings) {
394 // Get settings dictionary for the given patterns.
395 std::string pattern_str(CreatePatternString(primary_pattern,
396 secondary_pattern));
397 DictionaryValue* settings_dictionary = NULL;
398 bool found = pattern_pairs_settings->GetDictionaryWithoutPathExpansion(
399 pattern_str, &settings_dictionary);
401 if (!found && value) {
402 settings_dictionary = new DictionaryValue;
403 pattern_pairs_settings->SetWithoutPathExpansion(
404 pattern_str, settings_dictionary);
407 if (settings_dictionary) {
408 std::string res_dictionary_path;
409 if (GetResourceTypeName(content_type, &res_dictionary_path) &&
410 !resource_identifier.empty()) {
411 DictionaryValue* resource_dictionary = NULL;
412 found = settings_dictionary->GetDictionary(
413 res_dictionary_path, &resource_dictionary);
414 if (!found) {
415 if (value == NULL)
416 return; // Nothing to remove. Exit early.
417 resource_dictionary = new DictionaryValue;
418 settings_dictionary->Set(res_dictionary_path, resource_dictionary);
420 // Update resource dictionary.
421 if (value == NULL) {
422 resource_dictionary->RemoveWithoutPathExpansion(resource_identifier,
423 NULL);
424 if (resource_dictionary->empty()) {
425 settings_dictionary->RemoveWithoutPathExpansion(
426 res_dictionary_path, NULL);
428 } else {
429 resource_dictionary->SetWithoutPathExpansion(
430 resource_identifier, value->DeepCopy());
432 } else {
433 // Update settings dictionary.
434 std::string setting_path = GetTypeName(content_type);
435 if (value == NULL) {
436 settings_dictionary->RemoveWithoutPathExpansion(setting_path,
437 NULL);
438 } else {
439 settings_dictionary->SetWithoutPathExpansion(
440 setting_path, value->DeepCopy());
443 // Remove the settings dictionary if it is empty.
444 if (settings_dictionary->empty()) {
445 pattern_pairs_settings->RemoveWithoutPathExpansion(
446 pattern_str, NULL);
451 // static
452 void PrefProvider::CanonicalizeContentSettingsExceptions(
453 DictionaryValue* all_settings_dictionary) {
454 DCHECK(all_settings_dictionary);
456 std::vector<std::string> remove_items;
457 std::vector<std::pair<std::string, std::string> > move_items;
458 for (DictionaryValue::key_iterator i(all_settings_dictionary->begin_keys());
459 i != all_settings_dictionary->end_keys(); ++i) {
460 const std::string& pattern_str(*i);
461 std::pair<ContentSettingsPattern, ContentSettingsPattern> pattern_pair =
462 ParsePatternString(pattern_str);
463 if (!pattern_pair.first.IsValid() ||
464 !pattern_pair.second.IsValid()) {
465 LOG(ERROR) << "Invalid pattern strings: " << pattern_str;
466 continue;
469 const std::string canonicalized_pattern_str = CreatePatternString(
470 pattern_pair.first, pattern_pair.second);
472 if (canonicalized_pattern_str.empty() ||
473 canonicalized_pattern_str == pattern_str)
474 continue;
476 // Clear old pattern if prefs already have canonicalized pattern.
477 DictionaryValue* new_pattern_settings_dictionary = NULL;
478 if (all_settings_dictionary->GetDictionaryWithoutPathExpansion(
479 canonicalized_pattern_str, &new_pattern_settings_dictionary)) {
480 remove_items.push_back(pattern_str);
481 continue;
484 // Move old pattern to canonicalized pattern.
485 DictionaryValue* old_pattern_settings_dictionary = NULL;
486 if (all_settings_dictionary->GetDictionaryWithoutPathExpansion(
487 pattern_str, &old_pattern_settings_dictionary)) {
488 move_items.push_back(
489 std::make_pair(pattern_str, canonicalized_pattern_str));
493 for (size_t i = 0; i < remove_items.size(); ++i) {
494 all_settings_dictionary->RemoveWithoutPathExpansion(remove_items[i], NULL);
497 for (size_t i = 0; i < move_items.size(); ++i) {
498 Value* pattern_settings_dictionary = NULL;
499 all_settings_dictionary->RemoveWithoutPathExpansion(
500 move_items[i].first, &pattern_settings_dictionary);
501 all_settings_dictionary->SetWithoutPathExpansion(
502 move_items[i].second, pattern_settings_dictionary);
506 void PrefProvider::ShutdownOnUIThread() {
507 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
508 DCHECK(prefs_);
509 RemoveAllObservers();
510 pref_change_registrar_.RemoveAll();
511 prefs_ = NULL;
514 void PrefProvider::MigrateObsoleteContentSettingsPatternPref() {
515 // Ensure that |lock_| is not held by this thread, since this function will
516 // send out notifications (by |~DictionaryPrefUpdate|).
517 AssertLockNotHeld();
519 if (!prefs_->HasPrefPath(prefs::kContentSettingsPatterns))
520 return;
522 const DictionaryValue* patterns_dictionary =
523 prefs_->GetDictionary(prefs::kContentSettingsPatterns);
525 DictionaryPrefUpdate update(prefs_, prefs::kContentSettingsPatternPairs);
526 DictionaryValue* pattern_pairs_dictionary = update.Get();
527 for (DictionaryValue::key_iterator i(
528 patterns_dictionary->begin_keys());
529 i != patterns_dictionary->end_keys();
530 ++i) {
531 const std::string& key(*i);
532 // In the past a bug once corrupted dictionary keys. Test if the |key| is
533 // corrupted and skip a corrupted key. A dictionary |key| can contain two
534 // content settings patterns, a primary pattern and a secondary pattern.
535 // If the |key| contains two patterns than they are concataneted with a
536 // ','.
537 size_t sep_pos = key.find(",");
538 ContentSettingsPattern pattern =
539 ContentSettingsPattern::FromString(key.substr(0, sep_pos));
540 // Skip the current |key| if the primary |pattern| is invalid.
541 if (!pattern.IsValid())
542 continue;
543 // If the |key| contains a secondary pattern, and the obsolete pref
544 // dictionary also contains a key that equals the primary |pattern| then
545 // skip the current |key|.
546 if (sep_pos != std::string::npos &&
547 patterns_dictionary->HasKey(pattern.ToString())) {
548 continue;
551 // Copy the legacy content settings for the current |key| from the
552 // obsolete pref prefs::kContentSettingsPatterns to the pref
553 // prefs::kContentSettingsPatternPairs.
554 const DictionaryValue* dictionary = NULL;
555 bool found = patterns_dictionary->GetDictionaryWithoutPathExpansion(
556 key, &dictionary);
557 DCHECK(found);
558 std::string new_key = CreatePatternString(
559 pattern, ContentSettingsPattern::Wildcard());
560 // Existing values are overwritten.
561 pattern_pairs_dictionary->SetWithoutPathExpansion(
562 new_key, dictionary->DeepCopy());
565 prefs_->ClearPref(prefs::kContentSettingsPatterns);
568 void PrefProvider::MigrateObsoleteGeolocationPref() {
569 // Ensure that |lock_| is not held by this thread, since this function will
570 // send out notifications (by |~DictionaryPrefUpdate|).
571 AssertLockNotHeld();
573 if (!prefs_->HasPrefPath(prefs::kGeolocationContentSettings))
574 return;
576 DictionaryPrefUpdate update(prefs_,
577 prefs::kContentSettingsPatternPairs);
578 DictionaryValue* pattern_pairs_settings = update.Get();
580 const DictionaryValue* geolocation_settings =
581 prefs_->GetDictionary(prefs::kGeolocationContentSettings);
583 std::vector<std::pair<std::string, std::string> > corrupted_keys;
584 for (DictionaryValue::key_iterator i =
585 geolocation_settings->begin_keys();
586 i != geolocation_settings->end_keys();
587 ++i) {
588 const std::string& primary_key(*i);
589 GURL primary_url(primary_key);
590 DCHECK(primary_url.is_valid());
592 const DictionaryValue* requesting_origin_settings = NULL;
593 // The method GetDictionaryWithoutPathExpansion() returns false if the
594 // value for the given key is not a |DictionaryValue|. If the value for the
595 // |primary_key| is not a |DictionaryValue| then the location settings for
596 // this key are corrupted. Therefore they are ignored.
597 if (!geolocation_settings->GetDictionaryWithoutPathExpansion(
598 primary_key, &requesting_origin_settings))
599 continue;
601 for (DictionaryValue::key_iterator j =
602 requesting_origin_settings->begin_keys();
603 j != requesting_origin_settings->end_keys();
604 ++j) {
605 const std::string& secondary_key(*j);
606 GURL secondary_url(secondary_key);
607 // Save corrupted keys to remove them later.
608 if (!secondary_url.is_valid()) {
609 corrupted_keys.push_back(std::make_pair(primary_key, secondary_key));
610 continue;
613 const base::Value* value = NULL;
614 bool found = requesting_origin_settings->GetWithoutPathExpansion(
615 secondary_key, &value);
616 DCHECK(found);
618 ContentSettingsPattern primary_pattern =
619 ContentSettingsPattern::FromURLNoWildcard(primary_url);
620 ContentSettingsPattern secondary_pattern =
621 ContentSettingsPattern::FromURLNoWildcard(secondary_url);
622 DCHECK(primary_pattern.IsValid() && secondary_pattern.IsValid());
624 UpdatePatternPairsSettings(primary_pattern,
625 secondary_pattern,
626 CONTENT_SETTINGS_TYPE_GEOLOCATION,
627 std::string(),
628 value,
629 pattern_pairs_settings);
633 prefs_->ClearPref(prefs::kGeolocationContentSettings);
636 void PrefProvider::MigrateObsoleteNotificationsPrefs() {
637 // Ensure that |lock_| is not held by this thread, since this function will
638 // send out notifications (by |~DictionaryPrefUpdate|).
639 AssertLockNotHeld();
641 if (!prefs_->HasPrefPath(prefs::kDesktopNotificationAllowedOrigins) &&
642 !prefs_->HasPrefPath(prefs::kDesktopNotificationDeniedOrigins)) {
643 return;
646 DictionaryPrefUpdate update(prefs_, prefs::kContentSettingsPatternPairs);
647 DictionaryValue* pattern_pairs_settings = update.Get();
649 const ListValue* allowed_origins =
650 prefs_->GetList(prefs::kDesktopNotificationAllowedOrigins);
651 for (size_t i = 0; i < allowed_origins->GetSize(); ++i) {
652 std::string url_string;
653 bool status = allowed_origins->GetString(i, &url_string);
654 DCHECK(status);
655 ContentSettingsPattern primary_pattern =
656 ContentSettingsPattern::FromURLNoWildcard(GURL(url_string));
657 DCHECK(primary_pattern.IsValid());
658 scoped_ptr<base::Value> value(
659 Value::CreateIntegerValue(CONTENT_SETTING_ALLOW));
660 UpdatePatternPairsSettings(primary_pattern,
661 ContentSettingsPattern::Wildcard(),
662 CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
663 std::string(),
664 value.get(),
665 pattern_pairs_settings);
668 const ListValue* denied_origins =
669 prefs_->GetList(prefs::kDesktopNotificationDeniedOrigins);
670 for (size_t i = 0; i < denied_origins->GetSize(); ++i) {
671 std::string url_string;
672 bool status = denied_origins->GetString(i, &url_string);
673 DCHECK(status);
674 ContentSettingsPattern primary_pattern =
675 ContentSettingsPattern::FromURLNoWildcard(GURL(url_string));
676 DCHECK(primary_pattern.IsValid());
677 scoped_ptr<base::Value> value(
678 Value::CreateIntegerValue(CONTENT_SETTING_BLOCK));
679 UpdatePatternPairsSettings(primary_pattern,
680 ContentSettingsPattern::Wildcard(),
681 CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
682 std::string(),
683 value.get(),
684 pattern_pairs_settings);
687 prefs_->ClearPref(prefs::kDesktopNotificationAllowedOrigins);
688 prefs_->ClearPref(prefs::kDesktopNotificationDeniedOrigins);
691 void PrefProvider::AssertLockNotHeld() const {
692 #if !defined(NDEBUG)
693 // |Lock::Acquire()| will assert if the lock is held by this thread.
694 lock_.Acquire();
695 lock_.Release();
696 #endif
699 } // namespace content_settings