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_pref_provider.h" | 5 #include "chrome/browser/content_settings/content_settings_pref_provider.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 #include <utility> | 8 #include <utility> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
78 default_settings->Clear(); | 78 default_settings->Clear(); |
79 | 79 |
80 for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) { | 80 for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) { |
81 if (kTypeNames[i] != NULL) { | 81 if (kTypeNames[i] != NULL) { |
82 default_settings->SetInteger(kTypeNames[i], | 82 default_settings->SetInteger(kTypeNames[i], |
83 kDefaultSettings[i]); | 83 kDefaultSettings[i]); |
84 } | 84 } |
85 } | 85 } |
86 } | 86 } |
87 | 87 |
| 88 std::string CreatePatternString( |
| 89 const ContentSettingsPattern& requesting_pattern, |
| 90 const ContentSettingsPattern& embedding_pattern) { |
| 91 DCHECK(requesting_pattern == embedding_pattern); |
| 92 return requesting_pattern.ToString(); |
| 93 } |
| 94 |
| 95 ContentSetting ValueToContentSetting(Value* value) { |
| 96 int int_value; |
| 97 value->GetAsInteger(&int_value); |
| 98 return IntToContentSetting(int_value); |
| 99 } |
| 100 |
| 101 ContentSettingsType StringToContentSettingsType( |
| 102 const std::string& content_type_str) { |
| 103 for (size_t type = 0; type < arraysize(kTypeNames); ++type) { |
| 104 if ((kTypeNames[type] != NULL) && (kTypeNames[type] == content_type_str)) |
| 105 return ContentSettingsType(type); |
| 106 } |
| 107 for (size_t type = 0; type < arraysize(kResourceTypeNames); ++type) { |
| 108 if ((kResourceTypeNames[type] != NULL) && |
| 109 (kResourceTypeNames[type] == content_type_str)) { |
| 110 return ContentSettingsType(type); |
| 111 } |
| 112 } |
| 113 return CONTENT_SETTINGS_TYPE_DEFAULT; |
| 114 } |
| 115 |
| 116 ContentSetting FixObsoleteCookiePromptMode(ContentSettingsType content_type, |
| 117 ContentSetting setting) { |
| 118 if (content_type == CONTENT_SETTINGS_TYPE_COOKIES && |
| 119 setting == CONTENT_SETTING_ASK) { |
| 120 return CONTENT_SETTING_BLOCK; |
| 121 } |
| 122 return setting; |
| 123 } |
| 124 |
88 } // namespace | 125 } // namespace |
89 | 126 |
90 namespace content_settings { | 127 namespace content_settings { |
91 | 128 |
92 PrefDefaultProvider::PrefDefaultProvider(Profile* profile) | 129 PrefDefaultProvider::PrefDefaultProvider(Profile* profile) |
93 : profile_(profile), | 130 : profile_(profile), |
94 is_incognito_(profile_->IsOffTheRecord()), | 131 is_incognito_(profile_->IsOffTheRecord()), |
95 updating_preferences_(false) { | 132 updating_preferences_(false) { |
96 initializing_ = true; | 133 initializing_ = true; |
97 PrefService* prefs = profile->GetPrefs(); | 134 PrefService* prefs = profile->GetPrefs(); |
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
337 PrefService::SYNCABLE_PREF); | 374 PrefService::SYNCABLE_PREF); |
338 | 375 |
339 // Obsolete prefs, for migration: | 376 // Obsolete prefs, for migration: |
340 prefs->RegisterListPref(prefs::kPopupWhitelistedHosts, | 377 prefs->RegisterListPref(prefs::kPopupWhitelistedHosts, |
341 PrefService::UNSYNCABLE_PREF); | 378 PrefService::UNSYNCABLE_PREF); |
342 prefs->RegisterDictionaryPref(prefs::kPerHostContentSettings, | 379 prefs->RegisterDictionaryPref(prefs::kPerHostContentSettings, |
343 PrefService::UNSYNCABLE_PREF); | 380 PrefService::UNSYNCABLE_PREF); |
344 } | 381 } |
345 | 382 |
346 PrefProvider::PrefProvider(Profile* profile) | 383 PrefProvider::PrefProvider(Profile* profile) |
347 : BaseProvider(profile->IsOffTheRecord()), | 384 : profile_(profile), |
348 profile_(profile), | 385 is_incognito_(profile_->IsOffTheRecord()), |
349 updating_preferences_(false) { | 386 updating_preferences_(false) { |
350 Init(); | 387 Init(); |
351 } | 388 } |
352 | 389 |
353 void PrefProvider::Init() { | 390 void PrefProvider::Init() { |
354 initializing_ = true; | 391 initializing_ = true; |
355 PrefService* prefs = profile_->GetPrefs(); | 392 PrefService* prefs = profile_->GetPrefs(); |
356 | 393 |
357 // Migrate obsolete preferences. | 394 // Migrate obsolete preferences. |
358 MigrateObsoletePerhostPref(prefs); | 395 MigrateObsoletePerhostPref(prefs); |
359 MigrateObsoletePopupsPref(prefs); | 396 MigrateObsoletePopupsPref(prefs); |
360 | 397 |
361 // Verify preferences version. | 398 // Verify preferences version. |
362 if (!prefs->HasPrefPath(prefs::kContentSettingsVersion)) { | 399 if (!prefs->HasPrefPath(prefs::kContentSettingsVersion)) { |
363 prefs->SetInteger(prefs::kContentSettingsVersion, | 400 prefs->SetInteger(prefs::kContentSettingsVersion, |
364 ContentSettingsPattern::kContentSettingsPatternVersion); | 401 ContentSettingsPattern::kContentSettingsPatternVersion); |
365 } | 402 } |
366 if (prefs->GetInteger(prefs::kContentSettingsVersion) > | 403 if (prefs->GetInteger(prefs::kContentSettingsVersion) > |
367 ContentSettingsPattern::kContentSettingsPatternVersion) { | 404 ContentSettingsPattern::kContentSettingsPatternVersion) { |
368 LOG(ERROR) << "Unknown content settings version in preferences."; | 405 LOG(ERROR) << "Unknown content settings version in preferences."; |
369 return; | 406 return; |
370 } | 407 } |
371 | 408 |
372 // Read exceptions. | 409 // Read exceptions. |
373 ReadExceptions(false); | 410 ReadExceptions(false); |
374 | 411 |
375 if (!is_incognito()) { | 412 if (!is_incognito_) { |
376 UMA_HISTOGRAM_COUNTS("ContentSettings.NumberOfExceptions", | 413 UMA_HISTOGRAM_COUNTS("ContentSettings.NumberOfExceptions", |
377 host_content_settings()->size()); | 414 value_map_.size()); |
378 } | 415 } |
379 | 416 |
380 pref_change_registrar_.Init(prefs); | 417 pref_change_registrar_.Init(prefs); |
381 pref_change_registrar_.Add(prefs::kContentSettingsPatterns, this); | 418 pref_change_registrar_.Add(prefs::kContentSettingsPatterns, this); |
382 | 419 |
383 notification_registrar_.Add(this, NotificationType::PROFILE_DESTROYED, | 420 notification_registrar_.Add(this, NotificationType::PROFILE_DESTROYED, |
384 Source<Profile>(profile_)); | 421 Source<Profile>(profile_)); |
385 initializing_ = false; | 422 initializing_ = false; |
386 } | 423 } |
387 | 424 |
| 425 ContentSetting PrefProvider::GetContentSetting( |
| 426 const GURL& requesting_url, |
| 427 const GURL& embedding_url, |
| 428 ContentSettingsType content_type, |
| 429 const ResourceIdentifier& resource_identifier) const { |
| 430 // Support for item, top-level-frame URLs are not enabled yet. |
| 431 DCHECK(requesting_url == embedding_url); |
| 432 |
| 433 // For a |PrefProvider| used in a |HostContentSettingsMap| of a non incognito |
| 434 // profile, this will always return NULL. |
| 435 // TODO(markusheintz): I don't like this. I'd like to have an |
| 436 // IncognitoProviderWrapper that wrapps the pref provider for a host content |
| 437 // settings map of an incognito profile. |
| 438 Value* incognito_value = incognito_value_map_.GetValue( |
| 439 requesting_url, |
| 440 embedding_url, |
| 441 content_type, |
| 442 resource_identifier); |
| 443 if (incognito_value) |
| 444 return ValueToContentSetting(incognito_value); |
| 445 |
| 446 Value* value = value_map_.GetValue( |
| 447 requesting_url, |
| 448 embedding_url, |
| 449 content_type, |
| 450 resource_identifier); |
| 451 if (value) |
| 452 return ValueToContentSetting(value); |
| 453 |
| 454 return CONTENT_SETTING_DEFAULT; |
| 455 } |
| 456 |
| 457 void PrefProvider::GetAllContentSettingsRules( |
| 458 ContentSettingsType content_type, |
| 459 const ResourceIdentifier& resource_identifier, |
| 460 Rules* content_setting_rules) const { |
| 461 DCHECK_NE(RequiresResourceIdentifier(content_type), |
| 462 resource_identifier.empty()); |
| 463 DCHECK(content_setting_rules); |
| 464 content_setting_rules->clear(); |
| 465 |
| 466 const OriginIdentifierValueMap* map_to_return = |
| 467 is_incognito_ ? &incognito_value_map_ : &value_map_; |
| 468 |
| 469 base::AutoLock auto_lock(lock_); |
| 470 for (OriginIdentifierValueMap::const_iterator entry = map_to_return->begin(); |
| 471 entry != map_to_return->end(); |
| 472 ++entry) { |
| 473 if (entry->content_type == content_type && |
| 474 entry->identifier == resource_identifier) { |
| 475 ContentSetting setting = ValueToContentSetting(entry->value.get()); |
| 476 DCHECK(setting != CONTENT_SETTING_DEFAULT); |
| 477 Rule new_rule(entry->item_pattern, |
| 478 entry->top_level_frame_pattern, |
| 479 setting); |
| 480 content_setting_rules->push_back(new_rule); |
| 481 } |
| 482 } |
| 483 } |
| 484 |
388 void PrefProvider::SetContentSetting( | 485 void PrefProvider::SetContentSetting( |
389 const ContentSettingsPattern& requesting_pattern, | 486 const ContentSettingsPattern& requesting_pattern, |
390 const ContentSettingsPattern& embedding_pattern, | 487 const ContentSettingsPattern& embedding_pattern, |
391 ContentSettingsType content_type, | 488 ContentSettingsType content_type, |
392 const ResourceIdentifier& resource_identifier, | 489 const ResourceIdentifier& resource_identifier, |
393 ContentSetting setting) { | 490 ContentSetting setting) { |
394 // Support for embedding_patterns is not implemented yet. | 491 // Support for embedding_patterns is not implemented yet. |
395 DCHECK(requesting_pattern == embedding_pattern); | 492 DCHECK(requesting_pattern == embedding_pattern); |
396 | 493 |
397 DCHECK(kTypeNames[content_type] != NULL); // Don't call this for Geolocation. | 494 DCHECK(kTypeNames[content_type] != NULL); // Don't call this for Geolocation. |
398 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 495 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
399 DCHECK_NE(RequiresResourceIdentifier(content_type), | 496 DCHECK_NE(RequiresResourceIdentifier(content_type), |
400 resource_identifier.empty()); | 497 resource_identifier.empty()); |
401 DCHECK(content_type != CONTENT_SETTINGS_TYPE_PLUGINS || | 498 DCHECK(content_type != CONTENT_SETTINGS_TYPE_PLUGINS || |
402 setting != CONTENT_SETTING_ASK || | 499 setting != CONTENT_SETTING_ASK || |
403 CommandLine::ForCurrentProcess()->HasSwitch( | 500 CommandLine::ForCurrentProcess()->HasSwitch( |
404 switches::kEnableClickToPlay)); | 501 switches::kEnableClickToPlay)); |
405 | 502 |
406 bool early_exit = false; | |
407 std::string pattern_str(requesting_pattern.ToString()); | |
408 DictionaryValue* all_settings_dictionary = NULL; | |
409 | |
410 updating_preferences_ = true; | 503 updating_preferences_ = true; |
411 { | 504 { |
412 // Begin scope of update. | |
413 // profile_ may be NULL in unit tests. | |
414 DictionaryPrefUpdate update(profile_ ? profile_->GetPrefs() : NULL, | 505 DictionaryPrefUpdate update(profile_ ? profile_->GetPrefs() : NULL, |
415 prefs::kContentSettingsPatterns); | 506 prefs::kContentSettingsPatterns); |
| 507 DictionaryValue* all_settings_dictionary = NULL; |
416 | 508 |
417 // Select content-settings-map to write to. | 509 OriginIdentifierValueMap* map_to_modify = &incognito_value_map_; |
418 HostContentSettings* map_to_modify = incognito_settings(); | 510 if (!is_incognito_) { |
419 if (!is_incognito()) { | 511 map_to_modify = &value_map_; |
420 all_settings_dictionary = update.Get(); | 512 all_settings_dictionary = update.Get(); |
421 | |
422 map_to_modify = host_content_settings(); | |
423 } | 513 } |
424 | 514 |
425 // Update content-settings-map. | 515 // Update in memory value map. |
426 { | 516 { |
427 base::AutoLock auto_lock(lock()); | 517 base::AutoLock auto_lock(lock_); |
428 if (!map_to_modify->count(pattern_str)) | 518 if (setting == CONTENT_SETTING_DEFAULT) { |
429 (*map_to_modify)[pattern_str].content_settings = ContentSettings(); | 519 map_to_modify->DeleteValue( |
430 HostContentSettings::iterator i(map_to_modify->find(pattern_str)); | 520 requesting_pattern, |
431 ContentSettings& settings = i->second.content_settings; | 521 embedding_pattern, |
432 if (RequiresResourceIdentifier(content_type)) { | 522 content_type, |
433 settings.settings[content_type] = CONTENT_SETTING_DEFAULT; | 523 resource_identifier); |
434 if (setting != CONTENT_SETTING_DEFAULT) { | |
435 i->second.content_settings_for_resources[ | |
436 ContentSettingsTypeResourceIdentifierPair(content_type, | |
437 resource_identifier)] = setting; | |
438 } else { | |
439 i->second.content_settings_for_resources.erase( | |
440 ContentSettingsTypeResourceIdentifierPair(content_type, | |
441 resource_identifier)); | |
442 } | |
443 } else { | 524 } else { |
444 settings.settings[content_type] = setting; | 525 map_to_modify->SetValue( |
445 } | 526 requesting_pattern, |
446 if (AllDefault(i->second)) { | 527 embedding_pattern, |
447 map_to_modify->erase(i); | 528 content_type, |
448 if (all_settings_dictionary) | 529 resource_identifier, |
449 all_settings_dictionary->RemoveWithoutPathExpansion( | 530 Value::CreateIntegerValue(setting)); |
450 pattern_str, NULL); | |
451 | |
452 // We can't just return because |NotifyObservers()| needs to be called, | |
453 // without lock() being held. | |
454 early_exit = true; | |
455 } | 531 } |
456 } | 532 } |
457 | 533 |
458 // Update the content_settings preference. | 534 // Update the content settings preference. |
459 if (!early_exit && all_settings_dictionary) { | 535 std::string pattern_str(CreatePatternString(requesting_pattern, |
460 DictionaryValue* host_settings_dictionary = NULL; | 536 embedding_pattern)); |
| 537 if (all_settings_dictionary) { |
| 538 // Get settings dictionary for the pattern string (key). |
| 539 DictionaryValue* settings_dictionary = NULL; |
461 bool found = all_settings_dictionary->GetDictionaryWithoutPathExpansion( | 540 bool found = all_settings_dictionary->GetDictionaryWithoutPathExpansion( |
462 pattern_str, &host_settings_dictionary); | 541 pattern_str, &settings_dictionary); |
463 if (!found) { | 542 |
464 host_settings_dictionary = new DictionaryValue; | 543 if (!found && (setting != CONTENT_SETTING_DEFAULT)) { |
| 544 settings_dictionary = new DictionaryValue; |
465 all_settings_dictionary->SetWithoutPathExpansion( | 545 all_settings_dictionary->SetWithoutPathExpansion( |
466 pattern_str, host_settings_dictionary); | 546 pattern_str, settings_dictionary); |
467 DCHECK_NE(setting, CONTENT_SETTING_DEFAULT); | |
468 } | 547 } |
469 if (RequiresResourceIdentifier(content_type)) { | 548 |
470 std::string dictionary_path(kResourceTypeNames[content_type]); | 549 if (settings_dictionary) { |
471 DictionaryValue* resource_dictionary = NULL; | 550 if (RequiresResourceIdentifier(content_type)) { |
472 found = host_settings_dictionary->GetDictionary( | 551 // Get resource dictionary. |
473 dictionary_path, &resource_dictionary); | 552 std::string res_dictionary_path(kResourceTypeNames[content_type]); |
474 if (!found) { | 553 DictionaryValue* resource_dictionary = NULL; |
475 resource_dictionary = new DictionaryValue; | 554 found = settings_dictionary->GetDictionary( |
476 host_settings_dictionary->Set(dictionary_path, resource_dictionary); | 555 res_dictionary_path, &resource_dictionary); |
| 556 if (!found) { |
| 557 if (setting == CONTENT_SETTING_DEFAULT) |
| 558 return; // Nothing to remove. Exit early. |
| 559 resource_dictionary = new DictionaryValue; |
| 560 settings_dictionary->Set(res_dictionary_path, resource_dictionary); |
| 561 } |
| 562 // Update resource dictionary. |
| 563 if (setting == CONTENT_SETTING_DEFAULT) { |
| 564 resource_dictionary->RemoveWithoutPathExpansion(resource_identifier, |
| 565 NULL); |
| 566 if (resource_dictionary->empty()) { |
| 567 settings_dictionary->RemoveWithoutPathExpansion( |
| 568 res_dictionary_path, NULL); |
| 569 } |
| 570 } else { |
| 571 resource_dictionary->SetWithoutPathExpansion( |
| 572 resource_identifier, Value::CreateIntegerValue(setting)); |
| 573 } |
| 574 } else { |
| 575 // Update settings dictionary. |
| 576 std::string setting_path(kTypeNames[content_type]); |
| 577 if (setting == CONTENT_SETTING_DEFAULT) { |
| 578 settings_dictionary->RemoveWithoutPathExpansion(setting_path, |
| 579 NULL); |
| 580 } else { |
| 581 settings_dictionary->SetWithoutPathExpansion( |
| 582 setting_path, Value::CreateIntegerValue(setting)); |
| 583 } |
477 } | 584 } |
478 if (setting == CONTENT_SETTING_DEFAULT) { | 585 // Remove the settings dictionary if it is empty. |
479 resource_dictionary->RemoveWithoutPathExpansion(resource_identifier, | 586 if (settings_dictionary->empty()) { |
480 NULL); | 587 all_settings_dictionary->RemoveWithoutPathExpansion( |
481 } else { | 588 pattern_str, NULL); |
482 resource_dictionary->SetWithoutPathExpansion( | |
483 resource_identifier, Value::CreateIntegerValue(setting)); | |
484 } | |
485 } else { | |
486 std::string dictionary_path(kTypeNames[content_type]); | |
487 if (setting == CONTENT_SETTING_DEFAULT) { | |
488 host_settings_dictionary->RemoveWithoutPathExpansion(dictionary_path, | |
489 NULL); | |
490 } else { | |
491 host_settings_dictionary->SetWithoutPathExpansion( | |
492 dictionary_path, Value::CreateIntegerValue(setting)); | |
493 } | 589 } |
494 } | 590 } |
495 } | 591 } |
496 } // End scope of update. | 592 } |
497 updating_preferences_ = false; | 593 updating_preferences_ = false; |
498 | 594 |
499 ContentSettingsDetails details( | 595 ContentSettingsDetails details( |
500 requesting_pattern, content_type, std::string()); | 596 requesting_pattern, content_type, std::string()); |
501 NotifyObservers(details); | 597 NotifyObservers(details); |
502 } | 598 } |
503 | 599 |
504 void PrefProvider::ResetToDefaults() { | 600 void PrefProvider::ResetToDefaults() { |
505 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 601 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
506 | 602 |
507 { | 603 { |
508 base::AutoLock auto_lock(lock()); | 604 base::AutoLock auto_lock(lock_); |
509 host_content_settings()->clear(); | 605 value_map_.Clear(); |
510 incognito_settings()->clear(); | 606 incognito_value_map_.Clear(); |
511 } | 607 } |
512 | 608 |
513 if (!is_incognito()) { | 609 if (!is_incognito_) { |
514 PrefService* prefs = profile_->GetPrefs(); | 610 PrefService* prefs = profile_->GetPrefs(); |
515 updating_preferences_ = true; | 611 updating_preferences_ = true; |
516 prefs->ClearPref(prefs::kContentSettingsPatterns); | 612 prefs->ClearPref(prefs::kContentSettingsPatterns); |
517 updating_preferences_ = false; | 613 updating_preferences_ = false; |
518 } | 614 } |
519 } | 615 } |
520 | 616 |
521 void PrefProvider::ClearAllContentSettingsRules( | 617 void PrefProvider::ClearAllContentSettingsRules( |
522 ContentSettingsType content_type) { | 618 ContentSettingsType content_type) { |
523 DCHECK(kTypeNames[content_type] != NULL); // Don't call this for Geolocation. | 619 DCHECK(kTypeNames[content_type] != NULL); // Don't call this for Geolocation. |
524 | 620 |
525 DictionaryValue* all_settings_dictionary = NULL; | |
526 HostContentSettings* map_to_modify = incognito_settings(); | |
527 | |
528 updating_preferences_ = true; | 621 updating_preferences_ = true; |
529 { // Begin scope of update. | 622 { // Begin scope of update. |
530 DictionaryPrefUpdate update(profile_->GetPrefs(), | 623 DictionaryPrefUpdate update(profile_->GetPrefs(), |
531 prefs::kContentSettingsPatterns); | 624 prefs::kContentSettingsPatterns); |
532 | 625 |
533 if (!is_incognito()) { | 626 DictionaryValue* all_settings_dictionary = NULL; |
| 627 OriginIdentifierValueMap* map_to_modify = &incognito_value_map_; |
| 628 if (!is_incognito_) { |
534 all_settings_dictionary = update.Get(); | 629 all_settings_dictionary = update.Get(); |
535 map_to_modify = host_content_settings(); | 630 map_to_modify = &value_map_; |
536 } | 631 } |
537 | 632 |
538 { | 633 { |
539 base::AutoLock auto_lock(lock()); | 634 base::AutoLock auto_lock(lock_); |
540 for (HostContentSettings::iterator i(map_to_modify->begin()); | 635 |
541 i != map_to_modify->end(); ) { | 636 OriginIdentifierValueMap::iterator entry(map_to_modify->begin()); |
542 if (RequiresResourceIdentifier(content_type) || | 637 while (entry != map_to_modify->end()) { |
543 i->second.content_settings.settings[content_type] != | 638 if (entry->content_type == content_type) { |
544 CONTENT_SETTING_DEFAULT) { | 639 std::string pattern_str = CreatePatternString( |
545 if (RequiresResourceIdentifier(content_type)) | 640 entry->item_pattern, entry->top_level_frame_pattern); |
546 i->second.content_settings_for_resources.clear(); | 641 // Delete current |entry| and set |entry| to the next value map entry. |
547 i->second.content_settings.settings[content_type] = | 642 entry = map_to_modify->DeleteValue(entry); |
548 CONTENT_SETTING_DEFAULT; | 643 |
549 std::string host(i->first); | 644 // Update the content settings preference. |
550 if (AllDefault(i->second)) { | 645 if (all_settings_dictionary) { |
551 if (all_settings_dictionary) | 646 // Update the settings dictionary. |
552 all_settings_dictionary->RemoveWithoutPathExpansion(host, NULL); | 647 DictionaryValue* settings_dictionary; |
553 map_to_modify->erase(i++); | |
554 } else if (all_settings_dictionary) { | |
555 DictionaryValue* host_settings_dictionary; | |
556 bool found = | 648 bool found = |
557 all_settings_dictionary->GetDictionaryWithoutPathExpansion( | 649 all_settings_dictionary->GetDictionaryWithoutPathExpansion( |
558 host, &host_settings_dictionary); | 650 pattern_str, &settings_dictionary); |
559 DCHECK(found); | 651 DCHECK(found); |
560 host_settings_dictionary->RemoveWithoutPathExpansion( | 652 settings_dictionary->RemoveWithoutPathExpansion( |
561 kTypeNames[content_type], NULL); | 653 kTypeNames[content_type], NULL); |
562 ++i; | 654 // Remove empty dictionaries. |
| 655 if (settings_dictionary->empty()) |
| 656 all_settings_dictionary->RemoveWithoutPathExpansion(pattern_str, |
| 657 NULL); |
563 } | 658 } |
564 } else { | 659 } else { |
565 ++i; | 660 // No action is required, so move to the next value map entry. |
| 661 ++entry; |
566 } | 662 } |
567 } | 663 } |
568 } | 664 } |
569 } // End scope of update. | 665 } // End scope of update. |
570 updating_preferences_ = false; | 666 updating_preferences_ = false; |
571 | 667 |
572 ContentSettingsDetails details( | 668 ContentSettingsDetails details( |
573 ContentSettingsPattern(), content_type, std::string()); | 669 ContentSettingsPattern(), content_type, std::string()); |
574 NotifyObservers(details); | 670 NotifyObservers(details); |
575 } | 671 } |
(...skipping 10 matching lines...) Expand all Loading... |
586 return; | 682 return; |
587 | 683 |
588 std::string* name = Details<std::string>(details).ptr(); | 684 std::string* name = Details<std::string>(details).ptr(); |
589 if (*name == prefs::kContentSettingsPatterns) { | 685 if (*name == prefs::kContentSettingsPatterns) { |
590 ReadExceptions(true); | 686 ReadExceptions(true); |
591 } else { | 687 } else { |
592 NOTREACHED() << "Unexpected preference observed"; | 688 NOTREACHED() << "Unexpected preference observed"; |
593 return; | 689 return; |
594 } | 690 } |
595 | 691 |
596 if (!is_incognito()) { | 692 if (!is_incognito_) { |
597 ContentSettingsDetails details(ContentSettingsPattern(), | 693 ContentSettingsDetails details(ContentSettingsPattern(), |
598 CONTENT_SETTINGS_TYPE_DEFAULT, | 694 CONTENT_SETTINGS_TYPE_DEFAULT, |
599 std::string()); | 695 std::string()); |
600 NotifyObservers(details); | 696 NotifyObservers(details); |
601 } | 697 } |
602 } else if (type == NotificationType::PROFILE_DESTROYED) { | 698 } else if (type == NotificationType::PROFILE_DESTROYED) { |
603 DCHECK_EQ(profile_, Source<Profile>(source).ptr()); | 699 DCHECK_EQ(profile_, Source<Profile>(source).ptr()); |
604 UnregisterObservers(); | 700 UnregisterObservers(); |
605 } else { | 701 } else { |
606 NOTREACHED() << "Unexpected notification"; | 702 NOTREACHED() << "Unexpected notification"; |
607 } | 703 } |
608 } | 704 } |
609 | 705 |
610 PrefProvider::~PrefProvider() { | 706 PrefProvider::~PrefProvider() { |
611 UnregisterObservers(); | 707 UnregisterObservers(); |
612 } | 708 } |
613 | 709 |
614 // //////////////////////////////////////////////////////////////////////////// | 710 // //////////////////////////////////////////////////////////////////////////// |
615 // Private | 711 // Private |
616 | 712 |
617 void PrefProvider::ReadExceptions(bool overwrite) { | 713 void PrefProvider::ReadExceptions(bool overwrite) { |
618 base::AutoLock auto_lock(lock()); | 714 base::AutoLock auto_lock(lock_); |
619 | 715 |
620 PrefService* prefs = profile_->GetPrefs(); | 716 PrefService* prefs = profile_->GetPrefs(); |
621 const DictionaryValue* all_settings_dictionary = | 717 const DictionaryValue* all_settings_dictionary = |
622 prefs->GetDictionary(prefs::kContentSettingsPatterns); | 718 prefs->GetDictionary(prefs::kContentSettingsPatterns); |
623 | 719 |
624 if (overwrite) | 720 if (overwrite) |
625 host_content_settings()->clear(); | 721 value_map_.Clear(); |
626 | 722 |
627 updating_preferences_ = true; | 723 updating_preferences_ = true; |
628 | |
629 // Careful: The returned value could be NULL if the pref has never been set. | 724 // Careful: The returned value could be NULL if the pref has never been set. |
630 if (all_settings_dictionary != NULL) { | 725 if (all_settings_dictionary != NULL) { |
631 DictionaryPrefUpdate update(prefs, prefs::kContentSettingsPatterns); | 726 DictionaryPrefUpdate update(prefs, prefs::kContentSettingsPatterns); |
632 DictionaryValue* mutable_settings; | 727 DictionaryValue* mutable_settings; |
633 scoped_ptr<DictionaryValue> mutable_settings_scope; | 728 scoped_ptr<DictionaryValue> mutable_settings_scope; |
634 | 729 |
635 if (!is_incognito()) { | 730 if (!is_incognito_) { |
636 mutable_settings = update.Get(); | 731 mutable_settings = update.Get(); |
637 } else { | 732 } else { |
638 // Create copy as we do not want to persist anything in OTR prefs. | 733 // Create copy as we do not want to persist anything in OTR prefs. |
639 mutable_settings = all_settings_dictionary->DeepCopy(); | 734 mutable_settings = all_settings_dictionary->DeepCopy(); |
640 mutable_settings_scope.reset(mutable_settings); | 735 mutable_settings_scope.reset(mutable_settings); |
641 } | 736 } |
642 | |
643 // Convert all Unicode patterns into punycode form, then read. | 737 // Convert all Unicode patterns into punycode form, then read. |
644 CanonicalizeContentSettingsExceptions(mutable_settings); | 738 CanonicalizeContentSettingsExceptions(mutable_settings); |
645 | 739 |
646 for (DictionaryValue::key_iterator i(mutable_settings->begin_keys()); | 740 for (DictionaryValue::key_iterator i(mutable_settings->begin_keys()); |
647 i != mutable_settings->end_keys(); ++i) { | 741 i != mutable_settings->end_keys(); ++i) { |
648 const std::string& pattern(*i); | 742 const std::string& pattern_str(*i); |
649 if (!ContentSettingsPattern::LegacyFromString(pattern).IsValid()) | 743 ContentSettingsPattern pattern = |
| 744 ContentSettingsPattern::FromString(pattern_str); |
| 745 if (!pattern.IsValid()) |
650 LOG(WARNING) << "Invalid pattern stored in content settings"; | 746 LOG(WARNING) << "Invalid pattern stored in content settings"; |
651 DictionaryValue* pattern_settings_dictionary = NULL; | 747 |
| 748 // Get settings dictionary for the current pattern string, and read |
| 749 // settings from the dictionary. |
| 750 DictionaryValue* settings_dictionary = NULL; |
652 bool found = mutable_settings->GetDictionaryWithoutPathExpansion( | 751 bool found = mutable_settings->GetDictionaryWithoutPathExpansion( |
653 pattern, &pattern_settings_dictionary); | 752 pattern_str, &settings_dictionary); |
654 DCHECK(found); | 753 DCHECK(found); |
655 | 754 |
656 ExtendedContentSettings extended_settings; | 755 for (DictionaryValue::key_iterator i(settings_dictionary->begin_keys()); |
657 GetSettingsFromDictionary(pattern_settings_dictionary, | 756 i != settings_dictionary->end_keys(); |
658 &extended_settings.content_settings); | 757 ++i) { |
659 GetResourceSettingsFromDictionary( | 758 const std::string& content_type_str(*i); |
660 pattern_settings_dictionary, | 759 ContentSettingsType content_type = StringToContentSettingsType( |
661 &extended_settings.content_settings_for_resources); | 760 content_type_str); |
| 761 if (content_type == CONTENT_SETTINGS_TYPE_DEFAULT) { |
| 762 NOTREACHED(); |
| 763 LOG(WARNING) << "Skip settings for invalid content settings type '" |
| 764 << content_type_str << "'"; |
| 765 continue; |
| 766 } |
662 | 767 |
663 (*host_content_settings())[pattern] = extended_settings; | 768 if (RequiresResourceIdentifier(content_type)) { |
| 769 DictionaryValue* resource_dictionary = NULL; |
| 770 bool found = settings_dictionary->GetDictionary( |
| 771 content_type_str, &resource_dictionary); |
| 772 DCHECK(found); |
| 773 for (DictionaryValue::key_iterator j( |
| 774 resource_dictionary->begin_keys()); |
| 775 j != resource_dictionary->end_keys(); |
| 776 ++j) { |
| 777 const std::string& resource_identifier(*j); |
| 778 int setting = CONTENT_SETTING_DEFAULT; |
| 779 found = resource_dictionary->GetIntegerWithoutPathExpansion( |
| 780 resource_identifier, &setting); |
| 781 DCHECK(found); |
| 782 setting = ClickToPlayFixup(content_type, |
| 783 ContentSetting(setting)); |
| 784 value_map_.SetValue(pattern, |
| 785 pattern, |
| 786 content_type, |
| 787 resource_identifier, |
| 788 Value::CreateIntegerValue(setting)); |
| 789 } |
| 790 } else { |
| 791 int setting = CONTENT_SETTING_DEFAULT; |
| 792 bool found = settings_dictionary->GetIntegerWithoutPathExpansion( |
| 793 content_type_str, &setting); |
| 794 DCHECK(found); |
| 795 setting = FixObsoleteCookiePromptMode(content_type, |
| 796 ContentSetting(setting)); |
| 797 setting = ClickToPlayFixup(content_type, |
| 798 ContentSetting(setting)); |
| 799 value_map_.SetValue(pattern, |
| 800 pattern, |
| 801 content_type, |
| 802 ResourceIdentifier(""), |
| 803 Value::CreateIntegerValue(setting)); |
| 804 } |
| 805 } |
664 } | 806 } |
665 } | 807 } |
666 updating_preferences_ = false; | 808 updating_preferences_ = false; |
667 } | 809 } |
668 | 810 |
669 void PrefProvider::CanonicalizeContentSettingsExceptions( | 811 void PrefProvider::CanonicalizeContentSettingsExceptions( |
670 DictionaryValue* all_settings_dictionary) { | 812 DictionaryValue* all_settings_dictionary) { |
671 DCHECK(all_settings_dictionary); | 813 DCHECK(all_settings_dictionary); |
672 | 814 |
673 std::vector<std::string> remove_items; | 815 std::vector<std::string> remove_items; |
674 std::vector<std::pair<std::string, std::string> > move_items; | 816 std::vector<std::pair<std::string, std::string> > move_items; |
675 for (DictionaryValue::key_iterator i(all_settings_dictionary->begin_keys()); | 817 for (DictionaryValue::key_iterator i(all_settings_dictionary->begin_keys()); |
676 i != all_settings_dictionary->end_keys(); ++i) { | 818 i != all_settings_dictionary->end_keys(); ++i) { |
677 const std::string& pattern(*i); | 819 const std::string& pattern(*i); |
678 const std::string canonicalized_pattern = | 820 const std::string canonicalized_pattern = |
679 ContentSettingsPattern::LegacyFromString(pattern).ToString(); | 821 ContentSettingsPattern::FromString(pattern).ToString(); |
680 | 822 |
681 if (canonicalized_pattern.empty() || canonicalized_pattern == pattern) | 823 if (canonicalized_pattern.empty() || canonicalized_pattern == pattern) |
682 continue; | 824 continue; |
683 | 825 |
684 // Clear old pattern if prefs already have canonicalized pattern. | 826 // Clear old pattern if prefs already have canonicalized pattern. |
685 DictionaryValue* new_pattern_settings_dictionary = NULL; | 827 DictionaryValue* new_pattern_settings_dictionary = NULL; |
686 if (all_settings_dictionary->GetDictionaryWithoutPathExpansion( | 828 if (all_settings_dictionary->GetDictionaryWithoutPathExpansion( |
687 canonicalized_pattern, &new_pattern_settings_dictionary)) { | 829 canonicalized_pattern, &new_pattern_settings_dictionary)) { |
688 remove_items.push_back(pattern); | 830 remove_items.push_back(pattern); |
689 continue; | 831 continue; |
(...skipping 13 matching lines...) Expand all Loading... |
703 | 845 |
704 for (size_t i = 0; i < move_items.size(); ++i) { | 846 for (size_t i = 0; i < move_items.size(); ++i) { |
705 Value* pattern_settings_dictionary = NULL; | 847 Value* pattern_settings_dictionary = NULL; |
706 all_settings_dictionary->RemoveWithoutPathExpansion( | 848 all_settings_dictionary->RemoveWithoutPathExpansion( |
707 move_items[i].first, &pattern_settings_dictionary); | 849 move_items[i].first, &pattern_settings_dictionary); |
708 all_settings_dictionary->SetWithoutPathExpansion( | 850 all_settings_dictionary->SetWithoutPathExpansion( |
709 move_items[i].second, pattern_settings_dictionary); | 851 move_items[i].second, pattern_settings_dictionary); |
710 } | 852 } |
711 } | 853 } |
712 | 854 |
713 void PrefProvider::GetSettingsFromDictionary( | |
714 const DictionaryValue* dictionary, | |
715 ContentSettings* settings) { | |
716 for (DictionaryValue::key_iterator i(dictionary->begin_keys()); | |
717 i != dictionary->end_keys(); ++i) { | |
718 const std::string& content_type(*i); | |
719 for (size_t type = 0; type < arraysize(kTypeNames); ++type) { | |
720 if ((kTypeNames[type] != NULL) && (kTypeNames[type] == content_type)) { | |
721 int setting = CONTENT_SETTING_DEFAULT; | |
722 bool found = dictionary->GetIntegerWithoutPathExpansion(content_type, | |
723 &setting); | |
724 DCHECK(found); | |
725 settings->settings[type] = IntToContentSetting(setting); | |
726 break; | |
727 } | |
728 } | |
729 } | |
730 // Migrate obsolete cookie prompt mode. | |
731 if (settings->settings[CONTENT_SETTINGS_TYPE_COOKIES] == | |
732 CONTENT_SETTING_ASK) | |
733 settings->settings[CONTENT_SETTINGS_TYPE_COOKIES] = CONTENT_SETTING_BLOCK; | |
734 | |
735 settings->settings[CONTENT_SETTINGS_TYPE_PLUGINS] = | |
736 ClickToPlayFixup(CONTENT_SETTINGS_TYPE_PLUGINS, | |
737 settings->settings[CONTENT_SETTINGS_TYPE_PLUGINS]); | |
738 } | |
739 | |
740 void PrefProvider::GetResourceSettingsFromDictionary( | |
741 const DictionaryValue* dictionary, | |
742 ResourceContentSettings* settings) { | |
743 for (DictionaryValue::key_iterator i(dictionary->begin_keys()); | |
744 i != dictionary->end_keys(); ++i) { | |
745 const std::string& content_type(*i); | |
746 for (size_t type = 0; type < arraysize(kResourceTypeNames); ++type) { | |
747 if ((kResourceTypeNames[type] != NULL) && | |
748 (kResourceTypeNames[type] == content_type)) { | |
749 DictionaryValue* resource_dictionary = NULL; | |
750 bool found = dictionary->GetDictionary(content_type, | |
751 &resource_dictionary); | |
752 DCHECK(found); | |
753 for (DictionaryValue::key_iterator j(resource_dictionary->begin_keys()); | |
754 j != resource_dictionary->end_keys(); ++j) { | |
755 const std::string& resource_identifier(*j); | |
756 int setting = CONTENT_SETTING_DEFAULT; | |
757 bool found = resource_dictionary->GetIntegerWithoutPathExpansion( | |
758 resource_identifier, &setting); | |
759 DCHECK(found); | |
760 (*settings)[ContentSettingsTypeResourceIdentifierPair( | |
761 ContentSettingsType(type), resource_identifier)] = | |
762 ClickToPlayFixup(ContentSettingsType(type), | |
763 ContentSetting(setting)); | |
764 } | |
765 | |
766 break; | |
767 } | |
768 } | |
769 } | |
770 } | |
771 | |
772 void PrefProvider::NotifyObservers( | 855 void PrefProvider::NotifyObservers( |
773 const ContentSettingsDetails& details) { | 856 const ContentSettingsDetails& details) { |
774 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 857 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
775 if (initializing_ || profile_ == NULL) | 858 if (initializing_ || profile_ == NULL) |
776 return; | 859 return; |
777 NotificationService::current()->Notify( | 860 NotificationService::current()->Notify( |
778 NotificationType::CONTENT_SETTINGS_CHANGED, | 861 NotificationType::CONTENT_SETTINGS_CHANGED, |
779 Source<HostContentSettingsMap>( | 862 Source<HostContentSettingsMap>( |
780 profile_->GetHostContentSettingsMap()), | 863 profile_->GetHostContentSettingsMap()), |
781 Details<const ContentSettingsDetails>(&details)); | 864 Details<const ContentSettingsDetails>(&details)); |
(...skipping 12 matching lines...) Expand all Loading... |
794 void PrefProvider::MigrateObsoletePerhostPref(PrefService* prefs) { | 877 void PrefProvider::MigrateObsoletePerhostPref(PrefService* prefs) { |
795 if (prefs->HasPrefPath(prefs::kPerHostContentSettings)) { | 878 if (prefs->HasPrefPath(prefs::kPerHostContentSettings)) { |
796 const DictionaryValue* all_settings_dictionary = | 879 const DictionaryValue* all_settings_dictionary = |
797 prefs->GetDictionary(prefs::kPerHostContentSettings); | 880 prefs->GetDictionary(prefs::kPerHostContentSettings); |
798 DCHECK(all_settings_dictionary); | 881 DCHECK(all_settings_dictionary); |
799 for (DictionaryValue::key_iterator | 882 for (DictionaryValue::key_iterator |
800 i(all_settings_dictionary->begin_keys()); | 883 i(all_settings_dictionary->begin_keys()); |
801 i != all_settings_dictionary->end_keys(); ++i) { | 884 i != all_settings_dictionary->end_keys(); ++i) { |
802 const std::string& host(*i); | 885 const std::string& host(*i); |
803 ContentSettingsPattern pattern = | 886 ContentSettingsPattern pattern = |
804 ContentSettingsPattern::LegacyFromString( | 887 ContentSettingsPattern::FromString( |
805 std::string(ContentSettingsPattern::kDomainWildcard) + host); | 888 std::string(ContentSettingsPattern::kDomainWildcard) + host); |
806 DictionaryValue* host_settings_dictionary = NULL; | 889 DictionaryValue* host_settings_dictionary = NULL; |
807 bool found = all_settings_dictionary->GetDictionaryWithoutPathExpansion( | 890 bool found = all_settings_dictionary->GetDictionaryWithoutPathExpansion( |
808 host, &host_settings_dictionary); | 891 host, &host_settings_dictionary); |
809 DCHECK(found); | 892 DCHECK(found); |
810 ContentSettings settings; | 893 |
811 GetSettingsFromDictionary(host_settings_dictionary, &settings); | 894 for (DictionaryValue::key_iterator i( |
812 for (int j = 0; j < CONTENT_SETTINGS_NUM_TYPES; ++j) { | 895 host_settings_dictionary->begin_keys()); |
813 if (settings.settings[j] != CONTENT_SETTING_DEFAULT && | 896 i != host_settings_dictionary->end_keys(); |
814 !RequiresResourceIdentifier(ContentSettingsType(j))) { | 897 ++i) { |
815 SetContentSetting( | 898 const std::string& content_type_str(*i); |
816 pattern, | 899 ContentSettingsType content_type = |
817 pattern, | 900 StringToContentSettingsType(content_type_str); |
818 ContentSettingsType(j), | 901 |
819 "", | 902 if (content_type == CONTENT_SETTINGS_TYPE_DEFAULT) { |
820 settings.settings[j]); | 903 NOTREACHED(); |
| 904 LOG(DFATAL) << "Skip settings for invalid content settings type '" |
| 905 << content_type_str << "'"; |
| 906 continue; |
| 907 } |
| 908 |
| 909 if (!RequiresResourceIdentifier(content_type)) { |
| 910 int setting_int_value = CONTENT_SETTING_DEFAULT; |
| 911 bool found = |
| 912 host_settings_dictionary->GetIntegerWithoutPathExpansion( |
| 913 content_type_str, &setting_int_value); |
| 914 DCHECK(found); |
| 915 ContentSetting setting = IntToContentSetting(setting_int_value); |
| 916 |
| 917 setting = FixObsoleteCookiePromptMode(content_type, setting); |
| 918 setting = ClickToPlayFixup(content_type, setting); |
| 919 |
| 920 // TODO(markusheintz): Maybe this check can be removed. |
| 921 if (setting != CONTENT_SETTING_DEFAULT) { |
| 922 SetContentSetting( |
| 923 pattern, |
| 924 pattern, |
| 925 content_type, |
| 926 "", |
| 927 setting); |
| 928 } |
821 } | 929 } |
822 } | 930 } |
823 } | 931 } |
824 prefs->ClearPref(prefs::kPerHostContentSettings); | 932 prefs->ClearPref(prefs::kPerHostContentSettings); |
825 } | 933 } |
826 } | 934 } |
827 | 935 |
828 void PrefProvider::MigrateObsoletePopupsPref(PrefService* prefs) { | 936 void PrefProvider::MigrateObsoletePopupsPref(PrefService* prefs) { |
829 if (prefs->HasPrefPath(prefs::kPopupWhitelistedHosts)) { | 937 if (prefs->HasPrefPath(prefs::kPopupWhitelistedHosts)) { |
830 const ListValue* whitelist_pref = | 938 const ListValue* whitelist_pref = |
831 prefs->GetList(prefs::kPopupWhitelistedHosts); | 939 prefs->GetList(prefs::kPopupWhitelistedHosts); |
832 for (ListValue::const_iterator i(whitelist_pref->begin()); | 940 for (ListValue::const_iterator i(whitelist_pref->begin()); |
833 i != whitelist_pref->end(); ++i) { | 941 i != whitelist_pref->end(); ++i) { |
834 std::string host; | 942 std::string host; |
835 (*i)->GetAsString(&host); | 943 (*i)->GetAsString(&host); |
836 SetContentSetting(ContentSettingsPattern::LegacyFromString(host), | 944 SetContentSetting(ContentSettingsPattern::FromString(host), |
837 ContentSettingsPattern::LegacyFromString(host), | 945 ContentSettingsPattern::FromString(host), |
838 CONTENT_SETTINGS_TYPE_POPUPS, | 946 CONTENT_SETTINGS_TYPE_POPUPS, |
839 "", | 947 "", |
840 CONTENT_SETTING_ALLOW); | 948 CONTENT_SETTING_ALLOW); |
841 } | 949 } |
842 prefs->ClearPref(prefs::kPopupWhitelistedHosts); | 950 prefs->ClearPref(prefs::kPopupWhitelistedHosts); |
843 } | 951 } |
844 } | 952 } |
845 | 953 |
846 } // namespace content_settings | 954 } // namespace content_settings |
OLD | NEW |