host_content_settings_map.cc revision 5f1c94371a64b3196d4be9466099bb892df9b88e
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. 4 5#include "chrome/browser/content_settings/host_content_settings_map.h" 6 7#include <utility> 8 9#include "base/basictypes.h" 10#include "base/command_line.h" 11#include "base/prefs/pref_service.h" 12#include "base/stl_util.h" 13#include "base/strings/string_util.h" 14#include "base/strings/utf_string_conversions.h" 15#include "base/time/clock.h" 16#include "chrome/browser/chrome_notification_types.h" 17#include "chrome/browser/content_settings/content_settings_custom_extension_provider.h" 18#include "chrome/browser/content_settings/content_settings_default_provider.h" 19#include "chrome/browser/content_settings/content_settings_details.h" 20#include "chrome/browser/content_settings/content_settings_internal_extension_provider.h" 21#include "chrome/browser/content_settings/content_settings_observable_provider.h" 22#include "chrome/browser/content_settings/content_settings_policy_provider.h" 23#include "chrome/browser/content_settings/content_settings_pref_provider.h" 24#include "chrome/browser/content_settings/content_settings_provider.h" 25#include "chrome/browser/content_settings/content_settings_rule.h" 26#include "chrome/browser/content_settings/content_settings_utils.h" 27#include "chrome/browser/extensions/api/content_settings/content_settings_service.h" 28#include "chrome/browser/extensions/extension_service.h" 29#include "chrome/common/chrome_switches.h" 30#include "chrome/common/content_settings_pattern.h" 31#include "chrome/common/pref_names.h" 32#include "chrome/common/url_constants.h" 33#include "components/pref_registry/pref_registry_syncable.h" 34#include "content/public/browser/browser_thread.h" 35#include "content/public/browser/notification_service.h" 36#include "content/public/browser/notification_source.h" 37#include "content/public/browser/user_metrics.h" 38#include "content/public/common/content_switches.h" 39#include "extensions/browser/extension_prefs.h" 40#include "extensions/common/constants.h" 41#include "net/base/net_errors.h" 42#include "net/base/static_cookie_policy.h" 43#include "url/gurl.h" 44 45using base::UserMetricsAction; 46using content::BrowserThread; 47 48namespace { 49 50typedef std::vector<content_settings::Rule> Rules; 51 52typedef std::pair<std::string, std::string> StringPair; 53 54// TODO(bauerb): Expose constants. 55const char* kProviderNames[] = { 56 "platform_app", 57 "policy", 58 "extension", 59 "preference", 60 "default" 61}; 62 63content_settings::SettingSource kProviderSourceMap[] = { 64 content_settings::SETTING_SOURCE_EXTENSION, 65 content_settings::SETTING_SOURCE_POLICY, 66 content_settings::SETTING_SOURCE_EXTENSION, 67 content_settings::SETTING_SOURCE_USER, 68 content_settings::SETTING_SOURCE_USER, 69}; 70COMPILE_ASSERT(arraysize(kProviderSourceMap) == 71 HostContentSettingsMap::NUM_PROVIDER_TYPES, 72 kProviderSourceMap_has_incorrect_size); 73 74// Returns true if the |content_type| supports a resource identifier. 75// Resource identifiers are supported (but not required) for plug-ins. 76bool SupportsResourceIdentifier(ContentSettingsType content_type) { 77 return content_type == CONTENT_SETTINGS_TYPE_PLUGINS; 78} 79 80} // namespace 81 82HostContentSettingsMap::HostContentSettingsMap( 83 PrefService* prefs, 84 bool incognito) : 85#ifndef NDEBUG 86 used_from_thread_id_(base::PlatformThread::CurrentId()), 87#endif 88 prefs_(prefs), 89 is_off_the_record_(incognito) { 90 content_settings::ObservableProvider* policy_provider = 91 new content_settings::PolicyProvider(prefs_); 92 policy_provider->AddObserver(this); 93 content_settings_providers_[POLICY_PROVIDER] = policy_provider; 94 95 content_settings::ObservableProvider* pref_provider = 96 new content_settings::PrefProvider(prefs_, is_off_the_record_); 97 pref_provider->AddObserver(this); 98 content_settings_providers_[PREF_PROVIDER] = pref_provider; 99 100 content_settings::ObservableProvider* default_provider = 101 new content_settings::DefaultProvider(prefs_, is_off_the_record_); 102 default_provider->AddObserver(this); 103 content_settings_providers_[DEFAULT_PROVIDER] = default_provider; 104 105 if (!is_off_the_record_) { 106 // Migrate obsolete preferences. 107 MigrateObsoleteClearOnExitPref(); 108 } 109} 110 111#if defined(ENABLE_EXTENSIONS) 112void HostContentSettingsMap::RegisterExtensionService( 113 ExtensionService* extension_service) { 114 DCHECK(extension_service); 115 DCHECK(!content_settings_providers_[INTERNAL_EXTENSION_PROVIDER]); 116 DCHECK(!content_settings_providers_[CUSTOM_EXTENSION_PROVIDER]); 117 118 content_settings::InternalExtensionProvider* internal_extension_provider = 119 new content_settings::InternalExtensionProvider(extension_service); 120 internal_extension_provider->AddObserver(this); 121 content_settings_providers_[INTERNAL_EXTENSION_PROVIDER] = 122 internal_extension_provider; 123 124 content_settings::ObservableProvider* custom_extension_provider = 125 new content_settings::CustomExtensionProvider( 126 extensions::ContentSettingsService::Get( 127 extension_service->GetBrowserContext())->content_settings_store(), 128 is_off_the_record_); 129 custom_extension_provider->AddObserver(this); 130 content_settings_providers_[CUSTOM_EXTENSION_PROVIDER] = 131 custom_extension_provider; 132 133#ifndef NDEBUG 134 DCHECK(used_from_thread_id_ != base::kInvalidThreadId) 135 << "Used from multiple threads before initialization complete."; 136#endif 137 138 OnContentSettingChanged(ContentSettingsPattern(), 139 ContentSettingsPattern(), 140 CONTENT_SETTINGS_TYPE_DEFAULT, 141 std::string()); 142} 143#endif 144 145// static 146void HostContentSettingsMap::RegisterProfilePrefs( 147 user_prefs::PrefRegistrySyncable* registry) { 148 registry->RegisterIntegerPref( 149 prefs::kContentSettingsWindowLastTabIndex, 150 0, 151 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 152 registry->RegisterIntegerPref( 153 prefs::kContentSettingsDefaultWhitelistVersion, 154 0, 155 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); 156 registry->RegisterBooleanPref( 157 prefs::kContentSettingsClearOnExitMigrated, 158 false, 159 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); 160 161 // Register the prefs for the content settings providers. 162 content_settings::DefaultProvider::RegisterProfilePrefs(registry); 163 content_settings::PrefProvider::RegisterProfilePrefs(registry); 164 content_settings::PolicyProvider::RegisterProfilePrefs(registry); 165} 166 167ContentSetting HostContentSettingsMap::GetDefaultContentSettingFromProvider( 168 ContentSettingsType content_type, 169 content_settings::ProviderInterface* provider) const { 170 scoped_ptr<content_settings::RuleIterator> rule_iterator( 171 provider->GetRuleIterator(content_type, std::string(), false)); 172 173 ContentSettingsPattern wildcard = ContentSettingsPattern::Wildcard(); 174 while (rule_iterator->HasNext()) { 175 content_settings::Rule rule = rule_iterator->Next(); 176 if (rule.primary_pattern == wildcard && 177 rule.secondary_pattern == wildcard) { 178 return content_settings::ValueToContentSetting(rule.value.get()); 179 } 180 } 181 return CONTENT_SETTING_DEFAULT; 182} 183 184ContentSetting HostContentSettingsMap::GetDefaultContentSetting( 185 ContentSettingsType content_type, 186 std::string* provider_id) const { 187 UsedContentSettingsProviders(); 188 189 // Iterate through the list of providers and return the first non-NULL value 190 // that matches |primary_url| and |secondary_url|. 191 for (ConstProviderIterator provider = content_settings_providers_.begin(); 192 provider != content_settings_providers_.end(); 193 ++provider) { 194 if (provider->first == PREF_PROVIDER) 195 continue; 196 ContentSetting default_setting = 197 GetDefaultContentSettingFromProvider(content_type, provider->second); 198 if (default_setting != CONTENT_SETTING_DEFAULT) { 199 if (provider_id) 200 *provider_id = kProviderNames[provider->first]; 201 return default_setting; 202 } 203 } 204 205 // The method GetDefaultContentSetting always has to return an explicit 206 // value that is to be used as default. We here rely on the 207 // DefaultProvider to always provide a value. 208 NOTREACHED(); 209 return CONTENT_SETTING_DEFAULT; 210} 211 212ContentSetting HostContentSettingsMap::GetContentSetting( 213 const GURL& primary_url, 214 const GURL& secondary_url, 215 ContentSettingsType content_type, 216 const std::string& resource_identifier) const { 217 DCHECK(!ContentTypeHasCompoundValue(content_type)); 218 scoped_ptr<base::Value> value(GetWebsiteSetting( 219 primary_url, secondary_url, content_type, resource_identifier, NULL)); 220 return content_settings::ValueToContentSetting(value.get()); 221} 222 223void HostContentSettingsMap::GetSettingsForOneType( 224 ContentSettingsType content_type, 225 const std::string& resource_identifier, 226 ContentSettingsForOneType* settings) const { 227 DCHECK(SupportsResourceIdentifier(content_type) || 228 resource_identifier.empty()); 229 DCHECK(settings); 230 UsedContentSettingsProviders(); 231 232 settings->clear(); 233 for (ConstProviderIterator provider = content_settings_providers_.begin(); 234 provider != content_settings_providers_.end(); 235 ++provider) { 236 // For each provider, iterate first the incognito-specific rules, then the 237 // normal rules. 238 if (is_off_the_record_) { 239 AddSettingsForOneType(provider->second, 240 provider->first, 241 content_type, 242 resource_identifier, 243 settings, 244 true); 245 } 246 AddSettingsForOneType(provider->second, 247 provider->first, 248 content_type, 249 resource_identifier, 250 settings, 251 false); 252 } 253} 254 255void HostContentSettingsMap::SetDefaultContentSetting( 256 ContentSettingsType content_type, 257 ContentSetting setting) { 258 DCHECK(IsSettingAllowedForType(prefs_, setting, content_type)); 259 260 base::Value* value = NULL; 261 if (setting != CONTENT_SETTING_DEFAULT) 262 value = new base::FundamentalValue(setting); 263 SetWebsiteSetting( 264 ContentSettingsPattern::Wildcard(), 265 ContentSettingsPattern::Wildcard(), 266 content_type, 267 std::string(), 268 value); 269} 270 271void HostContentSettingsMap::SetWebsiteSetting( 272 const ContentSettingsPattern& primary_pattern, 273 const ContentSettingsPattern& secondary_pattern, 274 ContentSettingsType content_type, 275 const std::string& resource_identifier, 276 base::Value* value) { 277 DCHECK(IsValueAllowedForType(prefs_, value, content_type)); 278 DCHECK(SupportsResourceIdentifier(content_type) || 279 resource_identifier.empty()); 280 UsedContentSettingsProviders(); 281 282 for (ProviderIterator provider = content_settings_providers_.begin(); 283 provider != content_settings_providers_.end(); 284 ++provider) { 285 if (provider->second->SetWebsiteSetting(primary_pattern, 286 secondary_pattern, 287 content_type, 288 resource_identifier, 289 value)) { 290 return; 291 } 292 } 293 NOTREACHED(); 294} 295 296void HostContentSettingsMap::SetContentSetting( 297 const ContentSettingsPattern& primary_pattern, 298 const ContentSettingsPattern& secondary_pattern, 299 ContentSettingsType content_type, 300 const std::string& resource_identifier, 301 ContentSetting setting) { 302 DCHECK(!ContentTypeHasCompoundValue(content_type)); 303 304 if (setting == CONTENT_SETTING_ALLOW && 305 (content_type == CONTENT_SETTINGS_TYPE_GEOLOCATION || 306 content_type == CONTENT_SETTINGS_TYPE_NOTIFICATIONS)) { 307 UpdateLastUsageByPattern(primary_pattern, secondary_pattern, content_type); 308 } 309 310 base::Value* value = NULL; 311 if (setting != CONTENT_SETTING_DEFAULT) 312 value = new base::FundamentalValue(setting); 313 SetWebsiteSetting(primary_pattern, 314 secondary_pattern, 315 content_type, 316 resource_identifier, 317 value); 318} 319 320ContentSetting HostContentSettingsMap::GetContentSettingAndMaybeUpdateLastUsage( 321 const GURL& primary_url, 322 const GURL& secondary_url, 323 ContentSettingsType content_type, 324 const std::string& resource_identifier) { 325 DCHECK_CURRENTLY_ON(BrowserThread::UI); 326 327 ContentSetting setting = GetContentSetting( 328 primary_url, secondary_url, content_type, resource_identifier); 329 if (setting == CONTENT_SETTING_ALLOW) { 330 UpdateLastUsageByPattern( 331 ContentSettingsPattern::FromURLNoWildcard(primary_url), 332 ContentSettingsPattern::FromURLNoWildcard(secondary_url), 333 content_type); 334 } 335 return setting; 336} 337 338void HostContentSettingsMap::UpdateLastUsage(const GURL& primary_url, 339 const GURL& secondary_url, 340 ContentSettingsType content_type) { 341 UpdateLastUsageByPattern( 342 ContentSettingsPattern::FromURLNoWildcard(primary_url), 343 ContentSettingsPattern::FromURLNoWildcard(secondary_url), 344 content_type); 345} 346 347void HostContentSettingsMap::UpdateLastUsageByPattern( 348 const ContentSettingsPattern& primary_pattern, 349 const ContentSettingsPattern& secondary_pattern, 350 ContentSettingsType content_type) { 351 UsedContentSettingsProviders(); 352 353 GetPrefProvider()->UpdateLastUsage( 354 primary_pattern, secondary_pattern, content_type); 355} 356 357base::Time HostContentSettingsMap::GetLastUsage( 358 const GURL& primary_url, 359 const GURL& secondary_url, 360 ContentSettingsType content_type) { 361 return GetLastUsageByPattern( 362 ContentSettingsPattern::FromURLNoWildcard(primary_url), 363 ContentSettingsPattern::FromURLNoWildcard(secondary_url), 364 content_type); 365} 366 367base::Time HostContentSettingsMap::GetLastUsageByPattern( 368 const ContentSettingsPattern& primary_pattern, 369 const ContentSettingsPattern& secondary_pattern, 370 ContentSettingsType content_type) { 371 UsedContentSettingsProviders(); 372 373 return GetPrefProvider()->GetLastUsage( 374 primary_pattern, secondary_pattern, content_type); 375} 376 377void HostContentSettingsMap::SetPrefClockForTesting( 378 scoped_ptr<base::Clock> clock) { 379 UsedContentSettingsProviders(); 380 381 GetPrefProvider()->SetClockForTesting(clock.Pass()); 382} 383 384void HostContentSettingsMap::AddExceptionForURL( 385 const GURL& primary_url, 386 const GURL& secondary_url, 387 ContentSettingsType content_type, 388 ContentSetting setting) { 389 // TODO(markusheintz): Until the UI supports pattern pairs, both urls must 390 // match. 391 DCHECK(primary_url == secondary_url); 392 DCHECK(!ContentTypeHasCompoundValue(content_type)); 393 394 // Make sure there is no entry that would override the pattern we are about 395 // to insert for exactly this URL. 396 SetContentSetting(ContentSettingsPattern::FromURLNoWildcard(primary_url), 397 ContentSettingsPattern::Wildcard(), 398 content_type, 399 std::string(), 400 CONTENT_SETTING_DEFAULT); 401 402 SetContentSetting(ContentSettingsPattern::FromURL(primary_url), 403 ContentSettingsPattern::Wildcard(), 404 content_type, 405 std::string(), 406 setting); 407} 408 409void HostContentSettingsMap::ClearSettingsForOneType( 410 ContentSettingsType content_type) { 411 UsedContentSettingsProviders(); 412 for (ProviderIterator provider = content_settings_providers_.begin(); 413 provider != content_settings_providers_.end(); 414 ++provider) { 415 provider->second->ClearAllContentSettingsRules(content_type); 416 } 417} 418 419bool HostContentSettingsMap::IsValueAllowedForType( 420 PrefService* prefs, const base::Value* value, ContentSettingsType type) { 421 return ContentTypeHasCompoundValue(type) || IsSettingAllowedForType( 422 prefs, content_settings::ValueToContentSetting(value), type); 423} 424 425// static 426bool HostContentSettingsMap::IsSettingAllowedForType( 427 PrefService* prefs, 428 ContentSetting setting, 429 ContentSettingsType content_type) { 430 // We don't yet support stored content settings for mixed scripting. 431 if (content_type == CONTENT_SETTINGS_TYPE_MIXEDSCRIPT) 432 return false; 433 434 // BLOCK semantics are not implemented for fullscreen. 435 if (content_type == CONTENT_SETTINGS_TYPE_FULLSCREEN && 436 setting == CONTENT_SETTING_BLOCK) { 437 return false; 438 } 439 440 // We don't support ALLOW for media default setting. 441 if (content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM && 442 setting == CONTENT_SETTING_ALLOW) { 443 return false; 444 } 445 446#if defined(OS_ANDROID) 447 // App banners store a dictionary. 448 if (content_type == CONTENT_SETTINGS_TYPE_APP_BANNER) 449 return false; 450#endif 451 452 // DEFAULT, ALLOW and BLOCK are always allowed. 453 if (setting == CONTENT_SETTING_DEFAULT || 454 setting == CONTENT_SETTING_ALLOW || 455 setting == CONTENT_SETTING_BLOCK) { 456 return true; 457 } 458 switch (content_type) { 459 case CONTENT_SETTINGS_TYPE_COOKIES: 460 return setting == CONTENT_SETTING_SESSION_ONLY; 461 case CONTENT_SETTINGS_TYPE_PLUGINS: 462 case CONTENT_SETTINGS_TYPE_GEOLOCATION: 463 case CONTENT_SETTINGS_TYPE_NOTIFICATIONS: 464 case CONTENT_SETTINGS_TYPE_MOUSELOCK: 465 case CONTENT_SETTINGS_TYPE_MEDIASTREAM: 466 case CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC: 467 case CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA: 468 case CONTENT_SETTINGS_TYPE_PPAPI_BROKER: 469 case CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS: 470 case CONTENT_SETTINGS_TYPE_MIDI_SYSEX: 471 return setting == CONTENT_SETTING_ASK; 472 default: 473 return false; 474 } 475} 476 477// static 478bool HostContentSettingsMap::ContentTypeHasCompoundValue( 479 ContentSettingsType type) { 480 // Values for content type CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE, 481 // CONTENT_SETTINGS_TYPE_MEDIASTREAM, and 482 // CONTENT_SETTINGS_TYPE_SSL_CERT_DECISIONS are of type dictionary/map. 483 // Compound types like dictionaries can't be mapped to the type 484 // |ContentSetting|. 485#if defined(OS_ANDROID) 486 if (type == CONTENT_SETTINGS_TYPE_APP_BANNER) 487 return true; 488#endif 489 490 return (type == CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE || 491 type == CONTENT_SETTINGS_TYPE_MEDIASTREAM || 492 type == CONTENT_SETTINGS_TYPE_SSL_CERT_DECISIONS); 493} 494 495void HostContentSettingsMap::OnContentSettingChanged( 496 const ContentSettingsPattern& primary_pattern, 497 const ContentSettingsPattern& secondary_pattern, 498 ContentSettingsType content_type, 499 std::string resource_identifier) { 500 const ContentSettingsDetails details(primary_pattern, 501 secondary_pattern, 502 content_type, 503 resource_identifier); 504 content::NotificationService::current()->Notify( 505 chrome::NOTIFICATION_CONTENT_SETTINGS_CHANGED, 506 content::Source<HostContentSettingsMap>(this), 507 content::Details<const ContentSettingsDetails>(&details)); 508} 509 510HostContentSettingsMap::~HostContentSettingsMap() { 511 DCHECK(!prefs_); 512 STLDeleteValues(&content_settings_providers_); 513} 514 515void HostContentSettingsMap::ShutdownOnUIThread() { 516 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 517 DCHECK(prefs_); 518 prefs_ = NULL; 519 for (ProviderIterator it = content_settings_providers_.begin(); 520 it != content_settings_providers_.end(); 521 ++it) { 522 it->second->ShutdownOnUIThread(); 523 } 524} 525 526void HostContentSettingsMap::MigrateObsoleteClearOnExitPref() { 527 // Don't migrate more than once. 528 if (prefs_->HasPrefPath(prefs::kContentSettingsClearOnExitMigrated) && 529 prefs_->GetBoolean(prefs::kContentSettingsClearOnExitMigrated)) { 530 return; 531 } 532 533 if (!prefs_->GetBoolean(prefs::kClearSiteDataOnExit)) { 534 // Nothing to be done 535 prefs_->SetBoolean(prefs::kContentSettingsClearOnExitMigrated, true); 536 return; 537 } 538 539 // Change the default cookie settings: 540 // old new 541 // ---------------- ---------------- 542 // ALLOW SESSION_ONLY 543 // SESSION_ONLY SESSION_ONLY 544 // BLOCK BLOCK 545 ContentSetting default_setting = GetDefaultContentSettingFromProvider( 546 CONTENT_SETTINGS_TYPE_COOKIES, 547 content_settings_providers_[DEFAULT_PROVIDER]); 548 if (default_setting == CONTENT_SETTING_ALLOW) { 549 SetDefaultContentSetting( 550 CONTENT_SETTINGS_TYPE_COOKIES, CONTENT_SETTING_SESSION_ONLY); 551 } 552 553 // Change the exceptions using the same rules. 554 ContentSettingsForOneType exceptions; 555 AddSettingsForOneType(content_settings_providers_[PREF_PROVIDER], 556 PREF_PROVIDER, 557 CONTENT_SETTINGS_TYPE_COOKIES, 558 std::string(), 559 &exceptions, 560 false); 561 for (ContentSettingsForOneType::iterator it = exceptions.begin(); 562 it != exceptions.end(); ++it) { 563 if (it->setting != CONTENT_SETTING_ALLOW) 564 continue; 565 SetWebsiteSetting(it->primary_pattern, 566 it->secondary_pattern, 567 CONTENT_SETTINGS_TYPE_COOKIES, 568 std::string(), 569 new base::FundamentalValue(CONTENT_SETTING_SESSION_ONLY)); 570 } 571 572 prefs_->SetBoolean(prefs::kContentSettingsClearOnExitMigrated, true); 573} 574 575void HostContentSettingsMap::AddSettingsForOneType( 576 const content_settings::ProviderInterface* provider, 577 ProviderType provider_type, 578 ContentSettingsType content_type, 579 const std::string& resource_identifier, 580 ContentSettingsForOneType* settings, 581 bool incognito) const { 582 scoped_ptr<content_settings::RuleIterator> rule_iterator( 583 provider->GetRuleIterator(content_type, 584 resource_identifier, 585 incognito)); 586 while (rule_iterator->HasNext()) { 587 const content_settings::Rule& rule = rule_iterator->Next(); 588 ContentSetting setting_value = CONTENT_SETTING_DEFAULT; 589 // TODO(bauerb): Return rules as a list of values, not content settings. 590 // Handle the case using compound values for its exceptions and arbitrary 591 // values for its default setting. Here we assume all the exceptions 592 // are granted as |CONTENT_SETTING_ALLOW|. 593 if (ContentTypeHasCompoundValue(content_type) && 594 rule.value.get() && 595 rule.primary_pattern != ContentSettingsPattern::Wildcard()) { 596 setting_value = CONTENT_SETTING_ALLOW; 597 } else { 598 setting_value = content_settings::ValueToContentSetting(rule.value.get()); 599 } 600 settings->push_back(ContentSettingPatternSource( 601 rule.primary_pattern, rule.secondary_pattern, 602 setting_value, 603 kProviderNames[provider_type], 604 incognito)); 605 } 606} 607 608void HostContentSettingsMap::UsedContentSettingsProviders() const { 609#ifndef NDEBUG 610 if (used_from_thread_id_ == base::kInvalidThreadId) 611 return; 612 613 if (base::PlatformThread::CurrentId() != used_from_thread_id_) 614 used_from_thread_id_ = base::kInvalidThreadId; 615#endif 616} 617 618bool HostContentSettingsMap::ShouldAllowAllContent( 619 const GURL& primary_url, 620 const GURL& secondary_url, 621 ContentSettingsType content_type) { 622 if (content_type == CONTENT_SETTINGS_TYPE_NOTIFICATIONS || 623 content_type == CONTENT_SETTINGS_TYPE_GEOLOCATION || 624 content_type == CONTENT_SETTINGS_TYPE_MIDI_SYSEX) { 625 return false; 626 } 627#if defined(OS_ANDROID) || defined(OS_CHROMEOS) 628 if (content_type == CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER) { 629 return false; 630 } 631#endif 632 if (secondary_url.SchemeIs(content::kChromeUIScheme) && 633 content_type == CONTENT_SETTINGS_TYPE_COOKIES && 634 primary_url.SchemeIsSecure()) { 635 return true; 636 } 637 if (primary_url.SchemeIs(extensions::kExtensionScheme)) { 638 switch (content_type) { 639 case CONTENT_SETTINGS_TYPE_PLUGINS: 640 case CONTENT_SETTINGS_TYPE_MEDIASTREAM: 641 case CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC: 642 case CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA: 643 return false; 644 case CONTENT_SETTINGS_TYPE_COOKIES: 645 return secondary_url.SchemeIs(extensions::kExtensionScheme); 646 default: 647 return true; 648 } 649 } 650 return primary_url.SchemeIs(content::kChromeDevToolsScheme) || 651 primary_url.SchemeIs(content::kChromeUIScheme); 652} 653 654base::Value* HostContentSettingsMap::GetWebsiteSetting( 655 const GURL& primary_url, 656 const GURL& secondary_url, 657 ContentSettingsType content_type, 658 const std::string& resource_identifier, 659 content_settings::SettingInfo* info) const { 660 DCHECK(SupportsResourceIdentifier(content_type) || 661 resource_identifier.empty()); 662 663 // Check if the scheme of the requesting url is whitelisted. 664 if (ShouldAllowAllContent(primary_url, secondary_url, content_type)) { 665 if (info) { 666 info->source = content_settings::SETTING_SOURCE_WHITELIST; 667 info->primary_pattern = ContentSettingsPattern::Wildcard(); 668 info->secondary_pattern = ContentSettingsPattern::Wildcard(); 669 } 670 return new base::FundamentalValue(CONTENT_SETTING_ALLOW); 671 } 672 673 ContentSettingsPattern* primary_pattern = NULL; 674 ContentSettingsPattern* secondary_pattern = NULL; 675 if (info) { 676 primary_pattern = &info->primary_pattern; 677 secondary_pattern = &info->secondary_pattern; 678 } 679 680 // The list of |content_settings_providers_| is ordered according to their 681 // precedence. 682 for (ConstProviderIterator provider = content_settings_providers_.begin(); 683 provider != content_settings_providers_.end(); 684 ++provider) { 685 base::Value* value = content_settings::GetContentSettingValueAndPatterns( 686 provider->second, primary_url, secondary_url, content_type, 687 resource_identifier, is_off_the_record_, 688 primary_pattern, secondary_pattern); 689 if (value) { 690 if (info) 691 info->source = kProviderSourceMap[provider->first]; 692 return value; 693 } 694 } 695 696 if (info) { 697 info->source = content_settings::SETTING_SOURCE_NONE; 698 info->primary_pattern = ContentSettingsPattern(); 699 info->secondary_pattern = ContentSettingsPattern(); 700 } 701 return NULL; 702} 703 704// static 705HostContentSettingsMap::ProviderType 706 HostContentSettingsMap::GetProviderTypeFromSource( 707 const std::string& source) { 708 for (size_t i = 0; i < arraysize(kProviderNames); ++i) { 709 if (source == kProviderNames[i]) 710 return static_cast<ProviderType>(i); 711 } 712 713 NOTREACHED(); 714 return DEFAULT_PROVIDER; 715} 716 717content_settings::PrefProvider* HostContentSettingsMap::GetPrefProvider() { 718 return static_cast<content_settings::PrefProvider*>( 719 content_settings_providers_[PREF_PROVIDER]); 720} 721