host_content_settings_map.cc revision 116680a4aac90f2aa7413d9095a592090648e557
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 = base::Value::CreateIntegerValue(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 = base::Value::CreateIntegerValue(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 and 481 // CONTENT_SETTINGS_TYPE_MEDIASTREAM are of type dictionary/map. Compound 482 // types like dictionaries can't be mapped to the type |ContentSetting|. 483#if defined(OS_ANDROID) 484 if (type == CONTENT_SETTINGS_TYPE_APP_BANNER) 485 return true; 486#endif 487 488 return (type == CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE || 489 type == CONTENT_SETTINGS_TYPE_MEDIASTREAM); 490} 491 492void HostContentSettingsMap::OnContentSettingChanged( 493 const ContentSettingsPattern& primary_pattern, 494 const ContentSettingsPattern& secondary_pattern, 495 ContentSettingsType content_type, 496 std::string resource_identifier) { 497 const ContentSettingsDetails details(primary_pattern, 498 secondary_pattern, 499 content_type, 500 resource_identifier); 501 content::NotificationService::current()->Notify( 502 chrome::NOTIFICATION_CONTENT_SETTINGS_CHANGED, 503 content::Source<HostContentSettingsMap>(this), 504 content::Details<const ContentSettingsDetails>(&details)); 505} 506 507HostContentSettingsMap::~HostContentSettingsMap() { 508 DCHECK(!prefs_); 509 STLDeleteValues(&content_settings_providers_); 510} 511 512void HostContentSettingsMap::ShutdownOnUIThread() { 513 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 514 DCHECK(prefs_); 515 prefs_ = NULL; 516 for (ProviderIterator it = content_settings_providers_.begin(); 517 it != content_settings_providers_.end(); 518 ++it) { 519 it->second->ShutdownOnUIThread(); 520 } 521} 522 523void HostContentSettingsMap::MigrateObsoleteClearOnExitPref() { 524 // Don't migrate more than once. 525 if (prefs_->HasPrefPath(prefs::kContentSettingsClearOnExitMigrated) && 526 prefs_->GetBoolean(prefs::kContentSettingsClearOnExitMigrated)) { 527 return; 528 } 529 530 if (!prefs_->GetBoolean(prefs::kClearSiteDataOnExit)) { 531 // Nothing to be done 532 prefs_->SetBoolean(prefs::kContentSettingsClearOnExitMigrated, true); 533 return; 534 } 535 536 // Change the default cookie settings: 537 // old new 538 // ---------------- ---------------- 539 // ALLOW SESSION_ONLY 540 // SESSION_ONLY SESSION_ONLY 541 // BLOCK BLOCK 542 ContentSetting default_setting = GetDefaultContentSettingFromProvider( 543 CONTENT_SETTINGS_TYPE_COOKIES, 544 content_settings_providers_[DEFAULT_PROVIDER]); 545 if (default_setting == CONTENT_SETTING_ALLOW) { 546 SetDefaultContentSetting( 547 CONTENT_SETTINGS_TYPE_COOKIES, CONTENT_SETTING_SESSION_ONLY); 548 } 549 550 // Change the exceptions using the same rules. 551 ContentSettingsForOneType exceptions; 552 AddSettingsForOneType(content_settings_providers_[PREF_PROVIDER], 553 PREF_PROVIDER, 554 CONTENT_SETTINGS_TYPE_COOKIES, 555 std::string(), 556 &exceptions, 557 false); 558 for (ContentSettingsForOneType::iterator it = exceptions.begin(); 559 it != exceptions.end(); ++it) { 560 if (it->setting != CONTENT_SETTING_ALLOW) 561 continue; 562 SetWebsiteSetting(it->primary_pattern, 563 it->secondary_pattern, 564 CONTENT_SETTINGS_TYPE_COOKIES, 565 std::string(), 566 base::Value::CreateIntegerValue( 567 CONTENT_SETTING_SESSION_ONLY)); 568 } 569 570 prefs_->SetBoolean(prefs::kContentSettingsClearOnExitMigrated, true); 571} 572 573void HostContentSettingsMap::AddSettingsForOneType( 574 const content_settings::ProviderInterface* provider, 575 ProviderType provider_type, 576 ContentSettingsType content_type, 577 const std::string& resource_identifier, 578 ContentSettingsForOneType* settings, 579 bool incognito) const { 580 scoped_ptr<content_settings::RuleIterator> rule_iterator( 581 provider->GetRuleIterator(content_type, 582 resource_identifier, 583 incognito)); 584 while (rule_iterator->HasNext()) { 585 const content_settings::Rule& rule = rule_iterator->Next(); 586 ContentSetting setting_value = CONTENT_SETTING_DEFAULT; 587 // TODO(bauerb): Return rules as a list of values, not content settings. 588 // Handle the case using compound values for its exceptions and arbitrary 589 // values for its default setting. Here we assume all the exceptions 590 // are granted as |CONTENT_SETTING_ALLOW|. 591 if (ContentTypeHasCompoundValue(content_type) && 592 rule.value.get() && 593 rule.primary_pattern != ContentSettingsPattern::Wildcard()) { 594 setting_value = CONTENT_SETTING_ALLOW; 595 } else { 596 setting_value = content_settings::ValueToContentSetting(rule.value.get()); 597 } 598 settings->push_back(ContentSettingPatternSource( 599 rule.primary_pattern, rule.secondary_pattern, 600 setting_value, 601 kProviderNames[provider_type], 602 incognito)); 603 } 604} 605 606void HostContentSettingsMap::UsedContentSettingsProviders() const { 607#ifndef NDEBUG 608 if (used_from_thread_id_ == base::kInvalidThreadId) 609 return; 610 611 if (base::PlatformThread::CurrentId() != used_from_thread_id_) 612 used_from_thread_id_ = base::kInvalidThreadId; 613#endif 614} 615 616bool HostContentSettingsMap::ShouldAllowAllContent( 617 const GURL& primary_url, 618 const GURL& secondary_url, 619 ContentSettingsType content_type) { 620 if (content_type == CONTENT_SETTINGS_TYPE_NOTIFICATIONS || 621 content_type == CONTENT_SETTINGS_TYPE_GEOLOCATION || 622 content_type == CONTENT_SETTINGS_TYPE_MIDI_SYSEX) { 623 return false; 624 } 625#if defined(OS_ANDROID) || defined(OS_CHROMEOS) 626 if (content_type == CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER) { 627 return false; 628 } 629#endif 630 if (secondary_url.SchemeIs(content::kChromeUIScheme) && 631 content_type == CONTENT_SETTINGS_TYPE_COOKIES && 632 primary_url.SchemeIsSecure()) { 633 return true; 634 } 635 if (primary_url.SchemeIs(extensions::kExtensionScheme)) { 636 switch (content_type) { 637 case CONTENT_SETTINGS_TYPE_PLUGINS: 638 case CONTENT_SETTINGS_TYPE_MEDIASTREAM: 639 case CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC: 640 case CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA: 641 return false; 642 case CONTENT_SETTINGS_TYPE_COOKIES: 643 return secondary_url.SchemeIs(extensions::kExtensionScheme); 644 default: 645 return true; 646 } 647 } 648 return primary_url.SchemeIs(content::kChromeDevToolsScheme) || 649 primary_url.SchemeIs(content::kChromeUIScheme); 650} 651 652base::Value* HostContentSettingsMap::GetWebsiteSetting( 653 const GURL& primary_url, 654 const GURL& secondary_url, 655 ContentSettingsType content_type, 656 const std::string& resource_identifier, 657 content_settings::SettingInfo* info) const { 658 DCHECK(SupportsResourceIdentifier(content_type) || 659 resource_identifier.empty()); 660 661 // Check if the scheme of the requesting url is whitelisted. 662 if (ShouldAllowAllContent(primary_url, secondary_url, content_type)) { 663 if (info) { 664 info->source = content_settings::SETTING_SOURCE_WHITELIST; 665 info->primary_pattern = ContentSettingsPattern::Wildcard(); 666 info->secondary_pattern = ContentSettingsPattern::Wildcard(); 667 } 668 return base::Value::CreateIntegerValue(CONTENT_SETTING_ALLOW); 669 } 670 671 ContentSettingsPattern* primary_pattern = NULL; 672 ContentSettingsPattern* secondary_pattern = NULL; 673 if (info) { 674 primary_pattern = &info->primary_pattern; 675 secondary_pattern = &info->secondary_pattern; 676 } 677 678 // The list of |content_settings_providers_| is ordered according to their 679 // precedence. 680 for (ConstProviderIterator provider = content_settings_providers_.begin(); 681 provider != content_settings_providers_.end(); 682 ++provider) { 683 base::Value* value = content_settings::GetContentSettingValueAndPatterns( 684 provider->second, primary_url, secondary_url, content_type, 685 resource_identifier, is_off_the_record_, 686 primary_pattern, secondary_pattern); 687 if (value) { 688 if (info) 689 info->source = kProviderSourceMap[provider->first]; 690 return value; 691 } 692 } 693 694 if (info) { 695 info->source = content_settings::SETTING_SOURCE_NONE; 696 info->primary_pattern = ContentSettingsPattern(); 697 info->secondary_pattern = ContentSettingsPattern(); 698 } 699 return NULL; 700} 701 702// static 703HostContentSettingsMap::ProviderType 704 HostContentSettingsMap::GetProviderTypeFromSource( 705 const std::string& source) { 706 for (size_t i = 0; i < arraysize(kProviderNames); ++i) { 707 if (source == kProviderNames[i]) 708 return static_cast<ProviderType>(i); 709 } 710 711 NOTREACHED(); 712 return DEFAULT_PROVIDER; 713} 714 715content_settings::PrefProvider* HostContentSettingsMap::GetPrefProvider() { 716 return static_cast<content_settings::PrefProvider*>( 717 content_settings_providers_[PREF_PROVIDER]); 718} 719