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_pref_provide r.h" | 5 #include "components/content_settings/core/browser/content_settings_pref_provide r.h" |
| 6 | 6 |
| 7 #include <map> | 7 #include <map> |
| 8 #include <string> | 8 #include <string> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| 11 #include "base/auto_reset.h" | |
| 11 #include "base/bind.h" | 12 #include "base/bind.h" |
| 12 #include "base/memory/scoped_ptr.h" | 13 #include "base/memory/scoped_ptr.h" |
| 14 #include "base/memory/scoped_vector.h" | |
| 13 #include "base/metrics/histogram.h" | 15 #include "base/metrics/histogram.h" |
| 14 #include "base/prefs/pref_service.h" | 16 #include "base/prefs/pref_service.h" |
| 17 #include "base/prefs/scoped_user_pref_update.h" | |
| 15 #include "base/strings/string_split.h" | 18 #include "base/strings/string_split.h" |
| 16 #include "base/time/clock.h" | 19 #include "base/time/clock.h" |
| 17 #include "base/time/default_clock.h" | 20 #include "base/time/default_clock.h" |
| 18 #include "components/content_settings/core/browser/content_settings_pref.h" | 21 #include "components/content_settings/core/browser/content_settings_pref.h" |
| 19 #include "components/content_settings/core/browser/content_settings_rule.h" | 22 #include "components/content_settings/core/browser/content_settings_rule.h" |
| 20 #include "components/content_settings/core/browser/content_settings_utils.h" | 23 #include "components/content_settings/core/browser/content_settings_utils.h" |
| 21 #include "components/content_settings/core/browser/host_content_settings_map.h" | 24 #include "components/content_settings/core/browser/host_content_settings_map.h" |
| 22 #include "components/content_settings/core/common/content_settings.h" | 25 #include "components/content_settings/core/common/content_settings.h" |
| 23 #include "components/content_settings/core/common/content_settings_pattern.h" | 26 #include "components/content_settings/core/common/content_settings_pattern.h" |
| 24 #include "components/content_settings/core/common/pref_names.h" | 27 #include "components/content_settings/core/common/pref_names.h" |
| 25 #include "components/pref_registry/pref_registry_syncable.h" | 28 #include "components/pref_registry/pref_registry_syncable.h" |
| 26 | 29 |
| 27 namespace { | 30 namespace { |
| 28 | 31 |
| 32 const char kPerPluginPrefName[] = "per_plugin"; | |
| 33 | |
| 34 // Returns true and sets |pref_key| to the key in the content settings | |
| 35 // dictionary under which per-resource content settings are stored, | |
| 36 // if the given content type supports resource identifiers in user preferences. | |
| 37 bool GetResourceTypeName(ContentSettingsType content_type, | |
| 38 std::string* pref_key) { | |
| 39 if (content_type == CONTENT_SETTINGS_TYPE_PLUGINS) { | |
| 40 *pref_key = kPerPluginPrefName; | |
| 41 return true; | |
| 42 } | |
| 43 return false; | |
| 44 } | |
| 45 | |
| 46 // TODO(msramek): Check if we still need this migration code. If not, remove it. | |
| 47 ContentSetting FixObsoleteCookiePromptMode(ContentSettingsType content_type, | |
| 48 ContentSetting setting) { | |
| 49 if (content_type == CONTENT_SETTINGS_TYPE_COOKIES && | |
| 50 setting == CONTENT_SETTING_ASK) { | |
| 51 return CONTENT_SETTING_BLOCK; | |
| 52 } | |
| 53 return setting; | |
| 54 } | |
| 55 | |
| 56 // A helper function to duplicate |ContentSettingsPattern|, so that | |
| 57 // |ReadContentSettingsFromOldPref| can export them in a vector. We cannot pass | |
| 58 // them by pointer, because the original values will go out of scope when | |
| 59 // the vector is used in |WriteSettingsToNewPreferences|. | |
| 60 ContentSettingsPattern CopyPattern(const ContentSettingsPattern& pattern) { | |
| 61 return ContentSettingsPattern::FromString(pattern.ToString()); | |
| 62 } | |
| 63 | |
| 29 const char kAudioKey[] = "audio"; | 64 const char kAudioKey[] = "audio"; |
| 30 const char kVideoKey[] = "video"; | 65 const char kVideoKey[] = "video"; |
| 31 | 66 |
| 67 // A list of exception preferences corresponding to individual content settings | |
| 68 // types. Must be kept in sync with the enum |ContentSettingsType|. | |
| 69 const char* kContentSettingsExceptionsPrefs[] = { | |
| 70 prefs::kContentSettingsCookiesPatternPairs, | |
| 71 prefs::kContentSettingsImagesPatternPairs, | |
| 72 prefs::kContentSettingsJavaScriptPatternPairs, | |
| 73 prefs::kContentSettingsPluginsPatternPairs, | |
| 74 prefs::kContentSettingsPopupsPatternPairs, | |
| 75 prefs::kContentSettingsGeolocationPatternPairs, | |
| 76 prefs::kContentSettingsNotificationsPatternPairs, | |
| 77 prefs::kContentSettingsAutoSelectCertificatePatternPairs, | |
| 78 prefs::kContentSettingsFullScreenPatternPairs, | |
| 79 prefs::kContentSettingsMouseLockPatternPairs, | |
| 80 prefs::kContentSettingsMixedScriptPatternPairs, | |
| 81 prefs::kContentSettingsMediaStreamPatternPairs, | |
| 82 prefs::kContentSettingsMediaStreamMicPatternPairs, | |
| 83 prefs::kContentSettingsMediaStreamCameraPatternPairs, | |
| 84 prefs::kContentSettingsProtocolHandlersPatternPairs, | |
| 85 prefs::kContentSettingsPpapiBrokerPatternPairs, | |
| 86 prefs::kContentSettingsAutomaticDownloadsPatternPairs, | |
| 87 prefs::kContentSettingsMidiSysexPatternPairs, | |
| 88 prefs::kContentSettingsPushMessagingPatternPairs, | |
| 89 prefs::kContentSettingsSSLCertDecisionsPatternPairs, | |
| 90 #if defined(OS_WIN) | |
| 91 prefs::kContentSettingsMetroSwitchToDesktopPatternPairs, | |
| 92 #elif defined(OS_ANDROID) || defined(OS_CHROMEOS) | |
| 93 prefs::kContentSettingsProtectedMediaIdentifierPatternPairs, | |
| 94 #endif | |
| 95 prefs::kContentSettingsAppBannerPatternPairs | |
| 96 }; | |
| 97 static_assert(arraysize(kContentSettingsExceptionsPrefs) | |
| 98 == CONTENT_SETTINGS_NUM_TYPES, | |
| 99 "kContentSettingsExceptionsPrefs should have " | |
| 100 "CONTENT_SETTINGS_NUM_TYPES elements"); | |
| 101 | |
| 32 } // namespace | 102 } // namespace |
| 33 | 103 |
| 34 namespace content_settings { | 104 namespace content_settings { |
| 35 | 105 |
| 36 // //////////////////////////////////////////////////////////////////////////// | 106 // //////////////////////////////////////////////////////////////////////////// |
| 37 // PrefProvider: | 107 // PrefProvider: |
| 38 // | 108 // |
| 39 | 109 |
| 40 // static | 110 // static |
| 41 void PrefProvider::RegisterProfilePrefs( | 111 void PrefProvider::RegisterProfilePrefs( |
| 42 user_prefs::PrefRegistrySyncable* registry) { | 112 user_prefs::PrefRegistrySyncable* registry) { |
| 43 registry->RegisterIntegerPref( | 113 registry->RegisterIntegerPref( |
| 44 prefs::kContentSettingsVersion, | 114 prefs::kContentSettingsVersion, |
| 45 ContentSettingsPattern::kContentSettingsPatternVersion, | 115 ContentSettingsPattern::kContentSettingsPatternVersion, |
| 46 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); | 116 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); |
| 47 registry->RegisterDictionaryPref( | 117 registry->RegisterDictionaryPref( |
| 48 prefs::kContentSettingsPatternPairs, | 118 prefs::kContentSettingsPatternPairs, |
| 49 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); | 119 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); |
| 120 registry->RegisterBooleanPref( | |
| 121 prefs::kMigratedContentSettingsPatternPairs, | |
| 122 false, | |
| 123 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); | |
| 124 | |
| 125 for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) { | |
| 126 registry->RegisterDictionaryPref( | |
| 127 kContentSettingsExceptionsPrefs[i], | |
| 128 IsContentSettingsTypeSyncable(ContentSettingsType(i)) | |
| 129 ? user_prefs::PrefRegistrySyncable::SYNCABLE_PREF | |
| 130 : user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF | |
| 131 ); | |
| 132 } | |
| 50 } | 133 } |
| 51 | 134 |
| 52 PrefProvider::PrefProvider(PrefService* prefs, bool incognito) | 135 PrefProvider::PrefProvider(PrefService* prefs, bool incognito) |
| 53 : prefs_(prefs), | 136 : prefs_(prefs), |
| 54 clock_(new base::DefaultClock()) { | 137 clock_(new base::DefaultClock()), |
| 138 is_incognito_(incognito), | |
| 139 updating_old_preferences_(false) { | |
| 55 DCHECK(prefs_); | 140 DCHECK(prefs_); |
| 56 // Verify preferences version. | 141 // Verify preferences version. |
| 57 if (!prefs_->HasPrefPath(prefs::kContentSettingsVersion)) { | 142 if (!prefs_->HasPrefPath(prefs::kContentSettingsVersion)) { |
| 58 prefs_->SetInteger(prefs::kContentSettingsVersion, | 143 prefs_->SetInteger(prefs::kContentSettingsVersion, |
| 59 ContentSettingsPattern::kContentSettingsPatternVersion); | 144 ContentSettingsPattern::kContentSettingsPatternVersion); |
| 60 } | 145 } |
| 61 if (prefs_->GetInteger(prefs::kContentSettingsVersion) > | 146 if (prefs_->GetInteger(prefs::kContentSettingsVersion) > |
| 62 ContentSettingsPattern::kContentSettingsPatternVersion) { | 147 ContentSettingsPattern::kContentSettingsPatternVersion) { |
| 63 return; | 148 return; |
| 64 } | 149 } |
| 65 | 150 |
| 66 pref_change_registrar_.Init(prefs_); | 151 pref_change_registrar_.Init(prefs_); |
| 67 content_settings_pref_.reset(new ContentSettingsPref( | |
| 68 prefs_, &pref_change_registrar_, clock_.get(), incognito, | |
| 69 base::Bind(&PrefProvider::Notify, | |
| 70 base::Unretained(this)))); | |
| 71 | 152 |
| 72 if (!incognito) { | 153 pref_change_registrar_.Add(prefs::kContentSettingsPatternPairs, base::Bind( |
|
markusheintz_
2015/04/02 11:04:49
Do you need to register the pref change listener b
msramek
2015/04/02 16:22:55
No. I felt that it belongs here, since this is whe
| |
| 154 &PrefProvider::OnOldContentSettingsPatternPairsChanged, | |
| 155 base::Unretained(this))); | |
| 156 | |
| 157 for (size_t i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) { | |
| 158 content_settings_prefs_.push_back(new ContentSettingsPref( | |
| 159 ContentSettingsType(i), prefs_, &pref_change_registrar_, | |
| 160 kContentSettingsExceptionsPrefs[i], is_incognito_, | |
| 161 &updating_old_preferences_, base::Bind(&PrefProvider::Notify, | |
| 162 base::Unretained(this)))); | |
| 163 } | |
| 164 | |
| 165 // Migrate all the exceptions from the aggregate dictionary preference | |
| 166 // to the separate dictionaries. | |
| 167 MigrateAllExceptions(); | |
| 168 | |
| 169 ReadContentSettingsFromOldPref(); | |
|
raymes
2015/04/02 00:22:09
Why is it necessary to do this after we have migra
msramek
2015/04/02 16:22:55
Migration only happens once. The other one needs t
| |
| 170 | |
| 171 if (!is_incognito_) { | |
| 172 size_t num_exceptions = 0; | |
| 173 for (size_t i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) | |
| 174 num_exceptions += content_settings_prefs_[i]->GetNumExceptions(); | |
| 175 | |
| 73 UMA_HISTOGRAM_COUNTS("ContentSettings.NumberOfExceptions", | 176 UMA_HISTOGRAM_COUNTS("ContentSettings.NumberOfExceptions", |
| 74 content_settings_pref_->GetNumExceptions()); | 177 num_exceptions); |
| 178 | |
| 75 // Migrate the obsolete media content setting exceptions to the new | 179 // Migrate the obsolete media content setting exceptions to the new |
| 76 // settings. This needs to be done after ReadContentSettingsFromPref(). | 180 // settings. |
| 77 MigrateObsoleteMediaContentSetting(); | 181 MigrateObsoleteMediaContentSetting(); |
| 78 } | 182 } |
| 183 | |
| 79 } | 184 } |
| 80 | 185 |
| 81 PrefProvider::~PrefProvider() { | 186 PrefProvider::~PrefProvider() { |
| 82 DCHECK(!prefs_); | 187 DCHECK(!prefs_); |
| 83 } | 188 } |
| 84 | 189 |
| 85 RuleIterator* PrefProvider::GetRuleIterator( | 190 RuleIterator* PrefProvider::GetRuleIterator( |
| 86 ContentSettingsType content_type, | 191 ContentSettingsType content_type, |
| 87 const ResourceIdentifier& resource_identifier, | 192 const ResourceIdentifier& resource_identifier, |
| 88 bool incognito) const { | 193 bool incognito) const { |
| 89 return content_settings_pref_->GetRuleIterator(content_type, | 194 return content_settings_prefs_[content_type]->GetRuleIterator( |
| 90 resource_identifier, | 195 resource_identifier, |
| 91 incognito); | 196 incognito); |
| 92 } | 197 } |
| 93 | 198 |
| 94 bool PrefProvider::SetWebsiteSetting( | 199 bool PrefProvider::SetWebsiteSetting( |
| 95 const ContentSettingsPattern& primary_pattern, | 200 const ContentSettingsPattern& primary_pattern, |
| 96 const ContentSettingsPattern& secondary_pattern, | 201 const ContentSettingsPattern& secondary_pattern, |
| 97 ContentSettingsType content_type, | 202 ContentSettingsType content_type, |
| 98 const ResourceIdentifier& resource_identifier, | 203 const ResourceIdentifier& resource_identifier, |
| 99 base::Value* in_value) { | 204 base::Value* in_value) { |
| 100 DCHECK(CalledOnValidThread()); | 205 DCHECK(CalledOnValidThread()); |
| 101 DCHECK(prefs_); | 206 DCHECK(prefs_); |
| 102 | 207 |
| 103 return content_settings_pref_->SetWebsiteSetting(primary_pattern, | 208 // Default settings are set using a wildcard pattern for both |
| 104 secondary_pattern, | 209 // |primary_pattern| and |secondary_pattern|. Don't store default settings in |
| 105 content_type, | 210 // the |PrefProvider|. The |PrefProvider| handles settings for specific |
| 106 resource_identifier, | 211 // sites/origins defined by the |primary_pattern| and the |secondary_pattern|. |
| 107 in_value); | 212 // Default settings are handled by the |DefaultProvider|. |
| 213 if (primary_pattern == ContentSettingsPattern::Wildcard() && | |
|
markusheintz_
2015/04/02 11:04:48
Is it possible that the content_settings_pref hand
markusheintz_
2015/04/02 15:52:26
nit: Let's fix this later as discussed offline
msramek
2015/04/02 16:22:55
Acknowledged.
| |
| 214 secondary_pattern == ContentSettingsPattern::Wildcard() && | |
| 215 resource_identifier.empty()) { | |
| 216 return false; | |
| 217 } | |
| 218 | |
| 219 return content_settings_prefs_[content_type]->SetWebsiteSetting( | |
| 220 primary_pattern, | |
| 221 secondary_pattern, | |
| 222 resource_identifier, | |
| 223 in_value); | |
| 108 } | 224 } |
| 109 | 225 |
| 110 void PrefProvider::ClearAllContentSettingsRules( | 226 void PrefProvider::ClearAllContentSettingsRules( |
| 111 ContentSettingsType content_type) { | 227 ContentSettingsType content_type) { |
| 112 DCHECK(CalledOnValidThread()); | 228 DCHECK(CalledOnValidThread()); |
| 113 DCHECK(prefs_); | 229 DCHECK(prefs_); |
| 114 | 230 |
| 115 content_settings_pref_->ClearAllContentSettingsRules(content_type); | 231 content_settings_prefs_[content_type]->ClearAllContentSettingsRules(); |
| 116 } | 232 } |
| 117 | 233 |
| 118 void PrefProvider::ShutdownOnUIThread() { | 234 void PrefProvider::ShutdownOnUIThread() { |
| 119 DCHECK(CalledOnValidThread()); | 235 DCHECK(CalledOnValidThread()); |
| 120 DCHECK(prefs_); | 236 DCHECK(prefs_); |
| 121 RemoveAllObservers(); | 237 RemoveAllObservers(); |
| 122 pref_change_registrar_.RemoveAll(); | 238 pref_change_registrar_.RemoveAll(); |
| 123 prefs_ = NULL; | 239 prefs_ = NULL; |
| 124 } | 240 } |
| 125 | 241 |
| 126 void PrefProvider::UpdateLastUsage( | 242 void PrefProvider::UpdateLastUsage( |
| 127 const ContentSettingsPattern& primary_pattern, | 243 const ContentSettingsPattern& primary_pattern, |
| 128 const ContentSettingsPattern& secondary_pattern, | 244 const ContentSettingsPattern& secondary_pattern, |
| 129 ContentSettingsType content_type) { | 245 ContentSettingsType content_type) { |
| 130 content_settings_pref_->UpdateLastUsage(primary_pattern, | 246 content_settings_prefs_[content_type]->UpdateLastUsage(primary_pattern, |
| 131 secondary_pattern, | 247 secondary_pattern, |
| 132 content_type); | 248 clock_.get()); |
| 133 } | 249 } |
| 134 | 250 |
| 135 base::Time PrefProvider::GetLastUsage( | 251 base::Time PrefProvider::GetLastUsage( |
| 136 const ContentSettingsPattern& primary_pattern, | 252 const ContentSettingsPattern& primary_pattern, |
| 137 const ContentSettingsPattern& secondary_pattern, | 253 const ContentSettingsPattern& secondary_pattern, |
| 138 ContentSettingsType content_type) { | 254 ContentSettingsType content_type) { |
| 139 return content_settings_pref_->GetLastUsage(primary_pattern, | 255 return content_settings_prefs_[content_type]->GetLastUsage(primary_pattern, |
| 140 secondary_pattern, | 256 secondary_pattern); |
| 141 content_type); | |
| 142 } | 257 } |
| 143 | 258 |
| 144 // //////////////////////////////////////////////////////////////////////////// | 259 // //////////////////////////////////////////////////////////////////////////// |
| 145 // Private | 260 // Private |
| 146 | 261 |
| 262 PrefProvider::ContentSettingsPrefEntry::ContentSettingsPrefEntry( | |
| 263 const ContentSettingsPattern primary_pattern, | |
| 264 const ContentSettingsPattern secondary_pattern, | |
| 265 const ResourceIdentifier resource_identifier, | |
| 266 base::Value* value) | |
| 267 : primary_pattern(CopyPattern(primary_pattern)), | |
| 268 secondary_pattern(CopyPattern(secondary_pattern)), | |
| 269 resource_identifier(resource_identifier), | |
| 270 value(value) { | |
| 271 } | |
| 272 | |
| 273 PrefProvider::ContentSettingsPrefEntry::ContentSettingsPrefEntry( | |
| 274 const ContentSettingsPrefEntry& entry) | |
| 275 : primary_pattern(CopyPattern(entry.primary_pattern)), | |
| 276 secondary_pattern(CopyPattern(entry.secondary_pattern)), | |
| 277 resource_identifier(entry.resource_identifier), | |
| 278 value(entry.value->DeepCopy()) { | |
| 279 } | |
| 280 | |
| 281 PrefProvider::ContentSettingsPrefEntry& | |
| 282 PrefProvider::ContentSettingsPrefEntry::operator=( | |
| 283 const ContentSettingsPrefEntry& entry) { | |
| 284 this->primary_pattern = CopyPattern(entry.primary_pattern); | |
| 285 this->secondary_pattern = CopyPattern(entry.secondary_pattern); | |
| 286 this->resource_identifier = entry.resource_identifier; | |
| 287 this->value.reset(entry.value->DeepCopy()); | |
| 288 | |
| 289 return *this; | |
| 290 } | |
| 291 | |
| 292 PrefProvider::ContentSettingsPrefEntry::~ContentSettingsPrefEntry() {} | |
| 293 | |
| 147 void PrefProvider::MigrateObsoleteMediaContentSetting() { | 294 void PrefProvider::MigrateObsoleteMediaContentSetting() { |
| 148 std::vector<Rule> rules_to_delete; | 295 std::vector<Rule> rules_to_delete; |
| 149 { | 296 { |
| 150 scoped_ptr<RuleIterator> rule_iterator(GetRuleIterator( | 297 scoped_ptr<RuleIterator> rule_iterator(GetRuleIterator( |
| 151 CONTENT_SETTINGS_TYPE_MEDIASTREAM, std::string(), false)); | 298 CONTENT_SETTINGS_TYPE_MEDIASTREAM, std::string(), false)); |
| 152 while (rule_iterator->HasNext()) { | 299 while (rule_iterator->HasNext()) { |
| 153 // Skip default setting and rules without a value. | 300 // Skip default setting and rules without a value. |
| 154 const content_settings::Rule& rule = rule_iterator->Next(); | 301 const content_settings::Rule& rule = rule_iterator->Next(); |
| 155 DCHECK(rule.primary_pattern != ContentSettingsPattern::Wildcard()); | 302 DCHECK(rule.primary_pattern != ContentSettingsPattern::Wildcard()); |
| 156 if (!rule.value.get()) | 303 if (!rule.value.get()) |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 198 const ContentSettingsPattern& primary_pattern, | 345 const ContentSettingsPattern& primary_pattern, |
| 199 const ContentSettingsPattern& secondary_pattern, | 346 const ContentSettingsPattern& secondary_pattern, |
| 200 ContentSettingsType content_type, | 347 ContentSettingsType content_type, |
| 201 const std::string& resource_identifier) { | 348 const std::string& resource_identifier) { |
| 202 NotifyObservers(primary_pattern, | 349 NotifyObservers(primary_pattern, |
| 203 secondary_pattern, | 350 secondary_pattern, |
| 204 content_type, | 351 content_type, |
| 205 resource_identifier); | 352 resource_identifier); |
| 206 } | 353 } |
| 207 | 354 |
| 355 void PrefProvider::ReadContentSettingsFromOldPref() { | |
| 356 // |DictionaryPrefUpdate| sends out notifications when destructed. This | |
| 357 // construction order ensures |AutoLock| gets destroyed first and |old_lock_| | |
| 358 // is not held when the notifications are sent. Also, |auto_reset| must be | |
| 359 // still valid when the notifications are sent, so that |Observe| skips the | |
| 360 // notification. | |
| 361 base::AutoReset<bool> auto_reset(&updating_old_preferences_, true); | |
| 362 DictionaryPrefUpdate update(prefs_, prefs::kContentSettingsPatternPairs); | |
| 363 | |
| 364 ClearPrefEntryMap(); | |
| 365 | |
| 366 const base::DictionaryValue* all_settings_dictionary = | |
| 367 prefs_->GetDictionary(prefs::kContentSettingsPatternPairs); | |
| 368 | |
| 369 // Careful: The returned value could be NULL if the pref has never been set. | |
| 370 if (!all_settings_dictionary) | |
| 371 return; | |
| 372 | |
| 373 base::DictionaryValue* mutable_settings; | |
| 374 scoped_ptr<base::DictionaryValue> mutable_settings_scope; | |
| 375 | |
| 376 if (!is_incognito_) { | |
| 377 mutable_settings = update.Get(); | |
| 378 } else { | |
| 379 // Create copy as we do not want to persist anything in OTR prefs. | |
| 380 mutable_settings = all_settings_dictionary->DeepCopy(); | |
| 381 mutable_settings_scope.reset(mutable_settings); | |
| 382 } | |
| 383 // Convert all Unicode patterns into punycode form, then read. | |
| 384 ContentSettingsPref::CanonicalizeContentSettingsExceptions(mutable_settings); | |
| 385 | |
| 386 for (base::DictionaryValue::Iterator i(*mutable_settings); !i.IsAtEnd(); | |
| 387 i.Advance()) { | |
| 388 const std::string& pattern_str(i.key()); | |
| 389 std::pair<ContentSettingsPattern, ContentSettingsPattern> pattern_pair = | |
| 390 ParsePatternString(pattern_str); | |
| 391 if (!pattern_pair.first.IsValid() || | |
| 392 !pattern_pair.second.IsValid()) { | |
| 393 // TODO: Change this to DFATAL when crbug.com/132659 is fixed. | |
| 394 LOG(ERROR) << "Invalid pattern strings: " << pattern_str; | |
| 395 continue; | |
| 396 } | |
| 397 | |
| 398 // Get settings dictionary for the current pattern string, and read | |
| 399 // settings from the dictionary. | |
| 400 const base::DictionaryValue* settings_dictionary = NULL; | |
| 401 bool is_dictionary = i.value().GetAsDictionary(&settings_dictionary); | |
| 402 DCHECK(is_dictionary); | |
| 403 | |
| 404 for (size_t i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) { | |
| 405 ContentSettingsType content_type = static_cast<ContentSettingsType>(i); | |
| 406 | |
| 407 std::string res_dictionary_path; | |
| 408 if (GetResourceTypeName(content_type, &res_dictionary_path)) { | |
| 409 const base::DictionaryValue* resource_dictionary = NULL; | |
| 410 if (settings_dictionary->GetDictionary( | |
| 411 res_dictionary_path, &resource_dictionary)) { | |
| 412 for (base::DictionaryValue::Iterator j(*resource_dictionary); | |
| 413 !j.IsAtEnd(); | |
| 414 j.Advance()) { | |
| 415 const std::string& resource_identifier(j.key()); | |
| 416 int setting = CONTENT_SETTING_DEFAULT; | |
| 417 bool is_integer = j.value().GetAsInteger(&setting); | |
| 418 DCHECK(is_integer); | |
| 419 DCHECK_NE(CONTENT_SETTING_DEFAULT, setting); | |
| 420 | |
| 421 pref_entry_map_[content_type].push_back( | |
| 422 new ContentSettingsPrefEntry( | |
| 423 pattern_pair.first, | |
| 424 pattern_pair.second, | |
| 425 resource_identifier, | |
| 426 new base::FundamentalValue(setting))); | |
| 427 } | |
| 428 } | |
| 429 } | |
| 430 base::Value* value = NULL; | |
| 431 if (HostContentSettingsMap::ContentTypeHasCompoundValue(content_type)) { | |
| 432 const base::DictionaryValue* setting = NULL; | |
| 433 // TODO(xians): Handle the non-dictionary types. | |
| 434 if (settings_dictionary->GetDictionaryWithoutPathExpansion( | |
| 435 GetTypeName(ContentSettingsType(i)), &setting)) { | |
| 436 DCHECK(!setting->empty()); | |
| 437 value = setting->DeepCopy(); | |
| 438 } | |
| 439 } else { | |
| 440 int setting = CONTENT_SETTING_DEFAULT; | |
| 441 if (settings_dictionary->GetIntegerWithoutPathExpansion( | |
| 442 GetTypeName(ContentSettingsType(i)), &setting)) { | |
| 443 DCHECK_NE(CONTENT_SETTING_DEFAULT, setting); | |
| 444 setting = FixObsoleteCookiePromptMode(content_type, | |
| 445 ContentSetting(setting)); | |
| 446 value = new base::FundamentalValue(setting); | |
| 447 } | |
| 448 } | |
| 449 | |
| 450 // |entry_map| will take the ownership of |value|. | |
| 451 if (value != NULL) { | |
| 452 pref_entry_map_[content_type].push_back( | |
| 453 new ContentSettingsPrefEntry( | |
| 454 pattern_pair.first, | |
| 455 pattern_pair.second, | |
| 456 ResourceIdentifier(), | |
| 457 value)); | |
| 458 } | |
| 459 } | |
| 460 } | |
| 461 } | |
| 462 | |
| 463 void PrefProvider::WriteSettingsToNewPreferences(bool syncable_only) { | |
| 464 // The incognito provider cannot write the settings to avoid echo effect: | |
| 465 // New preference -> PrefProvider -> Old preference -> | |
| 466 // -> Incognito PrefProvider -> New preference -> etc. | |
| 467 if (is_incognito_) | |
| 468 return; | |
| 469 | |
| 470 if (updating_old_preferences_) | |
| 471 return; | |
| 472 | |
| 473 base::AutoReset<bool> auto_reset(&updating_old_preferences_, true); | |
| 474 base::AutoLock auto_lock(old_lock_); | |
| 475 | |
| 476 ReadContentSettingsFromOldPref(); | |
| 477 | |
| 478 for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) { | |
| 479 ContentSettingsType content_type = ContentSettingsType(i); | |
| 480 if (syncable_only && !IsContentSettingsTypeSyncable(content_type)) | |
| 481 return; | |
| 482 | |
| 483 content_settings_prefs_[content_type]->ClearAllContentSettingsRules(); | |
| 484 | |
| 485 for (size_t i = 0; i < pref_entry_map_[content_type].size(); ++i) { | |
| 486 #if defined(OS_CHROMEOS) || defined(OS_ANDROID) | |
| 487 // Protected Media Identifier "Allow" exceptions can not be migrated. | |
| 488 const base::FundamentalValue allow_value(CONTENT_SETTING_ALLOW); | |
| 489 if (content_type == CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER && | |
| 490 pref_entry_map_[content_type][i]->value->Equals(&allow_value)) { | |
| 491 continue; | |
| 492 } | |
| 493 #endif | |
| 494 | |
| 495 content_settings_prefs_[content_type]->SetWebsiteSetting( | |
| 496 pref_entry_map_[content_type][i]->primary_pattern, | |
| 497 pref_entry_map_[content_type][i]->secondary_pattern, | |
| 498 pref_entry_map_[content_type][i]->resource_identifier, | |
| 499 pref_entry_map_[content_type][i]->value->DeepCopy()); | |
|
raymes
2015/04/02 00:22:09
nit: you could probably save a copy here by releas
msramek
2015/04/02 16:22:55
Done.
| |
| 500 } | |
| 501 } | |
| 502 | |
| 503 ClearPrefEntryMap(); | |
| 504 } | |
| 505 | |
| 506 void PrefProvider::ClearPrefEntryMap() { | |
| 507 for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) | |
| 508 pref_entry_map_[i].clear(); | |
| 509 } | |
| 510 | |
| 511 void PrefProvider::OnOldContentSettingsPatternPairsChanged() { | |
| 512 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 513 | |
| 514 WriteSettingsToNewPreferences(true); | |
| 515 } | |
| 516 | |
| 517 void PrefProvider::MigrateAllExceptions() { | |
|
markusheintz_
2015/04/02 11:04:48
Looks like this method can be in-lined.
msramek
2015/04/02 16:22:55
Done.
| |
| 518 if (prefs_->GetBoolean(prefs::kMigratedContentSettingsPatternPairs)) | |
| 519 return; | |
| 520 | |
| 521 WriteSettingsToNewPreferences(false); | |
| 522 | |
| 523 prefs_->SetBoolean(prefs::kMigratedContentSettingsPatternPairs, true); | |
| 524 } | |
| 525 | |
| 208 void PrefProvider::SetClockForTesting(scoped_ptr<base::Clock> clock) { | 526 void PrefProvider::SetClockForTesting(scoped_ptr<base::Clock> clock) { |
| 209 clock_ = clock.Pass(); | 527 clock_ = clock.Pass(); |
| 210 content_settings_pref_->SetClockForTesting(clock_.get()); | 528 } |
| 529 | |
| 530 bool PrefProvider::TestAllLocks() const { | |
| 531 for (size_t i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) { | |
| 532 if (!content_settings_prefs_[i]->lock_.Try()) | |
| 533 return false; | |
| 534 content_settings_prefs_[i]->lock_.Release(); | |
| 535 } | |
| 536 return true; | |
| 211 } | 537 } |
| 212 | 538 |
| 213 } // namespace content_settings | 539 } // namespace content_settings |
| OLD | NEW |