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.
SupportsResourceIdentifier(ContentSettingsType content_type)72 bool SupportsResourceIdentifier(ContentSettingsType content_type) {
73 return content_type == CONTENT_SETTINGS_TYPE_PLUGINS;
74 }
75
76 } // namespace
77
HostContentSettingsMap(PrefService * prefs,bool incognito)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)
RegisterExtensionService(ExtensionService * extension_service)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
RegisterProfilePrefs(user_prefs::PrefRegistrySyncable * registry)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
GetDefaultContentSettingFromProvider(ContentSettingsType content_type,content_settings::ProviderInterface * provider) const162 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
GetDefaultContentSetting(ContentSettingsType content_type,std::string * provider_id) const179 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
GetContentSetting(const GURL & primary_url,const GURL & secondary_url,ContentSettingsType content_type,const std::string & resource_identifier) const207 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
GetSettingsForOneType(ContentSettingsType content_type,const std::string & resource_identifier,ContentSettingsForOneType * settings) const218 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
SetDefaultContentSetting(ContentSettingsType content_type,ContentSetting setting)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
SetWebsiteSetting(const ContentSettingsPattern & primary_pattern,const ContentSettingsPattern & secondary_pattern,ContentSettingsType content_type,const std::string & resource_identifier,base::Value * value)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
SetContentSetting(const ContentSettingsPattern & primary_pattern,const ContentSettingsPattern & secondary_pattern,ContentSettingsType content_type,const std::string & resource_identifier,ContentSetting setting)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
AddExceptionForURL(const GURL & primary_url,const GURL & secondary_url,ContentSettingsType content_type,ContentSetting setting)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
ClearSettingsForOneType(ContentSettingsType content_type)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
IsValueAllowedForType(PrefService * prefs,const base::Value * value,ContentSettingsType type)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
IsSettingAllowedForType(PrefService * prefs,ContentSetting setting,ContentSettingsType content_type)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
ContentTypeHasCompoundValue(ContentSettingsType type)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
OnContentSettingChanged(const ContentSettingsPattern & primary_pattern,const ContentSettingsPattern & secondary_pattern,ContentSettingsType content_type,std::string resource_identifier)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
~HostContentSettingsMap()420 HostContentSettingsMap::~HostContentSettingsMap() {
421 DCHECK(!prefs_);
422 STLDeleteValues(&content_settings_providers_);
423 }
424
ShutdownOnUIThread()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
MigrateObsoleteClearOnExitPref()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
AddSettingsForOneType(const content_settings::ProviderInterface * provider,ProviderType provider_type,ContentSettingsType content_type,const std::string & resource_identifier,ContentSettingsForOneType * settings,bool incognito) const485 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
UsedContentSettingsProviders() const518 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
ShouldAllowAllContent(const GURL & primary_url,const GURL & secondary_url,ContentSettingsType content_type)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
GetWebsiteSetting(const GURL & primary_url,const GURL & secondary_url,ContentSettingsType content_type,const std::string & resource_identifier,content_settings::SettingInfo * info) const559 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
GetProviderTypeFromSource(const std::string & source)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