Update mojo surfaces bindings and mojo/cc/ glue
[chromium-blink-merge.git] / chrome / browser / content_settings / host_content_settings_map.cc
blobf65ccbd2e43f59e6c3439867e8e4093d5e4e20c9
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.
5 #include "chrome/browser/content_settings/host_content_settings_map.h"
7 #include <utility>
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"
45 using base::UserMetricsAction;
46 using content::BrowserThread;
48 namespace {
50 typedef std::vector<content_settings::Rule> Rules;
52 typedef std::pair<std::string, std::string> StringPair;
54 // TODO(bauerb): Expose constants.
55 const char* kProviderNames[] = {
56 "platform_app",
57 "policy",
58 "extension",
59 "preference",
60 "default"
63 content_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,
70 COMPILE_ASSERT(arraysize(kProviderSourceMap) ==
71 HostContentSettingsMap::NUM_PROVIDER_TYPES,
72 kProviderSourceMap_has_incorrect_size);
74 // Returns true if the |content_type| supports a resource identifier.
75 // Resource identifiers are supported (but not required) for plug-ins.
76 bool SupportsResourceIdentifier(ContentSettingsType content_type) {
77 return content_type == CONTENT_SETTINGS_TYPE_PLUGINS;
80 } // namespace
82 HostContentSettingsMap::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;
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;
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;
105 if (!is_off_the_record_) {
106 // Migrate obsolete preferences.
107 MigrateObsoleteClearOnExitPref();
111 #if defined(ENABLE_EXTENSIONS)
112 void 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]);
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;
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;
133 #ifndef NDEBUG
134 DCHECK(used_from_thread_id_ != base::kInvalidThreadId)
135 << "Used from multiple threads before initialization complete.";
136 #endif
138 OnContentSettingChanged(ContentSettingsPattern(),
139 ContentSettingsPattern(),
140 CONTENT_SETTINGS_TYPE_DEFAULT,
141 std::string());
143 #endif
145 // static
146 void HostContentSettingsMap::RegisterProfilePrefs(
147 user_prefs::PrefRegistrySyncable* registry) {
148 registry->RegisterIntegerPref(
149 prefs::kContentSettingsWindowLastTabIndex,
151 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
152 registry->RegisterIntegerPref(
153 prefs::kContentSettingsDefaultWhitelistVersion,
155 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
156 registry->RegisterBooleanPref(
157 prefs::kContentSettingsClearOnExitMigrated,
158 false,
159 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
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);
167 ContentSetting 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));
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());
181 return CONTENT_SETTING_DEFAULT;
184 ContentSetting HostContentSettingsMap::GetDefaultContentSetting(
185 ContentSettingsType content_type,
186 std::string* provider_id) const {
187 UsedContentSettingsProviders();
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;
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;
212 ContentSetting 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());
223 void 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();
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);
246 AddSettingsForOneType(provider->second,
247 provider->first,
248 content_type,
249 resource_identifier,
250 settings,
251 false);
255 void HostContentSettingsMap::SetDefaultContentSetting(
256 ContentSettingsType content_type,
257 ContentSetting setting) {
258 DCHECK(IsSettingAllowedForType(prefs_, setting, content_type));
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);
271 void 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();
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;
293 NOTREACHED();
296 void HostContentSettingsMap::SetNarrowestWebsiteSetting(
297 const ContentSettingsPattern& primary_pattern,
298 const ContentSettingsPattern& secondary_pattern,
299 ContentSettingsType content_type,
300 const std::string& resource_identifier,
301 ContentSetting setting,
302 content_settings::SettingInfo existing_info) {
303 ContentSettingsPattern narrow_primary = primary_pattern;
304 ContentSettingsPattern narrow_secondary = secondary_pattern;
306 DCHECK_EQ(content_settings::SETTING_SOURCE_USER, existing_info.source);
307 ContentSettingsPattern::Relation r1 =
308 existing_info.primary_pattern.Compare(primary_pattern);
309 if (r1 == ContentSettingsPattern::PREDECESSOR) {
310 narrow_primary = existing_info.primary_pattern;
311 } else if (r1 == ContentSettingsPattern::IDENTITY) {
312 ContentSettingsPattern::Relation r2 =
313 existing_info.secondary_pattern.Compare(secondary_pattern);
314 DCHECK(r2 != ContentSettingsPattern::DISJOINT_ORDER_POST &&
315 r2 != ContentSettingsPattern::DISJOINT_ORDER_PRE);
316 if (r2 == ContentSettingsPattern::PREDECESSOR)
317 narrow_secondary = existing_info.secondary_pattern;
320 SetContentSetting(
321 narrow_primary, narrow_secondary, content_type, std::string(), setting);
324 void HostContentSettingsMap::SetContentSetting(
325 const ContentSettingsPattern& primary_pattern,
326 const ContentSettingsPattern& secondary_pattern,
327 ContentSettingsType content_type,
328 const std::string& resource_identifier,
329 ContentSetting setting) {
330 DCHECK(!ContentTypeHasCompoundValue(content_type));
332 if (setting == CONTENT_SETTING_ALLOW &&
333 (content_type == CONTENT_SETTINGS_TYPE_GEOLOCATION ||
334 content_type == CONTENT_SETTINGS_TYPE_NOTIFICATIONS)) {
335 UpdateLastUsageByPattern(primary_pattern, secondary_pattern, content_type);
338 base::Value* value = NULL;
339 if (setting != CONTENT_SETTING_DEFAULT)
340 value = new base::FundamentalValue(setting);
341 SetWebsiteSetting(primary_pattern,
342 secondary_pattern,
343 content_type,
344 resource_identifier,
345 value);
348 ContentSetting HostContentSettingsMap::GetContentSettingAndMaybeUpdateLastUsage(
349 const GURL& primary_url,
350 const GURL& secondary_url,
351 ContentSettingsType content_type,
352 const std::string& resource_identifier) {
353 DCHECK_CURRENTLY_ON(BrowserThread::UI);
355 ContentSetting setting = GetContentSetting(
356 primary_url, secondary_url, content_type, resource_identifier);
357 if (setting == CONTENT_SETTING_ALLOW) {
358 UpdateLastUsageByPattern(
359 ContentSettingsPattern::FromURLNoWildcard(primary_url),
360 ContentSettingsPattern::FromURLNoWildcard(secondary_url),
361 content_type);
363 return setting;
366 void HostContentSettingsMap::UpdateLastUsage(const GURL& primary_url,
367 const GURL& secondary_url,
368 ContentSettingsType content_type) {
369 UpdateLastUsageByPattern(
370 ContentSettingsPattern::FromURLNoWildcard(primary_url),
371 ContentSettingsPattern::FromURLNoWildcard(secondary_url),
372 content_type);
375 void HostContentSettingsMap::UpdateLastUsageByPattern(
376 const ContentSettingsPattern& primary_pattern,
377 const ContentSettingsPattern& secondary_pattern,
378 ContentSettingsType content_type) {
379 UsedContentSettingsProviders();
381 GetPrefProvider()->UpdateLastUsage(
382 primary_pattern, secondary_pattern, content_type);
385 base::Time HostContentSettingsMap::GetLastUsage(
386 const GURL& primary_url,
387 const GURL& secondary_url,
388 ContentSettingsType content_type) {
389 return GetLastUsageByPattern(
390 ContentSettingsPattern::FromURLNoWildcard(primary_url),
391 ContentSettingsPattern::FromURLNoWildcard(secondary_url),
392 content_type);
395 base::Time HostContentSettingsMap::GetLastUsageByPattern(
396 const ContentSettingsPattern& primary_pattern,
397 const ContentSettingsPattern& secondary_pattern,
398 ContentSettingsType content_type) {
399 UsedContentSettingsProviders();
401 return GetPrefProvider()->GetLastUsage(
402 primary_pattern, secondary_pattern, content_type);
405 void HostContentSettingsMap::AddObserver(content_settings::Observer* observer) {
406 observers_.AddObserver(observer);
409 void HostContentSettingsMap::RemoveObserver(
410 content_settings::Observer* observer) {
411 observers_.RemoveObserver(observer);
414 void HostContentSettingsMap::SetPrefClockForTesting(
415 scoped_ptr<base::Clock> clock) {
416 UsedContentSettingsProviders();
418 GetPrefProvider()->SetClockForTesting(clock.Pass());
421 void HostContentSettingsMap::AddExceptionForURL(
422 const GURL& primary_url,
423 const GURL& secondary_url,
424 ContentSettingsType content_type,
425 ContentSetting setting) {
426 // TODO(markusheintz): Until the UI supports pattern pairs, both urls must
427 // match.
428 DCHECK(primary_url == secondary_url);
429 DCHECK(!ContentTypeHasCompoundValue(content_type));
431 // Make sure there is no entry that would override the pattern we are about
432 // to insert for exactly this URL.
433 SetContentSetting(ContentSettingsPattern::FromURLNoWildcard(primary_url),
434 ContentSettingsPattern::Wildcard(),
435 content_type,
436 std::string(),
437 CONTENT_SETTING_DEFAULT);
439 SetContentSetting(ContentSettingsPattern::FromURL(primary_url),
440 ContentSettingsPattern::Wildcard(),
441 content_type,
442 std::string(),
443 setting);
446 void HostContentSettingsMap::ClearSettingsForOneType(
447 ContentSettingsType content_type) {
448 UsedContentSettingsProviders();
449 for (ProviderIterator provider = content_settings_providers_.begin();
450 provider != content_settings_providers_.end();
451 ++provider) {
452 provider->second->ClearAllContentSettingsRules(content_type);
456 bool HostContentSettingsMap::IsValueAllowedForType(
457 PrefService* prefs, const base::Value* value, ContentSettingsType type) {
458 return ContentTypeHasCompoundValue(type) || IsSettingAllowedForType(
459 prefs, content_settings::ValueToContentSetting(value), type);
462 // static
463 bool HostContentSettingsMap::IsSettingAllowedForType(
464 PrefService* prefs,
465 ContentSetting setting,
466 ContentSettingsType content_type) {
467 // We don't yet support stored content settings for mixed scripting.
468 if (content_type == CONTENT_SETTINGS_TYPE_MIXEDSCRIPT)
469 return false;
471 // BLOCK semantics are not implemented for fullscreen.
472 if (content_type == CONTENT_SETTINGS_TYPE_FULLSCREEN &&
473 setting == CONTENT_SETTING_BLOCK) {
474 return false;
477 // We don't support ALLOW for media default setting.
478 if (content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM &&
479 setting == CONTENT_SETTING_ALLOW) {
480 return false;
483 #if defined(OS_ANDROID)
484 // App banners store a dictionary.
485 if (content_type == CONTENT_SETTINGS_TYPE_APP_BANNER)
486 return false;
487 #endif
489 // DEFAULT, ALLOW and BLOCK are always allowed.
490 if (setting == CONTENT_SETTING_DEFAULT ||
491 setting == CONTENT_SETTING_ALLOW ||
492 setting == CONTENT_SETTING_BLOCK) {
493 return true;
495 switch (content_type) {
496 case CONTENT_SETTINGS_TYPE_COOKIES:
497 return setting == CONTENT_SETTING_SESSION_ONLY;
498 case CONTENT_SETTINGS_TYPE_PLUGINS:
499 case CONTENT_SETTINGS_TYPE_GEOLOCATION:
500 case CONTENT_SETTINGS_TYPE_NOTIFICATIONS:
501 case CONTENT_SETTINGS_TYPE_MOUSELOCK:
502 case CONTENT_SETTINGS_TYPE_MEDIASTREAM:
503 case CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC:
504 case CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA:
505 case CONTENT_SETTINGS_TYPE_PPAPI_BROKER:
506 case CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS:
507 case CONTENT_SETTINGS_TYPE_MIDI_SYSEX:
508 return setting == CONTENT_SETTING_ASK;
509 default:
510 return false;
514 // static
515 bool HostContentSettingsMap::ContentTypeHasCompoundValue(
516 ContentSettingsType type) {
517 // Values for content type CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE,
518 // CONTENT_SETTINGS_TYPE_MEDIASTREAM, and
519 // CONTENT_SETTINGS_TYPE_SSL_CERT_DECISIONS are of type dictionary/map.
520 // Compound types like dictionaries can't be mapped to the type
521 // |ContentSetting|.
522 #if defined(OS_ANDROID)
523 if (type == CONTENT_SETTINGS_TYPE_APP_BANNER)
524 return true;
525 #endif
527 return (type == CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE ||
528 type == CONTENT_SETTINGS_TYPE_MEDIASTREAM ||
529 type == CONTENT_SETTINGS_TYPE_SSL_CERT_DECISIONS);
532 void HostContentSettingsMap::OnContentSettingChanged(
533 const ContentSettingsPattern& primary_pattern,
534 const ContentSettingsPattern& secondary_pattern,
535 ContentSettingsType content_type,
536 std::string resource_identifier) {
537 FOR_EACH_OBSERVER(content_settings::Observer,
538 observers_,
539 OnContentSettingChanged(primary_pattern,
540 secondary_pattern,
541 content_type,
542 resource_identifier));
545 HostContentSettingsMap::~HostContentSettingsMap() {
546 DCHECK(!prefs_);
547 STLDeleteValues(&content_settings_providers_);
550 void HostContentSettingsMap::ShutdownOnUIThread() {
551 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
552 DCHECK(prefs_);
553 prefs_ = NULL;
554 for (ProviderIterator it = content_settings_providers_.begin();
555 it != content_settings_providers_.end();
556 ++it) {
557 it->second->ShutdownOnUIThread();
561 void HostContentSettingsMap::MigrateObsoleteClearOnExitPref() {
562 // Don't migrate more than once.
563 if (prefs_->HasPrefPath(prefs::kContentSettingsClearOnExitMigrated) &&
564 prefs_->GetBoolean(prefs::kContentSettingsClearOnExitMigrated)) {
565 return;
568 if (!prefs_->GetBoolean(prefs::kClearSiteDataOnExit)) {
569 // Nothing to be done
570 prefs_->SetBoolean(prefs::kContentSettingsClearOnExitMigrated, true);
571 return;
574 // Change the default cookie settings:
575 // old new
576 // ---------------- ----------------
577 // ALLOW SESSION_ONLY
578 // SESSION_ONLY SESSION_ONLY
579 // BLOCK BLOCK
580 ContentSetting default_setting = GetDefaultContentSettingFromProvider(
581 CONTENT_SETTINGS_TYPE_COOKIES,
582 content_settings_providers_[DEFAULT_PROVIDER]);
583 if (default_setting == CONTENT_SETTING_ALLOW) {
584 SetDefaultContentSetting(
585 CONTENT_SETTINGS_TYPE_COOKIES, CONTENT_SETTING_SESSION_ONLY);
588 // Change the exceptions using the same rules.
589 ContentSettingsForOneType exceptions;
590 AddSettingsForOneType(content_settings_providers_[PREF_PROVIDER],
591 PREF_PROVIDER,
592 CONTENT_SETTINGS_TYPE_COOKIES,
593 std::string(),
594 &exceptions,
595 false);
596 for (ContentSettingsForOneType::iterator it = exceptions.begin();
597 it != exceptions.end(); ++it) {
598 if (it->setting != CONTENT_SETTING_ALLOW)
599 continue;
600 SetWebsiteSetting(it->primary_pattern,
601 it->secondary_pattern,
602 CONTENT_SETTINGS_TYPE_COOKIES,
603 std::string(),
604 new base::FundamentalValue(CONTENT_SETTING_SESSION_ONLY));
607 prefs_->SetBoolean(prefs::kContentSettingsClearOnExitMigrated, true);
610 void HostContentSettingsMap::AddSettingsForOneType(
611 const content_settings::ProviderInterface* provider,
612 ProviderType provider_type,
613 ContentSettingsType content_type,
614 const std::string& resource_identifier,
615 ContentSettingsForOneType* settings,
616 bool incognito) const {
617 scoped_ptr<content_settings::RuleIterator> rule_iterator(
618 provider->GetRuleIterator(content_type,
619 resource_identifier,
620 incognito));
621 while (rule_iterator->HasNext()) {
622 const content_settings::Rule& rule = rule_iterator->Next();
623 ContentSetting setting_value = CONTENT_SETTING_DEFAULT;
624 // TODO(bauerb): Return rules as a list of values, not content settings.
625 // Handle the case using compound values for its exceptions and arbitrary
626 // values for its default setting. Here we assume all the exceptions
627 // are granted as |CONTENT_SETTING_ALLOW|.
628 if (ContentTypeHasCompoundValue(content_type) &&
629 rule.value.get() &&
630 rule.primary_pattern != ContentSettingsPattern::Wildcard()) {
631 setting_value = CONTENT_SETTING_ALLOW;
632 } else {
633 setting_value = content_settings::ValueToContentSetting(rule.value.get());
635 settings->push_back(ContentSettingPatternSource(
636 rule.primary_pattern, rule.secondary_pattern,
637 setting_value,
638 kProviderNames[provider_type],
639 incognito));
643 void HostContentSettingsMap::UsedContentSettingsProviders() const {
644 #ifndef NDEBUG
645 if (used_from_thread_id_ == base::kInvalidThreadId)
646 return;
648 if (base::PlatformThread::CurrentId() != used_from_thread_id_)
649 used_from_thread_id_ = base::kInvalidThreadId;
650 #endif
653 bool HostContentSettingsMap::ShouldAllowAllContent(
654 const GURL& primary_url,
655 const GURL& secondary_url,
656 ContentSettingsType content_type) {
657 if (content_type == CONTENT_SETTINGS_TYPE_NOTIFICATIONS ||
658 content_type == CONTENT_SETTINGS_TYPE_GEOLOCATION ||
659 content_type == CONTENT_SETTINGS_TYPE_MIDI_SYSEX) {
660 return false;
662 #if defined(OS_ANDROID) || defined(OS_CHROMEOS)
663 if (content_type == CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER) {
664 return false;
666 #endif
667 if (secondary_url.SchemeIs(content::kChromeUIScheme) &&
668 content_type == CONTENT_SETTINGS_TYPE_COOKIES &&
669 primary_url.SchemeIsSecure()) {
670 return true;
672 if (primary_url.SchemeIs(extensions::kExtensionScheme)) {
673 switch (content_type) {
674 case CONTENT_SETTINGS_TYPE_PLUGINS:
675 case CONTENT_SETTINGS_TYPE_MEDIASTREAM:
676 case CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC:
677 case CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA:
678 return false;
679 case CONTENT_SETTINGS_TYPE_COOKIES:
680 return secondary_url.SchemeIs(extensions::kExtensionScheme);
681 default:
682 return true;
685 return primary_url.SchemeIs(content::kChromeDevToolsScheme) ||
686 primary_url.SchemeIs(content::kChromeUIScheme);
689 base::Value* HostContentSettingsMap::GetWebsiteSetting(
690 const GURL& primary_url,
691 const GURL& secondary_url,
692 ContentSettingsType content_type,
693 const std::string& resource_identifier,
694 content_settings::SettingInfo* info) const {
695 DCHECK(SupportsResourceIdentifier(content_type) ||
696 resource_identifier.empty());
698 // Check if the scheme of the requesting url is whitelisted.
699 if (ShouldAllowAllContent(primary_url, secondary_url, content_type)) {
700 if (info) {
701 info->source = content_settings::SETTING_SOURCE_WHITELIST;
702 info->primary_pattern = ContentSettingsPattern::Wildcard();
703 info->secondary_pattern = ContentSettingsPattern::Wildcard();
705 return new base::FundamentalValue(CONTENT_SETTING_ALLOW);
708 ContentSettingsPattern* primary_pattern = NULL;
709 ContentSettingsPattern* secondary_pattern = NULL;
710 if (info) {
711 primary_pattern = &info->primary_pattern;
712 secondary_pattern = &info->secondary_pattern;
715 // The list of |content_settings_providers_| is ordered according to their
716 // precedence.
717 for (ConstProviderIterator provider = content_settings_providers_.begin();
718 provider != content_settings_providers_.end();
719 ++provider) {
720 base::Value* value = content_settings::GetContentSettingValueAndPatterns(
721 provider->second, primary_url, secondary_url, content_type,
722 resource_identifier, is_off_the_record_,
723 primary_pattern, secondary_pattern);
724 if (value) {
725 if (info)
726 info->source = kProviderSourceMap[provider->first];
727 return value;
731 if (info) {
732 info->source = content_settings::SETTING_SOURCE_NONE;
733 info->primary_pattern = ContentSettingsPattern();
734 info->secondary_pattern = ContentSettingsPattern();
736 return NULL;
739 // static
740 HostContentSettingsMap::ProviderType
741 HostContentSettingsMap::GetProviderTypeFromSource(
742 const std::string& source) {
743 for (size_t i = 0; i < arraysize(kProviderNames); ++i) {
744 if (source == kProviderNames[i])
745 return static_cast<ProviderType>(i);
748 NOTREACHED();
749 return DEFAULT_PROVIDER;
752 content_settings::PrefProvider* HostContentSettingsMap::GetPrefProvider() {
753 return static_cast<content_settings::PrefProvider*>(
754 content_settings_providers_[PREF_PROVIDER]);