Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / content_settings / cookie_settings.cc
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/cookie_settings.h"
6
7 #include "base/prefs/pref_service.h"
8 #include "chrome/browser/chrome_notification_types.h"
9 #include "chrome/browser/profiles/incognito_helpers.h"
10 #include "chrome/browser/profiles/profile.h"
11 #include "chrome/common/pref_names.h"
12 #include "components/content_settings/core/browser/content_settings_utils.h"
13 #include "components/content_settings/core/browser/host_content_settings_map.h"
14 #include "components/content_settings/core/common/content_settings_pattern.h"
15 #include "components/keyed_service/content/browser_context_dependency_manager.h"
16 #include "components/keyed_service/core/keyed_service.h"
17 #include "components/pref_registry/pref_registry_syncable.h"
18 #include "content/public/browser/browser_thread.h"
19 #include "content/public/browser/notification_service.h"
20 #include "content/public/browser/notification_source.h"
21 #include "content/public/browser/user_metrics.h"
22 #include "extensions/common/constants.h"
23 #include "net/base/net_errors.h"
24 #include "net/base/static_cookie_policy.h"
25 #include "url/gurl.h"
26
27 using base::UserMetricsAction;
28 using content::BrowserThread;
29
30 namespace {
31
32 bool IsValidSetting(ContentSetting setting) {
33   return (setting == CONTENT_SETTING_ALLOW ||
34           setting == CONTENT_SETTING_SESSION_ONLY ||
35           setting == CONTENT_SETTING_BLOCK);
36 }
37
38 bool IsAllowed(ContentSetting setting) {
39   DCHECK(IsValidSetting(setting));
40   return (setting == CONTENT_SETTING_ALLOW ||
41           setting == CONTENT_SETTING_SESSION_ONLY);
42 }
43
44 }  // namespace
45
46 // static
47 scoped_refptr<CookieSettings> CookieSettings::Factory::GetForProfile(
48     Profile* profile) {
49   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
50   return static_cast<CookieSettings*>(
51       GetInstance()->GetServiceForBrowserContext(profile, true).get());
52 }
53
54 // static
55 CookieSettings::Factory* CookieSettings::Factory::GetInstance() {
56   return Singleton<CookieSettings::Factory>::get();
57 }
58
59 CookieSettings::Factory::Factory()
60     : RefcountedBrowserContextKeyedServiceFactory(
61         "CookieSettings",
62         BrowserContextDependencyManager::GetInstance()) {
63 }
64
65 CookieSettings::Factory::~Factory() {}
66
67 void CookieSettings::Factory::RegisterProfilePrefs(
68     user_prefs::PrefRegistrySyncable* registry) {
69   registry->RegisterBooleanPref(
70       prefs::kBlockThirdPartyCookies,
71       false,
72       user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
73 }
74
75 content::BrowserContext* CookieSettings::Factory::GetBrowserContextToUse(
76     content::BrowserContext* context) const {
77   return chrome::GetBrowserContextRedirectedInIncognito(context);
78 }
79
80 scoped_refptr<RefcountedKeyedService>
81 CookieSettings::Factory::BuildServiceInstanceFor(
82     content::BrowserContext* context) const {
83   Profile* profile = static_cast<Profile*>(context);
84   return new CookieSettings(profile->GetHostContentSettingsMap(),
85                             profile->GetPrefs());
86 }
87
88 CookieSettings::CookieSettings(
89     HostContentSettingsMap* host_content_settings_map,
90     PrefService* prefs)
91     : host_content_settings_map_(host_content_settings_map),
92       block_third_party_cookies_(
93           prefs->GetBoolean(prefs::kBlockThirdPartyCookies)) {
94   if (block_third_party_cookies_) {
95     content::RecordAction(
96         UserMetricsAction("ThirdPartyCookieBlockingEnabled"));
97   } else {
98     content::RecordAction(
99         UserMetricsAction("ThirdPartyCookieBlockingDisabled"));
100   }
101
102   pref_change_registrar_.Init(prefs);
103   pref_change_registrar_.Add(
104       prefs::kBlockThirdPartyCookies,
105       base::Bind(&CookieSettings::OnBlockThirdPartyCookiesChanged,
106                  base::Unretained(this)));
107 }
108
109 ContentSetting
110 CookieSettings::GetDefaultCookieSetting(std::string* provider_id) const {
111   return host_content_settings_map_->GetDefaultContentSetting(
112       CONTENT_SETTINGS_TYPE_COOKIES, provider_id);
113 }
114
115 bool CookieSettings::IsReadingCookieAllowed(const GURL& url,
116                                             const GURL& first_party_url) const {
117   ContentSetting setting = GetCookieSetting(url, first_party_url, false, NULL);
118   return IsAllowed(setting);
119 }
120
121 bool CookieSettings::IsSettingCookieAllowed(const GURL& url,
122                                             const GURL& first_party_url) const {
123   ContentSetting setting = GetCookieSetting(url, first_party_url, true, NULL);
124   return IsAllowed(setting);
125 }
126
127 bool CookieSettings::IsCookieSessionOnly(const GURL& origin) const {
128   ContentSetting setting = GetCookieSetting(origin, origin, true, NULL);
129   DCHECK(IsValidSetting(setting));
130   return (setting == CONTENT_SETTING_SESSION_ONLY);
131 }
132
133 void CookieSettings::GetCookieSettings(
134     ContentSettingsForOneType* settings) const {
135   return host_content_settings_map_->GetSettingsForOneType(
136       CONTENT_SETTINGS_TYPE_COOKIES, std::string(), settings);
137 }
138
139 void CookieSettings::SetDefaultCookieSetting(ContentSetting setting) {
140   DCHECK(IsValidSetting(setting));
141   host_content_settings_map_->SetDefaultContentSetting(
142       CONTENT_SETTINGS_TYPE_COOKIES, setting);
143 }
144
145 void CookieSettings::SetCookieSetting(
146     const ContentSettingsPattern& primary_pattern,
147     const ContentSettingsPattern& secondary_pattern,
148     ContentSetting setting) {
149   DCHECK(IsValidSetting(setting));
150   if (setting == CONTENT_SETTING_SESSION_ONLY) {
151     DCHECK(secondary_pattern == ContentSettingsPattern::Wildcard());
152   }
153   host_content_settings_map_->SetContentSetting(primary_pattern,
154                                                 secondary_pattern,
155                                                 CONTENT_SETTINGS_TYPE_COOKIES,
156                                                 std::string(),
157                                                 setting);
158 }
159
160 void CookieSettings::ResetCookieSetting(
161     const ContentSettingsPattern& primary_pattern,
162     const ContentSettingsPattern& secondary_pattern) {
163   host_content_settings_map_->SetContentSetting(primary_pattern,
164                                                 secondary_pattern,
165                                                 CONTENT_SETTINGS_TYPE_COOKIES,
166                                                 std::string(),
167                                                 CONTENT_SETTING_DEFAULT);
168 }
169
170 void CookieSettings::ShutdownOnUIThread() {
171   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
172   pref_change_registrar_.RemoveAll();
173 }
174
175 ContentSetting CookieSettings::GetCookieSetting(
176     const GURL& url,
177     const GURL& first_party_url,
178     bool setting_cookie,
179     content_settings::SettingSource* source) const {
180   if (HostContentSettingsMap::ShouldAllowAllContent(
181         url, first_party_url, CONTENT_SETTINGS_TYPE_COOKIES))
182     return CONTENT_SETTING_ALLOW;
183
184   // First get any host-specific settings.
185   content_settings::SettingInfo info;
186   scoped_ptr<base::Value> value = host_content_settings_map_->GetWebsiteSetting(
187       url,
188       first_party_url,
189       CONTENT_SETTINGS_TYPE_COOKIES,
190       std::string(),
191       &info);
192   if (source)
193     *source = info.source;
194
195   // If no explicit exception has been made and third-party cookies are blocked
196   // by default, apply that rule.
197   if (info.primary_pattern.MatchesAllHosts() &&
198       info.secondary_pattern.MatchesAllHosts() &&
199       ShouldBlockThirdPartyCookies() &&
200       !first_party_url.SchemeIs(extensions::kExtensionScheme)) {
201     net::StaticCookiePolicy policy(
202         net::StaticCookiePolicy::BLOCK_ALL_THIRD_PARTY_COOKIES);
203     int rv;
204     if (setting_cookie)
205       rv = policy.CanSetCookie(url, first_party_url);
206     else
207       rv = policy.CanGetCookies(url, first_party_url);
208     DCHECK_NE(net::ERR_IO_PENDING, rv);
209     if (rv != net::OK)
210       return CONTENT_SETTING_BLOCK;
211   }
212
213   // We should always have a value, at least from the default provider.
214   DCHECK(value.get());
215   return content_settings::ValueToContentSetting(value.get());
216 }
217
218 CookieSettings::~CookieSettings() {}
219
220 void CookieSettings::OnBlockThirdPartyCookiesChanged() {
221   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
222
223   base::AutoLock auto_lock(lock_);
224   block_third_party_cookies_ = pref_change_registrar_.prefs()->GetBoolean(
225       prefs::kBlockThirdPartyCookies);
226 }
227
228 bool CookieSettings::ShouldBlockThirdPartyCookies() const {
229   base::AutoLock auto_lock(lock_);
230   return block_third_party_cookies_;
231 }