diff options
Diffstat (limited to 'components/content_settings/core/browser/content_settings_default_provider.cc')
-rw-r--r-- | components/content_settings/core/browser/content_settings_default_provider.cc | 257 |
1 files changed, 52 insertions, 205 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 0bf7514..6adccfd 100644 --- a/components/content_settings/core/browser/content_settings_default_provider.cc +++ b/components/content_settings/core/browser/content_settings_default_provider.cc @@ -28,6 +28,13 @@ namespace content_settings { namespace { +// Obsolete prefs to be removed from the pref file. +// TODO(msramek): Remove this cleanup code after two releases (i.e. in M48). +const char kObsoleteDefaultContentSettings[] = + "profile.default_content_settings"; +const char kObsoleteMigratedDefaultContentSettings[] = + "profile.migrated_default_content_settings"; + struct DefaultContentSettingInfo { // The profile preference associated with this default setting. const char* pref_name; @@ -107,38 +114,32 @@ class DefaultRuleIterator : public RuleIterator { // static void DefaultProvider::RegisterProfilePrefs( user_prefs::PrefRegistrySyncable* registry) { - // The registration of the preference prefs::kDefaultContentSettings should - // also include the default values for default content settings. This allows - // functional tests to get default content settings by reading the preference - // prefs::kDefaultContentSettings via pyauto. - // TODO(markusheintz): Write pyauto hooks for the content settings map as - // content settings should be read from the host content settings map. - base::DictionaryValue* default_content_settings = new base::DictionaryValue(); - registry->RegisterDictionaryPref( - 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. + // Register the default settings' preferences. for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) { ContentSettingsType type = static_cast<ContentSettingsType>(i); registry->RegisterIntegerPref(GetPrefName(type), GetDefaultValue(type), PrefRegistrationFlagsForType(type)); } + // Whether the deprecated mediastream default setting has already been + // migrated into microphone and camera default settings. + registry->RegisterBooleanPref(prefs::kMigratedDefaultMediaStreamSetting, + false); + + // Obsolete prefs ------------------------------------------------------- + + // The deprecated dictionary preference. + registry->RegisterDictionaryPref( + kObsoleteDefaultContentSettings, + new base::DictionaryValue(), + user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); + // Whether the deprecated dictionary preference has already been migrated // into the individual preferences in this profile. registry->RegisterBooleanPref( - prefs::kMigratedDefaultContentSettings, + kObsoleteMigratedDefaultContentSettings, false, user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); - - // Whether the deprecated mediastream default setting has already been - // migrated into microphone and camera default settings. - registry->RegisterBooleanPref(prefs::kMigratedDefaultMediaStreamSetting, - false); } DefaultProvider::DefaultProvider(PrefService* prefs, bool incognito) @@ -147,13 +148,8 @@ DefaultProvider::DefaultProvider(PrefService* prefs, bool incognito) updating_preferences_(false) { DCHECK(prefs_); - // Migrate the dictionary of default content settings to the new individual - // preferences. - MigrateDefaultSettings(); - - // Migrate the obsolete media stream default setting into the new microphone - // and camera settings. - MigrateObsoleteMediaContentSetting(); + // Remove the obsolete preferences from the pref file. + DiscardObsoletePreferences(); // Read global defaults. ReadDefaultSettings(); @@ -217,8 +213,6 @@ DefaultProvider::DefaultProvider(PrefService* prefs, bool incognito) pref_change_registrar_.Init(prefs_); PrefChangeRegistrar::NamedChangeCallback callback = base::Bind( &DefaultProvider::OnPreferenceChanged, base::Unretained(this)); - pref_change_registrar_.Add(prefs::kDefaultContentSettings, callback); - for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) { ContentSettingsType type = static_cast<ContentSettingsType>(i); pref_change_registrar_.Add(GetPrefName(type), callback); @@ -261,13 +255,7 @@ bool DefaultProvider::SetWebsiteSetting( base::AutoLock lock(lock_); 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 (IsContentSettingsTypeSyncable(content_type)) - WriteDictionaryPref(content_type, value.get()); + WriteToPref(content_type, value.get()); } NotifyObservers(ContentSettingsPattern(), @@ -313,7 +301,7 @@ void DefaultProvider::ReadDefaultSettings() { base::AutoLock lock(lock_); for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) { ContentSettingsType type = static_cast<ContentSettingsType>(i); - ChangeSetting(type, ReadIndividualPref(type).get()); + ChangeSetting(type, ReadFromPref(type).get()); } } @@ -333,8 +321,8 @@ void DefaultProvider::ChangeSetting(ContentSettingsType content_type, } } -void DefaultProvider::WriteIndividualPref(ContentSettingsType content_type, - base::Value* value) { +void DefaultProvider::WriteToPref(ContentSettingsType content_type, + base::Value* value) { if (IsValueEmptyOrDefault(content_type, value)) { prefs_->ClearPref(GetPrefName(content_type)); return; @@ -346,145 +334,53 @@ void DefaultProvider::WriteIndividualPref(ContentSettingsType content_type, prefs_->SetInteger(GetPrefName(content_type), 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) { - // If the dictionary preference gets synced from an old version - // of Chrome, we should update all individual preferences that - // are marked as syncable. - base::AutoReset<bool> auto_reset(&updating_preferences_, true); - - scoped_ptr<ValueMap> dictionary = ReadDictionaryPref(); + // Find out which content setting the preference corresponds to. + ContentSettingsType content_type = CONTENT_SETTINGS_TYPE_DEFAULT; - // Lock the memory map access, so that values are not read by - // |GetRuleIterator| at the same time as they are written here. Do not lock - // the preference access though; preference updates send out notifications - // whose callbacks may try to reacquire the lock on the same thread. - { - base::AutoLock lock(lock_); - for (const auto& it : *dictionary) { - if (!IsContentSettingsTypeSyncable(it.first)) - continue; - - DCHECK(default_settings_.find(it.first) != default_settings_.end()); - ChangeSetting(it.first, it.second.get()); - to_notify.push_back(it.first); - } - } - - // When the lock is released, write the new settings to preferences. - for (const auto& it : *dictionary) { - if (!IsContentSettingsTypeSyncable(it.first)) - continue; - WriteIndividualPref(it.first, it.second.get()); - } - } else { - // Find out which content setting the preference corresponds to. - ContentSettingsType content_type = CONTENT_SETTINGS_TYPE_DEFAULT; - - for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) { - ContentSettingsType type = static_cast<ContentSettingsType>(i); - if (GetPrefName(type) == name) { - content_type = type; - break; - } + for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) { + ContentSettingsType type = static_cast<ContentSettingsType>(i); + if (GetPrefName(type) == name) { + content_type = type; + break; } + } - if (content_type == CONTENT_SETTINGS_TYPE_DEFAULT) { - NOTREACHED() << "Unexpected preference observed"; - return; - } + if (content_type == CONTENT_SETTINGS_TYPE_DEFAULT) { + NOTREACHED() << "A change of the preference " << name << " was observed, " + "but the preference could not be mapped to a content " + "settings type."; + 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::AutoReset<bool> auto_reset(&updating_preferences_, true); - // Lock the memory map access, so that values are not read by // |GetRuleIterator| at the same time as they are written here. Do not lock // the preference access though; preference updates send out notifications // whose callbacks may try to reacquire the lock on the same thread. { base::AutoLock lock(lock_); - ChangeSetting(content_type, ReadIndividualPref(content_type).get()); + ChangeSetting(content_type, ReadFromPref(content_type).get()); } - if (IsContentSettingsTypeSyncable(content_type)) - WriteDictionaryPref(content_type, default_settings_[content_type].get()); - to_notify.push_back(content_type); } - for (const ContentSettingsType content_type : to_notify) { - NotifyObservers(ContentSettingsPattern(), - ContentSettingsPattern(), - content_type, - ResourceIdentifier()); - } + NotifyObservers(ContentSettingsPattern(), + ContentSettingsPattern(), + content_type, + ResourceIdentifier()); } -scoped_ptr<base::Value> DefaultProvider::ReadIndividualPref( +scoped_ptr<base::Value> DefaultProvider::ReadFromPref( ContentSettingsType content_type) { int int_value = prefs_->GetInteger(GetPrefName(content_type)); return ContentSettingToValue(IntToContentSetting(int_value)).Pass(); } -scoped_ptr<DefaultProvider::ValueMap> DefaultProvider::ReadDictionaryPref() { - const base::DictionaryValue* default_settings_dictionary = - prefs_->GetDictionary(prefs::kDefaultContentSettings); - - scoped_ptr<ValueMap> value_map = - GetSettingsFromDictionary(default_settings_dictionary); - - ForceDefaultsToBeExplicit(value_map.get()); - - // Migrate obsolete cookie prompt mode. - if (ValueToContentSetting( - (*value_map)[CONTENT_SETTINGS_TYPE_COOKIES].get()) == - CONTENT_SETTING_ASK) { - (*value_map)[CONTENT_SETTINGS_TYPE_COOKIES].reset( - new base::FundamentalValue(CONTENT_SETTING_BLOCK)); - } -#if defined(OS_ANDROID) || defined(OS_CHROMEOS) - // Migrate protected media from allow to ask. - if (ValueToContentSetting( - (*value_map)[CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER] - .get()) == CONTENT_SETTING_ALLOW) { - (*value_map)[CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER].reset( - new base::FundamentalValue(CONTENT_SETTING_ASK)); - } -#endif - return value_map.Pass(); -} - void DefaultProvider::ForceDefaultsToBeExplicit(ValueMap* value_map) { for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) { ContentSettingsType type = static_cast<ContentSettingsType>(i); @@ -495,58 +391,9 @@ void DefaultProvider::ForceDefaultsToBeExplicit(ValueMap* value_map) { } } -scoped_ptr<DefaultProvider::ValueMap> - DefaultProvider::GetSettingsFromDictionary( - const base::DictionaryValue* dictionary) { - scoped_ptr<ValueMap> value_map(new ValueMap()); - if (!dictionary) - return value_map.Pass(); - - for (base::DictionaryValue::Iterator i(*dictionary); - !i.IsAtEnd(); i.Advance()) { - const std::string& content_type(i.key()); - for (int type = 0; type < CONTENT_SETTINGS_NUM_TYPES; ++type) { - if (content_type == GetTypeName(ContentSettingsType(type))) { - int int_value = CONTENT_SETTING_DEFAULT; - bool is_integer = i.value().GetAsInteger(&int_value); - DCHECK(is_integer); - (*value_map)[ContentSettingsType(type)].reset( - ContentSettingToValue(IntToContentSetting(int_value)).release()); - break; - } - } - } - - return value_map.Pass(); -} - -void DefaultProvider::MigrateDefaultSettings() { - // Only do the migration once. - if (prefs_->GetBoolean(prefs::kMigratedDefaultContentSettings)) - return; - - scoped_ptr<DefaultProvider::ValueMap> value_map = ReadDictionaryPref(); - - for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) { - ContentSettingsType type = static_cast<ContentSettingsType>(i); - WriteIndividualPref(type, (*value_map)[type].get()); - } - - prefs_->SetBoolean(prefs::kMigratedDefaultContentSettings, true); -} - -void DefaultProvider::MigrateObsoleteMediaContentSetting() { - // We only do the migration once. - if (prefs_->GetBoolean(prefs::kMigratedDefaultMediaStreamSetting)) - return; - - scoped_ptr<base::Value> value = ReadIndividualPref( - CONTENT_SETTINGS_TYPE_MEDIASTREAM); - WriteIndividualPref(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, value.get()); - WriteIndividualPref(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, value.get()); - WriteIndividualPref(CONTENT_SETTINGS_TYPE_MEDIASTREAM, NULL); - - prefs_->SetBoolean(prefs::kMigratedDefaultMediaStreamSetting, true); +void DefaultProvider::DiscardObsoletePreferences() { + prefs_->ClearPref(kObsoleteDefaultContentSettings); + prefs_->ClearPref(kObsoleteMigratedDefaultContentSettings); } } // namespace content_settings |