OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "components/content_settings/core/browser/content_settings_default_prov ider.h" | 5 #include "components/content_settings/core/browser/content_settings_default_prov ider.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/auto_reset.h" | 10 #include "base/auto_reset.h" |
11 #include "base/basictypes.h" | 11 #include "base/basictypes.h" |
12 #include "base/bind.h" | 12 #include "base/bind.h" |
13 #include "base/command_line.h" | 13 #include "base/command_line.h" |
14 #include "base/metrics/histogram.h" | 14 #include "base/metrics/histogram.h" |
15 #include "base/prefs/pref_service.h" | 15 #include "base/prefs/pref_service.h" |
16 #include "base/prefs/scoped_user_pref_update.h" | 16 #include "base/prefs/scoped_user_pref_update.h" |
17 #include "components/content_settings/core/browser/content_settings_rule.h" | 17 #include "components/content_settings/core/browser/content_settings_rule.h" |
18 #include "components/content_settings/core/browser/content_settings_utils.h" | 18 #include "components/content_settings/core/browser/content_settings_utils.h" |
19 #include "components/content_settings/core/common/content_settings.h" | 19 #include "components/content_settings/core/common/content_settings.h" |
20 #include "components/content_settings/core/common/content_settings_pattern.h" | 20 #include "components/content_settings/core/common/content_settings_pattern.h" |
21 #include "components/content_settings/core/common/pref_names.h" | 21 #include "components/content_settings/core/common/pref_names.h" |
22 #include "components/pref_registry/pref_registry_syncable.h" | 22 #include "components/pref_registry/pref_registry_syncable.h" |
23 #include "url/gurl.h" | 23 #include "url/gurl.h" |
24 | 24 |
25 namespace { | 25 namespace { |
26 | 26 |
27 // The default setting for each content type. | 27 struct DefaultContentSettingInfo { |
28 const ContentSetting kDefaultSettings[] = { | 28 // The profile preference associated with this default setting. |
29 CONTENT_SETTING_ALLOW, // CONTENT_SETTINGS_TYPE_COOKIES | 29 const char* pref_name; |
30 CONTENT_SETTING_ALLOW, // CONTENT_SETTINGS_TYPE_IMAGES | 30 |
31 CONTENT_SETTING_ALLOW, // CONTENT_SETTINGS_TYPE_JAVASCRIPT | 31 // The default value of this default setting. |
32 CONTENT_SETTING_ALLOW, // CONTENT_SETTINGS_TYPE_PLUGINS | 32 const ContentSetting default_value; |
33 CONTENT_SETTING_BLOCK, // CONTENT_SETTINGS_TYPE_POPUPS | 33 |
34 CONTENT_SETTING_ASK, // CONTENT_SETTINGS_TYPE_GEOLOCATION | 34 // Whether this preference should be synced. |
35 CONTENT_SETTING_ASK, // CONTENT_SETTINGS_TYPE_NOTIFICATIONS | 35 const bool syncable; |
36 CONTENT_SETTING_DEFAULT, // CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE | 36 }; |
37 CONTENT_SETTING_ASK, // CONTENT_SETTINGS_TYPE_FULLSCREEN | 37 |
38 CONTENT_SETTING_ASK, // CONTENT_SETTINGS_TYPE_MOUSELOCK | 38 // The corresponding preference, default value and syncability for each |
39 CONTENT_SETTING_DEFAULT, // CONTENT_SETTINGS_TYPE_MIXEDSCRIPT | 39 // default content setting. This array must be kept in sync with the enum |
40 CONTENT_SETTING_ASK, // CONTENT_SETTINGS_TYPE_MEDIASTREAM | 40 // |ContentSettingsType|. |
41 CONTENT_SETTING_ASK, // CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC | 41 const DefaultContentSettingInfo kDefaultSettings[] = { |
42 CONTENT_SETTING_ASK, // CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA | 42 {prefs::kDefaultCookiesSetting, CONTENT_SETTING_ALLOW, true}, |
Bernhard Bauer
2015/03/26 10:12:34
Indent these lines by two spaces, and add a space
msramek
2015/03/27 16:17:46
Done.
| |
43 CONTENT_SETTING_DEFAULT, // CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS | 43 {prefs::kDefaultImagesSetting, CONTENT_SETTING_ALLOW, true}, |
44 CONTENT_SETTING_ASK, // CONTENT_SETTINGS_TYPE_PPAPI_BROKER | 44 {prefs::kDefaultJavaScriptSetting, CONTENT_SETTING_ALLOW, true}, |
45 CONTENT_SETTING_ASK, // CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS | 45 {prefs::kDefaultPluginsSetting, CONTENT_SETTING_ALLOW, true}, |
46 CONTENT_SETTING_ASK, // CONTENT_SETTINGS_TYPE_MIDI_SYSEX | 46 {prefs::kDefaultPopupsSetting, CONTENT_SETTING_BLOCK, true}, |
47 CONTENT_SETTING_ASK, // CONTENT_SETTINGS_TYPE_PUSH_MESSAGING | 47 {prefs::kDefaultGeolocationSetting, CONTENT_SETTING_ASK, false}, |
48 CONTENT_SETTING_ALLOW, // CONTENT_SETTINGS_TYPE_SSL_CERT_DECISIONS | 48 {prefs::kDefaultNotificationsSetting, CONTENT_SETTING_ASK, true}, |
49 {prefs::kDefaultAutoSelectCertificateSetting, CONTENT_SETTING_DEFAULT, | |
50 false}, | |
51 {prefs::kDefaultFullScreenSetting, CONTENT_SETTING_ASK, true}, | |
52 {prefs::kDefaultMouseLockSetting, CONTENT_SETTING_ASK, true}, | |
53 {prefs::kDefaultMixedScriptSetting, CONTENT_SETTING_DEFAULT, true}, | |
54 {prefs::kDefaultMediaStreamSetting, CONTENT_SETTING_ASK, false}, | |
55 {prefs::kDefaultMediaStreamMicSetting, CONTENT_SETTING_ASK, false}, | |
56 {prefs::kDefaultMediaStreamCameraSetting, CONTENT_SETTING_ASK, false}, | |
57 {prefs::kDefaultProtocolHandlersSetting, CONTENT_SETTING_DEFAULT, true}, | |
58 {prefs::kDefaultPpapiBrokerSetting, CONTENT_SETTING_ASK, false}, | |
59 {prefs::kDefaultAutomaticDownloadsSetting, CONTENT_SETTING_ASK, true}, | |
60 {prefs::kDefaultMidiSysexSetting, CONTENT_SETTING_ASK, true}, | |
61 {prefs::kDefaultPushMessagingSetting, CONTENT_SETTING_ASK, true}, | |
62 {prefs::kDefaultSSLCertDecisionsSetting, CONTENT_SETTING_ALLOW, false}, | |
49 #if defined(OS_WIN) | 63 #if defined(OS_WIN) |
50 CONTENT_SETTING_ASK, // CONTENT_SETTINGS_TYPE_METRO_SWITCH_TO_DESKTOP | 64 {prefs::kDefaultMetroSwitchToDesktopSetting, CONTENT_SETTING_ASK, true}, |
51 #elif defined(OS_ANDROID) || defined(OS_CHROMEOS) | 65 #elif defined(OS_ANDROID) || defined(OS_CHROMEOS) |
52 CONTENT_SETTING_ASK, // CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER | 66 {prefs::kDefaultProtectedMediaIdentifierSetting, CONTENT_SETTING_ASK, |
67 false}, | |
53 #endif | 68 #endif |
54 CONTENT_SETTING_DEFAULT, // CONTENT_SETTINGS_TYPE_APP_BANNER | 69 {prefs::kDefaultAppBannerSetting, CONTENT_SETTING_DEFAULT, false} |
55 }; | 70 }; |
56 static_assert(arraysize(kDefaultSettings) == CONTENT_SETTINGS_NUM_TYPES, | 71 static_assert(arraysize(kDefaultSettings) == CONTENT_SETTINGS_NUM_TYPES, |
57 "kDefaultSettings should have CONTENT_SETTINGS_NUM_TYPES " | 72 "kDefaultSettings should have CONTENT_SETTINGS_NUM_TYPES " |
58 "elements"); | 73 "elements"); |
59 | 74 |
60 } // namespace | 75 } // namespace |
61 | 76 |
62 namespace content_settings { | 77 namespace content_settings { |
63 | 78 |
64 namespace { | 79 namespace { |
(...skipping 27 matching lines...) Expand all Loading... | |
92 // also include the default values for default content settings. This allows | 107 // also include the default values for default content settings. This allows |
93 // functional tests to get default content settings by reading the preference | 108 // functional tests to get default content settings by reading the preference |
94 // prefs::kDefaultContentSettings via pyauto. | 109 // prefs::kDefaultContentSettings via pyauto. |
95 // TODO(markusheintz): Write pyauto hooks for the content settings map as | 110 // TODO(markusheintz): Write pyauto hooks for the content settings map as |
96 // content settings should be read from the host content settings map. | 111 // content settings should be read from the host content settings map. |
97 base::DictionaryValue* default_content_settings = new base::DictionaryValue(); | 112 base::DictionaryValue* default_content_settings = new base::DictionaryValue(); |
98 registry->RegisterDictionaryPref( | 113 registry->RegisterDictionaryPref( |
99 prefs::kDefaultContentSettings, | 114 prefs::kDefaultContentSettings, |
100 default_content_settings, | 115 default_content_settings, |
101 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); | 116 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); |
117 | |
118 // Register individual default setting preferences. | |
119 // TODO(msramek): The aggregate preference above is deprecated. Remove it | |
120 // after two stable releases. | |
121 for (size_t i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) { | |
Bernhard Bauer
2015/03/26 10:12:34
Use an int unless you really really need size_t.
msramek
2015/03/27 16:17:45
Ah. This is a leftover. I originally used size_t,
| |
122 registry->RegisterIntegerPref( | |
123 kDefaultSettings[i].pref_name, | |
124 kDefaultSettings[i].default_value, | |
125 kDefaultSettings[i].syncable | |
126 ? user_prefs::PrefRegistrySyncable::SYNCABLE_PREF | |
127 : user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); | |
128 } | |
129 | |
130 // Whether the deprecated dictionary preference has already been migrated | |
131 // into the individual preferences in this profile. | |
132 registry->RegisterBooleanPref( | |
133 prefs::kMigratedDefaultContentSettings, | |
134 false, | |
135 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); | |
102 } | 136 } |
103 | 137 |
104 DefaultProvider::DefaultProvider(PrefService* prefs, bool incognito) | 138 DefaultProvider::DefaultProvider(PrefService* prefs, bool incognito) |
105 : prefs_(prefs), | 139 : prefs_(prefs), |
106 is_incognito_(incognito), | 140 is_incognito_(incognito), |
107 updating_preferences_(false) { | 141 updating_preferences_(false) { |
108 DCHECK(prefs_); | 142 DCHECK(prefs_); |
109 | 143 |
144 // Migrate the dictionary of default content settings to the new individual | |
145 // preferences. | |
146 MigrateDefaultSettings(); | |
147 | |
110 // Read global defaults. | 148 // Read global defaults. |
111 ReadDefaultSettings(true); | 149 ReadDefaultSettings(); |
112 | 150 |
113 UMA_HISTOGRAM_ENUMERATION( | 151 UMA_HISTOGRAM_ENUMERATION( |
114 "ContentSettings.DefaultCookiesSetting", | 152 "ContentSettings.DefaultCookiesSetting", |
115 ValueToContentSetting( | 153 IntToContentSetting(prefs_->GetInteger( |
116 default_settings_[CONTENT_SETTINGS_TYPE_COOKIES].get()), | 154 kDefaultSettings[CONTENT_SETTINGS_TYPE_COOKIES].pref_name)), |
117 CONTENT_SETTING_NUM_SETTINGS); | 155 CONTENT_SETTING_NUM_SETTINGS); |
118 UMA_HISTOGRAM_ENUMERATION( | 156 UMA_HISTOGRAM_ENUMERATION( |
119 "ContentSettings.DefaultImagesSetting", | 157 "ContentSettings.DefaultImagesSetting", |
120 ValueToContentSetting( | 158 IntToContentSetting(prefs_->GetInteger( |
121 default_settings_[CONTENT_SETTINGS_TYPE_IMAGES].get()), | 159 kDefaultSettings[CONTENT_SETTINGS_TYPE_IMAGES].pref_name)), |
122 CONTENT_SETTING_NUM_SETTINGS); | 160 CONTENT_SETTING_NUM_SETTINGS); |
123 UMA_HISTOGRAM_ENUMERATION( | 161 UMA_HISTOGRAM_ENUMERATION( |
124 "ContentSettings.DefaultJavaScriptSetting", | 162 "ContentSettings.DefaultJavaScriptSetting", |
125 ValueToContentSetting( | 163 IntToContentSetting(prefs_->GetInteger( |
126 default_settings_[CONTENT_SETTINGS_TYPE_JAVASCRIPT].get()), | 164 kDefaultSettings[CONTENT_SETTINGS_TYPE_JAVASCRIPT].pref_name)), |
127 CONTENT_SETTING_NUM_SETTINGS); | 165 CONTENT_SETTING_NUM_SETTINGS); |
128 UMA_HISTOGRAM_ENUMERATION( | 166 UMA_HISTOGRAM_ENUMERATION( |
129 "ContentSettings.DefaultPluginsSetting", | 167 "ContentSettings.DefaultPluginsSetting", |
130 ValueToContentSetting( | 168 IntToContentSetting(prefs_->GetInteger( |
131 default_settings_[CONTENT_SETTINGS_TYPE_PLUGINS].get()), | 169 kDefaultSettings[CONTENT_SETTINGS_TYPE_PLUGINS].pref_name)), |
132 CONTENT_SETTING_NUM_SETTINGS); | 170 CONTENT_SETTING_NUM_SETTINGS); |
133 UMA_HISTOGRAM_ENUMERATION( | 171 UMA_HISTOGRAM_ENUMERATION( |
134 "ContentSettings.DefaultPopupsSetting", | 172 "ContentSettings.DefaultPopupsSetting", |
135 ValueToContentSetting( | 173 IntToContentSetting(prefs_->GetInteger( |
136 default_settings_[CONTENT_SETTINGS_TYPE_POPUPS].get()), | 174 kDefaultSettings[CONTENT_SETTINGS_TYPE_POPUPS].pref_name)), |
137 CONTENT_SETTING_NUM_SETTINGS); | 175 CONTENT_SETTING_NUM_SETTINGS); |
138 UMA_HISTOGRAM_ENUMERATION( | 176 UMA_HISTOGRAM_ENUMERATION( |
139 "ContentSettings.DefaultLocationSetting", | 177 "ContentSettings.DefaultLocationSetting", |
140 ValueToContentSetting( | 178 IntToContentSetting(prefs_->GetInteger( |
141 default_settings_[CONTENT_SETTINGS_TYPE_GEOLOCATION].get()), | 179 kDefaultSettings[CONTENT_SETTINGS_TYPE_GEOLOCATION].pref_name)), |
142 CONTENT_SETTING_NUM_SETTINGS); | 180 CONTENT_SETTING_NUM_SETTINGS); |
143 UMA_HISTOGRAM_ENUMERATION( | 181 UMA_HISTOGRAM_ENUMERATION( |
144 "ContentSettings.DefaultNotificationsSetting", | 182 "ContentSettings.DefaultNotificationsSetting", |
145 ValueToContentSetting( | 183 IntToContentSetting(prefs_->GetInteger( |
146 default_settings_[CONTENT_SETTINGS_TYPE_NOTIFICATIONS].get()), | 184 kDefaultSettings[CONTENT_SETTINGS_TYPE_NOTIFICATIONS].pref_name)), |
147 CONTENT_SETTING_NUM_SETTINGS); | 185 CONTENT_SETTING_NUM_SETTINGS); |
148 UMA_HISTOGRAM_ENUMERATION( | 186 UMA_HISTOGRAM_ENUMERATION( |
149 "ContentSettings.DefaultMouseCursorSetting", | 187 "ContentSettings.DefaultMouseCursorSetting", |
150 ValueToContentSetting( | 188 IntToContentSetting(prefs_->GetInteger( |
151 default_settings_[CONTENT_SETTINGS_TYPE_MOUSELOCK].get()), | 189 kDefaultSettings[CONTENT_SETTINGS_TYPE_MOUSELOCK].pref_name)), |
152 CONTENT_SETTING_NUM_SETTINGS); | 190 CONTENT_SETTING_NUM_SETTINGS); |
153 UMA_HISTOGRAM_ENUMERATION( | 191 UMA_HISTOGRAM_ENUMERATION( |
154 "ContentSettings.DefaultMediaStreamSetting", | 192 "ContentSettings.DefaultMediaStreamSetting", |
155 ValueToContentSetting( | 193 IntToContentSetting(prefs_->GetInteger( |
156 default_settings_[CONTENT_SETTINGS_TYPE_MEDIASTREAM].get()), | 194 kDefaultSettings[CONTENT_SETTINGS_TYPE_MEDIASTREAM].pref_name)), |
157 CONTENT_SETTING_NUM_SETTINGS); | 195 CONTENT_SETTING_NUM_SETTINGS); |
158 UMA_HISTOGRAM_ENUMERATION( | 196 UMA_HISTOGRAM_ENUMERATION( |
159 "ContentSettings.DefaultMIDISysExSetting", | 197 "ContentSettings.DefaultMIDISysExSetting", |
160 ValueToContentSetting( | 198 IntToContentSetting(prefs_->GetInteger( |
161 default_settings_[CONTENT_SETTINGS_TYPE_MIDI_SYSEX].get()), | 199 kDefaultSettings[CONTENT_SETTINGS_TYPE_MIDI_SYSEX].pref_name)), |
162 CONTENT_SETTING_NUM_SETTINGS); | 200 CONTENT_SETTING_NUM_SETTINGS); |
163 UMA_HISTOGRAM_ENUMERATION( | 201 UMA_HISTOGRAM_ENUMERATION( |
164 "ContentSettings.DefaultPushMessagingSetting", | 202 "ContentSettings.DefaultPushMessagingSetting", |
165 ValueToContentSetting( | 203 IntToContentSetting(prefs_->GetInteger( |
166 default_settings_[CONTENT_SETTINGS_TYPE_PUSH_MESSAGING].get()), | 204 kDefaultSettings[CONTENT_SETTINGS_TYPE_PUSH_MESSAGING].pref_name)), |
167 CONTENT_SETTING_NUM_SETTINGS); | 205 CONTENT_SETTING_NUM_SETTINGS); |
168 | 206 |
169 pref_change_registrar_.Init(prefs_); | 207 pref_change_registrar_.Init(prefs_); |
170 PrefChangeRegistrar::NamedChangeCallback callback = base::Bind( | 208 PrefChangeRegistrar::NamedChangeCallback callback = base::Bind( |
171 &DefaultProvider::OnPreferenceChanged, base::Unretained(this)); | 209 &DefaultProvider::OnPreferenceChanged, base::Unretained(this)); |
172 pref_change_registrar_.Add(prefs::kDefaultContentSettings, callback); | 210 pref_change_registrar_.Add(prefs::kDefaultContentSettings, callback); |
211 | |
212 for (size_t i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) | |
213 pref_change_registrar_.Add(kDefaultSettings[i].pref_name, callback); | |
173 } | 214 } |
174 | 215 |
175 DefaultProvider::~DefaultProvider() { | 216 DefaultProvider::~DefaultProvider() { |
176 } | 217 } |
177 | 218 |
178 bool DefaultProvider::SetWebsiteSetting( | 219 bool DefaultProvider::SetWebsiteSetting( |
179 const ContentSettingsPattern& primary_pattern, | 220 const ContentSettingsPattern& primary_pattern, |
180 const ContentSettingsPattern& secondary_pattern, | 221 const ContentSettingsPattern& secondary_pattern, |
181 ContentSettingsType content_type, | 222 ContentSettingsType content_type, |
182 const ResourceIdentifier& resource_identifier, | 223 const ResourceIdentifier& resource_identifier, |
(...skipping 10 matching lines...) Expand all Loading... | |
193 // The default settings may not be directly modified for OTR sessions. | 234 // The default settings may not be directly modified for OTR sessions. |
194 // Instead, they are synced to the main profile's setting. | 235 // Instead, they are synced to the main profile's setting. |
195 if (is_incognito_) | 236 if (is_incognito_) |
196 return false; | 237 return false; |
197 | 238 |
198 // Put |in_value| in a scoped pointer to ensure that it gets cleaned up | 239 // Put |in_value| in a scoped pointer to ensure that it gets cleaned up |
199 // properly if we don't pass on the ownership. | 240 // properly if we don't pass on the ownership. |
200 scoped_ptr<base::Value> value(in_value); | 241 scoped_ptr<base::Value> value(in_value); |
201 { | 242 { |
202 base::AutoReset<bool> auto_reset(&updating_preferences_, true); | 243 base::AutoReset<bool> auto_reset(&updating_preferences_, true); |
244 base::AutoLock lock(lock_); | |
203 | 245 |
204 // |DefaultProvider| should not send any notifications when holding | 246 ChangeSetting(content_type, value.get()); |
205 // |lock_|. |DictionaryPrefUpdate| destructor and | 247 WriteIndividualPref(content_type, value.get()); |
206 // |PrefService::SetInteger()| send out notifications. As a response, the | |
207 // upper layers may call |GetAllContentSettingRules| which acquires |lock_| | |
208 // again. | |
209 DictionaryPrefUpdate update(prefs_, prefs::kDefaultContentSettings); | |
210 base::DictionaryValue* default_settings_dictionary = update.Get(); | |
211 base::AutoLock lock(lock_); | |
212 if (value.get() == NULL || | |
213 ValueToContentSetting(value.get()) == kDefaultSettings[content_type]) { | |
214 // If |value| is NULL we need to reset the default setting the the | |
215 // hardcoded default. | |
216 default_settings_[content_type].reset( | |
217 new base::FundamentalValue(kDefaultSettings[content_type])); | |
218 | 248 |
219 // Remove the corresponding pref entry since the hardcoded default value | 249 // If the changed setting is syncable, write it to the old dictionary |
220 // is used. | 250 // preference as well, so it can be synced to older versions of Chrome. |
221 default_settings_dictionary->RemoveWithoutPathExpansion( | 251 // TODO(msramek): Remove this after two stable releases. |
222 GetTypeName(content_type), NULL); | 252 if (kDefaultSettings[content_type].syncable) |
223 } else { | 253 WriteDictionaryPref(content_type, value.get()); |
224 default_settings_[content_type].reset(value->DeepCopy()); | |
225 // Transfer ownership of |value| to the |default_settings_dictionary|. | |
226 default_settings_dictionary->SetWithoutPathExpansion( | |
227 GetTypeName(content_type), value.release()); | |
228 } | |
229 } | 254 } |
230 | 255 |
231 NotifyObservers(ContentSettingsPattern(), | 256 NotifyObservers(ContentSettingsPattern(), |
232 ContentSettingsPattern(), | 257 ContentSettingsPattern(), |
233 content_type, | 258 content_type, |
234 std::string()); | 259 std::string()); |
235 | 260 |
236 return true; | 261 return true; |
237 } | 262 } |
238 | 263 |
(...skipping 21 matching lines...) Expand all Loading... | |
260 } | 285 } |
261 | 286 |
262 void DefaultProvider::ShutdownOnUIThread() { | 287 void DefaultProvider::ShutdownOnUIThread() { |
263 DCHECK(CalledOnValidThread()); | 288 DCHECK(CalledOnValidThread()); |
264 DCHECK(prefs_); | 289 DCHECK(prefs_); |
265 RemoveAllObservers(); | 290 RemoveAllObservers(); |
266 pref_change_registrar_.RemoveAll(); | 291 pref_change_registrar_.RemoveAll(); |
267 prefs_ = NULL; | 292 prefs_ = NULL; |
268 } | 293 } |
269 | 294 |
295 void DefaultProvider::ReadDefaultSettings() { | |
296 base::AutoLock lock(lock_); | |
297 for (size_t i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) { | |
298 ContentSettingsType content_type = ContentSettingsType(i); | |
299 ChangeSetting(content_type, ReadIndividualPref(content_type).get()); | |
300 } | |
301 } | |
302 | |
303 bool DefaultProvider::IsValueEmptyOrDefault(ContentSettingsType content_type, | |
304 base::Value* value) { | |
305 return (value == NULL || | |
Bernhard Bauer
2015/03/26 10:12:34
Use nullptr, or just `!value` (which would also be
msramek
2015/03/27 16:17:45
Done.
| |
306 ValueToContentSetting(value) | |
307 == kDefaultSettings[content_type].default_value); | |
308 } | |
309 | |
310 void DefaultProvider::ChangeSetting(ContentSettingsType content_type, | |
311 base::Value* value) { | |
312 if (!value) { | |
313 default_settings_[content_type].reset( | |
314 kDefaultSettings[content_type].default_value != CONTENT_SETTING_DEFAULT | |
315 ? new base::FundamentalValue( | |
316 kDefaultSettings[content_type].default_value) | |
317 : NULL); | |
318 } else { | |
319 default_settings_[content_type].reset(value->DeepCopy()); | |
320 } | |
321 } | |
322 | |
323 void DefaultProvider::WriteIndividualPref(ContentSettingsType content_type, | |
324 base::Value* value) { | |
325 if (IsValueEmptyOrDefault(content_type, value)) { | |
326 prefs_->ClearPref(kDefaultSettings[content_type].pref_name); | |
327 return; | |
328 } | |
329 | |
330 int int_value = kDefaultSettings[content_type].default_value; | |
331 bool is_integer = value->GetAsInteger(&int_value); | |
332 DCHECK(is_integer); | |
333 prefs_->SetInteger(kDefaultSettings[content_type].pref_name, int_value); | |
334 } | |
335 | |
336 void DefaultProvider::WriteDictionaryPref(ContentSettingsType content_type, | |
337 base::Value* value) { | |
338 // |DefaultProvider| should not send any notifications when holding | |
339 // |lock_|. |DictionaryPrefUpdate| destructor and | |
340 // |PrefService::SetInteger()| send out notifications. As a response, the | |
341 // upper layers may call |GetAllContentSettingRules| which acquires |lock_| | |
342 // again. | |
343 DictionaryPrefUpdate update(prefs_, prefs::kDefaultContentSettings); | |
344 base::DictionaryValue* default_settings_dictionary = update.Get(); | |
345 | |
346 if (IsValueEmptyOrDefault(content_type, value)) { | |
347 default_settings_dictionary->RemoveWithoutPathExpansion( | |
348 GetTypeName(content_type), NULL); | |
349 return; | |
350 } | |
351 | |
352 default_settings_dictionary->SetWithoutPathExpansion( | |
353 GetTypeName(content_type), value->DeepCopy()); | |
354 } | |
355 | |
270 void DefaultProvider::OnPreferenceChanged(const std::string& name) { | 356 void DefaultProvider::OnPreferenceChanged(const std::string& name) { |
271 DCHECK(CalledOnValidThread()); | 357 DCHECK(CalledOnValidThread()); |
272 if (updating_preferences_) | 358 if (updating_preferences_) |
273 return; | 359 return; |
274 | 360 |
361 // Write the changed setting from individual preferences to dictionary, | |
362 // or vice versa - depending on which of them changed. | |
363 // TODO(msramek): This is only necessary in the phase of migration between | |
364 // the old dictionary preference and the new individual preferences. Remove | |
365 // this after two stable releases. | |
366 std::vector<ContentSettingsType> to_notify; | |
367 | |
275 if (name == prefs::kDefaultContentSettings) { | 368 if (name == prefs::kDefaultContentSettings) { |
276 ReadDefaultSettings(true); | 369 // If the dictionary preference gets synced from an old version |
370 // of Chrome, we should update all individual preferences that | |
371 // are marked as syncable. | |
372 base::AutoLock lock(lock_); | |
373 base::AutoReset<bool> auto_reset(&updating_preferences_, true); | |
374 | |
375 scoped_ptr<ValueMap> dictionary = ReadDictionaryPref(); | |
376 | |
377 for (ValueMap::iterator it = dictionary->begin(); | |
Bernhard Bauer
2015/03/26 10:12:34
Use a C++11-style loop?
msramek
2015/03/27 16:17:45
Done.
| |
378 it != dictionary->end(); ++it) { | |
379 if (!kDefaultSettings[it->first].syncable) | |
380 continue; | |
381 | |
382 DCHECK(default_settings_.find(it->first) != default_settings_.end()); | |
383 ChangeSetting(it->first, it->second.get()); | |
384 WriteIndividualPref(it->first, it->second.get()); | |
385 to_notify.push_back(it->first); | |
386 } | |
277 } else { | 387 } else { |
278 NOTREACHED() << "Unexpected preference observed"; | 388 // Find out which content setting the preference corresponds to. |
279 return; | 389 ContentSettingsType content_type = CONTENT_SETTINGS_TYPE_DEFAULT; |
390 | |
391 for (size_t i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) { | |
392 if (kDefaultSettings[i].pref_name == name) { | |
393 content_type = ContentSettingsType(i); | |
394 break; | |
395 } | |
396 } | |
397 | |
398 if (content_type == CONTENT_SETTINGS_TYPE_DEFAULT) { | |
399 NOTREACHED() << "Unexpected preference observed"; | |
400 return; | |
401 } | |
402 | |
403 // A new individual preference is changed. If it is syncable, we should | |
404 // change its entry in the dictionary preference as well, so that it | |
405 // can be synced to older versions of Chrome. | |
406 base::AutoLock lock(lock_); | |
407 base::AutoReset<bool> auto_reset(&updating_preferences_, true); | |
408 | |
409 ChangeSetting(content_type, ReadIndividualPref(content_type).get()); | |
410 if (kDefaultSettings[content_type].syncable) | |
411 WriteDictionaryPref(content_type, default_settings_[content_type].get()); | |
412 to_notify.push_back(content_type); | |
280 } | 413 } |
281 | 414 |
282 NotifyObservers(ContentSettingsPattern(), | 415 for (size_t i = 0; i < to_notify.size(); ++i) { |
283 ContentSettingsPattern(), | 416 NotifyObservers(ContentSettingsPattern(), |
284 CONTENT_SETTINGS_TYPE_DEFAULT, | 417 ContentSettingsPattern(), |
285 std::string()); | 418 to_notify[i], |
419 std::string()); | |
420 } | |
286 } | 421 } |
287 | 422 |
288 void DefaultProvider::ReadDefaultSettings(bool overwrite) { | 423 scoped_ptr<base::Value> DefaultProvider::ReadIndividualPref( |
289 base::AutoLock lock(lock_); | 424 ContentSettingsType content_type) { |
425 int int_value = prefs_->GetInteger(kDefaultSettings[content_type].pref_name); | |
426 | |
427 if (int_value == CONTENT_SETTING_DEFAULT) | |
428 return make_scoped_ptr((base::Value*)NULL); | |
Bernhard Bauer
2015/03/26 10:12:35
Use nullptr; that might even allow you to get rid
msramek
2015/03/27 16:17:45
Done.
Cast is necessary here even with nullptr. A
| |
429 else | |
430 return make_scoped_ptr(new base::FundamentalValue(int_value)); | |
431 } | |
432 | |
433 scoped_ptr<DefaultProvider::ValueMap> DefaultProvider::ReadDictionaryPref() { | |
290 const base::DictionaryValue* default_settings_dictionary = | 434 const base::DictionaryValue* default_settings_dictionary = |
291 prefs_->GetDictionary(prefs::kDefaultContentSettings); | 435 prefs_->GetDictionary(prefs::kDefaultContentSettings); |
292 | 436 |
293 if (overwrite) | 437 scoped_ptr<ValueMap> value_map = |
294 default_settings_.clear(); | 438 GetSettingsFromDictionary(default_settings_dictionary); |
295 | 439 |
296 // Careful: The returned value could be NULL if the pref has never been set. | 440 ForceDefaultsToBeExplicit(value_map.get()); |
297 if (default_settings_dictionary) | 441 return value_map.Pass(); |
298 GetSettingsFromDictionary(default_settings_dictionary); | |
299 | |
300 ForceDefaultsToBeExplicit(); | |
301 } | 442 } |
302 | 443 |
303 void DefaultProvider::ForceDefaultsToBeExplicit() { | 444 void DefaultProvider::ForceDefaultsToBeExplicit(ValueMap* value_map) { |
304 for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) { | 445 for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) { |
305 ContentSettingsType type = ContentSettingsType(i); | 446 ContentSettingsType type = ContentSettingsType(i); |
306 if (!default_settings_[type].get() && | 447 if (!(*value_map)[type].get() && |
307 kDefaultSettings[i] != CONTENT_SETTING_DEFAULT) { | 448 kDefaultSettings[i].default_value != CONTENT_SETTING_DEFAULT) { |
308 default_settings_[type].reset( | 449 (*value_map)[type].reset( |
309 new base::FundamentalValue(kDefaultSettings[i])); | 450 new base::FundamentalValue(kDefaultSettings[i].default_value)); |
310 } | 451 } |
311 } | 452 } |
312 } | 453 } |
313 | 454 |
314 void DefaultProvider::GetSettingsFromDictionary( | 455 scoped_ptr<DefaultProvider::ValueMap> |
315 const base::DictionaryValue* dictionary) { | 456 DefaultProvider::GetSettingsFromDictionary( |
457 const base::DictionaryValue* dictionary) { | |
458 if (!dictionary) | |
459 return make_scoped_ptr(new ValueMap()); | |
460 ValueMap* value_map = new ValueMap(); | |
Bernhard Bauer
2015/03/26 10:12:34
Put this into a scoped_ptr, and return it immediat
msramek
2015/03/27 16:17:46
Done. I just found it more elegant to create the s
| |
461 | |
316 for (base::DictionaryValue::Iterator i(*dictionary); | 462 for (base::DictionaryValue::Iterator i(*dictionary); |
317 !i.IsAtEnd(); i.Advance()) { | 463 !i.IsAtEnd(); i.Advance()) { |
318 const std::string& content_type(i.key()); | 464 const std::string& content_type(i.key()); |
319 for (size_t type = 0; type < CONTENT_SETTINGS_NUM_TYPES; ++type) { | 465 for (size_t type = 0; type < CONTENT_SETTINGS_NUM_TYPES; ++type) { |
320 if (content_type == GetTypeName(ContentSettingsType(type))) { | 466 if (content_type == GetTypeName(ContentSettingsType(type))) { |
321 int int_value = CONTENT_SETTING_DEFAULT; | 467 int int_value = CONTENT_SETTING_DEFAULT; |
322 bool is_integer = i.value().GetAsInteger(&int_value); | 468 bool is_integer = i.value().GetAsInteger(&int_value); |
323 DCHECK(is_integer); | 469 DCHECK(is_integer); |
324 default_settings_[ContentSettingsType(type)].reset( | 470 (*value_map)[ContentSettingsType(type)].reset( |
325 new base::FundamentalValue(int_value)); | 471 new base::FundamentalValue(int_value)); |
326 break; | 472 break; |
327 } | 473 } |
328 } | 474 } |
329 } | 475 } |
330 // Migrate obsolete cookie prompt mode. | 476 // Migrate obsolete cookie prompt mode. |
331 if (ValueToContentSetting( | 477 if (ValueToContentSetting( |
332 default_settings_[CONTENT_SETTINGS_TYPE_COOKIES].get()) == | 478 (*value_map)[CONTENT_SETTINGS_TYPE_COOKIES].get()) |
333 CONTENT_SETTING_ASK) { | 479 == CONTENT_SETTING_ASK) { |
334 default_settings_[CONTENT_SETTINGS_TYPE_COOKIES].reset( | 480 (*value_map)[CONTENT_SETTINGS_TYPE_COOKIES].reset( |
335 new base::FundamentalValue(CONTENT_SETTING_BLOCK)); | 481 new base::FundamentalValue(CONTENT_SETTING_BLOCK)); |
336 } | 482 } |
483 | |
484 return make_scoped_ptr(value_map); | |
485 } | |
486 | |
487 void DefaultProvider::MigrateDefaultSettings() { | |
488 // Only do the migration once. | |
489 if (prefs_->GetBoolean(prefs::kMigratedDefaultContentSettings)) | |
490 return; | |
491 | |
492 scoped_ptr<DefaultProvider::ValueMap> value_map = ReadDictionaryPref(); | |
493 | |
494 for (size_t i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) { | |
495 ContentSettingsType content_type = ContentSettingsType(i); | |
496 WriteIndividualPref(content_type, (*value_map)[content_type].get()); | |
497 } | |
498 | |
499 #if defined(OS_ANDROID) || defined(OS_CHROMEOS) | |
500 // For protected media identifier, it is desirable to just reset the setting | |
501 // instead of migrating it from the old preference. | |
502 WriteIndividualPref(CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER, NULL); | |
xhwang
2015/03/20 16:23:30
Thank you!
xhwang
2015/03/24 22:28:49
Just to double check. Will this only reset the "de
| |
503 #endif | |
504 | |
505 prefs_->SetBoolean(prefs::kMigratedDefaultContentSettings, true); | |
337 } | 506 } |
338 | 507 |
339 } // namespace content_settings | 508 } // namespace content_settings |
OLD | NEW |