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