| 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 |