summaryrefslogtreecommitdiffstats
path: root/components/content_settings
diff options
context:
space:
mode:
authormsramek <msramek@chromium.org>2015-03-24 06:27:07 -0700
committerCommit bot <commit-bot@chromium.org>2015-03-24 13:27:45 +0000
commit4e9ea92c1cdcb084be89748a08f5b2e05b37c950 (patch)
tree96182f8cfcbaebf3c62597b10304ed8b9574f5cb /components/content_settings
parentd5d61bfbe952814e030869af35ef338eb2ee9930 (diff)
downloadchromium_src-4e9ea92c1cdcb084be89748a08f5b2e05b37c950.zip
chromium_src-4e9ea92c1cdcb084be89748a08f5b2e05b37c950.tar.gz
chromium_src-4e9ea92c1cdcb084be89748a08f5b2e05b37c950.tar.bz2
Split the default content settings into syncable and nonsyncable.
Parallel to the default content setting dictionary pref, I added N individual integer prefs. Syncable preferences are kept in sync with the matching dictionary entries, so that they can be synced to/from old versions of Chrome. Default provider used the following, somewhat complicated, logic: - when we read from a dictionary and there is no value for a particular content type, we reset the value to default, except if default=CONTENT_SETTING_DEFAULT, then we reset it to NULL - when someone calls SetWebsiteSetting() with value NULL, we reset the value to default, except if default=CONTENT_SETTING_DEFAULT, then we keep NULL I kept this logic when working with the individual preferences, which explains why there are a lot of "if NULL" and "if default==..." checks. To make sure that we don't forget these checks on any read/write, I added two pairs of methods for reading to/writing from individual prefs/dictionary pref: (Read|Write)(Individual|Dictionary)Pref\(\) and a wrapper for writing to the cache ChangeSetting(). BUG=452388 TESTED=Between trunk and old M40 stable. Syncable settings are synced both ways. Nonsyncable settings are not synced either way. Review URL: https://codereview.chromium.org/1004733003 Cr-Commit-Position: refs/heads/master@{#321988}
Diffstat (limited to 'components/content_settings')
-rw-r--r--components/content_settings/core/browser/content_settings_default_provider.cc369
-rw-r--r--components/content_settings/core/browser/content_settings_default_provider.h53
-rw-r--r--components/content_settings/core/common/pref_names.cc57
-rw-r--r--components/content_settings/core/common/pref_names.h30
4 files changed, 398 insertions, 111 deletions
diff --git a/components/content_settings/core/browser/content_settings_default_provider.cc b/components/content_settings/core/browser/content_settings_default_provider.cc
index bd0f474..a0a3e33 100644
--- a/components/content_settings/core/browser/content_settings_default_provider.cc
+++ b/components/content_settings/core/browser/content_settings_default_provider.cc
@@ -24,34 +24,49 @@
namespace {
-// The default setting for each content type.
-const ContentSetting kDefaultSettings[] = {
- CONTENT_SETTING_ALLOW, // CONTENT_SETTINGS_TYPE_COOKIES
- CONTENT_SETTING_ALLOW, // CONTENT_SETTINGS_TYPE_IMAGES
- CONTENT_SETTING_ALLOW, // CONTENT_SETTINGS_TYPE_JAVASCRIPT
- CONTENT_SETTING_ALLOW, // CONTENT_SETTINGS_TYPE_PLUGINS
- CONTENT_SETTING_BLOCK, // CONTENT_SETTINGS_TYPE_POPUPS
- CONTENT_SETTING_ASK, // CONTENT_SETTINGS_TYPE_GEOLOCATION
- CONTENT_SETTING_ASK, // CONTENT_SETTINGS_TYPE_NOTIFICATIONS
- CONTENT_SETTING_DEFAULT, // CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE
- CONTENT_SETTING_ASK, // CONTENT_SETTINGS_TYPE_FULLSCREEN
- CONTENT_SETTING_ASK, // CONTENT_SETTINGS_TYPE_MOUSELOCK
- CONTENT_SETTING_DEFAULT, // CONTENT_SETTINGS_TYPE_MIXEDSCRIPT
- CONTENT_SETTING_ASK, // CONTENT_SETTINGS_TYPE_MEDIASTREAM
- CONTENT_SETTING_ASK, // CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
- CONTENT_SETTING_ASK, // CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA
- CONTENT_SETTING_DEFAULT, // CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS
- CONTENT_SETTING_ASK, // CONTENT_SETTINGS_TYPE_PPAPI_BROKER
- CONTENT_SETTING_ASK, // CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS
- CONTENT_SETTING_ASK, // CONTENT_SETTINGS_TYPE_MIDI_SYSEX
- CONTENT_SETTING_ASK, // CONTENT_SETTINGS_TYPE_PUSH_MESSAGING
- CONTENT_SETTING_ALLOW, // CONTENT_SETTINGS_TYPE_SSL_CERT_DECISIONS
+struct DefaultContentSettingInfo {
+ // The profile preference associated with this default setting.
+ const char* pref_name;
+
+ // The default value of this default setting.
+ const ContentSetting default_value;
+
+ // Whether this preference should be synced.
+ const bool syncable;
+};
+
+// The corresponding preference, default value and syncability for each
+// default content setting. This array must be kept in sync with the enum
+// |ContentSettingsType|.
+const DefaultContentSettingInfo kDefaultSettings[] = {
+ {prefs::kDefaultCookiesSetting, CONTENT_SETTING_ALLOW, true},
+ {prefs::kDefaultImagesSetting, CONTENT_SETTING_ALLOW, true},
+ {prefs::kDefaultJavaScriptSetting, CONTENT_SETTING_ALLOW, true},
+ {prefs::kDefaultPluginsSetting, CONTENT_SETTING_ALLOW, true},
+ {prefs::kDefaultPopupsSetting, CONTENT_SETTING_BLOCK, true},
+ {prefs::kDefaultGeolocationSetting, CONTENT_SETTING_ASK, false},
+ {prefs::kDefaultNotificationsSetting, CONTENT_SETTING_ASK, true},
+ {prefs::kDefaultAutoSelectCertificateSetting, CONTENT_SETTING_DEFAULT,
+ false},
+ {prefs::kDefaultFullScreenSetting, CONTENT_SETTING_ASK, true},
+ {prefs::kDefaultMouseLockSetting, CONTENT_SETTING_ASK, true},
+ {prefs::kDefaultMixedScriptSetting, CONTENT_SETTING_DEFAULT, true},
+ {prefs::kDefaultMediaStreamSetting, CONTENT_SETTING_ASK, false},
+ {prefs::kDefaultMediaStreamMicSetting, CONTENT_SETTING_ASK, false},
+ {prefs::kDefaultMediaStreamCameraSetting, CONTENT_SETTING_ASK, false},
+ {prefs::kDefaultProtocolHandlersSetting, CONTENT_SETTING_DEFAULT, true},
+ {prefs::kDefaultPpapiBrokerSetting, CONTENT_SETTING_ASK, false},
+ {prefs::kDefaultAutomaticDownloadsSetting, CONTENT_SETTING_ASK, true},
+ {prefs::kDefaultMidiSysexSetting, CONTENT_SETTING_ASK, true},
+ {prefs::kDefaultPushMessagingSetting, CONTENT_SETTING_ASK, true},
+ {prefs::kDefaultSSLCertDecisionsSetting, CONTENT_SETTING_ALLOW, false},
#if defined(OS_WIN)
- CONTENT_SETTING_ASK, // CONTENT_SETTINGS_TYPE_METRO_SWITCH_TO_DESKTOP
+ {prefs::kDefaultMetroSwitchToDesktopSetting, CONTENT_SETTING_ASK, true},
#elif defined(OS_ANDROID) || defined(OS_CHROMEOS)
- CONTENT_SETTING_ASK, // CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER
+ {prefs::kDefaultProtectedMediaIdentifierSetting, CONTENT_SETTING_ASK,
+ false},
#endif
- CONTENT_SETTING_DEFAULT, // CONTENT_SETTINGS_TYPE_APP_BANNER
+ {prefs::kDefaultAppBannerSetting, CONTENT_SETTING_DEFAULT, false}
};
static_assert(arraysize(kDefaultSettings) == CONTENT_SETTINGS_NUM_TYPES,
"kDefaultSettings should have CONTENT_SETTINGS_NUM_TYPES "
@@ -99,6 +114,25 @@ void DefaultProvider::RegisterProfilePrefs(
prefs::kDefaultContentSettings,
default_content_settings,
user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
+
+ // Register individual default setting preferences.
+ // TODO(msramek): The aggregate preference above is deprecated. Remove it
+ // after two stable releases.
+ for (size_t i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) {
+ registry->RegisterIntegerPref(
+ kDefaultSettings[i].pref_name,
+ kDefaultSettings[i].default_value,
+ kDefaultSettings[i].syncable
+ ? user_prefs::PrefRegistrySyncable::SYNCABLE_PREF
+ : user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
+ }
+
+ // Whether the deprecated dictionary preference has already been migrated
+ // into the individual preferences in this profile.
+ registry->RegisterBooleanPref(
+ prefs::kMigratedDefaultContentSettings,
+ false,
+ user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
}
DefaultProvider::DefaultProvider(PrefService* prefs, bool incognito)
@@ -107,69 +141,76 @@ DefaultProvider::DefaultProvider(PrefService* prefs, bool incognito)
updating_preferences_(false) {
DCHECK(prefs_);
+ // Migrate the dictionary of default content settings to the new individual
+ // preferences.
+ MigrateDefaultSettings();
+
// Read global defaults.
- ReadDefaultSettings(true);
+ ReadDefaultSettings();
UMA_HISTOGRAM_ENUMERATION(
"ContentSettings.DefaultCookiesSetting",
- ValueToContentSetting(
- default_settings_[CONTENT_SETTINGS_TYPE_COOKIES].get()),
+ IntToContentSetting(prefs_->GetInteger(
+ kDefaultSettings[CONTENT_SETTINGS_TYPE_COOKIES].pref_name)),
CONTENT_SETTING_NUM_SETTINGS);
UMA_HISTOGRAM_ENUMERATION(
"ContentSettings.DefaultImagesSetting",
- ValueToContentSetting(
- default_settings_[CONTENT_SETTINGS_TYPE_IMAGES].get()),
+ IntToContentSetting(prefs_->GetInteger(
+ kDefaultSettings[CONTENT_SETTINGS_TYPE_IMAGES].pref_name)),
CONTENT_SETTING_NUM_SETTINGS);
UMA_HISTOGRAM_ENUMERATION(
"ContentSettings.DefaultJavaScriptSetting",
- ValueToContentSetting(
- default_settings_[CONTENT_SETTINGS_TYPE_JAVASCRIPT].get()),
+ IntToContentSetting(prefs_->GetInteger(
+ kDefaultSettings[CONTENT_SETTINGS_TYPE_JAVASCRIPT].pref_name)),
CONTENT_SETTING_NUM_SETTINGS);
UMA_HISTOGRAM_ENUMERATION(
"ContentSettings.DefaultPluginsSetting",
- ValueToContentSetting(
- default_settings_[CONTENT_SETTINGS_TYPE_PLUGINS].get()),
+ IntToContentSetting(prefs_->GetInteger(
+ kDefaultSettings[CONTENT_SETTINGS_TYPE_PLUGINS].pref_name)),
CONTENT_SETTING_NUM_SETTINGS);
UMA_HISTOGRAM_ENUMERATION(
"ContentSettings.DefaultPopupsSetting",
- ValueToContentSetting(
- default_settings_[CONTENT_SETTINGS_TYPE_POPUPS].get()),
+ IntToContentSetting(prefs_->GetInteger(
+ kDefaultSettings[CONTENT_SETTINGS_TYPE_POPUPS].pref_name)),
CONTENT_SETTING_NUM_SETTINGS);
UMA_HISTOGRAM_ENUMERATION(
"ContentSettings.DefaultLocationSetting",
- ValueToContentSetting(
- default_settings_[CONTENT_SETTINGS_TYPE_GEOLOCATION].get()),
+ IntToContentSetting(prefs_->GetInteger(
+ kDefaultSettings[CONTENT_SETTINGS_TYPE_GEOLOCATION].pref_name)),
CONTENT_SETTING_NUM_SETTINGS);
UMA_HISTOGRAM_ENUMERATION(
"ContentSettings.DefaultNotificationsSetting",
- ValueToContentSetting(
- default_settings_[CONTENT_SETTINGS_TYPE_NOTIFICATIONS].get()),
+ IntToContentSetting(prefs_->GetInteger(
+ kDefaultSettings[CONTENT_SETTINGS_TYPE_NOTIFICATIONS].pref_name)),
CONTENT_SETTING_NUM_SETTINGS);
UMA_HISTOGRAM_ENUMERATION(
"ContentSettings.DefaultMouseCursorSetting",
- ValueToContentSetting(
- default_settings_[CONTENT_SETTINGS_TYPE_MOUSELOCK].get()),
+ IntToContentSetting(prefs_->GetInteger(
+ kDefaultSettings[CONTENT_SETTINGS_TYPE_MOUSELOCK].pref_name)),
CONTENT_SETTING_NUM_SETTINGS);
UMA_HISTOGRAM_ENUMERATION(
"ContentSettings.DefaultMediaStreamSetting",
- ValueToContentSetting(
- default_settings_[CONTENT_SETTINGS_TYPE_MEDIASTREAM].get()),
+ IntToContentSetting(prefs_->GetInteger(
+ kDefaultSettings[CONTENT_SETTINGS_TYPE_MEDIASTREAM].pref_name)),
CONTENT_SETTING_NUM_SETTINGS);
UMA_HISTOGRAM_ENUMERATION(
"ContentSettings.DefaultMIDISysExSetting",
- ValueToContentSetting(
- default_settings_[CONTENT_SETTINGS_TYPE_MIDI_SYSEX].get()),
+ IntToContentSetting(prefs_->GetInteger(
+ kDefaultSettings[CONTENT_SETTINGS_TYPE_MIDI_SYSEX].pref_name)),
CONTENT_SETTING_NUM_SETTINGS);
UMA_HISTOGRAM_ENUMERATION(
"ContentSettings.DefaultPushMessagingSetting",
- ValueToContentSetting(
- default_settings_[CONTENT_SETTINGS_TYPE_PUSH_MESSAGING].get()),
+ IntToContentSetting(prefs_->GetInteger(
+ kDefaultSettings[CONTENT_SETTINGS_TYPE_PUSH_MESSAGING].pref_name)),
CONTENT_SETTING_NUM_SETTINGS);
pref_change_registrar_.Init(prefs_);
PrefChangeRegistrar::NamedChangeCallback callback = base::Bind(
&DefaultProvider::OnPreferenceChanged, base::Unretained(this));
pref_change_registrar_.Add(prefs::kDefaultContentSettings, callback);
+
+ for (size_t i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i)
+ pref_change_registrar_.Add(kDefaultSettings[i].pref_name, callback);
}
DefaultProvider::~DefaultProvider() {
@@ -200,32 +241,16 @@ bool DefaultProvider::SetWebsiteSetting(
scoped_ptr<base::Value> value(in_value);
{
base::AutoReset<bool> auto_reset(&updating_preferences_, true);
-
- // |DefaultProvider| should not send any notifications when holding
- // |lock_|. |DictionaryPrefUpdate| destructor and
- // |PrefService::SetInteger()| send out notifications. As a response, the
- // upper layers may call |GetAllContentSettingRules| which acquires |lock_|
- // again.
- DictionaryPrefUpdate update(prefs_, prefs::kDefaultContentSettings);
- base::DictionaryValue* default_settings_dictionary = update.Get();
base::AutoLock lock(lock_);
- if (value.get() == NULL ||
- ValueToContentSetting(value.get()) == kDefaultSettings[content_type]) {
- // If |value| is NULL we need to reset the default setting the the
- // hardcoded default.
- default_settings_[content_type].reset(
- new base::FundamentalValue(kDefaultSettings[content_type]));
-
- // Remove the corresponding pref entry since the hardcoded default value
- // is used.
- default_settings_dictionary->RemoveWithoutPathExpansion(
- GetTypeName(content_type), NULL);
- } else {
- default_settings_[content_type].reset(value->DeepCopy());
- // Transfer ownership of |value| to the |default_settings_dictionary|.
- default_settings_dictionary->SetWithoutPathExpansion(
- GetTypeName(content_type), value.release());
- }
+
+ ChangeSetting(content_type, value.get());
+ WriteIndividualPref(content_type, value.get());
+
+ // If the changed setting is syncable, write it to the old dictionary
+ // preference as well, so it can be synced to older versions of Chrome.
+ // TODO(msramek): Remove this after two stable releases.
+ if (kDefaultSettings[content_type].syncable)
+ WriteDictionaryPref(content_type, value.get());
}
NotifyObservers(ContentSettingsPattern(),
@@ -267,52 +292,173 @@ void DefaultProvider::ShutdownOnUIThread() {
prefs_ = NULL;
}
+void DefaultProvider::ReadDefaultSettings() {
+ base::AutoLock lock(lock_);
+ for (size_t i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) {
+ ContentSettingsType content_type = ContentSettingsType(i);
+ ChangeSetting(content_type, ReadIndividualPref(content_type).get());
+ }
+}
+
+bool DefaultProvider::IsValueEmptyOrDefault(ContentSettingsType content_type,
+ base::Value* value) {
+ return (value == NULL ||
+ ValueToContentSetting(value)
+ == kDefaultSettings[content_type].default_value);
+}
+
+void DefaultProvider::ChangeSetting(ContentSettingsType content_type,
+ base::Value* value) {
+ if (!value) {
+ default_settings_[content_type].reset(
+ kDefaultSettings[content_type].default_value != CONTENT_SETTING_DEFAULT
+ ? new base::FundamentalValue(
+ kDefaultSettings[content_type].default_value)
+ : NULL);
+ } else {
+ default_settings_[content_type].reset(value->DeepCopy());
+ }
+}
+
+void DefaultProvider::WriteIndividualPref(ContentSettingsType content_type,
+ base::Value* value) {
+ if (IsValueEmptyOrDefault(content_type, value)) {
+ prefs_->ClearPref(kDefaultSettings[content_type].pref_name);
+ return;
+ }
+
+ int int_value = kDefaultSettings[content_type].default_value;
+ bool is_integer = value->GetAsInteger(&int_value);
+ DCHECK(is_integer);
+ prefs_->SetInteger(kDefaultSettings[content_type].pref_name, int_value);
+}
+
+void DefaultProvider::WriteDictionaryPref(ContentSettingsType content_type,
+ base::Value* value) {
+ // |DefaultProvider| should not send any notifications when holding
+ // |lock_|. |DictionaryPrefUpdate| destructor and
+ // |PrefService::SetInteger()| send out notifications. As a response, the
+ // upper layers may call |GetAllContentSettingRules| which acquires |lock_|
+ // again.
+ DictionaryPrefUpdate update(prefs_, prefs::kDefaultContentSettings);
+ base::DictionaryValue* default_settings_dictionary = update.Get();
+
+ if (IsValueEmptyOrDefault(content_type, value)) {
+ default_settings_dictionary->RemoveWithoutPathExpansion(
+ GetTypeName(content_type), NULL);
+ return;
+ }
+
+ default_settings_dictionary->SetWithoutPathExpansion(
+ GetTypeName(content_type), value->DeepCopy());
+}
+
void DefaultProvider::OnPreferenceChanged(const std::string& name) {
DCHECK(CalledOnValidThread());
if (updating_preferences_)
return;
+ // Write the changed setting from individual preferences to dictionary,
+ // or vice versa - depending on which of them changed.
+ // TODO(msramek): This is only necessary in the phase of migration between
+ // the old dictionary preference and the new individual preferences. Remove
+ // this after two stable releases.
+ std::vector<ContentSettingsType> to_notify;
+
if (name == prefs::kDefaultContentSettings) {
- ReadDefaultSettings(true);
+ // If the dictionary preference gets synced from an old version
+ // of Chrome, we should update all individual preferences that
+ // are marked as syncable.
+ base::AutoLock lock(lock_);
+ base::AutoReset<bool> auto_reset(&updating_preferences_, true);
+
+ scoped_ptr<ValueMap> dictionary = ReadDictionaryPref();
+
+ for (ValueMap::iterator it = dictionary->begin();
+ it != dictionary->end(); ++it) {
+ if (!kDefaultSettings[it->first].syncable)
+ continue;
+
+ DCHECK(default_settings_.find(it->first) != default_settings_.end());
+ ChangeSetting(it->first, it->second.get());
+ WriteIndividualPref(it->first, it->second.get());
+ to_notify.push_back(it->first);
+ }
} else {
- NOTREACHED() << "Unexpected preference observed";
- return;
+ // Find out which content setting the preference corresponds to.
+ ContentSettingsType content_type = CONTENT_SETTINGS_TYPE_DEFAULT;
+
+ for (size_t i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) {
+ if (kDefaultSettings[i].pref_name == name) {
+ content_type = ContentSettingsType(i);
+ break;
+ }
+ }
+
+ if (content_type == CONTENT_SETTINGS_TYPE_DEFAULT) {
+ NOTREACHED() << "Unexpected preference observed";
+ return;
+ }
+
+ // A new individual preference is changed. If it is syncable, we should
+ // change its entry in the dictionary preference as well, so that it
+ // can be synced to older versions of Chrome.
+ base::AutoLock lock(lock_);
+ base::AutoReset<bool> auto_reset(&updating_preferences_, true);
+
+ ChangeSetting(content_type, ReadIndividualPref(content_type).get());
+ if (kDefaultSettings[content_type].syncable)
+ WriteDictionaryPref(content_type, default_settings_[content_type].get());
+ to_notify.push_back(content_type);
}
- NotifyObservers(ContentSettingsPattern(),
- ContentSettingsPattern(),
- CONTENT_SETTINGS_TYPE_DEFAULT,
- std::string());
+ for (size_t i = 0; i < to_notify.size(); ++i) {
+ NotifyObservers(ContentSettingsPattern(),
+ ContentSettingsPattern(),
+ to_notify[i],
+ std::string());
+ }
}
-void DefaultProvider::ReadDefaultSettings(bool overwrite) {
- base::AutoLock lock(lock_);
+scoped_ptr<base::Value> DefaultProvider::ReadIndividualPref(
+ ContentSettingsType content_type) {
+ int int_value = prefs_->GetInteger(kDefaultSettings[content_type].pref_name);
+
+ if (int_value == CONTENT_SETTING_DEFAULT)
+ return make_scoped_ptr((base::Value*)NULL);
+ else
+ return make_scoped_ptr(new base::FundamentalValue(int_value));
+}
+
+scoped_ptr<DefaultProvider::ValueMap> DefaultProvider::ReadDictionaryPref() {
const base::DictionaryValue* default_settings_dictionary =
prefs_->GetDictionary(prefs::kDefaultContentSettings);
- if (overwrite)
- default_settings_.clear();
-
- // Careful: The returned value could be NULL if the pref has never been set.
- if (default_settings_dictionary)
- GetSettingsFromDictionary(default_settings_dictionary);
+ scoped_ptr<ValueMap> value_map =
+ GetSettingsFromDictionary(default_settings_dictionary);
- ForceDefaultsToBeExplicit();
+ ForceDefaultsToBeExplicit(value_map.get());
+ return value_map.Pass();
}
-void DefaultProvider::ForceDefaultsToBeExplicit() {
+void DefaultProvider::ForceDefaultsToBeExplicit(ValueMap* value_map) {
for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) {
ContentSettingsType type = ContentSettingsType(i);
- if (!default_settings_[type].get() &&
- kDefaultSettings[i] != CONTENT_SETTING_DEFAULT) {
- default_settings_[type].reset(
- new base::FundamentalValue(kDefaultSettings[i]));
+ if (!(*value_map)[type].get() &&
+ kDefaultSettings[i].default_value != CONTENT_SETTING_DEFAULT) {
+ (*value_map)[type].reset(
+ new base::FundamentalValue(kDefaultSettings[i].default_value));
}
}
}
-void DefaultProvider::GetSettingsFromDictionary(
- const base::DictionaryValue* dictionary) {
+scoped_ptr<DefaultProvider::ValueMap>
+ DefaultProvider::GetSettingsFromDictionary(
+ const base::DictionaryValue* dictionary) {
+ if (!dictionary)
+ return make_scoped_ptr(new ValueMap());
+ ValueMap* value_map = new ValueMap();
+
for (base::DictionaryValue::Iterator i(*dictionary);
!i.IsAtEnd(); i.Advance()) {
const std::string& content_type(i.key());
@@ -321,7 +467,7 @@ void DefaultProvider::GetSettingsFromDictionary(
int int_value = CONTENT_SETTING_DEFAULT;
bool is_integer = i.value().GetAsInteger(&int_value);
DCHECK(is_integer);
- default_settings_[ContentSettingsType(type)].reset(
+ (*value_map)[ContentSettingsType(type)].reset(
new base::FundamentalValue(int_value));
break;
}
@@ -329,11 +475,34 @@ void DefaultProvider::GetSettingsFromDictionary(
}
// Migrate obsolete cookie prompt mode.
if (ValueToContentSetting(
- default_settings_[CONTENT_SETTINGS_TYPE_COOKIES].get()) ==
- CONTENT_SETTING_ASK) {
- default_settings_[CONTENT_SETTINGS_TYPE_COOKIES].reset(
+ (*value_map)[CONTENT_SETTINGS_TYPE_COOKIES].get())
+ == CONTENT_SETTING_ASK) {
+ (*value_map)[CONTENT_SETTINGS_TYPE_COOKIES].reset(
new base::FundamentalValue(CONTENT_SETTING_BLOCK));
}
+
+ return make_scoped_ptr(value_map);
+}
+
+void DefaultProvider::MigrateDefaultSettings() {
+ // Only do the migration once.
+ if (prefs_->GetBoolean(prefs::kMigratedDefaultContentSettings))
+ return;
+
+ scoped_ptr<DefaultProvider::ValueMap> value_map = ReadDictionaryPref();
+
+ for (size_t i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) {
+ ContentSettingsType content_type = ContentSettingsType(i);
+ WriteIndividualPref(content_type, (*value_map)[content_type].get());
+ }
+
+#if defined(OS_ANDROID) || defined(OS_CHROMEOS)
+ // For protected media identifier, it is desirable to just reset the setting
+ // instead of migrating it from the old preference.
+ WriteIndividualPref(CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER, NULL);
+#endif
+
+ prefs_->SetBoolean(prefs::kMigratedDefaultContentSettings, true);
}
} // namespace content_settings
diff --git a/components/content_settings/core/browser/content_settings_default_provider.h b/components/content_settings/core/browser/content_settings_default_provider.h
index 6679bdc..2a58fa8 100644
--- a/components/content_settings/core/browser/content_settings_default_provider.h
+++ b/components/content_settings/core/browser/content_settings_default_provider.h
@@ -50,22 +50,53 @@ class DefaultProvider : public ObservableProvider {
void ShutdownOnUIThread() override;
private:
- // Sets the fields of |settings| based on the values in |dictionary|.
- void GetSettingsFromDictionary(const base::DictionaryValue* dictionary);
+ typedef linked_ptr<base::Value> ValuePtr;
+ typedef std::map<ContentSettingsType, ValuePtr> ValueMap;
+
+ // Reads all individual settings from the pref service.
+ void ReadDefaultSettings();
+
+ // Change the remembered setting in the memory.
+ void ChangeSetting(ContentSettingsType content_type, base::Value* value);
+
+ // True if |value| is NULL or it is the default value for |content_type|.
+ bool IsValueEmptyOrDefault(ContentSettingsType content_type,
+ base::Value* value);
+
+ // Parses a |DictionaryValue| into a |ValueMap|.
+ scoped_ptr<ValueMap> GetSettingsFromDictionary(
+ const base::DictionaryValue* dictionary);
- // Forces the default settings to be explicitly set instead of themselves
- // being CONTENT_SETTING_DEFAULT.
- void ForceDefaultsToBeExplicit();
+ // Forces the default settings in |value_map| to be explicitly set instead
+ // of themselves being CONTENT_SETTING_DEFAULT.
+ void ForceDefaultsToBeExplicit(ValueMap* value_map);
- // Reads the default settings from the preferences service. If |overwrite| is
- // true and the preference is missing, the local copy will be cleared as well.
- void ReadDefaultSettings(bool overwrite);
+ // Reads the dictionary prefrence and returns the dictionary parsed as
+ // a |ValueMap|.
+ scoped_ptr<ValueMap> ReadDictionaryPref();
+
+ // Reads an individual preference.
+ scoped_ptr<base::Value> ReadIndividualPref(ContentSettingsType content_type);
+
+ // Writes the value |value| to the individual preference corresponding
+ // to |content_type|. It's the responsibility of caller to obtain a lock
+ // and notify observers.
+ void WriteIndividualPref(ContentSettingsType content_type,
+ base::Value* value);
+
+ // Writes the value |value| to the dictionary preference entry corresponding
+ // to |content_type|. It's the responsibility of caller to obtain a lock
+ // and notify observers.
+ void WriteDictionaryPref(ContentSettingsType content_type,
+ base::Value* value);
// Called on prefs change.
void OnPreferenceChanged(const std::string& pref_name);
- typedef linked_ptr<base::Value> ValuePtr;
- typedef std::map<ContentSettingsType, ValuePtr> ValueMap;
+ // Migrates the dictionary settings to the individual settings. Only called
+ // once during the first run.
+ void MigrateDefaultSettings();
+
// Copies of the pref data, so that we can read it on the IO thread.
ValueMap default_settings_;
@@ -74,7 +105,7 @@ class DefaultProvider : public ObservableProvider {
// Whether this settings map is for an Incognito session.
bool is_incognito_;
- // Used around accesses to the |default_content_settings_| object to guarantee
+ // Used around accesses to the |default_settings_| object to guarantee
// thread safety.
mutable base::Lock lock_;
diff --git a/components/content_settings/core/common/pref_names.cc b/components/content_settings/core/common/pref_names.cc
index ef9b66c..10353a5 100644
--- a/components/content_settings/core/common/pref_names.cc
+++ b/components/content_settings/core/common/pref_names.cc
@@ -21,8 +21,65 @@ const char kContentSettingsWindowLastTabIndex[] =
"content_settings_window.last_tab_index";
// Dictionary of content settings applied to all hosts by default.
+// TODO(msramek): Deprecated. Use the individual preferences below.
const char kDefaultContentSettings[] = "profile.default_content_settings";
+// Whether |kDefaultContentSettings| has already been migrated to
+// |kDefault<type>Setting| prefs.
+const char kMigratedDefaultContentSettings[] =
+ "profile.migrated_default_content_settings";
+
+// Preferences storing the default values for individual content settings.
+const char kDefaultCookiesSetting[] =
+ "profile.default_content_setting_values.cookies";
+const char kDefaultImagesSetting[] =
+ "profile.default_content_setting_values.images";
+const char kDefaultJavaScriptSetting[] =
+ "profile.default_content_setting_values.javascript";
+const char kDefaultPluginsSetting[] =
+ "profile.default_content_setting_values.plugins";
+const char kDefaultPopupsSetting[] =
+ "profile.default_content_setting_values.popups";
+const char kDefaultGeolocationSetting[] =
+ "profile.default_content_setting_values.geolocation";
+const char kDefaultNotificationsSetting[] =
+ "profile.default_content_setting_values.notifications";
+const char kDefaultAutoSelectCertificateSetting[] =
+ "profile.default_content_setting_values.auto_select_certificate";
+const char kDefaultFullScreenSetting[] =
+ "profile.default_content_setting_values.fullscreen";
+const char kDefaultMouseLockSetting[] =
+ "profile.default_content_setting_values.mouselock";
+const char kDefaultMixedScriptSetting[] =
+ "profile.default_content_setting_values.mixed_script";
+const char kDefaultMediaStreamSetting[] =
+ "profile.default_content_setting_values.media_stream";
+const char kDefaultMediaStreamMicSetting[] =
+ "profile.default_content_setting_values.media_stream_mic";
+const char kDefaultMediaStreamCameraSetting[] =
+ "profile.default_content_setting_values.media_stream_camera";
+const char kDefaultProtocolHandlersSetting[] =
+ "profile.default_content_setting_values.protocol_handlers";
+const char kDefaultPpapiBrokerSetting[] =
+ "profile.default_content_setting_values.ppapi_broker";
+const char kDefaultAutomaticDownloadsSetting[] =
+ "profile.default_content_setting_values.automatic_downloads";
+const char kDefaultMidiSysexSetting[] =
+ "profile.default_content_setting_values.midi_sysex";
+const char kDefaultPushMessagingSetting[] =
+ "profile.default_content_setting_values.push_messaging";
+const char kDefaultSSLCertDecisionsSetting[] =
+ "profile.default_content_setting_values.ssl_cert_decisions";
+#if defined(OS_WIN)
+const char kDefaultMetroSwitchToDesktopSetting[] =
+ "profile.default_content_setting_values.metro_switch_to_desktop";
+#elif defined(OS_ANDROID) || defined(OS_CHROMEOS)
+const char kDefaultProtectedMediaIdentifierSetting[] =
+ "profile.default_content_setting_values.protected_media_identifier";
+#endif
+const char kDefaultAppBannerSetting[] =
+ "profile.default_content_setting_values.app_banner";
+
// Dictionary of content settings that can globally disallow all hosts by
// default. If a value is set, it means the setting is globally disallowed.
// If a value is not set, it means the setting is allowed.
diff --git a/components/content_settings/core/common/pref_names.h b/components/content_settings/core/common/pref_names.h
index 6bc4f45..77c6f53 100644
--- a/components/content_settings/core/common/pref_names.h
+++ b/components/content_settings/core/common/pref_names.h
@@ -5,6 +5,8 @@
#ifndef COMPONENTS_CONTENT_SETTINGS_CORE_COMMON_PREF_NAMES_H_
#define COMPONENTS_CONTENT_SETTINGS_CORE_COMMON_PREF_NAMES_H_
+#include "base/logging.h"
+
namespace prefs {
extern const char kContentSettingsVersion[];
@@ -12,6 +14,34 @@ extern const char kContentSettingsPatternPairs[];
extern const char kContentSettingsWindowLastTabIndex[];
extern const char kDefaultContentSettings[];
extern const char kOverrideContentSettings[];
+extern const char kMigratedDefaultContentSettings[];
+
+extern const char kDefaultCookiesSetting[];
+extern const char kDefaultImagesSetting[];
+extern const char kDefaultJavaScriptSetting[];
+extern const char kDefaultPluginsSetting[];
+extern const char kDefaultPopupsSetting[];
+extern const char kDefaultGeolocationSetting[];
+extern const char kDefaultNotificationsSetting[];
+extern const char kDefaultAutoSelectCertificateSetting[];
+extern const char kDefaultFullScreenSetting[];
+extern const char kDefaultMouseLockSetting[];
+extern const char kDefaultMixedScriptSetting[];
+extern const char kDefaultMediaStreamSetting[];
+extern const char kDefaultMediaStreamMicSetting[];
+extern const char kDefaultMediaStreamCameraSetting[];
+extern const char kDefaultProtocolHandlersSetting[];
+extern const char kDefaultPpapiBrokerSetting[];
+extern const char kDefaultAutomaticDownloadsSetting[];
+extern const char kDefaultMidiSysexSetting[];
+extern const char kDefaultPushMessagingSetting[];
+extern const char kDefaultSSLCertDecisionsSetting[];
+#if defined(OS_WIN)
+extern const char kDefaultMetroSwitchToDesktopSetting[];
+#elif defined(OS_ANDROID) || defined(OS_CHROMEOS)
+extern const char kDefaultProtectedMediaIdentifierSetting[];
+#endif
+extern const char kDefaultAppBannerSetting[];
extern const char kManagedDefaultCookiesSetting[];
extern const char kManagedDefaultImagesSetting[];