Adding instrumentation to locate the source of jankiness
[chromium-blink-merge.git] / chrome / browser / content_settings / host_content_settings_map.cc
blobd0bb869ca3b5f0206fe6bfe32704536541b70497
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/content_settings/content_settings_default_provider.h"
17 #include "chrome/browser/content_settings/content_settings_policy_provider.h"
18 #include "chrome/browser/content_settings/content_settings_pref_provider.h"
19 #include "chrome/browser/content_settings/content_settings_utils.h"
20 #include "chrome/common/chrome_switches.h"
21 #include "chrome/common/pref_names.h"
22 #include "chrome/common/url_constants.h"
23 #include "components/content_settings/core/browser/content_settings_details.h"
24 #include "components/content_settings/core/browser/content_settings_observable_provider.h"
25 #include "components/content_settings/core/browser/content_settings_provider.h"
26 #include "components/content_settings/core/browser/content_settings_rule.h"
27 #include "components/content_settings/core/common/content_settings_pattern.h"
28 #include "components/pref_registry/pref_registry_syncable.h"
29 #include "content/public/browser/browser_thread.h"
30 #include "net/base/net_errors.h"
31 #include "net/base/static_cookie_policy.h"
32 #include "url/gurl.h"
34 #if defined(ENABLE_EXTENSIONS)
35 #include "extensions/common/constants.h"
36 #endif
38 using content::BrowserThread;
40 namespace {
42 typedef std::vector<content_settings::Rule> Rules;
44 typedef std::pair<std::string, std::string> StringPair;
46 // TODO(bauerb): Expose constants.
47 const char* kProviderNames[] = {
48 "platform_app",
49 "policy",
50 "extension",
51 "override",
52 "preference",
53 "default"
56 content_settings::SettingSource kProviderSourceMap[] = {
57 content_settings::SETTING_SOURCE_EXTENSION,
58 content_settings::SETTING_SOURCE_POLICY,
59 content_settings::SETTING_SOURCE_EXTENSION,
60 content_settings::SETTING_SOURCE_USER,
61 content_settings::SETTING_SOURCE_USER,
62 content_settings::SETTING_SOURCE_USER,
64 COMPILE_ASSERT(arraysize(kProviderSourceMap) ==
65 HostContentSettingsMap::NUM_PROVIDER_TYPES,
66 kProviderSourceMap_has_incorrect_size);
68 // Returns true if the |content_type| supports a resource identifier.
69 // Resource identifiers are supported (but not required) for plug-ins.
70 bool SupportsResourceIdentifier(ContentSettingsType content_type) {
71 return content_type == CONTENT_SETTINGS_TYPE_PLUGINS;
74 } // namespace
76 HostContentSettingsMap::HostContentSettingsMap(PrefService* prefs,
77 bool incognito)
79 #ifndef NDEBUG
80 used_from_thread_id_(base::PlatformThread::CurrentId()),
81 #endif
82 prefs_(prefs),
83 is_off_the_record_(incognito) {
84 content_settings::ObservableProvider* policy_provider =
85 new content_settings::PolicyProvider(prefs_);
86 policy_provider->AddObserver(this);
87 content_settings_providers_[POLICY_PROVIDER] = policy_provider;
89 content_settings::ObservableProvider* pref_provider =
90 new content_settings::PrefProvider(prefs_, is_off_the_record_);
91 pref_provider->AddObserver(this);
92 content_settings_providers_[PREF_PROVIDER] = pref_provider;
94 content_settings::ObservableProvider* default_provider =
95 new content_settings::DefaultProvider(prefs_, is_off_the_record_);
96 default_provider->AddObserver(this);
97 content_settings_providers_[DEFAULT_PROVIDER] = default_provider;
99 content_settings_providers_[OVERRIDE_PROVIDER] =
100 new content_settings::OverrideProvider(prefs_, is_off_the_record_);
102 if (!is_off_the_record_) {
103 // Migrate obsolete preferences.
104 MigrateObsoleteClearOnExitPref();
108 // static
109 void HostContentSettingsMap::RegisterProfilePrefs(
110 user_prefs::PrefRegistrySyncable* registry) {
111 registry->RegisterIntegerPref(
112 prefs::kContentSettingsWindowLastTabIndex,
114 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
115 registry->RegisterBooleanPref(
116 prefs::kContentSettingsClearOnExitMigrated,
117 false,
118 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
120 // Register the prefs for the content settings providers.
121 content_settings::DefaultProvider::RegisterProfilePrefs(registry);
122 content_settings::PrefProvider::RegisterProfilePrefs(registry);
123 content_settings::PolicyProvider::RegisterProfilePrefs(registry);
124 content_settings::OverrideProvider::RegisterProfilePrefs(registry);
127 void HostContentSettingsMap::RegisterProvider(
128 ProviderType type,
129 scoped_ptr<content_settings::ObservableProvider> provider) {
130 DCHECK(!content_settings_providers_[type]);
131 provider->AddObserver(this);
132 content_settings_providers_[type] = provider.release();
134 #ifndef NDEBUG
135 DCHECK_NE(used_from_thread_id_, base::kInvalidThreadId)
136 << "Used from multiple threads before initialization complete.";
137 #endif
139 OnContentSettingChanged(ContentSettingsPattern(),
140 ContentSettingsPattern(),
141 CONTENT_SETTINGS_TYPE_DEFAULT,
142 std::string());
145 ContentSetting HostContentSettingsMap::GetDefaultContentSettingFromProvider(
146 ContentSettingsType content_type,
147 content_settings::ProviderInterface* provider) const {
148 scoped_ptr<content_settings::RuleIterator> rule_iterator(
149 provider->GetRuleIterator(content_type, std::string(), false));
151 ContentSettingsPattern wildcard = ContentSettingsPattern::Wildcard();
152 while (rule_iterator->HasNext()) {
153 content_settings::Rule rule = rule_iterator->Next();
154 if (rule.primary_pattern == wildcard &&
155 rule.secondary_pattern == wildcard) {
156 return content_settings::ValueToContentSetting(rule.value.get());
159 return CONTENT_SETTING_DEFAULT;
162 ContentSetting HostContentSettingsMap::GetDefaultContentSetting(
163 ContentSettingsType content_type,
164 std::string* provider_id) const {
165 UsedContentSettingsProviders();
167 // Iterate through the list of providers and return the first non-NULL value
168 // that matches |primary_url| and |secondary_url|.
169 for (ConstProviderIterator provider = content_settings_providers_.begin();
170 provider != content_settings_providers_.end();
171 ++provider) {
172 if (provider->first == PREF_PROVIDER ||
173 provider->first == OVERRIDE_PROVIDER)
174 continue;
175 ContentSetting default_setting =
176 GetDefaultContentSettingFromProvider(content_type, provider->second);
177 if (default_setting != CONTENT_SETTING_DEFAULT) {
178 if (provider_id)
179 *provider_id = kProviderNames[provider->first];
180 return default_setting;
184 return CONTENT_SETTING_DEFAULT;
187 ContentSetting HostContentSettingsMap::GetContentSetting(
188 const GURL& primary_url,
189 const GURL& secondary_url,
190 ContentSettingsType content_type,
191 const std::string& resource_identifier) const {
192 DCHECK(!ContentTypeHasCompoundValue(content_type));
193 scoped_ptr<base::Value> value = GetWebsiteSetting(
194 primary_url, secondary_url, content_type, resource_identifier, NULL);
195 return content_settings::ValueToContentSetting(value.get());
198 void HostContentSettingsMap::GetSettingsForOneType(
199 ContentSettingsType content_type,
200 const std::string& resource_identifier,
201 ContentSettingsForOneType* settings) const {
202 DCHECK(SupportsResourceIdentifier(content_type) ||
203 resource_identifier.empty());
204 DCHECK(settings);
205 UsedContentSettingsProviders();
207 settings->clear();
208 for (ConstProviderIterator provider = content_settings_providers_.begin();
209 provider != content_settings_providers_.end();
210 ++provider) {
211 if (provider->first == OVERRIDE_PROVIDER)
212 continue;
213 // For each provider, iterate first the incognito-specific rules, then the
214 // normal rules.
215 if (is_off_the_record_) {
216 AddSettingsForOneType(provider->second,
217 provider->first,
218 content_type,
219 resource_identifier,
220 settings,
221 true);
223 AddSettingsForOneType(provider->second,
224 provider->first,
225 content_type,
226 resource_identifier,
227 settings,
228 false);
232 void HostContentSettingsMap::SetDefaultContentSetting(
233 ContentSettingsType content_type,
234 ContentSetting setting) {
235 DCHECK(IsSettingAllowedForType(prefs_, setting, content_type));
237 base::Value* value = NULL;
238 if (setting != CONTENT_SETTING_DEFAULT)
239 value = new base::FundamentalValue(setting);
240 SetWebsiteSetting(
241 ContentSettingsPattern::Wildcard(),
242 ContentSettingsPattern::Wildcard(),
243 content_type,
244 std::string(),
245 value);
248 void HostContentSettingsMap::SetWebsiteSetting(
249 const ContentSettingsPattern& primary_pattern,
250 const ContentSettingsPattern& secondary_pattern,
251 ContentSettingsType content_type,
252 const std::string& resource_identifier,
253 base::Value* value) {
254 DCHECK(IsValueAllowedForType(prefs_, value, content_type));
255 DCHECK(SupportsResourceIdentifier(content_type) ||
256 resource_identifier.empty());
257 UsedContentSettingsProviders();
259 for (ProviderIterator provider = content_settings_providers_.begin();
260 provider != content_settings_providers_.end();
261 ++provider) {
262 if (provider->second->SetWebsiteSetting(primary_pattern,
263 secondary_pattern,
264 content_type,
265 resource_identifier,
266 value)) {
267 return;
270 NOTREACHED();
273 void HostContentSettingsMap::SetNarrowestWebsiteSetting(
274 const ContentSettingsPattern& primary_pattern,
275 const ContentSettingsPattern& secondary_pattern,
276 ContentSettingsType content_type,
277 const std::string& resource_identifier,
278 ContentSetting setting,
279 content_settings::SettingInfo existing_info) {
280 ContentSettingsPattern narrow_primary = primary_pattern;
281 ContentSettingsPattern narrow_secondary = secondary_pattern;
283 DCHECK_EQ(content_settings::SETTING_SOURCE_USER, existing_info.source);
284 ContentSettingsPattern::Relation r1 =
285 existing_info.primary_pattern.Compare(primary_pattern);
286 if (r1 == ContentSettingsPattern::PREDECESSOR) {
287 narrow_primary = existing_info.primary_pattern;
288 } else if (r1 == ContentSettingsPattern::IDENTITY) {
289 ContentSettingsPattern::Relation r2 =
290 existing_info.secondary_pattern.Compare(secondary_pattern);
291 DCHECK(r2 != ContentSettingsPattern::DISJOINT_ORDER_POST &&
292 r2 != ContentSettingsPattern::DISJOINT_ORDER_PRE);
293 if (r2 == ContentSettingsPattern::PREDECESSOR)
294 narrow_secondary = existing_info.secondary_pattern;
297 SetContentSetting(
298 narrow_primary, narrow_secondary, content_type, std::string(), setting);
301 void HostContentSettingsMap::SetContentSetting(
302 const ContentSettingsPattern& primary_pattern,
303 const ContentSettingsPattern& secondary_pattern,
304 ContentSettingsType content_type,
305 const std::string& resource_identifier,
306 ContentSetting setting) {
307 DCHECK(!ContentTypeHasCompoundValue(content_type));
309 if (setting == CONTENT_SETTING_ALLOW &&
310 (content_type == CONTENT_SETTINGS_TYPE_GEOLOCATION ||
311 content_type == CONTENT_SETTINGS_TYPE_NOTIFICATIONS)) {
312 UpdateLastUsageByPattern(primary_pattern, secondary_pattern, content_type);
315 base::Value* value = NULL;
316 if (setting != CONTENT_SETTING_DEFAULT)
317 value = new base::FundamentalValue(setting);
318 SetWebsiteSetting(primary_pattern,
319 secondary_pattern,
320 content_type,
321 resource_identifier,
322 value);
325 ContentSetting HostContentSettingsMap::GetContentSettingAndMaybeUpdateLastUsage(
326 const GURL& primary_url,
327 const GURL& secondary_url,
328 ContentSettingsType content_type,
329 const std::string& resource_identifier) {
330 DCHECK_CURRENTLY_ON(BrowserThread::UI);
332 ContentSetting setting = GetContentSetting(
333 primary_url, secondary_url, content_type, resource_identifier);
334 if (setting == CONTENT_SETTING_ALLOW) {
335 UpdateLastUsageByPattern(
336 ContentSettingsPattern::FromURLNoWildcard(primary_url),
337 ContentSettingsPattern::FromURLNoWildcard(secondary_url),
338 content_type);
340 return setting;
343 void HostContentSettingsMap::UpdateLastUsage(const GURL& primary_url,
344 const GURL& secondary_url,
345 ContentSettingsType content_type) {
346 UpdateLastUsageByPattern(
347 ContentSettingsPattern::FromURLNoWildcard(primary_url),
348 ContentSettingsPattern::FromURLNoWildcard(secondary_url),
349 content_type);
352 void HostContentSettingsMap::UpdateLastUsageByPattern(
353 const ContentSettingsPattern& primary_pattern,
354 const ContentSettingsPattern& secondary_pattern,
355 ContentSettingsType content_type) {
356 UsedContentSettingsProviders();
358 GetPrefProvider()->UpdateLastUsage(
359 primary_pattern, secondary_pattern, content_type);
361 FOR_EACH_OBSERVER(
362 content_settings::Observer,
363 observers_,
364 OnContentSettingUsed(primary_pattern, secondary_pattern, content_type));
367 base::Time HostContentSettingsMap::GetLastUsage(
368 const GURL& primary_url,
369 const GURL& secondary_url,
370 ContentSettingsType content_type) {
371 return GetLastUsageByPattern(
372 ContentSettingsPattern::FromURLNoWildcard(primary_url),
373 ContentSettingsPattern::FromURLNoWildcard(secondary_url),
374 content_type);
377 base::Time HostContentSettingsMap::GetLastUsageByPattern(
378 const ContentSettingsPattern& primary_pattern,
379 const ContentSettingsPattern& secondary_pattern,
380 ContentSettingsType content_type) {
381 UsedContentSettingsProviders();
383 return GetPrefProvider()->GetLastUsage(
384 primary_pattern, secondary_pattern, content_type);
387 ContentSetting HostContentSettingsMap::GetContentSettingWithoutOverride(
388 const GURL& primary_url,
389 const GURL& secondary_url,
390 ContentSettingsType content_type,
391 const std::string& resource_identifier) {
392 scoped_ptr<base::Value> value(GetWebsiteSettingWithoutOverride(
393 primary_url, secondary_url, content_type, resource_identifier, NULL));
394 return content_settings::ValueToContentSetting(value.get());
397 scoped_ptr<base::Value>
398 HostContentSettingsMap::GetWebsiteSettingWithoutOverride(
399 const GURL& primary_url,
400 const GURL& secondary_url,
401 ContentSettingsType content_type,
402 const std::string& resource_identifier,
403 content_settings::SettingInfo* info) const {
404 return GetWebsiteSettingInternal(primary_url,
405 secondary_url,
406 content_type,
407 resource_identifier,
408 info,
409 false);
412 void HostContentSettingsMap::SetContentSettingOverride(
413 ContentSettingsType content_type,
414 bool is_enabled) {
415 UsedContentSettingsProviders();
417 content_settings::OverrideProvider* override =
418 static_cast<content_settings::OverrideProvider*>(
419 content_settings_providers_[OVERRIDE_PROVIDER]);
420 override->SetOverrideSetting(content_type, is_enabled);
423 bool HostContentSettingsMap::GetContentSettingOverride(
424 ContentSettingsType content_type) {
425 UsedContentSettingsProviders();
427 content_settings::OverrideProvider* override =
428 static_cast<content_settings::OverrideProvider*>(
429 content_settings_providers_[OVERRIDE_PROVIDER]);
430 return override->IsEnabled(content_type);
433 void HostContentSettingsMap::AddObserver(content_settings::Observer* observer) {
434 observers_.AddObserver(observer);
437 void HostContentSettingsMap::RemoveObserver(
438 content_settings::Observer* observer) {
439 observers_.RemoveObserver(observer);
442 void HostContentSettingsMap::SetPrefClockForTesting(
443 scoped_ptr<base::Clock> clock) {
444 UsedContentSettingsProviders();
446 GetPrefProvider()->SetClockForTesting(clock.Pass());
449 void HostContentSettingsMap::AddExceptionForURL(
450 const GURL& primary_url,
451 const GURL& secondary_url,
452 ContentSettingsType content_type,
453 ContentSetting setting) {
454 // TODO(markusheintz): Until the UI supports pattern pairs, both urls must
455 // match.
456 DCHECK(primary_url == secondary_url);
457 DCHECK(!ContentTypeHasCompoundValue(content_type));
459 // Make sure there is no entry that would override the pattern we are about
460 // to insert for exactly this URL.
461 SetContentSetting(ContentSettingsPattern::FromURLNoWildcard(primary_url),
462 ContentSettingsPattern::Wildcard(),
463 content_type,
464 std::string(),
465 CONTENT_SETTING_DEFAULT);
467 SetContentSetting(ContentSettingsPattern::FromURL(primary_url),
468 ContentSettingsPattern::Wildcard(),
469 content_type,
470 std::string(),
471 setting);
474 void HostContentSettingsMap::ClearSettingsForOneType(
475 ContentSettingsType content_type) {
476 UsedContentSettingsProviders();
477 for (ProviderIterator provider = content_settings_providers_.begin();
478 provider != content_settings_providers_.end();
479 ++provider) {
480 provider->second->ClearAllContentSettingsRules(content_type);
484 bool HostContentSettingsMap::IsValueAllowedForType(
485 PrefService* prefs, const base::Value* value, ContentSettingsType type) {
486 return ContentTypeHasCompoundValue(type) || IsSettingAllowedForType(
487 prefs, content_settings::ValueToContentSetting(value), type);
490 // static
491 bool HostContentSettingsMap::IsSettingAllowedForType(
492 PrefService* prefs,
493 ContentSetting setting,
494 ContentSettingsType content_type) {
495 // We don't yet support stored content settings for mixed scripting.
496 if (content_type == CONTENT_SETTINGS_TYPE_MIXEDSCRIPT)
497 return false;
499 // BLOCK semantics are not implemented for fullscreen.
500 if (content_type == CONTENT_SETTINGS_TYPE_FULLSCREEN &&
501 setting == CONTENT_SETTING_BLOCK) {
502 return false;
505 // We don't support ALLOW for media default setting.
506 if (content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM &&
507 setting == CONTENT_SETTING_ALLOW) {
508 return false;
511 #if defined(OS_ANDROID)
512 // App banners store a dictionary.
513 if (content_type == CONTENT_SETTINGS_TYPE_APP_BANNER)
514 return false;
515 #endif
517 // DEFAULT, ALLOW and BLOCK are always allowed.
518 if (setting == CONTENT_SETTING_DEFAULT ||
519 setting == CONTENT_SETTING_ALLOW ||
520 setting == CONTENT_SETTING_BLOCK) {
521 return true;
523 switch (content_type) {
524 case CONTENT_SETTINGS_TYPE_COOKIES:
525 return setting == CONTENT_SETTING_SESSION_ONLY;
526 case CONTENT_SETTINGS_TYPE_PLUGINS:
527 case CONTENT_SETTINGS_TYPE_GEOLOCATION:
528 case CONTENT_SETTINGS_TYPE_NOTIFICATIONS:
529 case CONTENT_SETTINGS_TYPE_MOUSELOCK:
530 case CONTENT_SETTINGS_TYPE_MEDIASTREAM:
531 case CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC:
532 case CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA:
533 case CONTENT_SETTINGS_TYPE_PPAPI_BROKER:
534 case CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS:
535 case CONTENT_SETTINGS_TYPE_MIDI_SYSEX:
536 return setting == CONTENT_SETTING_ASK;
537 default:
538 return false;
542 // static
543 bool HostContentSettingsMap::ContentTypeHasCompoundValue(
544 ContentSettingsType type) {
545 // Values for content type CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE,
546 // CONTENT_SETTINGS_TYPE_MEDIASTREAM, and
547 // CONTENT_SETTINGS_TYPE_SSL_CERT_DECISIONS are of type dictionary/map.
548 // Compound types like dictionaries can't be mapped to the type
549 // |ContentSetting|.
550 #if defined(OS_ANDROID)
551 if (type == CONTENT_SETTINGS_TYPE_APP_BANNER)
552 return true;
553 #endif
555 return (type == CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE ||
556 type == CONTENT_SETTINGS_TYPE_MEDIASTREAM ||
557 type == CONTENT_SETTINGS_TYPE_SSL_CERT_DECISIONS);
560 void HostContentSettingsMap::OnContentSettingChanged(
561 const ContentSettingsPattern& primary_pattern,
562 const ContentSettingsPattern& secondary_pattern,
563 ContentSettingsType content_type,
564 std::string resource_identifier) {
565 FOR_EACH_OBSERVER(content_settings::Observer,
566 observers_,
567 OnContentSettingChanged(primary_pattern,
568 secondary_pattern,
569 content_type,
570 resource_identifier));
573 HostContentSettingsMap::~HostContentSettingsMap() {
574 DCHECK(!prefs_);
575 STLDeleteValues(&content_settings_providers_);
578 void HostContentSettingsMap::ShutdownOnUIThread() {
579 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
580 DCHECK(prefs_);
581 prefs_ = NULL;
582 for (ProviderIterator it = content_settings_providers_.begin();
583 it != content_settings_providers_.end();
584 ++it) {
585 it->second->ShutdownOnUIThread();
589 void HostContentSettingsMap::MigrateObsoleteClearOnExitPref() {
590 // Don't migrate more than once.
591 if (prefs_->HasPrefPath(prefs::kContentSettingsClearOnExitMigrated) &&
592 prefs_->GetBoolean(prefs::kContentSettingsClearOnExitMigrated)) {
593 return;
596 if (!prefs_->GetBoolean(prefs::kClearSiteDataOnExit)) {
597 // Nothing to be done
598 prefs_->SetBoolean(prefs::kContentSettingsClearOnExitMigrated, true);
599 return;
602 // Change the default cookie settings:
603 // old new
604 // ---------------- ----------------
605 // ALLOW SESSION_ONLY
606 // SESSION_ONLY SESSION_ONLY
607 // BLOCK BLOCK
608 ContentSetting default_setting = GetDefaultContentSettingFromProvider(
609 CONTENT_SETTINGS_TYPE_COOKIES,
610 content_settings_providers_[DEFAULT_PROVIDER]);
611 if (default_setting == CONTENT_SETTING_ALLOW) {
612 SetDefaultContentSetting(
613 CONTENT_SETTINGS_TYPE_COOKIES, CONTENT_SETTING_SESSION_ONLY);
616 // Change the exceptions using the same rules.
617 ContentSettingsForOneType exceptions;
618 AddSettingsForOneType(content_settings_providers_[PREF_PROVIDER],
619 PREF_PROVIDER,
620 CONTENT_SETTINGS_TYPE_COOKIES,
621 std::string(),
622 &exceptions,
623 false);
624 for (ContentSettingsForOneType::iterator it = exceptions.begin();
625 it != exceptions.end(); ++it) {
626 if (it->setting != CONTENT_SETTING_ALLOW)
627 continue;
628 SetWebsiteSetting(it->primary_pattern,
629 it->secondary_pattern,
630 CONTENT_SETTINGS_TYPE_COOKIES,
631 std::string(),
632 new base::FundamentalValue(CONTENT_SETTING_SESSION_ONLY));
635 prefs_->SetBoolean(prefs::kContentSettingsClearOnExitMigrated, true);
638 void HostContentSettingsMap::AddSettingsForOneType(
639 const content_settings::ProviderInterface* provider,
640 ProviderType provider_type,
641 ContentSettingsType content_type,
642 const std::string& resource_identifier,
643 ContentSettingsForOneType* settings,
644 bool incognito) const {
645 scoped_ptr<content_settings::RuleIterator> rule_iterator(
646 provider->GetRuleIterator(content_type,
647 resource_identifier,
648 incognito));
649 while (rule_iterator->HasNext()) {
650 const content_settings::Rule& rule = rule_iterator->Next();
651 ContentSetting setting_value = CONTENT_SETTING_DEFAULT;
652 // TODO(bauerb): Return rules as a list of values, not content settings.
653 // Handle the case using compound values for its exceptions and arbitrary
654 // values for its default setting. Here we assume all the exceptions
655 // are granted as |CONTENT_SETTING_ALLOW|.
656 if (ContentTypeHasCompoundValue(content_type) &&
657 rule.value.get() &&
658 rule.primary_pattern != ContentSettingsPattern::Wildcard()) {
659 setting_value = CONTENT_SETTING_ALLOW;
660 } else {
661 setting_value = content_settings::ValueToContentSetting(rule.value.get());
663 settings->push_back(ContentSettingPatternSource(
664 rule.primary_pattern, rule.secondary_pattern,
665 setting_value,
666 kProviderNames[provider_type],
667 incognito));
671 void HostContentSettingsMap::UsedContentSettingsProviders() const {
672 #ifndef NDEBUG
673 if (used_from_thread_id_ == base::kInvalidThreadId)
674 return;
676 if (base::PlatformThread::CurrentId() != used_from_thread_id_)
677 used_from_thread_id_ = base::kInvalidThreadId;
678 #endif
681 bool HostContentSettingsMap::ShouldAllowAllContent(
682 const GURL& primary_url,
683 const GURL& secondary_url,
684 ContentSettingsType content_type) {
685 if (content_type == CONTENT_SETTINGS_TYPE_NOTIFICATIONS ||
686 content_type == CONTENT_SETTINGS_TYPE_GEOLOCATION ||
687 content_type == CONTENT_SETTINGS_TYPE_MIDI_SYSEX) {
688 return false;
690 #if defined(OS_ANDROID) || defined(OS_CHROMEOS)
691 if (content_type == CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER) {
692 return false;
694 #endif
695 if (secondary_url.SchemeIs(content::kChromeUIScheme) &&
696 content_type == CONTENT_SETTINGS_TYPE_COOKIES &&
697 primary_url.SchemeIsSecure()) {
698 return true;
700 #if defined(ENABLE_EXTENSIONS)
701 if (primary_url.SchemeIs(extensions::kExtensionScheme)) {
702 switch (content_type) {
703 case CONTENT_SETTINGS_TYPE_PLUGINS:
704 case CONTENT_SETTINGS_TYPE_MEDIASTREAM:
705 case CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC:
706 case CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA:
707 return false;
708 case CONTENT_SETTINGS_TYPE_COOKIES:
709 return secondary_url.SchemeIs(extensions::kExtensionScheme);
710 default:
711 return true;
714 #endif
715 return primary_url.SchemeIs(content::kChromeDevToolsScheme) ||
716 primary_url.SchemeIs(content::kChromeUIScheme);
719 scoped_ptr<base::Value> HostContentSettingsMap::GetWebsiteSetting(
720 const GURL& primary_url,
721 const GURL& secondary_url,
722 ContentSettingsType content_type,
723 const std::string& resource_identifier,
724 content_settings::SettingInfo* info) const {
725 DCHECK(SupportsResourceIdentifier(content_type) ||
726 resource_identifier.empty());
728 // Check if the scheme of the requesting url is whitelisted.
729 if (ShouldAllowAllContent(primary_url, secondary_url, content_type)) {
730 if (info) {
731 info->source = content_settings::SETTING_SOURCE_WHITELIST;
732 info->primary_pattern = ContentSettingsPattern::Wildcard();
733 info->secondary_pattern = ContentSettingsPattern::Wildcard();
735 return scoped_ptr<base::Value>(
736 new base::FundamentalValue(CONTENT_SETTING_ALLOW));
739 return GetWebsiteSettingInternal(primary_url,
740 secondary_url,
741 content_type,
742 resource_identifier,
743 info,
744 true);
747 // static
748 HostContentSettingsMap::ProviderType
749 HostContentSettingsMap::GetProviderTypeFromSource(const std::string& source) {
750 for (size_t i = 0; i < arraysize(kProviderNames); ++i) {
751 if (source == kProviderNames[i])
752 return static_cast<ProviderType>(i);
755 NOTREACHED();
756 return DEFAULT_PROVIDER;
759 content_settings::PrefProvider* HostContentSettingsMap::GetPrefProvider() {
760 return static_cast<content_settings::PrefProvider*>(
761 content_settings_providers_[PREF_PROVIDER]);
764 scoped_ptr<base::Value> HostContentSettingsMap::GetWebsiteSettingInternal(
765 const GURL& primary_url,
766 const GURL& secondary_url,
767 ContentSettingsType content_type,
768 const std::string& resource_identifier,
769 content_settings::SettingInfo* info,
770 bool get_override) const {
771 UsedContentSettingsProviders();
772 ContentSettingsPattern* primary_pattern = NULL;
773 ContentSettingsPattern* secondary_pattern = NULL;
774 if (info) {
775 primary_pattern = &info->primary_pattern;
776 secondary_pattern = &info->secondary_pattern;
779 // The list of |content_settings_providers_| is ordered according to their
780 // precedence.
781 for (ConstProviderIterator provider = content_settings_providers_.begin();
782 provider != content_settings_providers_.end();
783 ++provider) {
784 if (!get_override && provider->first == OVERRIDE_PROVIDER)
785 continue;
787 scoped_ptr<base::Value> value(
788 content_settings::GetContentSettingValueAndPatterns(provider->second,
789 primary_url,
790 secondary_url,
791 content_type,
792 resource_identifier,
793 is_off_the_record_,
794 primary_pattern,
795 secondary_pattern));
796 if (value) {
797 if (info)
798 info->source = kProviderSourceMap[provider->first];
799 return value.Pass();
803 if (info) {
804 info->source = content_settings::SETTING_SOURCE_NONE;
805 info->primary_pattern = ContentSettingsPattern();
806 info->secondary_pattern = ContentSettingsPattern();
808 return scoped_ptr<base::Value>();