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