Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(145)

Side by Side Diff: chrome/browser/content_settings/pref_content_settings_provider.cc

Issue 6410022: Add content_settings::PrefProvider to HostContentSettingsMap. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: " Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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/pref_content_settings_provider.h" 5 #include "chrome/browser/content_settings/pref_content_settings_provider.h"
6 6
7 #include <string> 7 #include <string>
8 #include <vector>
9 #include <utility>
8 10
9 #include "base/command_line.h" 11 #include "base/command_line.h"
10 #include "chrome/browser/browser_thread.h" 12 #include "chrome/browser/browser_thread.h"
11 #include "chrome/browser/content_settings/content_settings_details.h" 13 #include "chrome/browser/content_settings/content_settings_details.h"
12 #include "chrome/browser/content_settings/content_settings_pattern.h" 14 #include "chrome/browser/content_settings/content_settings_pattern.h"
13 #include "chrome/browser/prefs/pref_service.h" 15 #include "chrome/browser/prefs/pref_service.h"
14 #include "chrome/browser/prefs/scoped_pref_update.h" 16 #include "chrome/browser/prefs/scoped_pref_update.h"
15 #include "chrome/browser/profiles/profile.h" 17 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/common/chrome_switches.h" 18 #include "chrome/common/chrome_switches.h"
19 #include "chrome/common/content_settings.h"
17 #include "chrome/common/notification_details.h" 20 #include "chrome/common/notification_details.h"
18 #include "chrome/common/notification_service.h" 21 #include "chrome/common/notification_service.h"
19 #include "chrome/common/notification_source.h" 22 #include "chrome/common/notification_source.h"
20 #include "chrome/common/pref_names.h" 23 #include "chrome/common/pref_names.h"
24 #include "googleurl/src/gurl.h"
25 #include "net/base/net_util.h"
21 26
22 namespace { 27 namespace {
23 28
29 // The preference keys where resource identifiers are stored for
30 // ContentSettingsType values that support resource identifiers.
31 const char* kResourceTypeNames[CONTENT_SETTINGS_NUM_TYPES] = {
32 NULL,
33 NULL,
34 NULL,
35 "per_plugin",
36 NULL,
37 NULL, // Not used for Geolocation
38 NULL, // Not used for Notifications
39 };
40
24 // The default setting for each content type. 41 // The default setting for each content type.
25 const ContentSetting kDefaultSettings[CONTENT_SETTINGS_NUM_TYPES] = { 42 const ContentSetting kDefaultSettings[CONTENT_SETTINGS_NUM_TYPES] = {
26 CONTENT_SETTING_ALLOW, // CONTENT_SETTINGS_TYPE_COOKIES 43 CONTENT_SETTING_ALLOW, // CONTENT_SETTINGS_TYPE_COOKIES
27 CONTENT_SETTING_ALLOW, // CONTENT_SETTINGS_TYPE_IMAGES 44 CONTENT_SETTING_ALLOW, // CONTENT_SETTINGS_TYPE_IMAGES
28 CONTENT_SETTING_ALLOW, // CONTENT_SETTINGS_TYPE_JAVASCRIPT 45 CONTENT_SETTING_ALLOW, // CONTENT_SETTINGS_TYPE_JAVASCRIPT
29 CONTENT_SETTING_ALLOW, // CONTENT_SETTINGS_TYPE_PLUGINS 46 CONTENT_SETTING_ALLOW, // CONTENT_SETTINGS_TYPE_PLUGINS
30 CONTENT_SETTING_BLOCK, // CONTENT_SETTINGS_TYPE_POPUPS 47 CONTENT_SETTING_BLOCK, // CONTENT_SETTINGS_TYPE_POPUPS
31 CONTENT_SETTING_ASK, // Not used for Geolocation 48 CONTENT_SETTING_ASK, // Not used for Geolocation
32 CONTENT_SETTING_ASK, // Not used for Notifications 49 CONTENT_SETTING_ASK, // Not used for Notifications
33 }; 50 };
34 51
35 // The names of the ContentSettingsType values, for use with dictionary prefs. 52 // The names of the ContentSettingsType values, for use with dictionary prefs.
36 const char* kTypeNames[CONTENT_SETTINGS_NUM_TYPES] = { 53 const char* kTypeNames[CONTENT_SETTINGS_NUM_TYPES] = {
37 "cookies", 54 "cookies",
38 "images", 55 "images",
39 "javascript", 56 "javascript",
40 "plugins", 57 "plugins",
41 "popups", 58 "popups",
42 NULL, // Not used for Geolocation 59 NULL, // Not used for Geolocation
43 NULL, // Not used for Notifications 60 NULL, // Not used for Notifications
44 }; 61 };
45 62
63 // True if a given content settings type requires additional resource
64 // identifiers.
65 const bool kRequiresResourceIdentifier[CONTENT_SETTINGS_NUM_TYPES] = {
66 false, // CONTENT_SETTINGS_TYPE_COOKIES
67 false, // CONTENT_SETTINGS_TYPE_IMAGES
68 false, // CONTET_SETTINGS_TYPE_JAVASCRIPT
69 true, // CONTENT_SETTINGS_TYPE_PLUGINS
70 false, // CONTENT_SETTINGS_TYPE_POPUPS
71 false, // Not used for Geolocation
72 false, // Not used for Notifications
73 };
46 74
47 // Map ASK for the plugins content type to BLOCK if click-to-play is 75 // Map ASK for the plugins content type to BLOCK if click-to-play is
48 // not enabled. 76 // not enabled.
49 ContentSetting ClickToPlayFixup(ContentSettingsType content_type, 77 ContentSetting ClickToPlayFixup(ContentSettingsType content_type,
50 ContentSetting setting) { 78 ContentSetting setting) {
51 if (setting == CONTENT_SETTING_ASK && 79 if (setting == CONTENT_SETTING_ASK &&
52 content_type == CONTENT_SETTINGS_TYPE_PLUGINS && 80 content_type == CONTENT_SETTINGS_TYPE_PLUGINS &&
53 !CommandLine::ForCurrentProcess()->HasSwitch( 81 !CommandLine::ForCurrentProcess()->HasSwitch(
54 switches::kEnableClickToPlay)) { 82 switches::kEnableClickToPlay)) {
55 return CONTENT_SETTING_BLOCK; 83 return CONTENT_SETTING_BLOCK;
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
254 Source<HostContentSettingsMap>(profile_->GetHostContentSettingsMap()), 282 Source<HostContentSettingsMap>(profile_->GetHostContentSettingsMap()),
255 Details<const ContentSettingsDetails>(&details)); 283 Details<const ContentSettingsDetails>(&details));
256 } 284 }
257 285
258 286
259 // static 287 // static
260 void PrefDefaultProvider::RegisterUserPrefs(PrefService* prefs) { 288 void PrefDefaultProvider::RegisterUserPrefs(PrefService* prefs) {
261 prefs->RegisterDictionaryPref(prefs::kDefaultContentSettings); 289 prefs->RegisterDictionaryPref(prefs::kDefaultContentSettings);
262 } 290 }
263 291
292 // ////////////////////////////////////////////////////////////////////////////
293 // PrefProvider::
294 //
295
296 // static
297 void PrefProvider::RegisterUserPrefs(PrefService* prefs) {
298 prefs->RegisterIntegerPref(prefs::kContentSettingsVersion,
299 ContentSettingsPattern::kContentSettingsPatternVersion);
300 prefs->RegisterDictionaryPref(prefs::kContentSettingsPatterns);
301
302 // Obsolete prefs, for migration:
303 prefs->RegisterListPref(prefs::kPopupWhitelistedHosts);
304 prefs->RegisterDictionaryPref(prefs::kPerHostContentSettings);
305 }
306
307 PrefProvider::PrefProvider(Profile* profile)
308 : profile_(profile),
309 is_off_the_record_(profile_->IsOffTheRecord()),
310 updating_preferences_(false) {
311 initializing_ = true;
312 PrefService* prefs = profile_->GetPrefs();
313
314 // Migrate obsolete preferences.
315 MigrateObsoletePerhostPref(prefs);
316 MigrateObsoletePopupsPref(prefs);
317
318 // Verify preferences version.
319 if (!prefs->HasPrefPath(prefs::kContentSettingsVersion)) {
320 prefs->SetInteger(prefs::kContentSettingsVersion,
321 ContentSettingsPattern::kContentSettingsPatternVersion);
322 }
323 if (prefs->GetInteger(prefs::kContentSettingsVersion) >
324 ContentSettingsPattern::kContentSettingsPatternVersion) {
325 LOG(ERROR) << "Unknown content settings version in preferences.";
326 return;
327 }
328
329 // Read exceptions.
330 ReadExceptions(false);
331
332 pref_change_registrar_.Init(prefs);
333 pref_change_registrar_.Add(prefs::kContentSettingsPatterns, this);
334
335 notification_registrar_.Add(this, NotificationType::PROFILE_DESTROYED,
336 Source<Profile>(profile_));
337 initializing_ = false;
338 }
339
340 bool PrefProvider::ContentSettingsTypeIsManaged(
341 ContentSettingsType content_type) {
342 return false;
343 }
344
345 ContentSetting PrefProvider::GetContentSetting(
346 const GURL& requesting_url,
347 const GURL& embedding_url,
348 ContentSettingsType content_type,
349 const ResourceIdentifier& resource_identifier) const {
350 // Support for embedding_patterns is not implemented yet.
351 DCHECK(requesting_url == embedding_url);
352
353 if (!RequiresResourceIdentifier(content_type))
354 return GetNonDefaultContentSettings(requesting_url).settings[content_type];
355
356 if (CommandLine::ForCurrentProcess()->HasSwitch(
357 switches::kEnableResourceContentSettings)) {
358 DCHECK(!resource_identifier.empty());
359 }
360
361 base::AutoLock auto_lock(lock_);
362
363 const std::string host(net::GetHostOrSpecFromURL(requesting_url));
364 ContentSettingsTypeResourceIdentifierPair
365 requested_setting(content_type, resource_identifier);
366
367 // Check for exact matches first.
368 HostContentSettings::const_iterator i(host_content_settings_.find(host));
369 if (i != host_content_settings_.end() &&
370 i->second.content_settings_for_resources.find(requested_setting) !=
371 i->second.content_settings_for_resources.end()) {
372 return i->second.content_settings_for_resources.find(
373 requested_setting)->second;
374 }
375
376 // If this map is not for an off-the-record profile, these searches will never
377 // match. The additional off-the-record exceptions always overwrite the
378 // regular ones.
379 i = off_the_record_settings_.find(host);
380 if (i != off_the_record_settings_.end() &&
381 i->second.content_settings_for_resources.find(requested_setting) !=
382 i->second.content_settings_for_resources.end()) {
383 return i->second.content_settings_for_resources.find(
384 requested_setting)->second;
385 }
386
387 // Match patterns starting with the most concrete pattern match.
388 for (std::string key =
389 std::string(ContentSettingsPattern::kDomainWildcard) + host; ; ) {
390 HostContentSettings::const_iterator i(off_the_record_settings_.find(key));
391 if (i != off_the_record_settings_.end() &&
392 i->second.content_settings_for_resources.find(requested_setting) !=
393 i->second.content_settings_for_resources.end()) {
394 return i->second.content_settings_for_resources.find(
395 requested_setting)->second;
396 }
397
398 i = host_content_settings_.find(key);
399 if (i != host_content_settings_.end() &&
400 i->second.content_settings_for_resources.find(requested_setting) !=
401 i->second.content_settings_for_resources.end()) {
402 return i->second.content_settings_for_resources.find(
403 requested_setting)->second;
404 }
405
406 const size_t next_dot =
407 key.find('.', ContentSettingsPattern::kDomainWildcardLength);
408 if (next_dot == std::string::npos)
409 break;
410 key.erase(ContentSettingsPattern::kDomainWildcardLength,
411 next_dot - ContentSettingsPattern::kDomainWildcardLength + 1);
412 }
413
414 return CONTENT_SETTING_DEFAULT;
415 }
416
417 void PrefProvider::SetContentSetting(
418 const ContentSettingsPattern& requesting_pattern,
419 const ContentSettingsPattern& embedding_pattern,
420 ContentSettingsType content_type,
421 const ResourceIdentifier& resource_identifier,
422 ContentSetting setting) {
423 // Support for embedding_patterns is not implemented yet.
424 DCHECK(requesting_pattern == embedding_pattern);
425
426 DCHECK(kTypeNames[content_type] != NULL); // Don't call this for Geolocation.
427 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
428 DCHECK_NE(RequiresResourceIdentifier(content_type),
429 resource_identifier.empty());
430 DCHECK(content_type != CONTENT_SETTINGS_TYPE_PLUGINS ||
431 setting != CONTENT_SETTING_ASK ||
432 CommandLine::ForCurrentProcess()->HasSwitch(
433 switches::kEnableClickToPlay));
434
435 const ContentSettingsPattern pattern(
436 requesting_pattern.CanonicalizePattern());
437
438 bool early_exit = false;
439 std::string pattern_str(pattern.AsString());
440 PrefService* prefs = NULL;
441 DictionaryValue* all_settings_dictionary = NULL;
442 HostContentSettings* map_to_modify = &off_the_record_settings_;
443 if (!is_off_the_record_) {
444 prefs = profile_->GetPrefs();
445 all_settings_dictionary =
446 prefs->GetMutableDictionary(prefs::kContentSettingsPatterns);
447 map_to_modify = &host_content_settings_;
448 }
449
450 {
451 base::AutoLock auto_lock(lock_);
452 if (!map_to_modify->count(pattern_str))
453 (*map_to_modify)[pattern_str].content_settings = ContentSettings();
454 HostContentSettings::iterator
455 i(map_to_modify->find(pattern_str));
456 ContentSettings& settings = i->second.content_settings;
457 if (RequiresResourceIdentifier(content_type)) {
458 settings.settings[content_type] = CONTENT_SETTING_DEFAULT;
459 if (setting != CONTENT_SETTING_DEFAULT) {
460 i->second.content_settings_for_resources[
461 ContentSettingsTypeResourceIdentifierPair(content_type,
462 resource_identifier)] = setting;
463 } else {
464 i->second.content_settings_for_resources.erase(
465 ContentSettingsTypeResourceIdentifierPair(content_type,
466 resource_identifier));
467 }
468 } else {
469 settings.settings[content_type] = setting;
470 }
471 if (AllDefault(i->second)) {
472 map_to_modify->erase(i);
473 if (all_settings_dictionary)
474 all_settings_dictionary->RemoveWithoutPathExpansion(pattern_str, NULL);
475
476 // We can't just return because |NotifyObservers()| needs to be called,
477 // without |lock_| being held.
478 early_exit = true;
479 }
480 }
481
482 if (!early_exit && all_settings_dictionary) {
483 DictionaryValue* host_settings_dictionary = NULL;
484 bool found = all_settings_dictionary->GetDictionaryWithoutPathExpansion(
485 pattern_str, &host_settings_dictionary);
486 if (!found) {
487 host_settings_dictionary = new DictionaryValue;
488 all_settings_dictionary->SetWithoutPathExpansion(
489 pattern_str, host_settings_dictionary);
490 DCHECK_NE(setting, CONTENT_SETTING_DEFAULT);
491 }
492 if (RequiresResourceIdentifier(content_type)) {
493 std::string dictionary_path(kResourceTypeNames[content_type]);
494 DictionaryValue* resource_dictionary = NULL;
495 found = host_settings_dictionary->GetDictionary(
496 dictionary_path, &resource_dictionary);
497 if (!found) {
498 resource_dictionary = new DictionaryValue;
499 host_settings_dictionary->Set(dictionary_path, resource_dictionary);
500 }
501 if (setting == CONTENT_SETTING_DEFAULT) {
502 resource_dictionary->RemoveWithoutPathExpansion(resource_identifier,
503 NULL);
504 } else {
505 resource_dictionary->SetWithoutPathExpansion(
506 resource_identifier, Value::CreateIntegerValue(setting));
507 }
508 } else {
509 std::string dictionary_path(kTypeNames[content_type]);
510 if (setting == CONTENT_SETTING_DEFAULT) {
511 host_settings_dictionary->RemoveWithoutPathExpansion(dictionary_path,
512 NULL);
513 } else {
514 host_settings_dictionary->SetWithoutPathExpansion(
515 dictionary_path, Value::CreateIntegerValue(setting));
516 }
517 }
518 }
519
520 updating_preferences_ = true;
521 if (!is_off_the_record_)
522 ScopedPrefUpdate update(prefs, prefs::kContentSettingsPatterns);
523 updating_preferences_ = false;
524
525 NotifyObservers(ContentSettingsDetails(pattern, content_type, ""));
526 }
527
528 void PrefProvider::GetAllContentSettingsRules(
529 ContentSettingsType content_type,
530 const ResourceIdentifier& resource_identifier,
531 Rules* content_setting_rules) const {
532 DCHECK(RequiresResourceIdentifier(content_type) !=
533 resource_identifier.empty());
534 DCHECK(content_setting_rules);
535 content_setting_rules->clear();
536
537 const HostContentSettings* map_to_return =
538 is_off_the_record_ ? &off_the_record_settings_ : &host_content_settings_;
539 ContentSettingsTypeResourceIdentifierPair
540 requested_setting(content_type, resource_identifier);
541
542 base::AutoLock auto_lock(lock_);
543 for (HostContentSettings::const_iterator i(map_to_return->begin());
544 i != map_to_return->end(); ++i) {
545 ContentSetting setting;
546 if (RequiresResourceIdentifier(content_type)) {
547 if (i->second.content_settings_for_resources.find(requested_setting) !=
548 i->second.content_settings_for_resources.end())
549 setting = i->second.content_settings_for_resources.find(
550 requested_setting)->second;
551 else
552 setting = CONTENT_SETTING_DEFAULT;
553 } else {
554 setting = i->second.content_settings.settings[content_type];
555 }
556 if (setting != CONTENT_SETTING_DEFAULT) {
557 // Use of push_back() relies on the map iterator traversing in order of
558 // ascending keys.
559 content_setting_rules->push_back(Rule(ContentSettingsPattern(i->first),
560 ContentSettingsPattern(i->first),
561 setting));
562 }
563 }
564 }
565
566 void PrefProvider::ResetToDefaults() {
567 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
568
569 {
570 base::AutoLock auto_lock(lock_);
571 host_content_settings_.clear();
572 off_the_record_settings_.clear();
573 }
574
575 if (!is_off_the_record_) {
576 PrefService* prefs = profile_->GetPrefs();
577 updating_preferences_ = true;
578 prefs->ClearPref(prefs::kContentSettingsPatterns);
579 updating_preferences_ = false;
580 }
581 }
582
583 void PrefProvider::ClearAllContentSettingsRules(
584 ContentSettingsType content_type) {
585 DCHECK(kTypeNames[content_type] != NULL); // Don't call this for Geolocation.
586
587 PrefService* prefs = NULL;
588 DictionaryValue* all_settings_dictionary = NULL;
589 HostContentSettings* map_to_modify = &off_the_record_settings_;
590
591 if (!is_off_the_record_) {
592 prefs = profile_->GetPrefs();
593 all_settings_dictionary =
594 prefs->GetMutableDictionary(prefs::kContentSettingsPatterns);
595 map_to_modify = &host_content_settings_;
596 }
597
598 {
599 base::AutoLock auto_lock(lock_);
600 for (HostContentSettings::iterator i(map_to_modify->begin());
601 i != map_to_modify->end(); ) {
602 if (RequiresResourceIdentifier(content_type) ||
603 i->second.content_settings.settings[content_type] !=
604 CONTENT_SETTING_DEFAULT) {
605 if (RequiresResourceIdentifier(content_type))
606 i->second.content_settings_for_resources.clear();
607 i->second.content_settings.settings[content_type] =
608 CONTENT_SETTING_DEFAULT;
609 std::string host(i->first);
610 if (AllDefault(i->second)) {
611 if (all_settings_dictionary)
612 all_settings_dictionary->
613 RemoveWithoutPathExpansion(host, NULL);
614 map_to_modify->erase(i++);
615 } else if (all_settings_dictionary) {
616 DictionaryValue* host_settings_dictionary;
617 bool found =
618 all_settings_dictionary->GetDictionaryWithoutPathExpansion(
619 host, &host_settings_dictionary);
620 DCHECK(found);
621 host_settings_dictionary->RemoveWithoutPathExpansion(
622 kTypeNames[content_type], NULL);
623 ++i;
624 }
625 } else {
626 ++i;
627 }
628 }
629 }
630
631 updating_preferences_ = true;
632 if (!is_off_the_record_)
633 ScopedPrefUpdate update(prefs, prefs::kContentSettingsPatterns);
634 updating_preferences_ = false;
635
636 NotifyObservers(
637 ContentSettingsDetails(ContentSettingsPattern(), content_type, ""));
638 }
639
640 void PrefProvider::Observe(
641 NotificationType type,
642 const NotificationSource& source,
643 const NotificationDetails& details) {
644 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
645
646 if (type == NotificationType::PREF_CHANGED) {
647 DCHECK_EQ(profile_->GetPrefs(), Source<PrefService>(source).ptr());
648 if (updating_preferences_)
649 return;
650
651 std::string* name = Details<std::string>(details).ptr();
652 if (*name == prefs::kContentSettingsPatterns) {
653 ReadExceptions(true);
654 } else {
655 NOTREACHED() << "Unexpected preference observed";
656 return;
657 }
658
659 if (!is_off_the_record_) {
660 NotifyObservers(ContentSettingsDetails(ContentSettingsPattern(),
661 CONTENT_SETTINGS_TYPE_DEFAULT,
662 ""));
663 }
664 } else if (type == NotificationType::PROFILE_DESTROYED) {
665 DCHECK_EQ(profile_, Source<Profile>(source).ptr());
666 UnregisterObservers();
667 } else {
668 NOTREACHED() << "Unexpected notification";
669 }
670 }
671
672 PrefProvider::~PrefProvider() {
673 UnregisterObservers();
674 }
675
676
677 // static
678 bool PrefProvider::RequiresResourceIdentifier(
679 ContentSettingsType content_type) {
680 if (CommandLine::ForCurrentProcess()->HasSwitch(
681 switches::kEnableResourceContentSettings)) {
682 return kRequiresResourceIdentifier[content_type];
683 } else {
684 return false;
685 }
686 }
687
688
689 // ////////////////////////////////////////////////////////////////////////////
690 // Private
691
692 bool PrefProvider::AllDefault(
693 const ExtendedContentSettings& settings) const {
694 for (size_t i = 0; i < arraysize(settings.content_settings.settings); ++i) {
695 if (settings.content_settings.settings[i] != CONTENT_SETTING_DEFAULT)
696 return false;
697 }
698 return settings.content_settings_for_resources.empty();
699 }
700
701 void PrefProvider::ReadExceptions(bool overwrite) {
702 base::AutoLock lock(lock_);
703
704 PrefService* prefs = profile_->GetPrefs();
705 DictionaryValue* all_settings_dictionary =
706 prefs->GetMutableDictionary(prefs::kContentSettingsPatterns);
707
708 if (overwrite)
709 host_content_settings_.clear();
710
711 // Careful: The returned value could be NULL if the pref has never been set.
712 if (all_settings_dictionary != NULL) {
713 // Convert all Unicode patterns into punycode form, then read.
714 CanonicalizeContentSettingsExceptions(all_settings_dictionary);
715
716 for (DictionaryValue::key_iterator i(all_settings_dictionary->begin_keys());
717 i != all_settings_dictionary->end_keys(); ++i) {
718 const std::string& pattern(*i);
719 if (!ContentSettingsPattern(pattern).IsValid())
720 LOG(WARNING) << "Invalid pattern stored in content settings";
721 DictionaryValue* pattern_settings_dictionary = NULL;
722 bool found = all_settings_dictionary->GetDictionaryWithoutPathExpansion(
723 pattern, &pattern_settings_dictionary);
724 DCHECK(found);
725 ContentSettings settings;
726 GetSettingsFromDictionary(pattern_settings_dictionary, &settings);
727 host_content_settings_[pattern].content_settings = settings;
728 GetResourceSettingsFromDictionary(
729 pattern_settings_dictionary,
730 &host_content_settings_[pattern].content_settings_for_resources);
731 }
732 }
733 }
734
735 void PrefProvider::CanonicalizeContentSettingsExceptions(
736 DictionaryValue* all_settings_dictionary) {
737 DCHECK(all_settings_dictionary);
738
739 std::vector<std::string> remove_items;
740 std::vector<std::pair<std::string, std::string> > move_items;
741 for (DictionaryValue::key_iterator i(all_settings_dictionary->begin_keys());
742 i != all_settings_dictionary->end_keys(); ++i) {
743 const std::string& pattern(*i);
744 const std::string canonicalized_pattern =
745 ContentSettingsPattern(pattern).CanonicalizePattern();
746
747 if (canonicalized_pattern.empty() || canonicalized_pattern == pattern)
748 continue;
749
750 // Clear old pattern if prefs already have canonicalized pattern.
751 DictionaryValue* new_pattern_settings_dictionary = NULL;
752 if (all_settings_dictionary->GetDictionaryWithoutPathExpansion(
753 canonicalized_pattern, &new_pattern_settings_dictionary)) {
754 remove_items.push_back(pattern);
755 continue;
756 }
757
758 // Move old pattern to canonicalized pattern.
759 DictionaryValue* old_pattern_settings_dictionary = NULL;
760 if (all_settings_dictionary->GetDictionaryWithoutPathExpansion(
761 pattern, &old_pattern_settings_dictionary)) {
762 move_items.push_back(std::make_pair(pattern, canonicalized_pattern));
763 }
764 }
765
766 for (size_t i = 0; i < remove_items.size(); ++i) {
767 all_settings_dictionary->RemoveWithoutPathExpansion(remove_items[i], NULL);
768 }
769
770 for (size_t i = 0; i < move_items.size(); ++i) {
771 Value* pattern_settings_dictionary = NULL;
772 all_settings_dictionary->RemoveWithoutPathExpansion(
773 move_items[i].first, &pattern_settings_dictionary);
774 all_settings_dictionary->SetWithoutPathExpansion(
775 move_items[i].second, pattern_settings_dictionary);
776 }
777 }
778
779 void PrefProvider::GetSettingsFromDictionary(
780 const DictionaryValue* dictionary,
781 ContentSettings* settings) {
782 for (DictionaryValue::key_iterator i(dictionary->begin_keys());
783 i != dictionary->end_keys(); ++i) {
784 const std::string& content_type(*i);
785 for (size_t type = 0; type < arraysize(kTypeNames); ++type) {
786 if ((kTypeNames[type] != NULL) && (kTypeNames[type] == content_type)) {
787 int setting = CONTENT_SETTING_DEFAULT;
788 bool found = dictionary->GetIntegerWithoutPathExpansion(content_type,
789 &setting);
790 DCHECK(found);
791 settings->settings[type] = IntToContentSetting(setting);
792 break;
793 }
794 }
795 }
796 // Migrate obsolete cookie prompt mode.
797 if (settings->settings[CONTENT_SETTINGS_TYPE_COOKIES] ==
798 CONTENT_SETTING_ASK)
799 settings->settings[CONTENT_SETTINGS_TYPE_COOKIES] = CONTENT_SETTING_BLOCK;
800
801 settings->settings[CONTENT_SETTINGS_TYPE_PLUGINS] =
802 ClickToPlayFixup(CONTENT_SETTINGS_TYPE_PLUGINS,
803 settings->settings[CONTENT_SETTINGS_TYPE_PLUGINS]);
804 }
805
806 void PrefProvider::GetResourceSettingsFromDictionary(
807 const DictionaryValue* dictionary,
808 ResourceContentSettings* settings) {
809 for (DictionaryValue::key_iterator i(dictionary->begin_keys());
810 i != dictionary->end_keys(); ++i) {
811 const std::string& content_type(*i);
812 for (size_t type = 0; type < arraysize(kResourceTypeNames); ++type) {
813 if ((kResourceTypeNames[type] != NULL) &&
814 (kResourceTypeNames[type] == content_type)) {
815 DictionaryValue* resource_dictionary = NULL;
816 bool found = dictionary->GetDictionary(content_type,
817 &resource_dictionary);
818 DCHECK(found);
819 for (DictionaryValue::key_iterator j(resource_dictionary->begin_keys());
820 j != resource_dictionary->end_keys(); ++j) {
821 const std::string& resource_identifier(*j);
822 int setting = CONTENT_SETTING_DEFAULT;
823 bool found = resource_dictionary->GetIntegerWithoutPathExpansion(
824 resource_identifier, &setting);
825 DCHECK(found);
826 (*settings)[ContentSettingsTypeResourceIdentifierPair(
827 ContentSettingsType(type), resource_identifier)] =
828 ClickToPlayFixup(ContentSettingsType(type),
829 ContentSetting(setting));
830 }
831
832 break;
833 }
834 }
835 }
836 }
837
838 void PrefProvider::NotifyObservers(
839 const ContentSettingsDetails& details) {
840 if (initializing_)
841 return;
842 NotificationService::current()->Notify(
843 NotificationType::CONTENT_SETTINGS_CHANGED,
844 Source<HostContentSettingsMap>(
845 profile_->GetHostContentSettingsMap()),
846 Details<const ContentSettingsDetails>(&details));
847 }
848
849 void PrefProvider::UnregisterObservers() {
850 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
851 if (!profile_)
852 return;
853 pref_change_registrar_.RemoveAll();
854 notification_registrar_.Remove(this, NotificationType::PROFILE_DESTROYED,
855 Source<Profile>(profile_));
856 profile_ = NULL;
857 }
858
859 void PrefProvider::MigrateObsoletePerhostPref(PrefService* prefs) {
860 if (prefs->HasPrefPath(prefs::kPerHostContentSettings)) {
861 const DictionaryValue* all_settings_dictionary =
862 prefs->GetDictionary(prefs::kPerHostContentSettings);
863 for (DictionaryValue::key_iterator i(all_settings_dictionary->begin_keys());
864 i != all_settings_dictionary->end_keys(); ++i) {
865 const std::string& host(*i);
866 ContentSettingsPattern pattern(
867 std::string(ContentSettingsPattern::kDomainWildcard) + host);
868 DictionaryValue* host_settings_dictionary = NULL;
869 bool found = all_settings_dictionary->GetDictionaryWithoutPathExpansion(
870 host, &host_settings_dictionary);
871 DCHECK(found);
872 ContentSettings settings;
873 GetSettingsFromDictionary(host_settings_dictionary, &settings);
874 for (int j = 0; j < CONTENT_SETTINGS_NUM_TYPES; ++j) {
875 if (settings.settings[j] != CONTENT_SETTING_DEFAULT &&
876 !RequiresResourceIdentifier(ContentSettingsType(j)))
877 SetContentSetting(
878 pattern,
879 pattern,
880 ContentSettingsType(j),
881 "",
882 settings.settings[j]);
883 }
884 }
885 prefs->ClearPref(prefs::kPerHostContentSettings);
886 }
887 }
888
889 void PrefProvider::MigrateObsoletePopupsPref(PrefService* prefs) {
890 if (prefs->HasPrefPath(prefs::kPopupWhitelistedHosts)) {
891 const ListValue* whitelist_pref =
892 prefs->GetList(prefs::kPopupWhitelistedHosts);
893 for (ListValue::const_iterator i(whitelist_pref->begin());
894 i != whitelist_pref->end(); ++i) {
895 std::string host;
896 (*i)->GetAsString(&host);
897 SetContentSetting(ContentSettingsPattern(host),
898 ContentSettingsPattern(host),
899 CONTENT_SETTINGS_TYPE_POPUPS,
900 "",
901 CONTENT_SETTING_ALLOW);
902 }
903 prefs->ClearPref(prefs::kPopupWhitelistedHosts);
904 }
905 }
906
907 // ////////////////////////////////////////////////////////////////////////////
908 // LEGACY TBR
909 //
910
911 ContentSettings PrefProvider::GetNonDefaultContentSettings(
912 const GURL& url) const {
913 base::AutoLock auto_lock(lock_);
914
915 const std::string host(net::GetHostOrSpecFromURL(url));
916 ContentSettings output;
917 for (int j = 0; j < CONTENT_SETTINGS_NUM_TYPES; ++j)
918 output.settings[j] = CONTENT_SETTING_DEFAULT;
919
920 // Check for exact matches first.
921 HostContentSettings::const_iterator i(host_content_settings_.find(host));
922 if (i != host_content_settings_.end())
923 output = i->second.content_settings;
924
925 // If this map is not for an off-the-record profile, these searches will never
926 // match. The additional off-the-record exceptions always overwrite the
927 // regular ones.
928 i = off_the_record_settings_.find(host);
929 if (i != off_the_record_settings_.end()) {
930 for (int j = 0; j < CONTENT_SETTINGS_NUM_TYPES; ++j)
931 if (i->second.content_settings.settings[j] != CONTENT_SETTING_DEFAULT)
932 output.settings[j] = i->second.content_settings.settings[j];
933 }
934
935 // Match patterns starting with the most concrete pattern match.
936 for (std::string key =
937 std::string(ContentSettingsPattern::kDomainWildcard) + host; ; ) {
938 HostContentSettings::const_iterator i(off_the_record_settings_.find(key));
939 if (i != off_the_record_settings_.end()) {
940 for (int j = 0; j < CONTENT_SETTINGS_NUM_TYPES; ++j) {
941 if (output.settings[j] == CONTENT_SETTING_DEFAULT)
942 output.settings[j] = i->second.content_settings.settings[j];
943 }
944 }
945 i = host_content_settings_.find(key);
946 if (i != host_content_settings_.end()) {
947 for (int j = 0; j < CONTENT_SETTINGS_NUM_TYPES; ++j) {
948 if (output.settings[j] == CONTENT_SETTING_DEFAULT)
949 output.settings[j] = i->second.content_settings.settings[j];
950 }
951 }
952 const size_t next_dot =
953 key.find('.', ContentSettingsPattern::kDomainWildcardLength);
954 if (next_dot == std::string::npos)
955 break;
956 key.erase(ContentSettingsPattern::kDomainWildcardLength,
957 next_dot - ContentSettingsPattern::kDomainWildcardLength + 1);
958 }
959
960 return output;
961 }
962
264 } // namespace content_settings 963 } // namespace content_settings
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698