Chromium Code Reviews| Index: components/content_settings/core/browser/content_settings_pref.cc |
| diff --git a/components/content_settings/core/browser/content_settings_pref.cc b/components/content_settings/core/browser/content_settings_pref.cc |
| index f32e3018b4cc0828d4b5b7efa7a596d5f022d82b..051bf86cb102893f0c932a259d59e7a85e83a857 100644 |
| --- a/components/content_settings/core/browser/content_settings_pref.cc |
| +++ b/components/content_settings/core/browser/content_settings_pref.cc |
| @@ -9,6 +9,7 @@ |
| #include "base/auto_reset.h" |
| #include "base/bind.h" |
| #include "base/metrics/histogram_macros.h" |
| +#include "base/strings/string_number_conversions.h" |
| #include "base/strings/string_split.h" |
| #include "components/content_settings/core/browser/content_settings_info.h" |
| #include "components/content_settings/core/browser/content_settings_registry.h" |
| @@ -24,6 +25,7 @@ |
| namespace { |
| const char kSettingPath[] = "setting"; |
| +const char kLastModifiedPath[] = "last_modified"; |
| const char kPerResourceIdentifierPrefName[] = "per_resource"; |
| // If the given content type supports resource identifiers in user preferences, |
| @@ -61,12 +63,14 @@ ContentSettingsPref::ContentSettingsPref( |
| PrefChangeRegistrar* registrar, |
| const std::string& pref_name, |
| bool incognito, |
| + bool store_last_modified, |
| NotifyObserversCallback notify_callback) |
| : content_type_(content_type), |
| prefs_(prefs), |
| registrar_(registrar), |
| pref_name_(pref_name), |
| is_incognito_(incognito), |
| + store_last_modified_(store_last_modified), |
| updating_preferences_(false), |
| notify_callback_(notify_callback) { |
| DCHECK(prefs_); |
| @@ -111,15 +115,15 @@ bool ContentSettingsPref::SetWebsiteSetting( |
| if (!is_incognito_) |
| map_to_modify = &value_map_; |
| + base::Time modified_time = |
| + store_last_modified_ ? base::Time::Now() : base::Time(); |
| + |
| { |
| base::AutoLock auto_lock(lock_); |
| if (value.get()) { |
| - map_to_modify->SetValue( |
| - primary_pattern, |
| - secondary_pattern, |
| - content_type_, |
| - resource_identifier, |
| - value->DeepCopy()); |
| + map_to_modify->SetValue(primary_pattern, secondary_pattern, content_type_, |
| + resource_identifier, modified_time, |
| + value->DeepCopy()); |
| } else { |
| map_to_modify->DeleteValue( |
| primary_pattern, |
| @@ -130,10 +134,8 @@ bool ContentSettingsPref::SetWebsiteSetting( |
| } |
| // Update the content settings preference. |
| if (!is_incognito_) { |
| - UpdatePref(primary_pattern, |
| - secondary_pattern, |
| - resource_identifier, |
| - value.get()); |
| + UpdatePref(primary_pattern, secondary_pattern, resource_identifier, |
| + modified_time, value.get()); |
| } |
| notify_callback_.Run( |
| @@ -240,6 +242,14 @@ void ContentSettingsPref::ReadContentSettingsFromPref() { |
| bool is_dictionary = i.value().GetAsDictionary(&settings_dictionary); |
| DCHECK(is_dictionary); |
| + // Get last modified timestamp. |
|
msramek
2017/04/19 10:49:16
We're using one last modified timestamp per patter
dullweber
2017/04/19 15:02:45
I just changed it to store a timestamp per resourc
raymes
2017/04/20 00:10:13
I think we'd like to remove the per-resource ident
|
| + std::string time_stamp_str; |
| + settings_dictionary->GetStringWithoutPathExpansion(kLastModifiedPath, |
| + &time_stamp_str); |
| + int64_t time_stamp = 0; |
| + base::StringToInt64(time_stamp_str, &time_stamp); |
| + base::Time last_modified = base::Time::FromInternalValue(time_stamp); |
| + |
| if (SupportsResourceIdentifiers(content_type_)) { |
| const base::DictionaryValue* resource_dictionary = NULL; |
| if (settings_dictionary->GetDictionary( |
| @@ -253,10 +263,8 @@ void ContentSettingsPref::ReadContentSettingsFromPref() { |
| DCHECK(is_integer); |
| DCHECK_NE(CONTENT_SETTING_DEFAULT, setting); |
| std::unique_ptr<base::Value> setting_ptr(new base::Value(setting)); |
| - value_map_.SetValue(pattern_pair.first, |
| - pattern_pair.second, |
| - content_type_, |
| - resource_identifier, |
| + value_map_.SetValue(pattern_pair.first, pattern_pair.second, |
| + content_type_, resource_identifier, last_modified, |
| setting_ptr->DeepCopy()); |
| } |
| } |
| @@ -264,13 +272,10 @@ void ContentSettingsPref::ReadContentSettingsFromPref() { |
| const base::Value* value = nullptr; |
| settings_dictionary->GetWithoutPathExpansion(kSettingPath, &value); |
| - |
| if (value) { |
| DCHECK(IsValueAllowedForType(value, content_type_)); |
| - value_map_.SetValue(pattern_pair.first, |
| - pattern_pair.second, |
| - content_type_, |
| - ResourceIdentifier(), |
| + value_map_.SetValue(pattern_pair.first, pattern_pair.second, |
| + content_type_, ResourceIdentifier(), last_modified, |
| value->DeepCopy()); |
| if (content_type_ == CONTENT_SETTINGS_TYPE_COOKIES) { |
| ContentSetting s = ValueToContentSetting(value); |
| @@ -321,6 +326,7 @@ void ContentSettingsPref::UpdatePref( |
| const ContentSettingsPattern& primary_pattern, |
| const ContentSettingsPattern& secondary_pattern, |
| const ResourceIdentifier& resource_identifier, |
| + const base::Time last_modified, |
| const base::Value* value) { |
| // Ensure that |lock_| is not held by this thread, since this function will |
| // send out notifications (by |~DictionaryPrefUpdate|). |
| @@ -364,18 +370,29 @@ void ContentSettingsPref::UpdatePref( |
| if (resource_dictionary->empty()) { |
| settings_dictionary->RemoveWithoutPathExpansion( |
| kPerResourceIdentifierPrefName, NULL); |
| + settings_dictionary->RemoveWithoutPathExpansion(kLastModifiedPath, |
| + NULL); |
| } |
| } else { |
| resource_dictionary->SetWithoutPathExpansion( |
| resource_identifier, value->DeepCopy()); |
| + // Update timestamp for whole resource dictionary. |
| + settings_dictionary->SetStringWithoutPathExpansion( |
| + kLastModifiedPath, |
| + base::Int64ToString(last_modified.ToInternalValue())); |
| } |
| } else { |
| // Update settings dictionary. |
| if (value == NULL) { |
| settings_dictionary->RemoveWithoutPathExpansion(kSettingPath, NULL); |
| + settings_dictionary->RemoveWithoutPathExpansion(kLastModifiedPath, |
| + NULL); |
| } else { |
| settings_dictionary->SetWithoutPathExpansion( |
| kSettingPath, value->DeepCopy()); |
| + settings_dictionary->SetStringWithoutPathExpansion( |
| + kLastModifiedPath, |
| + base::Int64ToString(last_modified.ToInternalValue())); |
| } |
| } |
| // Remove the settings dictionary if it is empty. |