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

Side by Side 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, 3 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 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/cookie_settings.h"
6
7 #include "base/command_line.h"
8 #include "base/memory/singleton.h"
9 #include "chrome/browser/content_settings/content_settings_pattern.h"
10 #include "chrome/browser/content_settings/host_content_settings_map.h"
11 #include "chrome/browser/prefs/pref_service.h"
12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/profiles/profile_dependency_manager.h"
14 #include "chrome/browser/profiles/profile_keyed_service.h"
15 #include "chrome/browser/profiles/profile_keyed_service_factory.h"
16 #include "chrome/common/chrome_notification_types.h"
17 #include "chrome/common/chrome_switches.h"
18 #include "chrome/common/pref_names.h"
19 #include "content/browser/browser_thread.h"
20 #include "content/browser/user_metrics.h"
21 #include "content/common/notification_service.h"
22 #include "content/common/notification_source.h"
23 #include "googleurl/src/gurl.h"
24 #include "net/base/net_errors.h"
25 #include "net/base/static_cookie_policy.h"
26
27 namespace {
28
29 // ProfileKeyedFactory is the owner of the ProfileKeyedServices. This wrapper
30 // class allows others to hold shared pointers to CookieSettings.
31 class CookieSettingsWrapper : public ProfileKeyedService {
32 public:
33 explicit CookieSettingsWrapper(scoped_refptr<CookieSettings> cookie_settings)
34 : cookie_settings_(cookie_settings) {}
35 virtual ~CookieSettingsWrapper() {}
36
37 CookieSettings* cookie_settings() { return cookie_settings_.get(); }
38
39 private:
40 // ProfileKeyedService methods:
41 virtual void Shutdown() OVERRIDE {
42 cookie_settings_->ShutdownOnUIThread();
43 }
44
45 scoped_refptr<CookieSettings> cookie_settings_;
46 };
47
48 } // namespace
49
50 class CookieSettings::Factory : public ProfileKeyedServiceFactory {
51 public:
52 static Factory* GetInstance();
53
54 CookieSettingsWrapper* GetWrapperForProfile(Profile* profile);
55
56 private:
57 friend struct DefaultSingletonTraits<Factory>;
58
59 Factory();
60 virtual ~Factory() {}
61
62 // PrefoileKeyedServiceFactory methods:
63 virtual CookieSettingsWrapper* BuildServiceInstanceFor(
64 Profile* profile) const OVERRIDE;
65 virtual bool ServiceRedirectedInIncognito() OVERRIDE { return true; }
66 };
67
68 // static
69 CookieSettings::Factory* CookieSettings::Factory::GetInstance() {
70 return Singleton<CookieSettings::Factory>::get();
71 }
72
73 CookieSettingsWrapper* CookieSettings::Factory::GetWrapperForProfile(
74 Profile* profile) {
75 return static_cast<CookieSettingsWrapper*>(
76 GetServiceForProfile(profile,true));
77 }
78
79 CookieSettings::Factory::Factory()
80 : ProfileKeyedServiceFactory(ProfileDependencyManager::GetInstance()) {
81 }
82
83 CookieSettingsWrapper* CookieSettings::Factory::BuildServiceInstanceFor(
84 Profile* profile) const {
85 scoped_refptr<CookieSettings> cookie_settings = new CookieSettings(
86 profile->GetHostContentSettingsMap(),
87 profile->GetPrefs(),
88 profile->IsOffTheRecord());
89 return new CookieSettingsWrapper(cookie_settings);
90 }
91
92 CookieSettings::CookieSettings(
93 HostContentSettingsMap* host_content_settings_map,
94 PrefService* prefs,
95 bool incognito)
96 : host_content_settings_map_(host_content_settings_map),
97 prefs_(prefs),
98 is_off_the_record_(incognito),
99 block_third_party_cookies_(false) {
100 block_third_party_cookies_ =
101 prefs_->GetBoolean(prefs::kBlockThirdPartyCookies);
102 if (block_third_party_cookies_) {
103 UserMetrics::RecordAction(
104 UserMetricsAction("ThirdPartyCookieBlockingEnabled"));
105 } else {
106 UserMetrics::RecordAction(
107 UserMetricsAction("ThirdPartyCookieBlockingDisabled"));
108 }
109
110 pref_change_registrar_.Init(prefs_);
111 pref_change_registrar_.Add(prefs::kBlockThirdPartyCookies, this);
112 }
113
114 CookieSettings::~CookieSettings() {
115 }
116
117 // static
118 CookieSettings* CookieSettings::GetForProfile(Profile* profile) {
119 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
120 CookieSettings* cookie_settings =
121 Factory::GetInstance()->GetWrapperForProfile(profile)->cookie_settings();
122 DCHECK(cookie_settings);
123 return cookie_settings;
124 }
125
126 ContentSetting CookieSettings::GetDefaultSetting() const {
127 ContentSetting allow_or_block =
128 host_content_settings_map_->GetDefaultContentSetting(
129 CONTENT_SETTINGS_TYPE_COOKIES);
130 DCHECK(allow_or_block == CONTENT_SETTING_ALLOW ||
131 allow_or_block == CONTENT_SETTING_BLOCK);
132 if (allow_or_block == CONTENT_SETTING_BLOCK)
133 return allow_or_block;
134 ContentSetting session_only =
135 host_content_settings_map_->GetDefaultContentSetting(
136 CONTENT_SETTINGS_TYPE_COOKIES_SESSION_ONLY);
137 DCHECK(allow_or_block == CONTENT_SETTING_ALLOW ||
138 allow_or_block == CONTENT_SETTING_SESSION_ONLY);
139 return session_only;
140 }
141
142 bool CookieSettings::IsReadingCookieAllowed(const GURL& url,
143 const GURL& first_party_url) const {
144 ContentSetting setting = GetCookieContentSetting(
145 url, first_party_url, CONTENT_SETTINGS_TYPE_COOKIES, false);
146 DCHECK(setting == CONTENT_SETTING_ALLOW ||
147 setting == CONTENT_SETTING_BLOCK);
148 return setting == CONTENT_SETTING_ALLOW;
149 }
150
151 bool CookieSettings::IsSettingCookieAllowed(const GURL& url,
152 const GURL& first_party_url) const {
153 ContentSetting setting = GetCookieContentSetting(
154 url, first_party_url, CONTENT_SETTINGS_TYPE_COOKIES, true);
155 DCHECK(setting == CONTENT_SETTING_ALLOW ||
156 setting == CONTENT_SETTING_BLOCK);
157 return setting == CONTENT_SETTING_ALLOW;
158 }
159
160 bool CookieSettings::IsCookieSessionOnly(const GURL& origin) const {
161 ContentSetting setting = GetCookieContentSetting(
162 origin, origin, CONTENT_SETTINGS_TYPE_COOKIES_SESSION_ONLY, true);
163 DCHECK(setting == CONTENT_SETTING_ALLOW ||
164 setting == CONTENT_SETTING_SESSION_ONLY);
165 return (setting == CONTENT_SETTING_SESSION_ONLY);
166 }
167
168 void CookieSettings::SetDefaultSetting(ContentSetting setting) {
169 DCHECK(setting == CONTENT_SETTING_ALLOW ||
170 setting == CONTENT_SETTING_SESSION_ONLY ||
171 setting == CONTENT_SETTING_BLOCK);
172 ContentSetting allowed = CONTENT_SETTING_BLOCK;
173 ContentSetting session_only = CONTENT_SETTING_ALLOW;
174 if (setting == CONTENT_SETTING_ALLOW ||
175 setting == CONTENT_SETTING_SESSION_ONLY)
176 allowed = CONTENT_SETTING_ALLOW;
177 if (setting == CONTENT_SETTING_SESSION_ONLY)
178 session_only = CONTENT_SETTING_SESSION_ONLY;
179 host_content_settings_map_->SetDefaultContentSetting(
180 CONTENT_SETTINGS_TYPE_COOKIES, allowed);
181 host_content_settings_map_->SetDefaultContentSetting(
182 CONTENT_SETTINGS_TYPE_COOKIES_SESSION_ONLY, session_only);
183 }
184
185 void CookieSettings::SetCookieSetting(
186 const ContentSettingsPattern& primary_pattern,
187 ContentSetting content_setting) {
188 DCHECK(content_setting == CONTENT_SETTING_ALLOW ||
189 content_setting == CONTENT_SETTING_SESSION_ONLY ||
190 content_setting == CONTENT_SETTING_BLOCK);
191 bool allowed =
192 content_setting == CONTENT_SETTING_ALLOW ||
193 content_setting == CONTENT_SETTING_SESSION_ONLY;
194 bool session_only = (content_setting == CONTENT_SETTING_SESSION_ONLY);
195 host_content_settings_map_->SetContentSetting(
196 primary_pattern, ContentSettingsPattern::Wildcard(),
197 CONTENT_SETTINGS_TYPE_COOKIES, "",
198 allowed ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK);
199 host_content_settings_map_->SetContentSetting(
200 primary_pattern, ContentSettingsPattern::Wildcard(),
201 CONTENT_SETTINGS_TYPE_COOKIES_SESSION_ONLY, "",
202 session_only ? CONTENT_SETTING_SESSION_ONLY : CONTENT_SETTING_ALLOW);
203 }
204
205 void CookieSettings::ResetCookieSetting(
206 const ContentSettingsPattern& primary_pattern) {
207 host_content_settings_map_->SetContentSetting(
208 primary_pattern, ContentSettingsPattern::Wildcard(),
209 CONTENT_SETTINGS_TYPE_COOKIES, "",
210 CONTENT_SETTING_DEFAULT);
211 host_content_settings_map_->SetContentSetting(
212 primary_pattern, ContentSettingsPattern::Wildcard(),
213 CONTENT_SETTINGS_TYPE_COOKIES_SESSION_ONLY, "",
214 CONTENT_SETTING_DEFAULT);
215 }
216
217 void CookieSettings::SetBlockThirdPartyCookies(bool block) {
218 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
219 DCHECK(prefs_);
220
221 // This setting may not be directly modified for OTR sessions. Instead, it
222 // is synced to the main profile's setting.
223 if (is_off_the_record_) {
224 NOTREACHED();
225 return;
226 }
227
228 // If the preference block-third-party-cookies is managed then do not allow to
229 // change it.
230 if (prefs_->IsManagedPreference(prefs::kBlockThirdPartyCookies)) {
231 NOTREACHED();
232 return;
233 }
234
235 {
236 base::AutoLock auto_lock(lock_);
237 block_third_party_cookies_ = block;
238 }
239
240 prefs_->SetBoolean(prefs::kBlockThirdPartyCookies, block);
241 }
242
243 void CookieSettings::Observe(int type,
244 const NotificationSource& source,
245 const NotificationDetails& details) {
246 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
247
248 if (type == chrome::NOTIFICATION_PREF_CHANGED) {
249 DCHECK_EQ(prefs_, Source<PrefService>(source).ptr());
250
251 std::string* name = Details<std::string>(details).ptr();
252 if (*name == prefs::kBlockThirdPartyCookies) {
253 base::AutoLock auto_lock(lock_);
254 block_third_party_cookies_ = prefs_->GetBoolean(
255 prefs::kBlockThirdPartyCookies);
256 } else {
257 NOTREACHED() << "Unexpected preference observed";
258 return;
259 }
260 } else {
261 NOTREACHED() << "Unexpected notification";
262 }
263 }
264
265 void CookieSettings::ShutdownOnUIThread() {
266 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
267 pref_change_registrar_.RemoveAll();
268 }
269
270 ContentSetting CookieSettings::GetCookieContentSetting(
271 const GURL& url,
272 const GURL& first_party_url,
273 ContentSettingsType content_type,
274 bool setting_cookie) const {
275 if (HostContentSettingsMap::ShouldAllowAllContent(
276 first_party_url, CONTENT_SETTINGS_TYPE_COOKIES))
277 return CONTENT_SETTING_ALLOW;
278
279 // First get any host-specific settings.
280 ContentSetting setting =
281 host_content_settings_map_->GetNonDefaultContentSetting(
282 url, first_party_url, content_type, "");
283
284 // Check if third-party cookie settings deny the cookie. This check makes
285 // sense only for the CONTENT_SETTINGS_TYPE_COOKIES, since the session only
286 // check is based on one url only.
287 if (content_type == CONTENT_SETTINGS_TYPE_COOKIES &&
288 setting == CONTENT_SETTING_DEFAULT &&
289 ShouldBlockThirdPartyCookies()) {
290 bool strict = CommandLine::ForCurrentProcess()->HasSwitch(
291 switches::kBlockReadingThirdPartyCookies);
292 net::StaticCookiePolicy policy(strict ?
293 net::StaticCookiePolicy::BLOCK_ALL_THIRD_PARTY_COOKIES :
294 net::StaticCookiePolicy::BLOCK_SETTING_THIRD_PARTY_COOKIES);
295 int rv;
296 if (setting_cookie)
297 rv = policy.CanSetCookie(url, first_party_url);
298 else
299 rv = policy.CanGetCookies(url, first_party_url);
300 DCHECK_NE(net::ERR_IO_PENDING, rv);
301 if (rv != net::OK)
302 setting = CONTENT_SETTING_BLOCK;
303 }
304
305 // If no other policy has changed the setting, use the default.
306 if (setting == CONTENT_SETTING_DEFAULT) {
307 setting =
308 host_content_settings_map_->GetDefaultContentSetting(content_type);
309 }
310 return setting;
311 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698