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..05c777a012ef6930a628d049d9209b6d9e0bd769 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, |
@@ -51,6 +53,18 @@ bool IsValueAllowedForType(const base::Value* value, ContentSettingsType type) { |
return value->GetType() == base::Value::Type::DICTIONARY; |
} |
+// Extract a timestamp from |dictionary[path]|. Will return base::Time() if no |
+// timestamp exists. |
+base::Time GetTimeStamp(const base::DictionaryValue* dictionary, |
+ 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.
|
+ std::string timestamp_str; |
+ dictionary->GetStringWithoutPathExpansion(path, ×tamp_str); |
+ int64_t timestamp = 0; |
+ base::StringToInt64(timestamp_str, ×tamp); |
+ base::Time last_modified = base::Time::FromInternalValue(timestamp); |
+ return last_modified; |
+} |
+ |
} // namespace |
namespace content_settings { |
@@ -61,12 +75,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 +127,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 +146,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( |
@@ -142,6 +156,22 @@ bool ContentSettingsPref::SetWebsiteSetting( |
return true; |
} |
+void ContentSettingsPref::DeleteWebsiteSetting( |
+ const ContentSettingsPattern& primary_pattern, |
+ const ContentSettingsPattern& secondary_pattern, |
+ base::Time begin_time) { |
+ OriginIdentifierValueMap* map_to_modify = &incognito_value_map_; |
+ if (!is_incognito_) |
+ map_to_modify = &value_map_; |
+ |
+ base::Time last_modified = map_to_modify->GetLastModified( |
+ primary_pattern, secondary_pattern, content_type_, ResourceIdentifier()); |
+ if (begin_time <= last_modified) { |
+ SetWebsiteSetting(primary_pattern, secondary_pattern, ResourceIdentifier(), |
+ nullptr); |
+ } |
+} |
+ |
void ContentSettingsPref::ClearPref() { |
DCHECK(thread_checker_.CalledOnValidThread()); |
DCHECK(prefs_); |
@@ -253,10 +283,9 @@ 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, |
+ // Per resource settings don't support last_modified timestamps. |
+ value_map_.SetValue(pattern_pair.first, pattern_pair.second, |
+ content_type_, resource_identifier, base::Time(), |
setting_ptr->DeepCopy()); |
} |
} |
@@ -264,13 +293,12 @@ void ContentSettingsPref::ReadContentSettingsFromPref() { |
const base::Value* value = nullptr; |
settings_dictionary->GetWithoutPathExpansion(kSettingPath, &value); |
- |
if (value) { |
+ base::Time last_modified = |
+ GetTimeStamp(settings_dictionary, kLastModifiedPath); |
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 +349,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|). |
@@ -353,7 +382,7 @@ void ContentSettingsPref::UpdatePref( |
if (!found) { |
if (value == NULL) |
return; // Nothing to remove. Exit early. |
- resource_dictionary = new base::DictionaryValue; |
+ resource_dictionary = new base::DictionaryValue(); |
raymes
2017/04/24 03:20:22
nit: () isn't needed
dullweber
2017/04/25 10:50:44
Done.
|
settings_dictionary->Set( |
kPerResourceIdentifierPrefName, resource_dictionary); |
} |
@@ -373,9 +402,14 @@ void ContentSettingsPref::UpdatePref( |
// Update settings dictionary. |
if (value == NULL) { |
settings_dictionary->RemoveWithoutPathExpansion(kSettingPath, NULL); |
+ settings_dictionary->RemoveWithoutPathExpansion(kLastModifiedPath, |
+ 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
|
} else { |
settings_dictionary->SetWithoutPathExpansion( |
kSettingPath, value->DeepCopy()); |
+ settings_dictionary->SetStringWithoutPathExpansion( |
+ kLastModifiedPath, |
+ base::Int64ToString(last_modified.ToInternalValue())); |
} |
} |
// Remove the settings dictionary if it is empty. |