Chromium Code Reviews| 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 |