Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2000)

Unified Diff: chrome/browser/content_settings/cookie_settings.cc

Issue 7713034: HostContentSettingsMap refactoring. (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Code review comments. Threading fixes. Mac + win fixes. Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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..18266fe7b7d0dde803ac67bb40824f754b91bf91
--- /dev/null
+++ b/chrome/browser/content_settings/cookie_settings.cc
@@ -0,0 +1,311 @@
+// 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 "base/memory/singleton.h"
+#include "chrome/browser/content_settings/content_settings_pattern.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/browser/profiles/profile_keyed_service_factory.h"
+#include "chrome/common/chrome_notification_types.h"
+#include "chrome/common/chrome_switches.h"
+#include "chrome/common/pref_names.h"
+#include "content/browser/browser_thread.h"
+#include "content/browser/user_metrics.h"
+#include "content/common/notification_service.h"
+#include "content/common/notification_source.h"
+#include "googleurl/src/gurl.h"
+#include "net/base/net_errors.h"
+#include "net/base/static_cookie_policy.h"
+
+namespace {
+
+// ProfileKeyedFactory is the owner of the ProfileKeyedServices. 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_;
+};
+
+} // namespace
+
+class CookieSettings::Factory : public ProfileKeyedServiceFactory {
+ public:
+ static Factory* GetInstance();
+
+ CookieSettingsWrapper* GetWrapperForProfile(Profile* profile);
+
+ private:
+ friend struct DefaultSingletonTraits<Factory>;
+
+ Factory();
+ virtual ~Factory() {}
+
+ // PrefoileKeyedServiceFactory methods:
+ virtual CookieSettingsWrapper* BuildServiceInstanceFor(
+ Profile* profile) const OVERRIDE;
+ virtual bool ServiceRedirectedInIncognito() OVERRIDE { return true; }
+};
+
+// 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()) {
+}
+
+CookieSettingsWrapper* CookieSettings::Factory::BuildServiceInstanceFor(
+ Profile* profile) const {
+ scoped_refptr<CookieSettings> cookie_settings = new CookieSettings(
+ profile->GetHostContentSettingsMap(),
+ profile->GetPrefs(),
+ profile->IsOffTheRecord());
+ return new CookieSettingsWrapper(cookie_settings);
+}
+
+CookieSettings::CookieSettings(
+ HostContentSettingsMap* host_content_settings_map,
+ PrefService* prefs,
+ bool incognito)
+ : host_content_settings_map_(host_content_settings_map),
+ prefs_(prefs),
+ is_off_the_record_(incognito),
+ block_third_party_cookies_(false) {
+ 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::GetDefaultSetting() const {
+ ContentSetting allow_or_block =
+ host_content_settings_map_->GetDefaultContentSetting(
+ CONTENT_SETTINGS_TYPE_COOKIES);
+ DCHECK(allow_or_block == CONTENT_SETTING_ALLOW ||
+ allow_or_block == CONTENT_SETTING_BLOCK);
+ if (allow_or_block == CONTENT_SETTING_BLOCK)
+ return allow_or_block;
+ ContentSetting session_only =
+ host_content_settings_map_->GetDefaultContentSetting(
+ CONTENT_SETTINGS_TYPE_COOKIES_SESSION_ONLY);
+ DCHECK(allow_or_block == CONTENT_SETTING_ALLOW ||
+ allow_or_block == CONTENT_SETTING_SESSION_ONLY);
+ return session_only;
+}
+
+bool CookieSettings::IsReadingCookieAllowed(const GURL& url,
+ const GURL& first_party_url) const {
+ ContentSetting setting = GetCookieContentSetting(
+ url, first_party_url, CONTENT_SETTINGS_TYPE_COOKIES, false);
+ DCHECK(setting == CONTENT_SETTING_ALLOW ||
+ setting == CONTENT_SETTING_BLOCK);
+ return setting == CONTENT_SETTING_ALLOW;
+}
+
+bool CookieSettings::IsSettingCookieAllowed(const GURL& url,
+ const GURL& first_party_url) const {
+ ContentSetting setting = GetCookieContentSetting(
+ url, first_party_url, CONTENT_SETTINGS_TYPE_COOKIES, true);
+ DCHECK(setting == CONTENT_SETTING_ALLOW ||
+ setting == CONTENT_SETTING_BLOCK);
+ return setting == CONTENT_SETTING_ALLOW;
+}
+
+bool CookieSettings::IsCookieSessionOnly(const GURL& origin) const {
+ ContentSetting setting = GetCookieContentSetting(
+ origin, origin, CONTENT_SETTINGS_TYPE_COOKIES_SESSION_ONLY, true);
+ DCHECK(setting == CONTENT_SETTING_ALLOW ||
+ setting == CONTENT_SETTING_SESSION_ONLY);
+ return (setting == CONTENT_SETTING_SESSION_ONLY);
+}
+
+void CookieSettings::SetDefaultSetting(ContentSetting setting) {
+ DCHECK(setting == CONTENT_SETTING_ALLOW ||
+ setting == CONTENT_SETTING_SESSION_ONLY ||
+ setting == CONTENT_SETTING_BLOCK);
+ ContentSetting allowed = CONTENT_SETTING_BLOCK;
+ ContentSetting session_only = CONTENT_SETTING_ALLOW;
+ if (setting == CONTENT_SETTING_ALLOW ||
+ setting == CONTENT_SETTING_SESSION_ONLY)
+ allowed = CONTENT_SETTING_ALLOW;
+ if (setting == CONTENT_SETTING_SESSION_ONLY)
+ session_only = CONTENT_SETTING_SESSION_ONLY;
+ host_content_settings_map_->SetDefaultContentSetting(
+ CONTENT_SETTINGS_TYPE_COOKIES, allowed);
+ host_content_settings_map_->SetDefaultContentSetting(
+ CONTENT_SETTINGS_TYPE_COOKIES_SESSION_ONLY, session_only);
+}
+
+void CookieSettings::SetCookieSetting(
+ const ContentSettingsPattern& primary_pattern,
+ ContentSetting content_setting) {
+ DCHECK(content_setting == CONTENT_SETTING_ALLOW ||
+ content_setting == CONTENT_SETTING_SESSION_ONLY ||
+ content_setting == CONTENT_SETTING_BLOCK);
+ bool allowed =
+ content_setting == CONTENT_SETTING_ALLOW ||
+ content_setting == CONTENT_SETTING_SESSION_ONLY;
+ bool session_only = (content_setting == CONTENT_SETTING_SESSION_ONLY);
+ host_content_settings_map_->SetContentSetting(
+ primary_pattern, ContentSettingsPattern::Wildcard(),
+ CONTENT_SETTINGS_TYPE_COOKIES, "",
+ allowed ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK);
+ host_content_settings_map_->SetContentSetting(
+ primary_pattern, ContentSettingsPattern::Wildcard(),
+ CONTENT_SETTINGS_TYPE_COOKIES_SESSION_ONLY, "",
+ session_only ? CONTENT_SETTING_SESSION_ONLY : CONTENT_SETTING_ALLOW);
+}
+
+void CookieSettings::ResetCookieSetting(
+ const ContentSettingsPattern& primary_pattern) {
+ host_content_settings_map_->SetContentSetting(
+ primary_pattern, ContentSettingsPattern::Wildcard(),
+ CONTENT_SETTINGS_TYPE_COOKIES, "",
+ CONTENT_SETTING_DEFAULT);
+ host_content_settings_map_->SetContentSetting(
+ primary_pattern, ContentSettingsPattern::Wildcard(),
+ CONTENT_SETTINGS_TYPE_COOKIES_SESSION_ONLY, "",
+ CONTENT_SETTING_DEFAULT);
+}
+
+void CookieSettings::SetBlockThirdPartyCookies(bool block) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK(prefs_);
+
+ // This setting may not be directly modified for OTR sessions. Instead, it
+ // is synced to the main profile's setting.
+ if (is_off_the_record_) {
+ NOTREACHED();
+ return;
+ }
+
+ // If the preference block-third-party-cookies is managed then do not allow to
+ // change it.
+ if (prefs_->IsManagedPreference(prefs::kBlockThirdPartyCookies)) {
+ NOTREACHED();
+ return;
+ }
+
+ {
+ base::AutoLock auto_lock(lock_);
+ block_third_party_cookies_ = block;
+ }
+
+ prefs_->SetBoolean(prefs::kBlockThirdPartyCookies, block);
+}
+
+void CookieSettings::Observe(int type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ if (type == chrome::NOTIFICATION_PREF_CHANGED) {
+ DCHECK_EQ(prefs_, Source<PrefService>(source).ptr());
+
+ std::string* name = 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::GetCookieContentSetting(
+ const GURL& url,
+ const GURL& first_party_url,
+ ContentSettingsType content_type,
+ bool setting_cookie) const {
+ if (HostContentSettingsMap::ShouldAllowAllContent(
+ first_party_url, CONTENT_SETTINGS_TYPE_COOKIES))
+ return CONTENT_SETTING_ALLOW;
+
+ // First get any host-specific settings.
+ ContentSetting setting =
+ host_content_settings_map_->GetNonDefaultContentSetting(
+ url, first_party_url, content_type, "");
+
+ // Check if third-party cookie settings deny the cookie. This check makes
+ // sense only for the CONTENT_SETTINGS_TYPE_COOKIES, since the session only
+ // check is based on one url only.
+ if (content_type == CONTENT_SETTINGS_TYPE_COOKIES &&
+ setting == CONTENT_SETTING_DEFAULT &&
+ 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)
+ setting = CONTENT_SETTING_BLOCK;
+ }
+
+ // If no other policy has changed the setting, use the default.
+ if (setting == CONTENT_SETTING_DEFAULT) {
+ setting =
+ host_content_settings_map_->GetDefaultContentSetting(content_type);
+ }
+ return setting;
+}

Powered by Google App Engine
This is Rietveld 408576698