| Index: chrome/browser/content_settings/cookie_settings.cc
|
| diff --git a/chrome/browser/content_settings/cookie_settings.cc b/chrome/browser/content_settings/cookie_settings.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..141ea6729eee839571d887ba92e01ce2d0a9433e
|
| --- /dev/null
|
| +++ b/chrome/browser/content_settings/cookie_settings.cc
|
| @@ -0,0 +1,250 @@
|
| +// Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "chrome/browser/content_settings/cookie_settings.h"
|
| +
|
| +#include "base/command_line.h"
|
| +#include "chrome/browser/content_settings/content_settings_utils.h"
|
| +#include "chrome/browser/content_settings/host_content_settings_map.h"
|
| +#include "chrome/browser/prefs/pref_service.h"
|
| +#include "chrome/browser/profiles/profile.h"
|
| +#include "chrome/browser/profiles/profile_dependency_manager.h"
|
| +#include "chrome/browser/profiles/profile_keyed_service.h"
|
| +#include "chrome/common/chrome_notification_types.h"
|
| +#include "chrome/common/chrome_switches.h"
|
| +#include "chrome/common/content_settings_pattern.h"
|
| +#include "chrome/common/pref_names.h"
|
| +#include "content/browser/browser_thread.h"
|
| +#include "content/browser/user_metrics.h"
|
| +#include "content/public/browser/notification_service.h"
|
| +#include "content/public/browser/notification_source.h"
|
| +#include "googleurl/src/gurl.h"
|
| +#include "net/base/net_errors.h"
|
| +#include "net/base/static_cookie_policy.h"
|
| +
|
| +namespace {
|
| +
|
| +bool IsValidSetting(ContentSetting setting) {
|
| + return (setting == CONTENT_SETTING_ALLOW ||
|
| + setting == CONTENT_SETTING_SESSION_ONLY ||
|
| + setting == CONTENT_SETTING_BLOCK);
|
| +}
|
| +
|
| +bool IsAllowed(ContentSetting setting) {
|
| + DCHECK(IsValidSetting(setting));
|
| + return (setting == CONTENT_SETTING_ALLOW ||
|
| + setting == CONTENT_SETTING_SESSION_ONLY);
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +// |ProfileKeyedFactory| is the owner of the |ProfileKeyedService|s. This
|
| +// wrapper class allows others to hold shared pointers to CookieSettings.
|
| +class CookieSettingsWrapper : public ProfileKeyedService {
|
| + public:
|
| + explicit CookieSettingsWrapper(scoped_refptr<CookieSettings> cookie_settings)
|
| + : cookie_settings_(cookie_settings) {}
|
| + virtual ~CookieSettingsWrapper() {}
|
| +
|
| + CookieSettings* cookie_settings() { return cookie_settings_.get(); }
|
| +
|
| + private:
|
| + // ProfileKeyedService methods:
|
| + virtual void Shutdown() OVERRIDE {
|
| + cookie_settings_->ShutdownOnUIThread();
|
| + }
|
| +
|
| + scoped_refptr<CookieSettings> cookie_settings_;
|
| +};
|
| +
|
| +// static
|
| +CookieSettings::Factory* CookieSettings::Factory::GetInstance() {
|
| + return Singleton<CookieSettings::Factory>::get();
|
| +}
|
| +
|
| +CookieSettingsWrapper* CookieSettings::Factory::GetWrapperForProfile(
|
| + Profile* profile) {
|
| + return static_cast<CookieSettingsWrapper*>(
|
| + GetServiceForProfile(profile,true));
|
| +}
|
| +
|
| +CookieSettings::Factory::Factory()
|
| + : ProfileKeyedServiceFactory(ProfileDependencyManager::GetInstance()) {
|
| +}
|
| +
|
| +ProfileKeyedService* CookieSettings::Factory::BuildServiceInstanceFor(
|
| + Profile* profile) const {
|
| + scoped_refptr<CookieSettings> cookie_settings = new CookieSettings(
|
| + profile->GetHostContentSettingsMap(),
|
| + profile->GetPrefs());
|
| + return new CookieSettingsWrapper(cookie_settings);
|
| +}
|
| +
|
| +CookieSettings::CookieSettings(
|
| + HostContentSettingsMap* host_content_settings_map,
|
| + PrefService* prefs)
|
| + : host_content_settings_map_(host_content_settings_map),
|
| + block_third_party_cookies_(
|
| + prefs->GetBoolean(prefs::kBlockThirdPartyCookies)) {
|
| + if (block_third_party_cookies_) {
|
| + UserMetrics::RecordAction(
|
| + UserMetricsAction("ThirdPartyCookieBlockingEnabled"));
|
| + } else {
|
| + UserMetrics::RecordAction(
|
| + UserMetricsAction("ThirdPartyCookieBlockingDisabled"));
|
| + }
|
| +
|
| + pref_change_registrar_.Init(prefs);
|
| + pref_change_registrar_.Add(prefs::kBlockThirdPartyCookies, this);
|
| +}
|
| +
|
| +CookieSettings::~CookieSettings() {
|
| +}
|
| +
|
| +// static
|
| +CookieSettings* CookieSettings::GetForProfile(Profile* profile) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + CookieSettings* cookie_settings =
|
| + Factory::GetInstance()->GetWrapperForProfile(profile)->cookie_settings();
|
| + DCHECK(cookie_settings);
|
| + return cookie_settings;
|
| +}
|
| +
|
| +ContentSetting
|
| +CookieSettings::GetDefaultCookieSetting(std::string* provider_id) const {
|
| + return host_content_settings_map_->GetDefaultContentSetting(
|
| + CONTENT_SETTINGS_TYPE_COOKIES, provider_id);
|
| +}
|
| +
|
| +bool CookieSettings::IsReadingCookieAllowed(const GURL& url,
|
| + const GURL& first_party_url) const {
|
| + ContentSetting setting = GetCookieSetting(url, first_party_url, false);
|
| + return IsAllowed(setting);
|
| +}
|
| +
|
| +bool CookieSettings::IsSettingCookieAllowed(const GURL& url,
|
| + const GURL& first_party_url) const {
|
| + ContentSetting setting = GetCookieSetting(url, first_party_url, true);
|
| + return IsAllowed(setting);
|
| +}
|
| +
|
| +bool CookieSettings::IsCookieSessionOnly(const GURL& origin) const {
|
| + ContentSetting setting = GetCookieSetting(origin, origin, true);
|
| + DCHECK(IsValidSetting(setting));
|
| + return (setting == CONTENT_SETTING_SESSION_ONLY);
|
| +}
|
| +
|
| +void CookieSettings::GetCookieSettings(
|
| + ContentSettingsForOneType* settings) const {
|
| + return host_content_settings_map_->GetSettingsForOneType(
|
| + CONTENT_SETTINGS_TYPE_COOKIES, "", settings);
|
| +}
|
| +
|
| +void CookieSettings::SetDefaultCookieSetting(ContentSetting setting) {
|
| + DCHECK(IsValidSetting(setting));
|
| + host_content_settings_map_->SetDefaultContentSetting(
|
| + CONTENT_SETTINGS_TYPE_COOKIES, setting);
|
| +}
|
| +
|
| +void CookieSettings::SetCookieSetting(
|
| + const ContentSettingsPattern& primary_pattern,
|
| + const ContentSettingsPattern& secondary_pattern,
|
| + ContentSetting setting) {
|
| + DCHECK(IsValidSetting(setting));
|
| + if (setting == CONTENT_SETTING_SESSION_ONLY) {
|
| + DCHECK(secondary_pattern == ContentSettingsPattern::Wildcard());
|
| + }
|
| + host_content_settings_map_->SetContentSetting(
|
| + primary_pattern, secondary_pattern, CONTENT_SETTINGS_TYPE_COOKIES, "",
|
| + setting);
|
| +}
|
| +
|
| +void CookieSettings::ResetCookieSetting(
|
| + const ContentSettingsPattern& primary_pattern,
|
| + const ContentSettingsPattern& secondary_pattern) {
|
| + host_content_settings_map_->SetContentSetting(
|
| + primary_pattern, secondary_pattern, CONTENT_SETTINGS_TYPE_COOKIES, "",
|
| + CONTENT_SETTING_DEFAULT);
|
| +}
|
| +
|
| +void CookieSettings::Observe(int type,
|
| + const content::NotificationSource& source,
|
| + const content::NotificationDetails& details) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| +
|
| + if (type == chrome::NOTIFICATION_PREF_CHANGED) {
|
| + PrefService* prefs = content::Source<PrefService>(source).ptr();
|
| + std::string* name = content::Details<std::string>(details).ptr();
|
| + if (*name == prefs::kBlockThirdPartyCookies) {
|
| + base::AutoLock auto_lock(lock_);
|
| + block_third_party_cookies_ = prefs->GetBoolean(
|
| + prefs::kBlockThirdPartyCookies);
|
| + } else {
|
| + NOTREACHED() << "Unexpected preference observed";
|
| + return;
|
| + }
|
| + } else {
|
| + NOTREACHED() << "Unexpected notification";
|
| + }
|
| +}
|
| +
|
| +void CookieSettings::ShutdownOnUIThread() {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + pref_change_registrar_.RemoveAll();
|
| +}
|
| +
|
| +ContentSetting CookieSettings::GetCookieSetting(
|
| + const GURL& url,
|
| + const GURL& first_party_url,
|
| + bool setting_cookie) const {
|
| + if (HostContentSettingsMap::ShouldAllowAllContent(
|
| + first_party_url,
|
| + CONTENT_SETTINGS_TYPE_COOKIES)) {
|
| + return CONTENT_SETTING_ALLOW;
|
| + }
|
| +
|
| + ContentSettingsPattern primary_pattern;
|
| + ContentSettingsPattern secondary_pattern;
|
| + // First get any host-specific settings.
|
| + scoped_ptr<base::Value> value(
|
| + host_content_settings_map_->GetContentSettingValue(
|
| + url, first_party_url, CONTENT_SETTINGS_TYPE_COOKIES, "",
|
| + &primary_pattern, &secondary_pattern));
|
| +
|
| + // If no explicit exception has been made and third-party cookies are blocked
|
| + // by default, apply that rule.
|
| + if (primary_pattern == ContentSettingsPattern::Wildcard() &&
|
| + secondary_pattern == ContentSettingsPattern::Wildcard() &&
|
| + ShouldBlockThirdPartyCookies()) {
|
| + bool strict = CommandLine::ForCurrentProcess()->HasSwitch(
|
| + switches::kBlockReadingThirdPartyCookies);
|
| + net::StaticCookiePolicy policy(strict ?
|
| + net::StaticCookiePolicy::BLOCK_ALL_THIRD_PARTY_COOKIES :
|
| + net::StaticCookiePolicy::BLOCK_SETTING_THIRD_PARTY_COOKIES);
|
| + int rv;
|
| + if (setting_cookie)
|
| + rv = policy.CanSetCookie(url, first_party_url);
|
| + else
|
| + rv = policy.CanGetCookies(url, first_party_url);
|
| + DCHECK_NE(net::ERR_IO_PENDING, rv);
|
| + if (rv != net::OK)
|
| + return CONTENT_SETTING_BLOCK;
|
| + }
|
| +
|
| + // We should always have a value, at least from the default provider.
|
| + DCHECK(value.get());
|
| + return content_settings::ValueToContentSetting(value.get());
|
| +}
|
| +
|
| +// static
|
| +void CookieSettings::RegisterUserPrefs(PrefService* prefs) {
|
| + prefs->RegisterBooleanPref(prefs::kBlockThirdPartyCookies,
|
| + false,
|
| + PrefService::SYNCABLE_PREF);
|
| +}
|
| +
|
| +bool CookieSettings::ShouldBlockThirdPartyCookies() const {
|
| + base::AutoLock auto_lock(lock_);
|
| + return block_third_party_cookies_;
|
| +}
|
|
|