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

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 ios 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";
27 const char kPerResourceIdentifierPrefName[] = "per_resource"; 29 const char kPerResourceIdentifierPrefName[] = "per_resource";
28 30
29 // If the given content type supports resource identifiers in user preferences, 31 // 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 32 // returns true and sets |pref_key| to the key in the content settings
31 // dictionary under which per-resource content settings are stored. 33 // dictionary under which per-resource content settings are stored.
32 // Otherwise, returns false. 34 // Otherwise, returns false.
33 bool SupportsResourceIdentifiers(ContentSettingsType content_type) { 35 bool SupportsResourceIdentifiers(ContentSettingsType content_type) {
34 return content_type == CONTENT_SETTINGS_TYPE_PLUGINS; 36 return content_type == CONTENT_SETTINGS_TYPE_PLUGINS;
35 } 37 }
36 38
37 bool IsValueAllowedForType(const base::Value* value, ContentSettingsType type) { 39 bool IsValueAllowedForType(const base::Value* value, ContentSettingsType type) {
38 const content_settings::ContentSettingsInfo* info = 40 const content_settings::ContentSettingsInfo* info =
39 content_settings::ContentSettingsRegistry::GetInstance()->Get(type); 41 content_settings::ContentSettingsRegistry::GetInstance()->Get(type);
40 if (info) { 42 if (info) {
41 int setting; 43 int setting;
42 if (!value->GetAsInteger(&setting)) 44 if (!value->GetAsInteger(&setting))
43 return false; 45 return false;
44 if (setting == CONTENT_SETTING_DEFAULT) 46 if (setting == CONTENT_SETTING_DEFAULT)
45 return false; 47 return false;
46 return info->IsSettingValid(IntToContentSetting(setting)); 48 return info->IsSettingValid(IntToContentSetting(setting));
47 } 49 }
48 50
49 // TODO(raymes): We should permit different types of base::Value for 51 // TODO(raymes): We should permit different types of base::Value for
50 // website settings. 52 // website settings.
51 return value->GetType() == base::Value::Type::DICTIONARY; 53 return value->GetType() == base::Value::Type::DICTIONARY;
52 } 54 }
53 55
56 // Extract a timestamp from |dictionary[path]|. Will return base::Time() if no
57 // timestamp exists.
58 base::Time GetTimeStamp(const base::DictionaryValue* dictionary,
59 const std::string& path) {
raymes 2017/04/24 03:20:22 Do we need to pass this in if it's always kLastMod
dullweber 2017/04/25 10:50:44 Done.
60 std::string timestamp_str;
61 dictionary->GetStringWithoutPathExpansion(path, &timestamp_str);
62 int64_t timestamp = 0;
63 base::StringToInt64(timestamp_str, &timestamp);
64 base::Time last_modified = base::Time::FromInternalValue(timestamp);
65 return last_modified;
66 }
67
54 } // namespace 68 } // namespace
55 69
56 namespace content_settings { 70 namespace content_settings {
57 71
58 ContentSettingsPref::ContentSettingsPref( 72 ContentSettingsPref::ContentSettingsPref(
59 ContentSettingsType content_type, 73 ContentSettingsType content_type,
60 PrefService* prefs, 74 PrefService* prefs,
61 PrefChangeRegistrar* registrar, 75 PrefChangeRegistrar* registrar,
62 const std::string& pref_name, 76 const std::string& pref_name,
63 bool incognito, 77 bool incognito,
78 bool store_last_modified,
64 NotifyObserversCallback notify_callback) 79 NotifyObserversCallback notify_callback)
65 : content_type_(content_type), 80 : content_type_(content_type),
66 prefs_(prefs), 81 prefs_(prefs),
67 registrar_(registrar), 82 registrar_(registrar),
68 pref_name_(pref_name), 83 pref_name_(pref_name),
69 is_incognito_(incognito), 84 is_incognito_(incognito),
85 store_last_modified_(store_last_modified),
70 updating_preferences_(false), 86 updating_preferences_(false),
71 notify_callback_(notify_callback) { 87 notify_callback_(notify_callback) {
72 DCHECK(prefs_); 88 DCHECK(prefs_);
73 89
74 ReadContentSettingsFromPref(); 90 ReadContentSettingsFromPref();
75 91
76 registrar_->Add( 92 registrar_->Add(
77 pref_name_, 93 pref_name_,
78 base::Bind(&ContentSettingsPref::OnPrefChanged, base::Unretained(this))); 94 base::Bind(&ContentSettingsPref::OnPrefChanged, base::Unretained(this)));
79 } 95 }
(...skipping 24 matching lines...) Expand all
104 !resource_identifier.empty()); 120 !resource_identifier.empty());
105 121
106 // At this point take the ownership of the |in_value|. 122 // At this point take the ownership of the |in_value|.
107 std::unique_ptr<base::Value> value(in_value); 123 std::unique_ptr<base::Value> value(in_value);
108 124
109 // Update in memory value map. 125 // Update in memory value map.
110 OriginIdentifierValueMap* map_to_modify = &incognito_value_map_; 126 OriginIdentifierValueMap* map_to_modify = &incognito_value_map_;
111 if (!is_incognito_) 127 if (!is_incognito_)
112 map_to_modify = &value_map_; 128 map_to_modify = &value_map_;
113 129
130 base::Time modified_time =
131 store_last_modified_ ? base::Time::Now() : base::Time();
132
114 { 133 {
115 base::AutoLock auto_lock(lock_); 134 base::AutoLock auto_lock(lock_);
116 if (value.get()) { 135 if (value.get()) {
117 map_to_modify->SetValue( 136 map_to_modify->SetValue(primary_pattern, secondary_pattern, content_type_,
118 primary_pattern, 137 resource_identifier, modified_time,
119 secondary_pattern, 138 value->DeepCopy());
120 content_type_,
121 resource_identifier,
122 value->DeepCopy());
123 } else { 139 } else {
124 map_to_modify->DeleteValue( 140 map_to_modify->DeleteValue(
125 primary_pattern, 141 primary_pattern,
126 secondary_pattern, 142 secondary_pattern,
127 content_type_, 143 content_type_,
128 resource_identifier); 144 resource_identifier);
129 } 145 }
130 } 146 }
131 // Update the content settings preference. 147 // Update the content settings preference.
132 if (!is_incognito_) { 148 if (!is_incognito_) {
133 UpdatePref(primary_pattern, 149 UpdatePref(primary_pattern, secondary_pattern, resource_identifier,
134 secondary_pattern, 150 modified_time, value.get());
135 resource_identifier,
136 value.get());
137 } 151 }
138 152
139 notify_callback_.Run( 153 notify_callback_.Run(
140 primary_pattern, secondary_pattern, content_type_, resource_identifier); 154 primary_pattern, secondary_pattern, content_type_, resource_identifier);
141 155
142 return true; 156 return true;
143 } 157 }
144 158
159 void ContentSettingsPref::DeleteWebsiteSetting(
160 const ContentSettingsPattern& primary_pattern,
161 const ContentSettingsPattern& secondary_pattern,
162 base::Time begin_time) {
163 OriginIdentifierValueMap* map_to_modify = &incognito_value_map_;
164 if (!is_incognito_)
165 map_to_modify = &value_map_;
166
167 base::Time last_modified = map_to_modify->GetLastModified(
168 primary_pattern, secondary_pattern, content_type_, ResourceIdentifier());
169 if (begin_time <= last_modified) {
170 SetWebsiteSetting(primary_pattern, secondary_pattern, ResourceIdentifier(),
171 nullptr);
172 }
173 }
174
145 void ContentSettingsPref::ClearPref() { 175 void ContentSettingsPref::ClearPref() {
146 DCHECK(thread_checker_.CalledOnValidThread()); 176 DCHECK(thread_checker_.CalledOnValidThread());
147 DCHECK(prefs_); 177 DCHECK(prefs_);
148 178
149 { 179 {
150 base::AutoLock auto_lock(lock_); 180 base::AutoLock auto_lock(lock_);
151 value_map_.clear(); 181 value_map_.clear();
152 } 182 }
153 183
154 { 184 {
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 kPerResourceIdentifierPrefName, &resource_dictionary)) { 276 kPerResourceIdentifierPrefName, &resource_dictionary)) {
247 for (base::DictionaryValue::Iterator j(*resource_dictionary); 277 for (base::DictionaryValue::Iterator j(*resource_dictionary);
248 !j.IsAtEnd(); 278 !j.IsAtEnd();
249 j.Advance()) { 279 j.Advance()) {
250 const std::string& resource_identifier(j.key()); 280 const std::string& resource_identifier(j.key());
251 int setting = CONTENT_SETTING_DEFAULT; 281 int setting = CONTENT_SETTING_DEFAULT;
252 bool is_integer = j.value().GetAsInteger(&setting); 282 bool is_integer = j.value().GetAsInteger(&setting);
253 DCHECK(is_integer); 283 DCHECK(is_integer);
254 DCHECK_NE(CONTENT_SETTING_DEFAULT, setting); 284 DCHECK_NE(CONTENT_SETTING_DEFAULT, setting);
255 std::unique_ptr<base::Value> setting_ptr(new base::Value(setting)); 285 std::unique_ptr<base::Value> setting_ptr(new base::Value(setting));
256 value_map_.SetValue(pattern_pair.first, 286 // Per resource settings don't support last_modified timestamps.
257 pattern_pair.second, 287 value_map_.SetValue(pattern_pair.first, pattern_pair.second,
258 content_type_, 288 content_type_, resource_identifier, base::Time(),
259 resource_identifier,
260 setting_ptr->DeepCopy()); 289 setting_ptr->DeepCopy());
261 } 290 }
262 } 291 }
263 } 292 }
264 293
265 const base::Value* value = nullptr; 294 const base::Value* value = nullptr;
266 settings_dictionary->GetWithoutPathExpansion(kSettingPath, &value); 295 settings_dictionary->GetWithoutPathExpansion(kSettingPath, &value);
267
268 if (value) { 296 if (value) {
297 base::Time last_modified =
298 GetTimeStamp(settings_dictionary, kLastModifiedPath);
269 DCHECK(IsValueAllowedForType(value, content_type_)); 299 DCHECK(IsValueAllowedForType(value, content_type_));
270 value_map_.SetValue(pattern_pair.first, 300 value_map_.SetValue(pattern_pair.first, pattern_pair.second,
271 pattern_pair.second, 301 content_type_, ResourceIdentifier(), last_modified,
272 content_type_,
273 ResourceIdentifier(),
274 value->DeepCopy()); 302 value->DeepCopy());
275 if (content_type_ == CONTENT_SETTINGS_TYPE_COOKIES) { 303 if (content_type_ == CONTENT_SETTINGS_TYPE_COOKIES) {
276 ContentSetting s = ValueToContentSetting(value); 304 ContentSetting s = ValueToContentSetting(value);
277 switch (s) { 305 switch (s) {
278 case CONTENT_SETTING_ALLOW : 306 case CONTENT_SETTING_ALLOW :
279 ++cookies_allow_exception_count; 307 ++cookies_allow_exception_count;
280 break; 308 break;
281 case CONTENT_SETTING_BLOCK : 309 case CONTENT_SETTING_BLOCK :
282 ++cookies_block_exception_count; 310 ++cookies_block_exception_count;
283 break; 311 break;
(...skipping 30 matching lines...) Expand all
314 notify_callback_.Run(ContentSettingsPattern(), 342 notify_callback_.Run(ContentSettingsPattern(),
315 ContentSettingsPattern(), 343 ContentSettingsPattern(),
316 content_type_, 344 content_type_,
317 ResourceIdentifier()); 345 ResourceIdentifier());
318 } 346 }
319 347
320 void ContentSettingsPref::UpdatePref( 348 void ContentSettingsPref::UpdatePref(
321 const ContentSettingsPattern& primary_pattern, 349 const ContentSettingsPattern& primary_pattern,
322 const ContentSettingsPattern& secondary_pattern, 350 const ContentSettingsPattern& secondary_pattern,
323 const ResourceIdentifier& resource_identifier, 351 const ResourceIdentifier& resource_identifier,
352 const base::Time last_modified,
324 const base::Value* value) { 353 const base::Value* value) {
325 // Ensure that |lock_| is not held by this thread, since this function will 354 // Ensure that |lock_| is not held by this thread, since this function will
326 // send out notifications (by |~DictionaryPrefUpdate|). 355 // send out notifications (by |~DictionaryPrefUpdate|).
327 AssertLockNotHeld(); 356 AssertLockNotHeld();
328 357
329 base::AutoReset<bool> auto_reset(&updating_preferences_, true); 358 base::AutoReset<bool> auto_reset(&updating_preferences_, true);
330 { 359 {
331 DictionaryPrefUpdate update(prefs_, pref_name_); 360 DictionaryPrefUpdate update(prefs_, pref_name_);
332 base::DictionaryValue* pattern_pairs_settings = update.Get(); 361 base::DictionaryValue* pattern_pairs_settings = update.Get();
333 362
(...skipping 12 matching lines...) Expand all
346 375
347 if (settings_dictionary) { 376 if (settings_dictionary) {
348 if (SupportsResourceIdentifiers(content_type_) && 377 if (SupportsResourceIdentifiers(content_type_) &&
349 !resource_identifier.empty()) { 378 !resource_identifier.empty()) {
350 base::DictionaryValue* resource_dictionary = NULL; 379 base::DictionaryValue* resource_dictionary = NULL;
351 found = settings_dictionary->GetDictionary( 380 found = settings_dictionary->GetDictionary(
352 kPerResourceIdentifierPrefName, &resource_dictionary); 381 kPerResourceIdentifierPrefName, &resource_dictionary);
353 if (!found) { 382 if (!found) {
354 if (value == NULL) 383 if (value == NULL)
355 return; // Nothing to remove. Exit early. 384 return; // Nothing to remove. Exit early.
356 resource_dictionary = new base::DictionaryValue; 385 resource_dictionary = new base::DictionaryValue();
raymes 2017/04/24 03:20:22 nit: () isn't needed
dullweber 2017/04/25 10:50:44 Done.
357 settings_dictionary->Set( 386 settings_dictionary->Set(
358 kPerResourceIdentifierPrefName, resource_dictionary); 387 kPerResourceIdentifierPrefName, resource_dictionary);
359 } 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);
364 if (resource_dictionary->empty()) { 393 if (resource_dictionary->empty()) {
365 settings_dictionary->RemoveWithoutPathExpansion( 394 settings_dictionary->RemoveWithoutPathExpansion(
366 kPerResourceIdentifierPrefName, NULL); 395 kPerResourceIdentifierPrefName, NULL);
367 } 396 }
368 } else { 397 } else {
369 resource_dictionary->SetWithoutPathExpansion( 398 resource_dictionary->SetWithoutPathExpansion(
370 resource_identifier, value->DeepCopy()); 399 resource_identifier, value->DeepCopy());
371 } 400 }
372 } else { 401 } else {
373 // Update settings dictionary. 402 // Update settings dictionary.
374 if (value == NULL) { 403 if (value == NULL) {
375 settings_dictionary->RemoveWithoutPathExpansion(kSettingPath, NULL); 404 settings_dictionary->RemoveWithoutPathExpansion(kSettingPath, NULL);
405 settings_dictionary->RemoveWithoutPathExpansion(kLastModifiedPath,
406 NULL);
raymes 2017/04/24 03:20:22 nullptr
dullweber 2017/04/25 10:50:44 Done, I replaced all NULLs in this file with nullp
376 } else { 407 } else {
377 settings_dictionary->SetWithoutPathExpansion( 408 settings_dictionary->SetWithoutPathExpansion(
378 kSettingPath, value->DeepCopy()); 409 kSettingPath, value->DeepCopy());
410 settings_dictionary->SetStringWithoutPathExpansion(
411 kLastModifiedPath,
412 base::Int64ToString(last_modified.ToInternalValue()));
379 } 413 }
380 } 414 }
381 // Remove the settings dictionary if it is empty. 415 // Remove the settings dictionary if it is empty.
382 if (settings_dictionary->empty()) { 416 if (settings_dictionary->empty()) {
383 pattern_pairs_settings->RemoveWithoutPathExpansion( 417 pattern_pairs_settings->RemoveWithoutPathExpansion(
384 pattern_str, NULL); 418 pattern_str, NULL);
385 } 419 }
386 } 420 }
387 } 421 }
388 } 422 }
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
445 479
446 void ContentSettingsPref::AssertLockNotHeld() const { 480 void ContentSettingsPref::AssertLockNotHeld() const {
447 #if !defined(NDEBUG) 481 #if !defined(NDEBUG)
448 // |Lock::Acquire()| will assert if the lock is held by this thread. 482 // |Lock::Acquire()| will assert if the lock is held by this thread.
449 lock_.Acquire(); 483 lock_.Acquire();
450 lock_.Release(); 484 lock_.Release();
451 #endif 485 #endif
452 } 486 }
453 487
454 } // namespace content_settings 488 } // namespace content_settings
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698