Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(829)

Side by Side Diff: components/content_settings/core/browser/content_settings_pref.cc

Issue 976243002: Split content settings pref related logic into a separate class (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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.h"
6
7 #include <map>
8 #include <string>
9 #include <utility>
10 6
11 #include "base/auto_reset.h" 7 #include "base/auto_reset.h"
12 #include "base/bind.h" 8 #include "base/bind.h"
13 #include "base/command_line.h"
14 #include "base/memory/scoped_ptr.h" 9 #include "base/memory/scoped_ptr.h"
15 #include "base/metrics/histogram.h" 10 #include "base/metrics/histogram.h"
16 #include "base/prefs/pref_service.h"
17 #include "base/prefs/scoped_user_pref_update.h" 11 #include "base/prefs/scoped_user_pref_update.h"
18 #include "base/strings/string_split.h" 12 #include "base/strings/string_split.h"
19 #include "base/time/clock.h" 13 #include "base/time/clock.h"
20 #include "base/time/default_clock.h"
21 #include "components/content_settings/core/browser/content_settings_rule.h" 14 #include "components/content_settings/core/browser/content_settings_rule.h"
22 #include "components/content_settings/core/browser/content_settings_utils.h" 15 #include "components/content_settings/core/browser/content_settings_utils.h"
23 #include "components/content_settings/core/browser/host_content_settings_map.h" 16 #include "components/content_settings/core/browser/host_content_settings_map.h"
24 #include "components/content_settings/core/common/content_settings.h" 17 #include "components/content_settings/core/common/content_settings.h"
25 #include "components/content_settings/core/common/content_settings_pattern.h" 18 #include "components/content_settings/core/common/content_settings_pattern.h"
26 #include "components/content_settings/core/common/pref_names.h" 19 #include "components/content_settings/core/common/pref_names.h"
27 #include "components/pref_registry/pref_registry_syncable.h"
28 #include "url/gurl.h" 20 #include "url/gurl.h"
29 21
30 namespace { 22 namespace {
31 23
32 typedef std::pair<std::string, std::string> StringPair; 24 typedef std::pair<std::string, std::string> StringPair;
33 typedef std::map<std::string, std::string> StringMap;
34 25
35 const char kPerPluginPrefName[] = "per_plugin"; 26 const char kPerPluginPrefName[] = "per_plugin";
36 const char kAudioKey[] = "audio";
37 const char kVideoKey[] = "video";
38 const char kLastUsed[] = "last_used"; 27 const char kLastUsed[] = "last_used";
39 28
40 ContentSetting FixObsoleteCookiePromptMode(ContentSettingsType content_type, 29 ContentSetting FixObsoleteCookiePromptMode(ContentSettingsType content_type,
41 ContentSetting setting) { 30 ContentSetting setting) {
42 if (content_type == CONTENT_SETTINGS_TYPE_COOKIES && 31 if (content_type == CONTENT_SETTINGS_TYPE_COOKIES &&
43 setting == CONTENT_SETTING_ASK) { 32 setting == CONTENT_SETTING_ASK) {
44 return CONTENT_SETTING_BLOCK; 33 return CONTENT_SETTING_BLOCK;
45 } 34 }
46 return setting; 35 return setting;
47 } 36 }
48 37
49 // If the given content type supports resource identifiers in user preferences, 38 // If the given content type supports resource identifiers in user preferences,
50 // returns true and sets |pref_key| to the key in the content settings 39 // returns true and sets |pref_key| to the key in the content settings
51 // dictionary under which per-resource content settings are stored. 40 // dictionary under which per-resource content settings are stored.
52 // Otherwise, returns false. 41 // Otherwise, returns false.
53 bool GetResourceTypeName(ContentSettingsType content_type, 42 bool GetResourceTypeName(ContentSettingsType content_type,
54 std::string* pref_key) { 43 std::string* pref_key) {
55 if (content_type == CONTENT_SETTINGS_TYPE_PLUGINS) { 44 if (content_type == CONTENT_SETTINGS_TYPE_PLUGINS) {
56 *pref_key = kPerPluginPrefName; 45 *pref_key = kPerPluginPrefName;
57 return true; 46 return true;
58 } 47 }
59 return false; 48 return false;
60 } 49 }
61 50
62 } // namespace 51 } // namespace
63 52
64 namespace content_settings { 53 namespace content_settings {
65 54
66 // //////////////////////////////////////////////////////////////////////////// 55 ContentSettingsPref::ContentSettingsPref(
67 // PrefProvider: 56 PrefService* prefs,
68 // 57 PrefChangeRegistrar* registrar,
69 58 base::Clock* clock,
70 // static 59 bool incognito,
71 void PrefProvider::RegisterProfilePrefs( 60 NotifyObserversCallback notify_callback)
72 user_prefs::PrefRegistrySyncable* registry) {
73 registry->RegisterIntegerPref(
74 prefs::kContentSettingsVersion,
75 ContentSettingsPattern::kContentSettingsPatternVersion,
76 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
77 registry->RegisterDictionaryPref(
78 prefs::kContentSettingsPatternPairs,
79 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
80 }
81
82 PrefProvider::PrefProvider(PrefService* prefs, bool incognito)
83 : prefs_(prefs), 61 : prefs_(prefs),
84 clock_(new base::DefaultClock()), 62 clock_(clock),
63 registrar_(registrar),
85 is_incognito_(incognito), 64 is_incognito_(incognito),
86 updating_preferences_(false) { 65 updating_preferences_(false),
66 notify_callback_(notify_callback) {
87 DCHECK(prefs_); 67 DCHECK(prefs_);
88 // Verify preferences version.
89 if (!prefs_->HasPrefPath(prefs::kContentSettingsVersion)) {
90 prefs_->SetInteger(prefs::kContentSettingsVersion,
91 ContentSettingsPattern::kContentSettingsPatternVersion);
92 }
93 if (prefs_->GetInteger(prefs::kContentSettingsVersion) >
94 ContentSettingsPattern::kContentSettingsPatternVersion) {
95 return;
96 }
97 68
98 // Read content settings exceptions. 69 // Read content settings exceptions.
99 ReadContentSettingsFromPref(); 70 ReadContentSettingsFromPref();
100 71
101 if (!is_incognito_) { 72 registrar->Add(
102 UMA_HISTOGRAM_COUNTS("ContentSettings.NumberOfExceptions",
103 value_map_.size());
104 }
105
106 // Migrate the obsolete media content setting exceptions to the new settings.
107 // This needs to be done after ReadContentSettingsFromPref().
108 if (!is_incognito_)
109 MigrateObsoleteMediaContentSetting();
110
111 pref_change_registrar_.Init(prefs_);
112 pref_change_registrar_.Add(
113 prefs::kContentSettingsPatternPairs, 73 prefs::kContentSettingsPatternPairs,
114 base::Bind(&PrefProvider::OnContentSettingsPatternPairsChanged, 74 base::Bind(&ContentSettingsPref::OnContentSettingsPatternPairsChanged,
115 base::Unretained(this))); 75 base::Unretained(this)));
116 } 76 }
117 77
118 bool PrefProvider::SetWebsiteSetting( 78 ContentSettingsPref::~ContentSettingsPref() {
79 }
80
81 RuleIterator* ContentSettingsPref::GetRuleIterator(
82 ContentSettingsType content_type,
83 const ResourceIdentifier& resource_identifier,
84 bool incognito) const {
85 if (incognito)
86 return incognito_value_map_.GetRuleIterator(content_type,
87 resource_identifier,
88 &lock_);
89 return value_map_.GetRuleIterator(content_type, resource_identifier, &lock_);
90 }
91
92 bool ContentSettingsPref::SetWebsiteSetting(
119 const ContentSettingsPattern& primary_pattern, 93 const ContentSettingsPattern& primary_pattern,
120 const ContentSettingsPattern& secondary_pattern, 94 const ContentSettingsPattern& secondary_pattern,
121 ContentSettingsType content_type, 95 ContentSettingsType content_type,
122 const ResourceIdentifier& resource_identifier, 96 const ResourceIdentifier& resource_identifier,
123 base::Value* in_value) { 97 base::Value* in_value) {
124 DCHECK(CalledOnValidThread()); 98 DCHECK(thread_checker_.CalledOnValidThread());
125 DCHECK(prefs_); 99 DCHECK(prefs_);
100
126 // Default settings are set using a wildcard pattern for both 101 // Default settings are set using a wildcard pattern for both
127 // |primary_pattern| and |secondary_pattern|. Don't store default settings in 102 // |primary_pattern| and |secondary_pattern|. Don't store default settings in
128 // the |PrefProvider|. The |PrefProvider| handles settings for specific 103 // the |PrefProvider|. The |PrefProvider| handles settings for specific
129 // sites/origins defined by the |primary_pattern| and the |secondary_pattern|. 104 // sites/origins defined by the |primary_pattern| and the |secondary_pattern|.
130 // Default settings are handled by the |DefaultProvider|. 105 // Default settings are handled by the |DefaultProvider|.
131 if (primary_pattern == ContentSettingsPattern::Wildcard() && 106 if (primary_pattern == ContentSettingsPattern::Wildcard() &&
132 secondary_pattern == ContentSettingsPattern::Wildcard() && 107 secondary_pattern == ContentSettingsPattern::Wildcard() &&
133 resource_identifier.empty()) { 108 resource_identifier.empty()) {
134 return false; 109 return false;
135 } 110 }
(...skipping 24 matching lines...) Expand all
160 } 135 }
161 // Update the content settings preference. 136 // Update the content settings preference.
162 if (!is_incognito_) { 137 if (!is_incognito_) {
163 UpdatePref(primary_pattern, 138 UpdatePref(primary_pattern,
164 secondary_pattern, 139 secondary_pattern,
165 content_type, 140 content_type,
166 resource_identifier, 141 resource_identifier,
167 value.get()); 142 value.get());
168 } 143 }
169 144
170 NotifyObservers( 145 notify_callback_.Run(
171 primary_pattern, secondary_pattern, content_type, resource_identifier); 146 primary_pattern, secondary_pattern, content_type, resource_identifier);
172 147
173 return true; 148 return true;
174 } 149 }
175 150
176 void PrefProvider::ClearAllContentSettingsRules( 151 void ContentSettingsPref::ClearAllContentSettingsRules(
177 ContentSettingsType content_type) { 152 ContentSettingsType content_type) {
178 DCHECK(CalledOnValidThread()); 153 DCHECK(thread_checker_.CalledOnValidThread());
179 DCHECK(prefs_); 154 DCHECK(prefs_);
180 155
181 OriginIdentifierValueMap* map_to_modify = &incognito_value_map_; 156 OriginIdentifierValueMap* map_to_modify = &incognito_value_map_;
182 if (!is_incognito_) 157 if (!is_incognito_)
183 map_to_modify = &value_map_; 158 map_to_modify = &value_map_;
184 159
185 std::vector<Rule> rules_to_delete; 160 std::vector<Rule> rules_to_delete;
186 { 161 {
187 base::AutoLock auto_lock(lock_); 162 base::AutoLock auto_lock(lock_);
188 scoped_ptr<RuleIterator> rule_iterator( 163 scoped_ptr<RuleIterator> rule_iterator(
189 map_to_modify->GetRuleIterator(content_type, std::string(), NULL)); 164 map_to_modify->GetRuleIterator(content_type, std::string(), NULL));
190 // Copy the rules; we cannot call |UpdatePref| while holding |lock_|. 165 // Copy the rules; we cannot call |UpdatePref| while holding |lock_|.
191 while (rule_iterator->HasNext()) 166 while (rule_iterator->HasNext())
192 rules_to_delete.push_back(rule_iterator->Next()); 167 rules_to_delete.push_back(rule_iterator->Next());
193 168
194 map_to_modify->DeleteValues(content_type, std::string()); 169 map_to_modify->DeleteValues(content_type, std::string());
195 } 170 }
196 171
197 for (std::vector<Rule>::const_iterator it = rules_to_delete.begin(); 172 for (std::vector<Rule>::const_iterator it = rules_to_delete.begin();
198 it != rules_to_delete.end(); ++it) { 173 it != rules_to_delete.end(); ++it) {
199 UpdatePref(it->primary_pattern, 174 UpdatePref(it->primary_pattern,
200 it->secondary_pattern, 175 it->secondary_pattern,
201 content_type, 176 content_type,
202 std::string(), 177 std::string(),
203 NULL); 178 NULL);
204 } 179 }
205 NotifyObservers(ContentSettingsPattern(), 180 notify_callback_.Run(ContentSettingsPattern(),
206 ContentSettingsPattern(), 181 ContentSettingsPattern(),
207 content_type, 182 content_type,
208 std::string()); 183 std::string());
209 } 184 }
210 185
211 PrefProvider::~PrefProvider() { 186 void ContentSettingsPref::UpdateLastUsage(
212 DCHECK(!prefs_);
213 }
214
215 RuleIterator* PrefProvider::GetRuleIterator(
216 ContentSettingsType content_type,
217 const ResourceIdentifier& resource_identifier,
218 bool incognito) const {
219 if (incognito)
220 return incognito_value_map_.GetRuleIterator(content_type,
221 resource_identifier,
222 &lock_);
223 return value_map_.GetRuleIterator(content_type, resource_identifier, &lock_);
224 }
225
226 // ////////////////////////////////////////////////////////////////////////////
227 // Private
228
229 void PrefProvider::UpdatePref(
230 const ContentSettingsPattern& primary_pattern, 187 const ContentSettingsPattern& primary_pattern,
231 const ContentSettingsPattern& secondary_pattern, 188 const ContentSettingsPattern& secondary_pattern,
232 ContentSettingsType content_type, 189 ContentSettingsType content_type) {
233 const ResourceIdentifier& resource_identifier, 190 // Don't write if in incognito.
234 const base::Value* value) { 191 if (is_incognito_) {
192 return;
193 }
194
235 // Ensure that |lock_| is not held by this thread, since this function will 195 // Ensure that |lock_| is not held by this thread, since this function will
236 // send out notifications (by |~DictionaryPrefUpdate|). 196 // send out notifications (by |~DictionaryPrefUpdate|).
237 AssertLockNotHeld(); 197 AssertLockNotHeld();
238 198
239 base::AutoReset<bool> auto_reset(&updating_preferences_, true); 199 base::AutoReset<bool> auto_reset(&updating_preferences_, true);
240 { 200 {
241 DictionaryPrefUpdate update(prefs_, 201 DictionaryPrefUpdate update(prefs_, prefs::kContentSettingsPatternPairs);
242 prefs::kContentSettingsPatternPairs);
243 base::DictionaryValue* pattern_pairs_settings = update.Get(); 202 base::DictionaryValue* pattern_pairs_settings = update.Get();
244 203
245 // Get settings dictionary for the given patterns. 204 std::string pattern_str(
246 std::string pattern_str(CreatePatternString(primary_pattern, 205 CreatePatternString(primary_pattern, secondary_pattern));
247 secondary_pattern));
248 base::DictionaryValue* settings_dictionary = NULL; 206 base::DictionaryValue* settings_dictionary = NULL;
249 bool found = pattern_pairs_settings->GetDictionaryWithoutPathExpansion( 207 bool found = pattern_pairs_settings->GetDictionaryWithoutPathExpansion(
250 pattern_str, &settings_dictionary); 208 pattern_str, &settings_dictionary);
251 209
252 if (!found && value) { 210 if (!found) {
253 settings_dictionary = new base::DictionaryValue; 211 settings_dictionary = new base::DictionaryValue;
254 pattern_pairs_settings->SetWithoutPathExpansion( 212 pattern_pairs_settings->SetWithoutPathExpansion(pattern_str,
255 pattern_str, settings_dictionary); 213 settings_dictionary);
256 } 214 }
257 215
258 if (settings_dictionary) { 216 base::DictionaryValue* last_used_dictionary = NULL;
259 std::string res_dictionary_path; 217 found = settings_dictionary->GetDictionaryWithoutPathExpansion(
260 if (GetResourceTypeName(content_type, &res_dictionary_path) && 218 kLastUsed, &last_used_dictionary);
261 !resource_identifier.empty()) { 219
262 base::DictionaryValue* resource_dictionary = NULL; 220 if (!found) {
263 found = settings_dictionary->GetDictionary( 221 last_used_dictionary = new base::DictionaryValue;
264 res_dictionary_path, &resource_dictionary); 222 settings_dictionary->SetWithoutPathExpansion(kLastUsed,
265 if (!found) { 223 last_used_dictionary);
266 if (value == NULL)
267 return; // Nothing to remove. Exit early.
268 resource_dictionary = new base::DictionaryValue;
269 settings_dictionary->Set(res_dictionary_path, resource_dictionary);
270 }
271 // Update resource dictionary.
272 if (value == NULL) {
273 resource_dictionary->RemoveWithoutPathExpansion(resource_identifier,
274 NULL);
275 if (resource_dictionary->empty()) {
276 settings_dictionary->RemoveWithoutPathExpansion(
277 res_dictionary_path, NULL);
278 }
279 } else {
280 resource_dictionary->SetWithoutPathExpansion(
281 resource_identifier, value->DeepCopy());
282 }
283 } else {
284 // Update settings dictionary.
285 std::string setting_path = GetTypeName(content_type);
286 if (value == NULL) {
287 settings_dictionary->RemoveWithoutPathExpansion(setting_path,
288 NULL);
289 settings_dictionary->RemoveWithoutPathExpansion(kLastUsed, NULL);
290 } else {
291 settings_dictionary->SetWithoutPathExpansion(
292 setting_path, value->DeepCopy());
293 }
294 }
295 // Remove the settings dictionary if it is empty.
296 if (settings_dictionary->empty()) {
297 pattern_pairs_settings->RemoveWithoutPathExpansion(
298 pattern_str, NULL);
299 }
300 } 224 }
225
226 std::string settings_path = GetTypeName(content_type);
227 last_used_dictionary->Set(
228 settings_path, new base::FundamentalValue(clock_->Now().ToDoubleT()));
301 } 229 }
302 } 230 }
303 231
232 base::Time ContentSettingsPref::GetLastUsage(
233 const ContentSettingsPattern& primary_pattern,
234 const ContentSettingsPattern& secondary_pattern,
235 ContentSettingsType content_type) {
236 const base::DictionaryValue* pattern_pairs_settings =
237 prefs_->GetDictionary(prefs::kContentSettingsPatternPairs);
238 std::string pattern_str(
239 CreatePatternString(primary_pattern, secondary_pattern));
304 240
305 void PrefProvider::MigrateObsoleteMediaContentSetting() { 241 const base::DictionaryValue* settings_dictionary = NULL;
306 std::vector<Rule> rules_to_delete; 242 bool found = pattern_pairs_settings->GetDictionaryWithoutPathExpansion(
307 { 243 pattern_str, &settings_dictionary);
308 scoped_ptr<RuleIterator> rule_iterator(GetRuleIterator(
309 CONTENT_SETTINGS_TYPE_MEDIASTREAM, std::string(), false));
310 while (rule_iterator->HasNext()) {
311 // Skip default setting and rules without a value.
312 const content_settings::Rule& rule = rule_iterator->Next();
313 DCHECK(rule.primary_pattern != ContentSettingsPattern::Wildcard());
314 if (!rule.value.get())
315 continue;
316 rules_to_delete.push_back(rule);
317 }
318 }
319 244
320 for (std::vector<Rule>::const_iterator it = rules_to_delete.begin(); 245 if (!found)
321 it != rules_to_delete.end(); ++it) { 246 return base::Time();
322 const base::DictionaryValue* value_dict = NULL;
323 if (!it->value->GetAsDictionary(&value_dict) || value_dict->empty())
324 return;
325 247
326 std::string audio_device, video_device; 248 const base::DictionaryValue* last_used_dictionary = NULL;
327 value_dict->GetString(kAudioKey, &audio_device); 249 found = settings_dictionary->GetDictionaryWithoutPathExpansion(
328 value_dict->GetString(kVideoKey, &video_device); 250 kLastUsed, &last_used_dictionary);
329 // Add the exception to the new microphone content setting.
330 if (!audio_device.empty()) {
331 SetWebsiteSetting(it->primary_pattern,
332 it->secondary_pattern,
333 CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
334 std::string(),
335 new base::FundamentalValue(CONTENT_SETTING_ALLOW));
336 }
337 // Add the exception to the new camera content setting.
338 if (!video_device.empty()) {
339 SetWebsiteSetting(it->primary_pattern,
340 it->secondary_pattern,
341 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA,
342 std::string(),
343 new base::FundamentalValue(CONTENT_SETTING_ALLOW));
344 }
345 251
346 // Remove the old exception in CONTENT_SETTINGS_TYPE_MEDIASTREAM. 252 if (!found)
347 SetWebsiteSetting(it->primary_pattern, 253 return base::Time();
348 it->secondary_pattern, 254
349 CONTENT_SETTINGS_TYPE_MEDIASTREAM, 255 double last_used_time;
350 std::string(), 256 found = last_used_dictionary->GetDoubleWithoutPathExpansion(
351 NULL); 257 GetTypeName(content_type), &last_used_time);
352 } 258
259 if (!found)
260 return base::Time();
261
262 return base::Time::FromDoubleT(last_used_time);
353 } 263 }
354 264
355 void PrefProvider::ReadContentSettingsFromPref() { 265 size_t ContentSettingsPref::GetNumExceptions() {
266 return value_map_.size();
267 }
268
269 void ContentSettingsPref::SetClockForTesting(base::Clock* clock) {
270 clock_ = clock;
271 }
272
273 void ContentSettingsPref::ReadContentSettingsFromPref() {
356 // |DictionaryPrefUpdate| sends out notifications when destructed. This 274 // |DictionaryPrefUpdate| sends out notifications when destructed. This
357 // construction order ensures |AutoLock| gets destroyed first and |lock_| is 275 // construction order ensures |AutoLock| gets destroyed first and |lock_| is
358 // not held when the notifications are sent. Also, |auto_reset| must be still 276 // not held when the notifications are sent. Also, |auto_reset| must be still
359 // valid when the notifications are sent, so that |Observe| skips the 277 // valid when the notifications are sent, so that |Observe| skips the
360 // notification. 278 // notification.
361 base::AutoReset<bool> auto_reset(&updating_preferences_, true); 279 base::AutoReset<bool> auto_reset(&updating_preferences_, true);
362 DictionaryPrefUpdate update(prefs_, prefs::kContentSettingsPatternPairs); 280 DictionaryPrefUpdate update(prefs_, prefs::kContentSettingsPatternPairs);
363 base::AutoLock auto_lock(lock_); 281 base::AutoLock auto_lock(lock_);
364 282
365 const base::DictionaryValue* all_settings_dictionary = 283 const base::DictionaryValue* all_settings_dictionary =
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
477 } 395 }
478 } 396 }
479 UMA_HISTOGRAM_COUNTS("ContentSettings.NumberOfBlockCookiesExceptions", 397 UMA_HISTOGRAM_COUNTS("ContentSettings.NumberOfBlockCookiesExceptions",
480 cookies_block_exception_count); 398 cookies_block_exception_count);
481 UMA_HISTOGRAM_COUNTS("ContentSettings.NumberOfAllowCookiesExceptions", 399 UMA_HISTOGRAM_COUNTS("ContentSettings.NumberOfAllowCookiesExceptions",
482 cookies_allow_exception_count); 400 cookies_allow_exception_count);
483 UMA_HISTOGRAM_COUNTS("ContentSettings.NumberOfSessionOnlyCookiesExceptions", 401 UMA_HISTOGRAM_COUNTS("ContentSettings.NumberOfSessionOnlyCookiesExceptions",
484 cookies_session_only_exception_count); 402 cookies_session_only_exception_count);
485 } 403 }
486 404
487 void PrefProvider::OnContentSettingsPatternPairsChanged() { 405 void ContentSettingsPref::OnContentSettingsPatternPairsChanged() {
488 DCHECK(CalledOnValidThread()); 406 DCHECK(thread_checker_.CalledOnValidThread());
489 407
490 if (updating_preferences_) 408 if (updating_preferences_)
491 return; 409 return;
492 410
493 ReadContentSettingsFromPref(); 411 ReadContentSettingsFromPref();
494 412
495 NotifyObservers(ContentSettingsPattern(), 413 notify_callback_.Run(ContentSettingsPattern(),
496 ContentSettingsPattern(), 414 ContentSettingsPattern(),
497 CONTENT_SETTINGS_TYPE_DEFAULT, 415 CONTENT_SETTINGS_TYPE_DEFAULT,
498 std::string()); 416 std::string());
417 }
418
419 void ContentSettingsPref::UpdatePref(
420 const ContentSettingsPattern& primary_pattern,
421 const ContentSettingsPattern& secondary_pattern,
422 ContentSettingsType content_type,
423 const ResourceIdentifier& resource_identifier,
424 const base::Value* value) {
425 // Ensure that |lock_| is not held by this thread, since this function will
426 // send out notifications (by |~DictionaryPrefUpdate|).
427 AssertLockNotHeld();
428
429 base::AutoReset<bool> auto_reset(&updating_preferences_, true);
430 {
431 DictionaryPrefUpdate update(prefs_,
432 prefs::kContentSettingsPatternPairs);
433 base::DictionaryValue* pattern_pairs_settings = update.Get();
434
435 // Get settings dictionary for the given patterns.
436 std::string pattern_str(CreatePatternString(primary_pattern,
437 secondary_pattern));
438 base::DictionaryValue* settings_dictionary = NULL;
439 bool found = pattern_pairs_settings->GetDictionaryWithoutPathExpansion(
440 pattern_str, &settings_dictionary);
441
442 if (!found && value) {
443 settings_dictionary = new base::DictionaryValue;
444 pattern_pairs_settings->SetWithoutPathExpansion(
445 pattern_str, settings_dictionary);
446 }
447
448 if (settings_dictionary) {
449 std::string res_dictionary_path;
450 if (GetResourceTypeName(content_type, &res_dictionary_path) &&
451 !resource_identifier.empty()) {
452 base::DictionaryValue* resource_dictionary = NULL;
453 found = settings_dictionary->GetDictionary(
454 res_dictionary_path, &resource_dictionary);
455 if (!found) {
456 if (value == NULL)
457 return; // Nothing to remove. Exit early.
458 resource_dictionary = new base::DictionaryValue;
459 settings_dictionary->Set(res_dictionary_path, resource_dictionary);
460 }
461 // Update resource dictionary.
462 if (value == NULL) {
463 resource_dictionary->RemoveWithoutPathExpansion(resource_identifier,
464 NULL);
465 if (resource_dictionary->empty()) {
466 settings_dictionary->RemoveWithoutPathExpansion(
467 res_dictionary_path, NULL);
468 }
469 } else {
470 resource_dictionary->SetWithoutPathExpansion(
471 resource_identifier, value->DeepCopy());
472 }
473 } else {
474 // Update settings dictionary.
475 std::string setting_path = GetTypeName(content_type);
476 if (value == NULL) {
477 settings_dictionary->RemoveWithoutPathExpansion(setting_path,
478 NULL);
479 settings_dictionary->RemoveWithoutPathExpansion(kLastUsed, NULL);
480 } else {
481 settings_dictionary->SetWithoutPathExpansion(
482 setting_path, value->DeepCopy());
483 }
484 }
485 // Remove the settings dictionary if it is empty.
486 if (settings_dictionary->empty()) {
487 pattern_pairs_settings->RemoveWithoutPathExpansion(
488 pattern_str, NULL);
489 }
490 }
491 }
499 } 492 }
500 493
501 // static 494 // static
502 void PrefProvider::CanonicalizeContentSettingsExceptions( 495 void ContentSettingsPref::CanonicalizeContentSettingsExceptions(
503 base::DictionaryValue* all_settings_dictionary) { 496 base::DictionaryValue* all_settings_dictionary) {
504 DCHECK(all_settings_dictionary); 497 DCHECK(all_settings_dictionary);
505 498
506 std::vector<std::string> remove_items; 499 std::vector<std::string> remove_items;
507 base::StringPairs move_items; 500 base::StringPairs move_items;
508 for (base::DictionaryValue::Iterator i(*all_settings_dictionary); 501 for (base::DictionaryValue::Iterator i(*all_settings_dictionary);
509 !i.IsAtEnd(); 502 !i.IsAtEnd();
510 i.Advance()) { 503 i.Advance()) {
511 const std::string& pattern_str(i.key()); 504 const std::string& pattern_str(i.key());
512 std::pair<ContentSettingsPattern, ContentSettingsPattern> pattern_pair = 505 std::pair<ContentSettingsPattern, ContentSettingsPattern> pattern_pair =
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
547 540
548 for (size_t i = 0; i < move_items.size(); ++i) { 541 for (size_t i = 0; i < move_items.size(); ++i) {
549 scoped_ptr<base::Value> pattern_settings_dictionary; 542 scoped_ptr<base::Value> pattern_settings_dictionary;
550 all_settings_dictionary->RemoveWithoutPathExpansion( 543 all_settings_dictionary->RemoveWithoutPathExpansion(
551 move_items[i].first, &pattern_settings_dictionary); 544 move_items[i].first, &pattern_settings_dictionary);
552 all_settings_dictionary->SetWithoutPathExpansion( 545 all_settings_dictionary->SetWithoutPathExpansion(
553 move_items[i].second, pattern_settings_dictionary.release()); 546 move_items[i].second, pattern_settings_dictionary.release());
554 } 547 }
555 } 548 }
556 549
557 void PrefProvider::ShutdownOnUIThread() { 550 void ContentSettingsPref::AssertLockNotHeld() const {
558 DCHECK(CalledOnValidThread());
559 DCHECK(prefs_);
560 RemoveAllObservers();
561 pref_change_registrar_.RemoveAll();
562 prefs_ = NULL;
563 }
564
565 void PrefProvider::UpdateLastUsage(
566 const ContentSettingsPattern& primary_pattern,
567 const ContentSettingsPattern& secondary_pattern,
568 ContentSettingsType content_type) {
569 // Don't write if in incognito.
570 if (is_incognito_) {
571 return;
572 }
573
574 // Ensure that |lock_| is not held by this thread, since this function will
575 // send out notifications (by |~DictionaryPrefUpdate|).
576 AssertLockNotHeld();
577
578 base::AutoReset<bool> auto_reset(&updating_preferences_, true);
579 {
580 DictionaryPrefUpdate update(prefs_, prefs::kContentSettingsPatternPairs);
581 base::DictionaryValue* pattern_pairs_settings = update.Get();
582
583 std::string pattern_str(
584 CreatePatternString(primary_pattern, secondary_pattern));
585 base::DictionaryValue* settings_dictionary = NULL;
586 bool found = pattern_pairs_settings->GetDictionaryWithoutPathExpansion(
587 pattern_str, &settings_dictionary);
588
589 if (!found) {
590 settings_dictionary = new base::DictionaryValue;
591 pattern_pairs_settings->SetWithoutPathExpansion(pattern_str,
592 settings_dictionary);
593 }
594
595 base::DictionaryValue* last_used_dictionary = NULL;
596 found = settings_dictionary->GetDictionaryWithoutPathExpansion(
597 kLastUsed, &last_used_dictionary);
598
599 if (!found) {
600 last_used_dictionary = new base::DictionaryValue;
601 settings_dictionary->SetWithoutPathExpansion(kLastUsed,
602 last_used_dictionary);
603 }
604
605 std::string settings_path = GetTypeName(content_type);
606 last_used_dictionary->Set(
607 settings_path, new base::FundamentalValue(clock_->Now().ToDoubleT()));
608 }
609 }
610
611 base::Time PrefProvider::GetLastUsage(
612 const ContentSettingsPattern& primary_pattern,
613 const ContentSettingsPattern& secondary_pattern,
614 ContentSettingsType content_type) {
615 const base::DictionaryValue* pattern_pairs_settings =
616 prefs_->GetDictionary(prefs::kContentSettingsPatternPairs);
617 std::string pattern_str(
618 CreatePatternString(primary_pattern, secondary_pattern));
619
620 const base::DictionaryValue* settings_dictionary = NULL;
621 bool found = pattern_pairs_settings->GetDictionaryWithoutPathExpansion(
622 pattern_str, &settings_dictionary);
623
624 if (!found)
625 return base::Time();
626
627 const base::DictionaryValue* last_used_dictionary = NULL;
628 found = settings_dictionary->GetDictionaryWithoutPathExpansion(
629 kLastUsed, &last_used_dictionary);
630
631 if (!found)
632 return base::Time();
633
634 double last_used_time;
635 found = last_used_dictionary->GetDoubleWithoutPathExpansion(
636 GetTypeName(content_type), &last_used_time);
637
638 if (!found)
639 return base::Time();
640
641 return base::Time::FromDoubleT(last_used_time);
642 }
643
644 void PrefProvider::AssertLockNotHeld() const {
645 #if !defined(NDEBUG) 551 #if !defined(NDEBUG)
646 // |Lock::Acquire()| will assert if the lock is held by this thread. 552 // |Lock::Acquire()| will assert if the lock is held by this thread.
647 lock_.Acquire(); 553 lock_.Acquire();
648 lock_.Release(); 554 lock_.Release();
649 #endif 555 #endif
650 } 556 }
651 557
652 void PrefProvider::SetClockForTesting(scoped_ptr<base::Clock> clock) {
653 clock_ = clock.Pass();
654 }
655
656 } // namespace content_settings 558 } // namespace content_settings
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698