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

Side by Side Diff: chrome/browser/content_settings/pref_content_settings_provider.cc

Issue 5528010: Implement preference and policy based content settings providers. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/chrome/browser/content_settings
Patch Set: updates Created 10 years 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) 2010 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/pref_content_settings_provider.h"
6
7 #include "base/command_line.h"
8 #include "chrome/browser/browser_thread.h"
9 #include "chrome/browser/content_settings/content_settings_details.h"
10 #include "chrome/browser/content_settings/content_settings_pattern.h"
11 #include "chrome/browser/prefs/pref_service.h"
12 #include "chrome/browser/prefs/scoped_pref_update.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/common/chrome_switches.h"
15 #include "chrome/common/notification_details.h"
16 #include "chrome/common/notification_service.h"
17 #include "chrome/common/notification_source.h"
18 #include "chrome/common/pref_names.h"
19
20 namespace {
21
22 // The default setting for each content type.
23 const ContentSetting kDefaultSettings[CONTENT_SETTINGS_NUM_TYPES] = {
24 CONTENT_SETTING_ALLOW, // CONTENT_SETTINGS_TYPE_COOKIES
25 CONTENT_SETTING_ALLOW, // CONTENT_SETTINGS_TYPE_IMAGES
26 CONTENT_SETTING_ALLOW, // CONTENT_SETTINGS_TYPE_JAVASCRIPT
27 CONTENT_SETTING_ALLOW, // CONTENT_SETTINGS_TYPE_PLUGINS
28 CONTENT_SETTING_BLOCK, // CONTENT_SETTINGS_TYPE_POPUPS
29 CONTENT_SETTING_ASK, // Not used for Geolocation
30 CONTENT_SETTING_ASK, // Not used for Notifications
31 };
32
33 // The names of the ContentSettingsType values, for use with dictionary prefs.
34 const char* kTypeNames[CONTENT_SETTINGS_NUM_TYPES] = {
35 "cookies",
36 "images",
37 "javascript",
38 "plugins",
39 "popups",
40 NULL, // Not used for Geolocation
41 NULL, // Not used for Notifications
42 };
43
44
45 // Map ASK for the plugins content type to BLOCK if click-to-play is
46 // not enabled.
47 ContentSetting ClickToPlayFixup(ContentSettingsType content_type,
48 ContentSetting setting) {
49 if (setting == CONTENT_SETTING_ASK &&
50 content_type == CONTENT_SETTINGS_TYPE_PLUGINS &&
51 !CommandLine::ForCurrentProcess()->HasSwitch(
52 switches::kEnableClickToPlay)) {
53 return CONTENT_SETTING_BLOCK;
54 }
55 return setting;
56 }
57
58 } // namespace
59
60 PrefContentSettingsProvider::PrefContentSettingsProvider(Profile* profile)
61 : profile_(profile),
62 is_off_the_record_(profile_->IsOffTheRecord()),
63 updating_preferences_(false) {
64 PrefService* prefs = profile->GetPrefs();
65
66 // Read global defaults.
67 DCHECK_EQ(arraysize(kTypeNames),
68 static_cast<size_t>(CONTENT_SETTINGS_NUM_TYPES));
69 ReadDefaultSettings(true);
70
71 pref_change_registrar_.Init(prefs);
72 pref_change_registrar_.Add(prefs::kDefaultContentSettings, this);
73 notification_registrar_.Add(this, NotificationType::PROFILE_DESTROYED,
74 Source<Profile>(profile_));
75 }
76
77 PrefContentSettingsProvider::~PrefContentSettingsProvider() {
78 UnregisterObservers();
79 }
80
81 bool PrefContentSettingsProvider::CanProvideDefaultSetting(
82 ContentSettingsType content_type) const {
83 return true;
84 }
85
86 ContentSetting PrefContentSettingsProvider::ProvideDefaultSetting(
87 ContentSettingsType content_type) const {
88 AutoLock lock(lock_);
89 return default_content_settings_.settings[content_type];
90 }
91
92 void PrefContentSettingsProvider::UpdateDefaultSetting(
93 ContentSettingsType content_type,
94 ContentSetting setting) {
95 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
96 DCHECK(kTypeNames[content_type] != NULL); // Don't call this for Geolocation.
97 DCHECK(content_type != CONTENT_SETTINGS_TYPE_PLUGINS ||
98 setting != CONTENT_SETTING_ASK ||
99 CommandLine::ForCurrentProcess()->HasSwitch(
100 switches::kEnableClickToPlay));
101
102 // The default settings may not be directly modified for OTR sessions.
103 // Instead, they are synced to the main profile's setting.
104 if (is_off_the_record_)
105 return;
106
107 PrefService* prefs = profile_->GetPrefs();
108
109 DictionaryValue* default_settings_dictionary =
110 prefs->GetMutableDictionary(prefs::kDefaultContentSettings);
111 std::string dictionary_path(kTypeNames[content_type]);
112 updating_preferences_ = true;
113 {
114 AutoLock lock(lock_);
115 ScopedPrefUpdate update(prefs, prefs::kDefaultContentSettings);
116 if ((setting == CONTENT_SETTING_DEFAULT) ||
117 (setting == kDefaultSettings[content_type])) {
118 default_content_settings_.settings[content_type] =
119 kDefaultSettings[content_type];
120 default_settings_dictionary->RemoveWithoutPathExpansion(dictionary_path,
121 NULL);
122 } else {
123 default_content_settings_.settings[content_type] = setting;
124 default_settings_dictionary->SetWithoutPathExpansion(
125 dictionary_path, Value::CreateIntegerValue(setting));
126 }
127 }
128 updating_preferences_ = false;
129
130 NotifyObservers(
131 ContentSettingsDetails(ContentSettingsPattern(), content_type, ""));
132 }
133
134 bool PrefContentSettingsProvider::DefaultSettingIsManaged(
135 ContentSettingsType content_type) const {
136 return false;
137 }
138
139 void PrefContentSettingsProvider::ResetToDefaults() {
140 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
141 AutoLock lock(lock_);
142 default_content_settings_ = ContentSettings();
143 ForceDefaultsToBeExplicit();
144
145 if (!is_off_the_record_) {
146 PrefService* prefs = profile_->GetPrefs();
147 updating_preferences_ = true;
148 prefs->ClearPref(prefs::kDefaultContentSettings);
149 updating_preferences_ = false;
150 }
151 }
152
153 void PrefContentSettingsProvider::Observe(NotificationType type,
154 const NotificationSource& source,
155 const NotificationDetails& details) {
156 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
157
158 if (type == NotificationType::PREF_CHANGED) {
159 DCHECK_EQ(profile_->GetPrefs(), Source<PrefService>(source).ptr());
160 if (updating_preferences_)
161 return;
162
163 std::string* name = Details<std::string>(details).ptr();
164 if (*name == prefs::kDefaultContentSettings) {
165 ReadDefaultSettings(true);
166 } else {
167 NOTREACHED() << "Unexpected preference observed";
168 return;
169 }
170
171 if (!is_off_the_record_) {
172 NotifyObservers(ContentSettingsDetails(
173 ContentSettingsPattern(), CONTENT_SETTINGS_TYPE_DEFAULT, ""));
174 }
175 } else if (type == NotificationType::PROFILE_DESTROYED) {
176 DCHECK_EQ(profile_, Source<Profile>(source).ptr());
177 UnregisterObservers();
178 } else {
179 NOTREACHED() << "Unexpected notification";
180 }
181 }
182
183 void PrefContentSettingsProvider::UnregisterObservers() {
184 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
185 if (!profile_)
186 return;
187 pref_change_registrar_.RemoveAll();
188 notification_registrar_.Remove(this, NotificationType::PROFILE_DESTROYED,
189 Source<Profile>(profile_));
190 profile_ = NULL;
191 }
192
193 void PrefContentSettingsProvider::ReadDefaultSettings(bool overwrite) {
194 PrefService* prefs = profile_->GetPrefs();
195 const DictionaryValue* default_settings_dictionary =
196 prefs->GetDictionary(prefs::kDefaultContentSettings);
197
198 AutoLock lock(lock_);
199
200 if (overwrite)
201 default_content_settings_ = ContentSettings();
202
203 // Careful: The returned value could be NULL if the pref has never been set.
204 if (default_settings_dictionary != NULL) {
205 GetSettingsFromDictionary(default_settings_dictionary,
206 &default_content_settings_);
207 }
208 ForceDefaultsToBeExplicit();
209 }
210
211 void PrefContentSettingsProvider::ForceDefaultsToBeExplicit() {
212 DCHECK_EQ(arraysize(kDefaultSettings),
213 static_cast<size_t>(CONTENT_SETTINGS_NUM_TYPES));
214
215 for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) {
216 if (default_content_settings_.settings[i] == CONTENT_SETTING_DEFAULT)
217 default_content_settings_.settings[i] = kDefaultSettings[i];
218 }
219 }
220
221 void PrefContentSettingsProvider::GetSettingsFromDictionary(
222 const DictionaryValue* dictionary,
223 ContentSettings* settings) {
224 for (DictionaryValue::key_iterator i(dictionary->begin_keys());
225 i != dictionary->end_keys(); ++i) {
226 const std::string& content_type(*i);
227 for (size_t type = 0; type < arraysize(kTypeNames); ++type) {
228 if ((kTypeNames[type] != NULL) && (kTypeNames[type] == content_type)) {
229 int setting = CONTENT_SETTING_DEFAULT;
230 bool found = dictionary->GetIntegerWithoutPathExpansion(content_type,
231 &setting);
232 DCHECK(found);
233 settings->settings[type] = IntToContentSetting(setting);
234 break;
235 }
236 }
237 }
238 // Migrate obsolete cookie prompt mode.
239 if (settings->settings[CONTENT_SETTINGS_TYPE_COOKIES] ==
240 CONTENT_SETTING_ASK)
241 settings->settings[CONTENT_SETTINGS_TYPE_COOKIES] = CONTENT_SETTING_BLOCK;
242
243 settings->settings[CONTENT_SETTINGS_TYPE_PLUGINS] =
244 ClickToPlayFixup(CONTENT_SETTINGS_TYPE_PLUGINS,
245 settings->settings[CONTENT_SETTINGS_TYPE_PLUGINS]);
246 }
247
248 void PrefContentSettingsProvider::NotifyObservers(
249 const ContentSettingsDetails& details) {
250 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
251 if (profile_ == NULL)
252 return;
253 NotificationService::current()->Notify(
254 NotificationType::CONTENT_SETTINGS_CHANGED,
255 Source<HostContentSettingsMap>(profile_->GetHostContentSettingsMap()),
256 Details<const ContentSettingsDetails>(&details));
257 }
258
259
260 // static
261 void PrefContentSettingsProvider::RegisterUserPrefs(PrefService* prefs) {
262 prefs->RegisterDictionaryPref(prefs::kDefaultContentSettings);
263 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698