OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chrome/browser/content_settings/host_content_settings_map.h" | |
6 | |
7 #include <utility> | |
8 | |
9 #include "base/basictypes.h" | |
10 #include "base/command_line.h" | |
11 #include "base/prefs/pref_service.h" | |
12 #include "base/stl_util.h" | |
13 #include "base/strings/string_util.h" | |
14 #include "base/strings/utf_string_conversions.h" | |
15 #include "base/time/clock.h" | |
16 #include "chrome/browser/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/pref_names.h" | |
21 #include "chrome/common/url_constants.h" | |
22 #include "components/content_settings/core/browser/content_settings_details.h" | |
23 #include "components/content_settings/core/browser/content_settings_observable_p
rovider.h" | |
24 #include "components/content_settings/core/browser/content_settings_provider.h" | |
25 #include "components/content_settings/core/browser/content_settings_rule.h" | |
26 #include "components/content_settings/core/common/content_settings_pattern.h" | |
27 #include "components/pref_registry/pref_registry_syncable.h" | |
28 #include "net/base/net_errors.h" | |
29 #include "net/base/static_cookie_policy.h" | |
30 #include "url/gurl.h" | |
31 | |
32 #if defined(ENABLE_EXTENSIONS) | |
33 #include "extensions/common/constants.h" | |
34 #endif | |
35 | |
36 namespace { | |
37 | |
38 typedef std::vector<content_settings::Rule> Rules; | |
39 | |
40 typedef std::pair<std::string, std::string> StringPair; | |
41 | |
42 // TODO(bauerb): Expose constants. | |
43 const char* kProviderNames[] = { | |
44 "platform_app", | |
45 "policy", | |
46 "extension", | |
47 "override", | |
48 "preference", | |
49 "default" | |
50 }; | |
51 | |
52 content_settings::SettingSource kProviderSourceMap[] = { | |
53 content_settings::SETTING_SOURCE_EXTENSION, | |
54 content_settings::SETTING_SOURCE_POLICY, | |
55 content_settings::SETTING_SOURCE_EXTENSION, | |
56 content_settings::SETTING_SOURCE_USER, | |
57 content_settings::SETTING_SOURCE_USER, | |
58 content_settings::SETTING_SOURCE_USER, | |
59 }; | |
60 COMPILE_ASSERT(arraysize(kProviderSourceMap) == | |
61 HostContentSettingsMap::NUM_PROVIDER_TYPES, | |
62 kProviderSourceMap_has_incorrect_size); | |
63 | |
64 // Returns true if the |content_type| supports a resource identifier. | |
65 // Resource identifiers are supported (but not required) for plug-ins. | |
66 bool SupportsResourceIdentifier(ContentSettingsType content_type) { | |
67 return content_type == CONTENT_SETTINGS_TYPE_PLUGINS; | |
68 } | |
69 | |
70 } // namespace | |
71 | |
72 HostContentSettingsMap::HostContentSettingsMap(PrefService* prefs, | |
73 bool incognito) | |
74 : | |
75 #ifndef NDEBUG | |
76 used_from_thread_id_(base::PlatformThread::CurrentId()), | |
77 #endif | |
78 prefs_(prefs), | |
79 is_off_the_record_(incognito) { | |
80 content_settings::ObservableProvider* policy_provider = | |
81 new content_settings::PolicyProvider(prefs_); | |
82 policy_provider->AddObserver(this); | |
83 content_settings_providers_[POLICY_PROVIDER] = policy_provider; | |
84 | |
85 content_settings::ObservableProvider* pref_provider = | |
86 new content_settings::PrefProvider(prefs_, is_off_the_record_); | |
87 pref_provider->AddObserver(this); | |
88 content_settings_providers_[PREF_PROVIDER] = pref_provider; | |
89 | |
90 content_settings::ObservableProvider* default_provider = | |
91 new content_settings::DefaultProvider(prefs_, is_off_the_record_); | |
92 default_provider->AddObserver(this); | |
93 content_settings_providers_[DEFAULT_PROVIDER] = default_provider; | |
94 | |
95 content_settings_providers_[OVERRIDE_PROVIDER] = | |
96 new content_settings::OverrideProvider(prefs_, is_off_the_record_); | |
97 } | |
98 | |
99 // static | |
100 void HostContentSettingsMap::RegisterProfilePrefs( | |
101 user_prefs::PrefRegistrySyncable* registry) { | |
102 registry->RegisterIntegerPref( | |
103 prefs::kContentSettingsWindowLastTabIndex, | |
104 0, | |
105 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); | |
106 | |
107 // Register the prefs for the content settings providers. | |
108 content_settings::DefaultProvider::RegisterProfilePrefs(registry); | |
109 content_settings::PrefProvider::RegisterProfilePrefs(registry); | |
110 content_settings::PolicyProvider::RegisterProfilePrefs(registry); | |
111 content_settings::OverrideProvider::RegisterProfilePrefs(registry); | |
112 } | |
113 | |
114 void HostContentSettingsMap::RegisterProvider( | |
115 ProviderType type, | |
116 scoped_ptr<content_settings::ObservableProvider> provider) { | |
117 DCHECK(!content_settings_providers_[type]); | |
118 provider->AddObserver(this); | |
119 content_settings_providers_[type] = provider.release(); | |
120 | |
121 #ifndef NDEBUG | |
122 DCHECK_NE(used_from_thread_id_, base::kInvalidThreadId) | |
123 << "Used from multiple threads before initialization complete."; | |
124 #endif | |
125 | |
126 OnContentSettingChanged(ContentSettingsPattern(), | |
127 ContentSettingsPattern(), | |
128 CONTENT_SETTINGS_TYPE_DEFAULT, | |
129 std::string()); | |
130 } | |
131 | |
132 ContentSetting HostContentSettingsMap::GetDefaultContentSettingFromProvider( | |
133 ContentSettingsType content_type, | |
134 content_settings::ProviderInterface* provider) const { | |
135 scoped_ptr<content_settings::RuleIterator> rule_iterator( | |
136 provider->GetRuleIterator(content_type, std::string(), false)); | |
137 | |
138 ContentSettingsPattern wildcard = ContentSettingsPattern::Wildcard(); | |
139 while (rule_iterator->HasNext()) { | |
140 content_settings::Rule rule = rule_iterator->Next(); | |
141 if (rule.primary_pattern == wildcard && | |
142 rule.secondary_pattern == wildcard) { | |
143 return content_settings::ValueToContentSetting(rule.value.get()); | |
144 } | |
145 } | |
146 return CONTENT_SETTING_DEFAULT; | |
147 } | |
148 | |
149 ContentSetting HostContentSettingsMap::GetDefaultContentSetting( | |
150 ContentSettingsType content_type, | |
151 std::string* provider_id) const { | |
152 UsedContentSettingsProviders(); | |
153 | |
154 // Iterate through the list of providers and return the first non-NULL value | |
155 // that matches |primary_url| and |secondary_url|. | |
156 for (ConstProviderIterator provider = content_settings_providers_.begin(); | |
157 provider != content_settings_providers_.end(); | |
158 ++provider) { | |
159 if (provider->first == PREF_PROVIDER || | |
160 provider->first == OVERRIDE_PROVIDER) | |
161 continue; | |
162 ContentSetting default_setting = | |
163 GetDefaultContentSettingFromProvider(content_type, provider->second); | |
164 if (default_setting != CONTENT_SETTING_DEFAULT) { | |
165 if (provider_id) | |
166 *provider_id = kProviderNames[provider->first]; | |
167 return default_setting; | |
168 } | |
169 } | |
170 | |
171 return CONTENT_SETTING_DEFAULT; | |
172 } | |
173 | |
174 ContentSetting HostContentSettingsMap::GetContentSetting( | |
175 const GURL& primary_url, | |
176 const GURL& secondary_url, | |
177 ContentSettingsType content_type, | |
178 const std::string& resource_identifier) const { | |
179 DCHECK(!ContentTypeHasCompoundValue(content_type)); | |
180 scoped_ptr<base::Value> value = GetWebsiteSetting( | |
181 primary_url, secondary_url, content_type, resource_identifier, NULL); | |
182 return content_settings::ValueToContentSetting(value.get()); | |
183 } | |
184 | |
185 void HostContentSettingsMap::GetSettingsForOneType( | |
186 ContentSettingsType content_type, | |
187 const std::string& resource_identifier, | |
188 ContentSettingsForOneType* settings) const { | |
189 DCHECK(SupportsResourceIdentifier(content_type) || | |
190 resource_identifier.empty()); | |
191 DCHECK(settings); | |
192 UsedContentSettingsProviders(); | |
193 | |
194 settings->clear(); | |
195 for (ConstProviderIterator provider = content_settings_providers_.begin(); | |
196 provider != content_settings_providers_.end(); | |
197 ++provider) { | |
198 if (provider->first == OVERRIDE_PROVIDER) | |
199 continue; | |
200 // For each provider, iterate first the incognito-specific rules, then the | |
201 // normal rules. | |
202 if (is_off_the_record_) { | |
203 AddSettingsForOneType(provider->second, | |
204 provider->first, | |
205 content_type, | |
206 resource_identifier, | |
207 settings, | |
208 true); | |
209 } | |
210 AddSettingsForOneType(provider->second, | |
211 provider->first, | |
212 content_type, | |
213 resource_identifier, | |
214 settings, | |
215 false); | |
216 } | |
217 } | |
218 | |
219 void HostContentSettingsMap::SetDefaultContentSetting( | |
220 ContentSettingsType content_type, | |
221 ContentSetting setting) { | |
222 DCHECK(IsSettingAllowedForType(prefs_, setting, content_type)); | |
223 | |
224 base::Value* value = NULL; | |
225 if (setting != CONTENT_SETTING_DEFAULT) | |
226 value = new base::FundamentalValue(setting); | |
227 SetWebsiteSetting( | |
228 ContentSettingsPattern::Wildcard(), | |
229 ContentSettingsPattern::Wildcard(), | |
230 content_type, | |
231 std::string(), | |
232 value); | |
233 } | |
234 | |
235 void HostContentSettingsMap::SetWebsiteSetting( | |
236 const ContentSettingsPattern& primary_pattern, | |
237 const ContentSettingsPattern& secondary_pattern, | |
238 ContentSettingsType content_type, | |
239 const std::string& resource_identifier, | |
240 base::Value* value) { | |
241 DCHECK(IsValueAllowedForType(prefs_, value, content_type)); | |
242 DCHECK(SupportsResourceIdentifier(content_type) || | |
243 resource_identifier.empty()); | |
244 UsedContentSettingsProviders(); | |
245 | |
246 for (ProviderIterator provider = content_settings_providers_.begin(); | |
247 provider != content_settings_providers_.end(); | |
248 ++provider) { | |
249 if (provider->second->SetWebsiteSetting(primary_pattern, | |
250 secondary_pattern, | |
251 content_type, | |
252 resource_identifier, | |
253 value)) { | |
254 return; | |
255 } | |
256 } | |
257 NOTREACHED(); | |
258 } | |
259 | |
260 void HostContentSettingsMap::SetNarrowestWebsiteSetting( | |
261 const ContentSettingsPattern& primary_pattern, | |
262 const ContentSettingsPattern& secondary_pattern, | |
263 ContentSettingsType content_type, | |
264 const std::string& resource_identifier, | |
265 ContentSetting setting, | |
266 content_settings::SettingInfo existing_info) { | |
267 ContentSettingsPattern narrow_primary = primary_pattern; | |
268 ContentSettingsPattern narrow_secondary = secondary_pattern; | |
269 | |
270 DCHECK_EQ(content_settings::SETTING_SOURCE_USER, existing_info.source); | |
271 ContentSettingsPattern::Relation r1 = | |
272 existing_info.primary_pattern.Compare(primary_pattern); | |
273 if (r1 == ContentSettingsPattern::PREDECESSOR) { | |
274 narrow_primary = existing_info.primary_pattern; | |
275 } else if (r1 == ContentSettingsPattern::IDENTITY) { | |
276 ContentSettingsPattern::Relation r2 = | |
277 existing_info.secondary_pattern.Compare(secondary_pattern); | |
278 DCHECK(r2 != ContentSettingsPattern::DISJOINT_ORDER_POST && | |
279 r2 != ContentSettingsPattern::DISJOINT_ORDER_PRE); | |
280 if (r2 == ContentSettingsPattern::PREDECESSOR) | |
281 narrow_secondary = existing_info.secondary_pattern; | |
282 } | |
283 | |
284 SetContentSetting( | |
285 narrow_primary, narrow_secondary, content_type, std::string(), setting); | |
286 } | |
287 | |
288 void HostContentSettingsMap::SetContentSetting( | |
289 const ContentSettingsPattern& primary_pattern, | |
290 const ContentSettingsPattern& secondary_pattern, | |
291 ContentSettingsType content_type, | |
292 const std::string& resource_identifier, | |
293 ContentSetting setting) { | |
294 DCHECK(!ContentTypeHasCompoundValue(content_type)); | |
295 | |
296 if (setting == CONTENT_SETTING_ALLOW && | |
297 (content_type == CONTENT_SETTINGS_TYPE_GEOLOCATION || | |
298 content_type == CONTENT_SETTINGS_TYPE_NOTIFICATIONS)) { | |
299 UpdateLastUsageByPattern(primary_pattern, secondary_pattern, content_type); | |
300 } | |
301 | |
302 base::Value* value = NULL; | |
303 if (setting != CONTENT_SETTING_DEFAULT) | |
304 value = new base::FundamentalValue(setting); | |
305 SetWebsiteSetting(primary_pattern, | |
306 secondary_pattern, | |
307 content_type, | |
308 resource_identifier, | |
309 value); | |
310 } | |
311 | |
312 ContentSetting HostContentSettingsMap::GetContentSettingAndMaybeUpdateLastUsage( | |
313 const GURL& primary_url, | |
314 const GURL& secondary_url, | |
315 ContentSettingsType content_type, | |
316 const std::string& resource_identifier) { | |
317 DCHECK(thread_checker_.CalledOnValidThread()); | |
318 | |
319 ContentSetting setting = GetContentSetting( | |
320 primary_url, secondary_url, content_type, resource_identifier); | |
321 if (setting == CONTENT_SETTING_ALLOW) { | |
322 UpdateLastUsageByPattern( | |
323 ContentSettingsPattern::FromURLNoWildcard(primary_url), | |
324 ContentSettingsPattern::FromURLNoWildcard(secondary_url), | |
325 content_type); | |
326 } | |
327 return setting; | |
328 } | |
329 | |
330 void HostContentSettingsMap::UpdateLastUsage(const GURL& primary_url, | |
331 const GURL& secondary_url, | |
332 ContentSettingsType content_type) { | |
333 UpdateLastUsageByPattern( | |
334 ContentSettingsPattern::FromURLNoWildcard(primary_url), | |
335 ContentSettingsPattern::FromURLNoWildcard(secondary_url), | |
336 content_type); | |
337 } | |
338 | |
339 void HostContentSettingsMap::UpdateLastUsageByPattern( | |
340 const ContentSettingsPattern& primary_pattern, | |
341 const ContentSettingsPattern& secondary_pattern, | |
342 ContentSettingsType content_type) { | |
343 UsedContentSettingsProviders(); | |
344 | |
345 GetPrefProvider()->UpdateLastUsage( | |
346 primary_pattern, secondary_pattern, content_type); | |
347 | |
348 FOR_EACH_OBSERVER( | |
349 content_settings::Observer, | |
350 observers_, | |
351 OnContentSettingUsed(primary_pattern, secondary_pattern, content_type)); | |
352 } | |
353 | |
354 base::Time HostContentSettingsMap::GetLastUsage( | |
355 const GURL& primary_url, | |
356 const GURL& secondary_url, | |
357 ContentSettingsType content_type) { | |
358 return GetLastUsageByPattern( | |
359 ContentSettingsPattern::FromURLNoWildcard(primary_url), | |
360 ContentSettingsPattern::FromURLNoWildcard(secondary_url), | |
361 content_type); | |
362 } | |
363 | |
364 base::Time HostContentSettingsMap::GetLastUsageByPattern( | |
365 const ContentSettingsPattern& primary_pattern, | |
366 const ContentSettingsPattern& secondary_pattern, | |
367 ContentSettingsType content_type) { | |
368 UsedContentSettingsProviders(); | |
369 | |
370 return GetPrefProvider()->GetLastUsage( | |
371 primary_pattern, secondary_pattern, content_type); | |
372 } | |
373 | |
374 ContentSetting HostContentSettingsMap::GetContentSettingWithoutOverride( | |
375 const GURL& primary_url, | |
376 const GURL& secondary_url, | |
377 ContentSettingsType content_type, | |
378 const std::string& resource_identifier) { | |
379 scoped_ptr<base::Value> value(GetWebsiteSettingWithoutOverride( | |
380 primary_url, secondary_url, content_type, resource_identifier, NULL)); | |
381 return content_settings::ValueToContentSetting(value.get()); | |
382 } | |
383 | |
384 scoped_ptr<base::Value> | |
385 HostContentSettingsMap::GetWebsiteSettingWithoutOverride( | |
386 const GURL& primary_url, | |
387 const GURL& secondary_url, | |
388 ContentSettingsType content_type, | |
389 const std::string& resource_identifier, | |
390 content_settings::SettingInfo* info) const { | |
391 return GetWebsiteSettingInternal(primary_url, | |
392 secondary_url, | |
393 content_type, | |
394 resource_identifier, | |
395 info, | |
396 false); | |
397 } | |
398 | |
399 void HostContentSettingsMap::SetContentSettingOverride( | |
400 ContentSettingsType content_type, | |
401 bool is_enabled) { | |
402 UsedContentSettingsProviders(); | |
403 | |
404 content_settings::OverrideProvider* override = | |
405 static_cast<content_settings::OverrideProvider*>( | |
406 content_settings_providers_[OVERRIDE_PROVIDER]); | |
407 override->SetOverrideSetting(content_type, is_enabled); | |
408 } | |
409 | |
410 bool HostContentSettingsMap::GetContentSettingOverride( | |
411 ContentSettingsType content_type) { | |
412 UsedContentSettingsProviders(); | |
413 | |
414 content_settings::OverrideProvider* override = | |
415 static_cast<content_settings::OverrideProvider*>( | |
416 content_settings_providers_[OVERRIDE_PROVIDER]); | |
417 return override->IsEnabled(content_type); | |
418 } | |
419 | |
420 void HostContentSettingsMap::AddObserver(content_settings::Observer* observer) { | |
421 observers_.AddObserver(observer); | |
422 } | |
423 | |
424 void HostContentSettingsMap::RemoveObserver( | |
425 content_settings::Observer* observer) { | |
426 observers_.RemoveObserver(observer); | |
427 } | |
428 | |
429 void HostContentSettingsMap::SetPrefClockForTesting( | |
430 scoped_ptr<base::Clock> clock) { | |
431 UsedContentSettingsProviders(); | |
432 | |
433 GetPrefProvider()->SetClockForTesting(clock.Pass()); | |
434 } | |
435 | |
436 void HostContentSettingsMap::AddExceptionForURL( | |
437 const GURL& primary_url, | |
438 const GURL& secondary_url, | |
439 ContentSettingsType content_type, | |
440 ContentSetting setting) { | |
441 // TODO(markusheintz): Until the UI supports pattern pairs, both urls must | |
442 // match. | |
443 DCHECK(primary_url == secondary_url); | |
444 DCHECK(!ContentTypeHasCompoundValue(content_type)); | |
445 | |
446 // Make sure there is no entry that would override the pattern we are about | |
447 // to insert for exactly this URL. | |
448 SetContentSetting(ContentSettingsPattern::FromURLNoWildcard(primary_url), | |
449 ContentSettingsPattern::Wildcard(), | |
450 content_type, | |
451 std::string(), | |
452 CONTENT_SETTING_DEFAULT); | |
453 | |
454 SetContentSetting(ContentSettingsPattern::FromURL(primary_url), | |
455 ContentSettingsPattern::Wildcard(), | |
456 content_type, | |
457 std::string(), | |
458 setting); | |
459 } | |
460 | |
461 void HostContentSettingsMap::ClearSettingsForOneType( | |
462 ContentSettingsType content_type) { | |
463 UsedContentSettingsProviders(); | |
464 for (ProviderIterator provider = content_settings_providers_.begin(); | |
465 provider != content_settings_providers_.end(); | |
466 ++provider) { | |
467 provider->second->ClearAllContentSettingsRules(content_type); | |
468 } | |
469 } | |
470 | |
471 bool HostContentSettingsMap::IsValueAllowedForType( | |
472 PrefService* prefs, const base::Value* value, ContentSettingsType type) { | |
473 return ContentTypeHasCompoundValue(type) || IsSettingAllowedForType( | |
474 prefs, content_settings::ValueToContentSetting(value), type); | |
475 } | |
476 | |
477 // static | |
478 bool HostContentSettingsMap::IsSettingAllowedForType( | |
479 PrefService* prefs, | |
480 ContentSetting setting, | |
481 ContentSettingsType content_type) { | |
482 // We don't yet support stored content settings for mixed scripting. | |
483 if (content_type == CONTENT_SETTINGS_TYPE_MIXEDSCRIPT) | |
484 return false; | |
485 | |
486 // BLOCK semantics are not implemented for fullscreen. | |
487 if (content_type == CONTENT_SETTINGS_TYPE_FULLSCREEN && | |
488 setting == CONTENT_SETTING_BLOCK) { | |
489 return false; | |
490 } | |
491 | |
492 // We don't support ALLOW for media default setting. | |
493 if (content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM && | |
494 setting == CONTENT_SETTING_ALLOW) { | |
495 return false; | |
496 } | |
497 | |
498 #if defined(OS_ANDROID) | |
499 // App banners store a dictionary. | |
500 if (content_type == CONTENT_SETTINGS_TYPE_APP_BANNER) | |
501 return false; | |
502 #endif | |
503 | |
504 // DEFAULT, ALLOW and BLOCK are always allowed. | |
505 if (setting == CONTENT_SETTING_DEFAULT || | |
506 setting == CONTENT_SETTING_ALLOW || | |
507 setting == CONTENT_SETTING_BLOCK) { | |
508 return true; | |
509 } | |
510 switch (content_type) { | |
511 case CONTENT_SETTINGS_TYPE_COOKIES: | |
512 return setting == CONTENT_SETTING_SESSION_ONLY; | |
513 case CONTENT_SETTINGS_TYPE_PLUGINS: | |
514 case CONTENT_SETTINGS_TYPE_GEOLOCATION: | |
515 case CONTENT_SETTINGS_TYPE_NOTIFICATIONS: | |
516 case CONTENT_SETTINGS_TYPE_MOUSELOCK: | |
517 case CONTENT_SETTINGS_TYPE_MEDIASTREAM: | |
518 case CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC: | |
519 case CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA: | |
520 case CONTENT_SETTINGS_TYPE_PPAPI_BROKER: | |
521 case CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS: | |
522 case CONTENT_SETTINGS_TYPE_MIDI_SYSEX: | |
523 return setting == CONTENT_SETTING_ASK; | |
524 default: | |
525 return false; | |
526 } | |
527 } | |
528 | |
529 // static | |
530 bool HostContentSettingsMap::ContentTypeHasCompoundValue( | |
531 ContentSettingsType type) { | |
532 // Values for content type CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE, | |
533 // CONTENT_SETTINGS_TYPE_MEDIASTREAM, and | |
534 // CONTENT_SETTINGS_TYPE_SSL_CERT_DECISIONS are of type dictionary/map. | |
535 // Compound types like dictionaries can't be mapped to the type | |
536 // |ContentSetting|. | |
537 #if defined(OS_ANDROID) | |
538 if (type == CONTENT_SETTINGS_TYPE_APP_BANNER) | |
539 return true; | |
540 #endif | |
541 | |
542 return (type == CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE || | |
543 type == CONTENT_SETTINGS_TYPE_MEDIASTREAM || | |
544 type == CONTENT_SETTINGS_TYPE_SSL_CERT_DECISIONS); | |
545 } | |
546 | |
547 void HostContentSettingsMap::OnContentSettingChanged( | |
548 const ContentSettingsPattern& primary_pattern, | |
549 const ContentSettingsPattern& secondary_pattern, | |
550 ContentSettingsType content_type, | |
551 std::string resource_identifier) { | |
552 FOR_EACH_OBSERVER(content_settings::Observer, | |
553 observers_, | |
554 OnContentSettingChanged(primary_pattern, | |
555 secondary_pattern, | |
556 content_type, | |
557 resource_identifier)); | |
558 } | |
559 | |
560 HostContentSettingsMap::~HostContentSettingsMap() { | |
561 DCHECK(!prefs_); | |
562 STLDeleteValues(&content_settings_providers_); | |
563 } | |
564 | |
565 void HostContentSettingsMap::ShutdownOnUIThread() { | |
566 DCHECK(thread_checker_.CalledOnValidThread()); | |
567 DCHECK(prefs_); | |
568 prefs_ = NULL; | |
569 for (ProviderIterator it = content_settings_providers_.begin(); | |
570 it != content_settings_providers_.end(); | |
571 ++it) { | |
572 it->second->ShutdownOnUIThread(); | |
573 } | |
574 } | |
575 | |
576 void HostContentSettingsMap::AddSettingsForOneType( | |
577 const content_settings::ProviderInterface* provider, | |
578 ProviderType provider_type, | |
579 ContentSettingsType content_type, | |
580 const std::string& resource_identifier, | |
581 ContentSettingsForOneType* settings, | |
582 bool incognito) const { | |
583 scoped_ptr<content_settings::RuleIterator> rule_iterator( | |
584 provider->GetRuleIterator(content_type, | |
585 resource_identifier, | |
586 incognito)); | |
587 while (rule_iterator->HasNext()) { | |
588 const content_settings::Rule& rule = rule_iterator->Next(); | |
589 ContentSetting setting_value = CONTENT_SETTING_DEFAULT; | |
590 // TODO(bauerb): Return rules as a list of values, not content settings. | |
591 // Handle the case using compound values for its exceptions and arbitrary | |
592 // values for its default setting. Here we assume all the exceptions | |
593 // are granted as |CONTENT_SETTING_ALLOW|. | |
594 if (ContentTypeHasCompoundValue(content_type) && | |
595 rule.value.get() && | |
596 rule.primary_pattern != ContentSettingsPattern::Wildcard()) { | |
597 setting_value = CONTENT_SETTING_ALLOW; | |
598 } else { | |
599 setting_value = content_settings::ValueToContentSetting(rule.value.get()); | |
600 } | |
601 settings->push_back(ContentSettingPatternSource( | |
602 rule.primary_pattern, rule.secondary_pattern, | |
603 setting_value, | |
604 kProviderNames[provider_type], | |
605 incognito)); | |
606 } | |
607 } | |
608 | |
609 void HostContentSettingsMap::UsedContentSettingsProviders() const { | |
610 #ifndef NDEBUG | |
611 if (used_from_thread_id_ == base::kInvalidThreadId) | |
612 return; | |
613 | |
614 if (base::PlatformThread::CurrentId() != used_from_thread_id_) | |
615 used_from_thread_id_ = base::kInvalidThreadId; | |
616 #endif | |
617 } | |
618 | |
619 bool HostContentSettingsMap::ShouldAllowAllContent( | |
620 const GURL& primary_url, | |
621 const GURL& secondary_url, | |
622 ContentSettingsType content_type) { | |
623 if (content_type == CONTENT_SETTINGS_TYPE_NOTIFICATIONS || | |
624 content_type == CONTENT_SETTINGS_TYPE_GEOLOCATION || | |
625 content_type == CONTENT_SETTINGS_TYPE_MIDI_SYSEX) { | |
626 return false; | |
627 } | |
628 #if defined(OS_ANDROID) || defined(OS_CHROMEOS) | |
629 if (content_type == CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER) { | |
630 return false; | |
631 } | |
632 #endif | |
633 if (secondary_url.SchemeIs(content::kChromeUIScheme) && | |
634 content_type == CONTENT_SETTINGS_TYPE_COOKIES && | |
635 primary_url.SchemeIsSecure()) { | |
636 return true; | |
637 } | |
638 #if defined(ENABLE_EXTENSIONS) | |
639 if (primary_url.SchemeIs(extensions::kExtensionScheme)) { | |
640 switch (content_type) { | |
641 case CONTENT_SETTINGS_TYPE_PLUGINS: | |
642 case CONTENT_SETTINGS_TYPE_MEDIASTREAM: | |
643 case CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC: | |
644 case CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA: | |
645 return false; | |
646 case CONTENT_SETTINGS_TYPE_COOKIES: | |
647 return secondary_url.SchemeIs(extensions::kExtensionScheme); | |
648 default: | |
649 return true; | |
650 } | |
651 } | |
652 #endif | |
653 return primary_url.SchemeIs(content::kChromeDevToolsScheme) || | |
654 primary_url.SchemeIs(content::kChromeUIScheme); | |
655 } | |
656 | |
657 scoped_ptr<base::Value> HostContentSettingsMap::GetWebsiteSetting( | |
658 const GURL& primary_url, | |
659 const GURL& secondary_url, | |
660 ContentSettingsType content_type, | |
661 const std::string& resource_identifier, | |
662 content_settings::SettingInfo* info) const { | |
663 DCHECK(SupportsResourceIdentifier(content_type) || | |
664 resource_identifier.empty()); | |
665 | |
666 // Check if the scheme of the requesting url is whitelisted. | |
667 if (ShouldAllowAllContent(primary_url, secondary_url, content_type)) { | |
668 if (info) { | |
669 info->source = content_settings::SETTING_SOURCE_WHITELIST; | |
670 info->primary_pattern = ContentSettingsPattern::Wildcard(); | |
671 info->secondary_pattern = ContentSettingsPattern::Wildcard(); | |
672 } | |
673 return scoped_ptr<base::Value>( | |
674 new base::FundamentalValue(CONTENT_SETTING_ALLOW)); | |
675 } | |
676 | |
677 return GetWebsiteSettingInternal(primary_url, | |
678 secondary_url, | |
679 content_type, | |
680 resource_identifier, | |
681 info, | |
682 true); | |
683 } | |
684 | |
685 // static | |
686 HostContentSettingsMap::ProviderType | |
687 HostContentSettingsMap::GetProviderTypeFromSource(const std::string& source) { | |
688 for (size_t i = 0; i < arraysize(kProviderNames); ++i) { | |
689 if (source == kProviderNames[i]) | |
690 return static_cast<ProviderType>(i); | |
691 } | |
692 | |
693 NOTREACHED(); | |
694 return DEFAULT_PROVIDER; | |
695 } | |
696 | |
697 content_settings::PrefProvider* HostContentSettingsMap::GetPrefProvider() { | |
698 return static_cast<content_settings::PrefProvider*>( | |
699 content_settings_providers_[PREF_PROVIDER]); | |
700 } | |
701 | |
702 scoped_ptr<base::Value> HostContentSettingsMap::GetWebsiteSettingInternal( | |
703 const GURL& primary_url, | |
704 const GURL& secondary_url, | |
705 ContentSettingsType content_type, | |
706 const std::string& resource_identifier, | |
707 content_settings::SettingInfo* info, | |
708 bool get_override) const { | |
709 UsedContentSettingsProviders(); | |
710 ContentSettingsPattern* primary_pattern = NULL; | |
711 ContentSettingsPattern* secondary_pattern = NULL; | |
712 if (info) { | |
713 primary_pattern = &info->primary_pattern; | |
714 secondary_pattern = &info->secondary_pattern; | |
715 } | |
716 | |
717 // The list of |content_settings_providers_| is ordered according to their | |
718 // precedence. | |
719 for (ConstProviderIterator provider = content_settings_providers_.begin(); | |
720 provider != content_settings_providers_.end(); | |
721 ++provider) { | |
722 if (!get_override && provider->first == OVERRIDE_PROVIDER) | |
723 continue; | |
724 | |
725 scoped_ptr<base::Value> value( | |
726 content_settings::GetContentSettingValueAndPatterns(provider->second, | |
727 primary_url, | |
728 secondary_url, | |
729 content_type, | |
730 resource_identifier, | |
731 is_off_the_record_, | |
732 primary_pattern, | |
733 secondary_pattern)); | |
734 if (value) { | |
735 if (info) | |
736 info->source = kProviderSourceMap[provider->first]; | |
737 return value.Pass(); | |
738 } | |
739 } | |
740 | |
741 if (info) { | |
742 info->source = content_settings::SETTING_SOURCE_NONE; | |
743 info->primary_pattern = ContentSettingsPattern(); | |
744 info->secondary_pattern = ContentSettingsPattern(); | |
745 } | |
746 return scoped_ptr<base::Value>(); | |
747 } | |
OLD | NEW |