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

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

Issue 2812113004: Write last_modified date to Content Settings in the PrefProvider (Closed)
Patch Set: fix comments Created 3 years, 8 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 2015 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.h" 5 #include "components/content_settings/core/browser/content_settings_pref.h"
6 6
7 #include <memory> 7 #include <memory>
8 8
9 #include "base/auto_reset.h" 9 #include "base/auto_reset.h"
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/metrics/histogram_macros.h" 11 #include "base/metrics/histogram_macros.h"
12 #include "base/strings/string_number_conversions.h"
12 #include "base/strings/string_split.h" 13 #include "base/strings/string_split.h"
13 #include "components/content_settings/core/browser/content_settings_info.h" 14 #include "components/content_settings/core/browser/content_settings_info.h"
14 #include "components/content_settings/core/browser/content_settings_registry.h" 15 #include "components/content_settings/core/browser/content_settings_registry.h"
15 #include "components/content_settings/core/browser/content_settings_rule.h" 16 #include "components/content_settings/core/browser/content_settings_rule.h"
16 #include "components/content_settings/core/browser/content_settings_utils.h" 17 #include "components/content_settings/core/browser/content_settings_utils.h"
17 #include "components/content_settings/core/browser/host_content_settings_map.h" 18 #include "components/content_settings/core/browser/host_content_settings_map.h"
18 #include "components/content_settings/core/common/content_settings.h" 19 #include "components/content_settings/core/common/content_settings.h"
19 #include "components/content_settings/core/common/content_settings_pattern.h" 20 #include "components/content_settings/core/common/content_settings_pattern.h"
20 #include "components/content_settings/core/common/pref_names.h" 21 #include "components/content_settings/core/common/pref_names.h"
21 #include "components/prefs/scoped_user_pref_update.h" 22 #include "components/prefs/scoped_user_pref_update.h"
22 #include "url/gurl.h" 23 #include "url/gurl.h"
23 24
24 namespace { 25 namespace {
25 26
26 const char kSettingPath[] = "setting"; 27 const char kSettingPath[] = "setting";
28 const char kLastModifiedPath[] = "last_modified";
29 const char kPerResourceLastModifiedPath[] = "per_resource_last_modified";
27 const char kPerResourceIdentifierPrefName[] = "per_resource"; 30 const char kPerResourceIdentifierPrefName[] = "per_resource";
28 31
29 // If the given content type supports resource identifiers in user preferences, 32 // If the given content type supports resource identifiers in user preferences,
30 // returns true and sets |pref_key| to the key in the content settings 33 // returns true and sets |pref_key| to the key in the content settings
31 // dictionary under which per-resource content settings are stored. 34 // dictionary under which per-resource content settings are stored.
32 // Otherwise, returns false. 35 // Otherwise, returns false.
33 bool SupportsResourceIdentifiers(ContentSettingsType content_type) { 36 bool SupportsResourceIdentifiers(ContentSettingsType content_type) {
34 return content_type == CONTENT_SETTINGS_TYPE_PLUGINS; 37 return content_type == CONTENT_SETTINGS_TYPE_PLUGINS;
35 } 38 }
36 39
37 bool IsValueAllowedForType(const base::Value* value, ContentSettingsType type) { 40 bool IsValueAllowedForType(const base::Value* value, ContentSettingsType type) {
38 const content_settings::ContentSettingsInfo* info = 41 const content_settings::ContentSettingsInfo* info =
39 content_settings::ContentSettingsRegistry::GetInstance()->Get(type); 42 content_settings::ContentSettingsRegistry::GetInstance()->Get(type);
40 if (info) { 43 if (info) {
41 int setting; 44 int setting;
42 if (!value->GetAsInteger(&setting)) 45 if (!value->GetAsInteger(&setting))
43 return false; 46 return false;
44 if (setting == CONTENT_SETTING_DEFAULT) 47 if (setting == CONTENT_SETTING_DEFAULT)
45 return false; 48 return false;
46 return info->IsSettingValid(IntToContentSetting(setting)); 49 return info->IsSettingValid(IntToContentSetting(setting));
47 } 50 }
48 51
49 // TODO(raymes): We should permit different types of base::Value for 52 // TODO(raymes): We should permit different types of base::Value for
50 // website settings. 53 // website settings.
51 return value->GetType() == base::Value::Type::DICTIONARY; 54 return value->GetType() == base::Value::Type::DICTIONARY;
52 } 55 }
53 56
57 // Extract a timestamp from |dictionary[path]|. Will return base::Time() if no
58 // timestamp exists or |dictionary| is NULL.
59 base::Time GetTimeStamp(const base::DictionaryValue* dictionary,
60 const std::string& path) {
61 if (!dictionary) {
62 return base::Time();
63 }
64 std::string timestamp_str;
65 dictionary->GetStringWithoutPathExpansion(path, &timestamp_str);
66 int64_t timestamp = 0;
67 base::StringToInt64(timestamp_str, &timestamp);
68 base::Time last_modified = base::Time::FromInternalValue(timestamp);
69 return last_modified;
70 }
71
54 } // namespace 72 } // namespace
55 73
56 namespace content_settings { 74 namespace content_settings {
57 75
58 ContentSettingsPref::ContentSettingsPref( 76 ContentSettingsPref::ContentSettingsPref(
59 ContentSettingsType content_type, 77 ContentSettingsType content_type,
60 PrefService* prefs, 78 PrefService* prefs,
61 PrefChangeRegistrar* registrar, 79 PrefChangeRegistrar* registrar,
62 const std::string& pref_name, 80 const std::string& pref_name,
63 bool incognito, 81 bool incognito,
82 bool store_last_modified,
64 NotifyObserversCallback notify_callback) 83 NotifyObserversCallback notify_callback)
65 : content_type_(content_type), 84 : content_type_(content_type),
66 prefs_(prefs), 85 prefs_(prefs),
67 registrar_(registrar), 86 registrar_(registrar),
68 pref_name_(pref_name), 87 pref_name_(pref_name),
69 is_incognito_(incognito), 88 is_incognito_(incognito),
89 store_last_modified_(store_last_modified),
70 updating_preferences_(false), 90 updating_preferences_(false),
71 notify_callback_(notify_callback) { 91 notify_callback_(notify_callback) {
72 DCHECK(prefs_); 92 DCHECK(prefs_);
73 93
74 ReadContentSettingsFromPref(); 94 ReadContentSettingsFromPref();
75 95
76 registrar_->Add( 96 registrar_->Add(
77 pref_name_, 97 pref_name_,
78 base::Bind(&ContentSettingsPref::OnPrefChanged, base::Unretained(this))); 98 base::Bind(&ContentSettingsPref::OnPrefChanged, base::Unretained(this)));
79 } 99 }
(...skipping 24 matching lines...) Expand all
104 !resource_identifier.empty()); 124 !resource_identifier.empty());
105 125
106 // At this point take the ownership of the |in_value|. 126 // At this point take the ownership of the |in_value|.
107 std::unique_ptr<base::Value> value(in_value); 127 std::unique_ptr<base::Value> value(in_value);
108 128
109 // Update in memory value map. 129 // Update in memory value map.
110 OriginIdentifierValueMap* map_to_modify = &incognito_value_map_; 130 OriginIdentifierValueMap* map_to_modify = &incognito_value_map_;
111 if (!is_incognito_) 131 if (!is_incognito_)
112 map_to_modify = &value_map_; 132 map_to_modify = &value_map_;
113 133
134 base::Time modified_time =
135 store_last_modified_ ? base::Time::Now() : base::Time();
136
114 { 137 {
115 base::AutoLock auto_lock(lock_); 138 base::AutoLock auto_lock(lock_);
116 if (value.get()) { 139 if (value.get()) {
117 map_to_modify->SetValue( 140 map_to_modify->SetValue(primary_pattern, secondary_pattern, content_type_,
118 primary_pattern, 141 resource_identifier, modified_time,
119 secondary_pattern, 142 value->DeepCopy());
120 content_type_,
121 resource_identifier,
122 value->DeepCopy());
123 } else { 143 } else {
124 map_to_modify->DeleteValue( 144 map_to_modify->DeleteValue(
125 primary_pattern, 145 primary_pattern,
126 secondary_pattern, 146 secondary_pattern,
127 content_type_, 147 content_type_,
128 resource_identifier); 148 resource_identifier);
129 } 149 }
130 } 150 }
131 // Update the content settings preference. 151 // Update the content settings preference.
132 if (!is_incognito_) { 152 if (!is_incognito_) {
133 UpdatePref(primary_pattern, 153 UpdatePref(primary_pattern, secondary_pattern, resource_identifier,
134 secondary_pattern, 154 modified_time, value.get());
135 resource_identifier,
136 value.get());
137 } 155 }
138 156
139 notify_callback_.Run( 157 notify_callback_.Run(
140 primary_pattern, secondary_pattern, content_type_, resource_identifier); 158 primary_pattern, secondary_pattern, content_type_, resource_identifier);
141 159
142 return true; 160 return true;
143 } 161 }
144 162
145 void ContentSettingsPref::ClearPref() { 163 void ContentSettingsPref::ClearPref() {
146 DCHECK(thread_checker_.CalledOnValidThread()); 164 DCHECK(thread_checker_.CalledOnValidThread());
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 // Get settings dictionary for the current pattern string, and read 255 // Get settings dictionary for the current pattern string, and read
238 // settings from the dictionary. 256 // settings from the dictionary.
239 const base::DictionaryValue* settings_dictionary = NULL; 257 const base::DictionaryValue* settings_dictionary = NULL;
240 bool is_dictionary = i.value().GetAsDictionary(&settings_dictionary); 258 bool is_dictionary = i.value().GetAsDictionary(&settings_dictionary);
241 DCHECK(is_dictionary); 259 DCHECK(is_dictionary);
242 260
243 if (SupportsResourceIdentifiers(content_type_)) { 261 if (SupportsResourceIdentifiers(content_type_)) {
244 const base::DictionaryValue* resource_dictionary = NULL; 262 const base::DictionaryValue* resource_dictionary = NULL;
245 if (settings_dictionary->GetDictionary( 263 if (settings_dictionary->GetDictionary(
246 kPerResourceIdentifierPrefName, &resource_dictionary)) { 264 kPerResourceIdentifierPrefName, &resource_dictionary)) {
265 const base::DictionaryValue* timestamp_dictionary = NULL;
266 settings_dictionary->GetDictionary(kPerResourceLastModifiedPath,
267 &timestamp_dictionary);
247 for (base::DictionaryValue::Iterator j(*resource_dictionary); 268 for (base::DictionaryValue::Iterator j(*resource_dictionary);
248 !j.IsAtEnd(); 269 !j.IsAtEnd();
249 j.Advance()) { 270 j.Advance()) {
250 const std::string& resource_identifier(j.key()); 271 const std::string& resource_identifier(j.key());
272 base::Time last_modified =
273 GetTimeStamp(timestamp_dictionary, resource_identifier);
251 int setting = CONTENT_SETTING_DEFAULT; 274 int setting = CONTENT_SETTING_DEFAULT;
252 bool is_integer = j.value().GetAsInteger(&setting); 275 bool is_integer = j.value().GetAsInteger(&setting);
253 DCHECK(is_integer); 276 DCHECK(is_integer);
254 DCHECK_NE(CONTENT_SETTING_DEFAULT, setting); 277 DCHECK_NE(CONTENT_SETTING_DEFAULT, setting);
255 std::unique_ptr<base::Value> setting_ptr(new base::Value(setting)); 278 std::unique_ptr<base::Value> setting_ptr(new base::Value(setting));
256 value_map_.SetValue(pattern_pair.first, 279 value_map_.SetValue(pattern_pair.first, pattern_pair.second,
257 pattern_pair.second, 280 content_type_, resource_identifier, last_modified,
258 content_type_,
259 resource_identifier,
260 setting_ptr->DeepCopy()); 281 setting_ptr->DeepCopy());
261 } 282 }
262 } 283 }
263 } 284 }
264 285
265 const base::Value* value = nullptr; 286 const base::Value* value = nullptr;
266 settings_dictionary->GetWithoutPathExpansion(kSettingPath, &value); 287 settings_dictionary->GetWithoutPathExpansion(kSettingPath, &value);
267
268 if (value) { 288 if (value) {
289 base::Time last_modified =
290 GetTimeStamp(settings_dictionary, kLastModifiedPath);
269 DCHECK(IsValueAllowedForType(value, content_type_)); 291 DCHECK(IsValueAllowedForType(value, content_type_));
270 value_map_.SetValue(pattern_pair.first, 292 value_map_.SetValue(pattern_pair.first, pattern_pair.second,
271 pattern_pair.second, 293 content_type_, ResourceIdentifier(), last_modified,
272 content_type_,
273 ResourceIdentifier(),
274 value->DeepCopy()); 294 value->DeepCopy());
275 if (content_type_ == CONTENT_SETTINGS_TYPE_COOKIES) { 295 if (content_type_ == CONTENT_SETTINGS_TYPE_COOKIES) {
276 ContentSetting s = ValueToContentSetting(value); 296 ContentSetting s = ValueToContentSetting(value);
277 switch (s) { 297 switch (s) {
278 case CONTENT_SETTING_ALLOW : 298 case CONTENT_SETTING_ALLOW :
279 ++cookies_allow_exception_count; 299 ++cookies_allow_exception_count;
280 break; 300 break;
281 case CONTENT_SETTING_BLOCK : 301 case CONTENT_SETTING_BLOCK :
282 ++cookies_block_exception_count; 302 ++cookies_block_exception_count;
283 break; 303 break;
(...skipping 30 matching lines...) Expand all
314 notify_callback_.Run(ContentSettingsPattern(), 334 notify_callback_.Run(ContentSettingsPattern(),
315 ContentSettingsPattern(), 335 ContentSettingsPattern(),
316 content_type_, 336 content_type_,
317 ResourceIdentifier()); 337 ResourceIdentifier());
318 } 338 }
319 339
320 void ContentSettingsPref::UpdatePref( 340 void ContentSettingsPref::UpdatePref(
321 const ContentSettingsPattern& primary_pattern, 341 const ContentSettingsPattern& primary_pattern,
322 const ContentSettingsPattern& secondary_pattern, 342 const ContentSettingsPattern& secondary_pattern,
323 const ResourceIdentifier& resource_identifier, 343 const ResourceIdentifier& resource_identifier,
344 const base::Time last_modified,
324 const base::Value* value) { 345 const base::Value* value) {
325 // Ensure that |lock_| is not held by this thread, since this function will 346 // Ensure that |lock_| is not held by this thread, since this function will
326 // send out notifications (by |~DictionaryPrefUpdate|). 347 // send out notifications (by |~DictionaryPrefUpdate|).
327 AssertLockNotHeld(); 348 AssertLockNotHeld();
328 349
329 base::AutoReset<bool> auto_reset(&updating_preferences_, true); 350 base::AutoReset<bool> auto_reset(&updating_preferences_, true);
330 { 351 {
331 DictionaryPrefUpdate update(prefs_, pref_name_); 352 DictionaryPrefUpdate update(prefs_, pref_name_);
332 base::DictionaryValue* pattern_pairs_settings = update.Get(); 353 base::DictionaryValue* pattern_pairs_settings = update.Get();
333 354
(...skipping 12 matching lines...) Expand all
346 367
347 if (settings_dictionary) { 368 if (settings_dictionary) {
348 if (SupportsResourceIdentifiers(content_type_) && 369 if (SupportsResourceIdentifiers(content_type_) &&
349 !resource_identifier.empty()) { 370 !resource_identifier.empty()) {
350 base::DictionaryValue* resource_dictionary = NULL; 371 base::DictionaryValue* resource_dictionary = NULL;
351 found = settings_dictionary->GetDictionary( 372 found = settings_dictionary->GetDictionary(
352 kPerResourceIdentifierPrefName, &resource_dictionary); 373 kPerResourceIdentifierPrefName, &resource_dictionary);
353 if (!found) { 374 if (!found) {
354 if (value == NULL) 375 if (value == NULL)
355 return; // Nothing to remove. Exit early. 376 return; // Nothing to remove. Exit early.
356 resource_dictionary = new base::DictionaryValue; 377 resource_dictionary = new base::DictionaryValue();
357 settings_dictionary->Set( 378 settings_dictionary->Set(
358 kPerResourceIdentifierPrefName, resource_dictionary); 379 kPerResourceIdentifierPrefName, resource_dictionary);
359 } 380 }
381 base::DictionaryValue* timestamp_dictionary = NULL;
382 bool has_timestamps = settings_dictionary->GetDictionary(
383 kPerResourceLastModifiedPath, &timestamp_dictionary);
384 if (!has_timestamps) {
385 timestamp_dictionary = new base::DictionaryValue();
386 settings_dictionary->Set(kPerResourceLastModifiedPath,
387 timestamp_dictionary);
388 }
360 // Update resource dictionary. 389 // Update resource dictionary.
361 if (value == NULL) { 390 if (value == NULL) {
362 resource_dictionary->RemoveWithoutPathExpansion(resource_identifier, 391 resource_dictionary->RemoveWithoutPathExpansion(resource_identifier,
363 NULL); 392 NULL);
393 timestamp_dictionary->RemoveWithoutPathExpansion(resource_identifier,
394 NULL);
364 if (resource_dictionary->empty()) { 395 if (resource_dictionary->empty()) {
365 settings_dictionary->RemoveWithoutPathExpansion( 396 settings_dictionary->RemoveWithoutPathExpansion(
366 kPerResourceIdentifierPrefName, NULL); 397 kPerResourceIdentifierPrefName, NULL);
398 settings_dictionary->RemoveWithoutPathExpansion(
399 kPerResourceLastModifiedPath, NULL);
367 } 400 }
368 } else { 401 } else {
369 resource_dictionary->SetWithoutPathExpansion( 402 resource_dictionary->SetWithoutPathExpansion(
370 resource_identifier, value->DeepCopy()); 403 resource_identifier, value->DeepCopy());
404 timestamp_dictionary->SetStringWithoutPathExpansion(
405 resource_identifier,
406 base::Int64ToString(last_modified.ToInternalValue()));
371 } 407 }
372 } else { 408 } else {
373 // Update settings dictionary. 409 // Update settings dictionary.
374 if (value == NULL) { 410 if (value == NULL) {
375 settings_dictionary->RemoveWithoutPathExpansion(kSettingPath, NULL); 411 settings_dictionary->RemoveWithoutPathExpansion(kSettingPath, NULL);
412 settings_dictionary->RemoveWithoutPathExpansion(kLastModifiedPath,
413 NULL);
376 } else { 414 } else {
377 settings_dictionary->SetWithoutPathExpansion( 415 settings_dictionary->SetWithoutPathExpansion(
378 kSettingPath, value->DeepCopy()); 416 kSettingPath, value->DeepCopy());
417 settings_dictionary->SetStringWithoutPathExpansion(
418 kLastModifiedPath,
419 base::Int64ToString(last_modified.ToInternalValue()));
379 } 420 }
380 } 421 }
381 // Remove the settings dictionary if it is empty. 422 // Remove the settings dictionary if it is empty.
382 if (settings_dictionary->empty()) { 423 if (settings_dictionary->empty()) {
383 pattern_pairs_settings->RemoveWithoutPathExpansion( 424 pattern_pairs_settings->RemoveWithoutPathExpansion(
384 pattern_str, NULL); 425 pattern_str, NULL);
385 } 426 }
386 } 427 }
387 } 428 }
388 } 429 }
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
445 486
446 void ContentSettingsPref::AssertLockNotHeld() const { 487 void ContentSettingsPref::AssertLockNotHeld() const {
447 #if !defined(NDEBUG) 488 #if !defined(NDEBUG)
448 // |Lock::Acquire()| will assert if the lock is held by this thread. 489 // |Lock::Acquire()| will assert if the lock is held by this thread.
449 lock_.Acquire(); 490 lock_.Acquire();
450 lock_.Release(); 491 lock_.Release();
451 #endif 492 #endif
452 } 493 }
453 494
454 } // namespace content_settings 495 } // namespace content_settings
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698