summaryrefslogtreecommitdiff
path: root/chromium/components/content_settings
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/components/content_settings')
-rw-r--r--chromium/components/content_settings/core/browser/BUILD.gn1
-rw-r--r--chromium/components/content_settings/core/browser/DEPS1
-rw-r--r--chromium/components/content_settings/core/browser/content_settings_default_provider.cc12
-rw-r--r--chromium/components/content_settings/core/browser/content_settings_info.cc23
-rw-r--r--chromium/components/content_settings/core/browser/content_settings_info.h1
-rw-r--r--chromium/components/content_settings/core/browser/content_settings_origin_identifier_value_map.cc34
-rw-r--r--chromium/components/content_settings/core/browser/content_settings_origin_identifier_value_map.h29
-rw-r--r--chromium/components/content_settings/core/browser/content_settings_policy_provider.cc24
-rw-r--r--chromium/components/content_settings/core/browser/content_settings_pref.cc177
-rw-r--r--chromium/components/content_settings/core/browser/content_settings_pref.h24
-rw-r--r--chromium/components/content_settings/core/browser/content_settings_pref_provider.cc45
-rw-r--r--chromium/components/content_settings/core/browser/content_settings_pref_provider.h19
-rw-r--r--chromium/components/content_settings/core/browser/content_settings_registry.cc7
-rw-r--r--chromium/components/content_settings/core/browser/content_settings_registry_unittest.cc19
-rw-r--r--chromium/components/content_settings/core/browser/cookie_settings_unittest.cc3
-rw-r--r--chromium/components/content_settings/core/browser/host_content_settings_map.cc84
-rw-r--r--chromium/components/content_settings/core/browser/host_content_settings_map.h37
-rw-r--r--chromium/components/content_settings/core/browser/website_settings_registry.cc8
-rw-r--r--chromium/components/content_settings/core/common/content_settings.cc85
-rw-r--r--chromium/components/content_settings/core/common/content_settings_types.h4
20 files changed, 431 insertions, 206 deletions
diff --git a/chromium/components/content_settings/core/browser/BUILD.gn b/chromium/components/content_settings/core/browser/BUILD.gn
index 3e4fa6688f5..44e44e36352 100644
--- a/chromium/components/content_settings/core/browser/BUILD.gn
+++ b/chromium/components/content_settings/core/browser/BUILD.gn
@@ -54,6 +54,7 @@ static_library("browser") {
"//components/url_formatter",
"//extensions/features",
"//net",
+ "//services/preferences/public/cpp",
"//url",
]
diff --git a/chromium/components/content_settings/core/browser/DEPS b/chromium/components/content_settings/core/browser/DEPS
index eddae7bcb63..01dbe2ae6df 100644
--- a/chromium/components/content_settings/core/browser/DEPS
+++ b/chromium/components/content_settings/core/browser/DEPS
@@ -8,4 +8,5 @@ include_rules = [
"+extensions/features",
"+net/base",
"+net/cookies",
+ "+services/preferences/public",
]
diff --git a/chromium/components/content_settings/core/browser/content_settings_default_provider.cc b/chromium/components/content_settings/core/browser/content_settings_default_provider.cc
index 261fedb9d6b..ffa75aa7da7 100644
--- a/chromium/components/content_settings/core/browser/content_settings_default_provider.cc
+++ b/chromium/components/content_settings/core/browser/content_settings_default_provider.cc
@@ -11,6 +11,8 @@
#include "base/bind.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
+#include "components/content_settings/core/browser/content_settings_info.h"
+#include "components/content_settings/core/browser/content_settings_registry.h"
#include "components/content_settings/core/browser/content_settings_rule.h"
#include "components/content_settings/core/browser/content_settings_utils.h"
#include "components/content_settings/core/browser/website_settings_info.h"
@@ -186,6 +188,10 @@ DefaultProvider::DefaultProvider(PrefService* prefs, bool incognito)
IntToContentSetting(prefs_->GetInteger(
GetPrefName(CONTENT_SETTINGS_TYPE_AUTOPLAY))),
CONTENT_SETTING_NUM_SETTINGS);
+ UMA_HISTOGRAM_ENUMERATION("ContentSettings.DefaultSubresourceFilterSetting",
+ IntToContentSetting(prefs_->GetInteger(GetPrefName(
+ CONTENT_SETTINGS_TYPE_SUBRESOURCE_FILTER))),
+ CONTENT_SETTING_NUM_SETTINGS);
#endif
pref_change_registrar_.Init(prefs_);
PrefChangeRegistrar::NamedChangeCallback callback = base::Bind(
@@ -296,6 +302,10 @@ bool DefaultProvider::IsValueEmptyOrDefault(ContentSettingsType content_type,
void DefaultProvider::ChangeSetting(ContentSettingsType content_type,
base::Value* value) {
+ const ContentSettingsInfo* info =
+ ContentSettingsRegistry::GetInstance()->Get(content_type);
+ DCHECK(!info || !value ||
+ info->IsDefaultSettingValid(ValueToContentSetting(value)));
default_settings_[content_type] =
value ? base::WrapUnique(value->DeepCopy())
: ContentSettingToValue(GetDefaultValue(content_type));
@@ -363,6 +373,8 @@ std::unique_ptr<base::Value> DefaultProvider::ReadFromPref(
}
void DefaultProvider::DiscardObsoletePreferences() {
+ if (is_incognito_)
+ return;
// These prefs were never stored on iOS/Android so they don't need to be
// deleted.
#if !defined(OS_IOS)
diff --git a/chromium/components/content_settings/core/browser/content_settings_info.cc b/chromium/components/content_settings/core/browser/content_settings_info.cc
index c111944e286..41fd1375bb0 100644
--- a/chromium/components/content_settings/core/browser/content_settings_info.cc
+++ b/chromium/components/content_settings/core/browser/content_settings_info.cc
@@ -5,6 +5,7 @@
#include "components/content_settings/core/browser/content_settings_info.h"
#include "base/stl_util.h"
+#include "components/content_settings/core/browser/website_settings_info.h"
namespace content_settings {
@@ -24,4 +25,26 @@ bool ContentSettingsInfo::IsSettingValid(ContentSetting setting) const {
return base::ContainsKey(valid_settings_, setting);
}
+// TODO(raymes): Find a better way to deal with the special-casing in
+// IsDefaultSettingValid.
+bool ContentSettingsInfo::IsDefaultSettingValid(ContentSetting setting) const {
+ ContentSettingsType type = website_settings_info_->type();
+#if defined(OS_ANDROID) || defined(OS_CHROMEOS)
+ // Don't support ALLOW for protected media default setting until migration.
+ if (type == CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER &&
+ setting == CONTENT_SETTING_ALLOW) {
+ return false;
+ }
+#endif
+
+ // Don't support ALLOW for the default media settings.
+ if ((type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA ||
+ type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC) &&
+ setting == CONTENT_SETTING_ALLOW) {
+ return false;
+ }
+
+ return base::ContainsKey(valid_settings_, setting);
+}
+
} // namespace content_settings
diff --git a/chromium/components/content_settings/core/browser/content_settings_info.h b/chromium/components/content_settings/core/browser/content_settings_info.h
index d1eb3a58248..07a176741aa 100644
--- a/chromium/components/content_settings/core/browser/content_settings_info.h
+++ b/chromium/components/content_settings/core/browser/content_settings_info.h
@@ -46,6 +46,7 @@ class ContentSettingsInfo {
}
bool IsSettingValid(ContentSetting setting) const;
+ bool IsDefaultSettingValid(ContentSetting setting) const;
IncognitoBehavior incognito_behavior() const { return incognito_behavior_; }
diff --git a/chromium/components/content_settings/core/browser/content_settings_origin_identifier_value_map.cc b/chromium/components/content_settings/core/browser/content_settings_origin_identifier_value_map.cc
index 3f6133b67a8..8bb2f98613c 100644
--- a/chromium/components/content_settings/core/browser/content_settings_origin_identifier_value_map.cc
+++ b/chromium/components/content_settings/core/browser/content_settings_origin_identifier_value_map.cc
@@ -38,10 +38,10 @@ class RuleIteratorImpl : public RuleIterator {
Rule Next() override {
DCHECK(HasNext());
- DCHECK(current_rule_->second.get());
+ DCHECK(current_rule_->second.value.get());
Rule to_return(current_rule_->first.primary_pattern,
current_rule_->first.secondary_pattern,
- current_rule_->second.get()->DeepCopy());
+ current_rule_->second.value.get()->DeepCopy());
++current_rule_;
return to_return;
}
@@ -83,6 +83,10 @@ bool OriginIdentifierValueMap::PatternPair::operator<(
std::tie(other.primary_pattern, other.secondary_pattern);
}
+OriginIdentifierValueMap::ValueEntry::ValueEntry() : last_modified(), value(){};
+
+OriginIdentifierValueMap::ValueEntry::~ValueEntry(){};
+
std::unique_ptr<RuleIterator> OriginIdentifierValueMap::GetRuleIterator(
ContentSettingsType content_type,
const ResourceIdentifier& resource_identifier,
@@ -129,17 +133,37 @@ base::Value* OriginIdentifierValueMap::GetValue(
for (const auto& entry : it->second) {
if (entry.first.primary_pattern.Matches(primary_url) &&
entry.first.secondary_pattern.Matches(secondary_url)) {
- return entry.second.get();
+ return entry.second.value.get();
}
}
return nullptr;
}
+base::Time OriginIdentifierValueMap::GetLastModified(
+ const ContentSettingsPattern& primary_pattern,
+ const ContentSettingsPattern& secondary_pattern,
+ ContentSettingsType content_type,
+ const ResourceIdentifier& resource_identifier) const {
+ DCHECK(primary_pattern.IsValid());
+ DCHECK(secondary_pattern.IsValid());
+
+ EntryMapKey key(content_type, resource_identifier);
+ PatternPair patterns(primary_pattern, secondary_pattern);
+ EntryMap::const_iterator it = entries_.find(key);
+ if (it == entries_.end())
+ return base::Time();
+ Rules::const_iterator r = it->second.find(patterns);
+ if (r == it->second.end())
+ return base::Time();
+ return r->second.last_modified;
+}
+
void OriginIdentifierValueMap::SetValue(
const ContentSettingsPattern& primary_pattern,
const ContentSettingsPattern& secondary_pattern,
ContentSettingsType content_type,
const ResourceIdentifier& resource_identifier,
+ base::Time last_modified,
base::Value* value) {
DCHECK(primary_pattern.IsValid());
DCHECK(secondary_pattern.IsValid());
@@ -150,7 +174,9 @@ void OriginIdentifierValueMap::SetValue(
EntryMapKey key(content_type, resource_identifier);
PatternPair patterns(primary_pattern, secondary_pattern);
// This will create the entry and the linked_ptr if needed.
- entries_[key][patterns].reset(value);
+ ValueEntry* entry = &entries_[key][patterns];
+ entry->value.reset(value);
+ entry->last_modified = last_modified;
}
void OriginIdentifierValueMap::DeleteValue(
diff --git a/chromium/components/content_settings/core/browser/content_settings_origin_identifier_value_map.h b/chromium/components/content_settings/core/browser/content_settings_origin_identifier_value_map.h
index 1ac2fe56bed..f27816b6574 100644
--- a/chromium/components/content_settings/core/browser/content_settings_origin_identifier_value_map.h
+++ b/chromium/components/content_settings/core/browser/content_settings_origin_identifier_value_map.h
@@ -13,6 +13,7 @@
#include "base/macros.h"
#include "base/memory/linked_ptr.h"
+#include "base/time/time.h"
#include "components/content_settings/core/common/content_settings.h"
class GURL;
@@ -44,7 +45,14 @@ class OriginIdentifierValueMap {
bool operator<(const OriginIdentifierValueMap::PatternPair& other) const;
};
- typedef std::map<PatternPair, linked_ptr<base::Value> > Rules;
+ struct ValueEntry {
+ base::Time last_modified;
+ linked_ptr<base::Value> value;
+ ValueEntry();
+ ~ValueEntry();
+ };
+
+ typedef std::map<PatternPair, ValueEntry> Rules;
typedef std::map<EntryMapKey, Rules> EntryMap;
EntryMap::iterator begin() {
@@ -92,15 +100,22 @@ class OriginIdentifierValueMap {
ContentSettingsType content_type,
const ResourceIdentifier& resource_identifier) const;
- // Sets the |value| for the given |primary_pattern|, |secondary_pattern|,
- // |content_type|, |resource_identifier| tuple. The method takes the ownership
- // of the passed |value|.
- void SetValue(
+ base::Time GetLastModified(
const ContentSettingsPattern& primary_pattern,
const ContentSettingsPattern& secondary_pattern,
ContentSettingsType content_type,
- const ResourceIdentifier& resource_identifier,
- base::Value* value);
+ const ResourceIdentifier& resource_identifier) const;
+
+ // Sets the |value| for the given |primary_pattern|, |secondary_pattern|,
+ // |content_type|, |resource_identifier| tuple. The method takes the ownership
+ // of the passed |value|. The caller can also store a |last_modified| date
+ // for each value.
+ void SetValue(const ContentSettingsPattern& primary_pattern,
+ const ContentSettingsPattern& secondary_pattern,
+ ContentSettingsType content_type,
+ const ResourceIdentifier& resource_identifier,
+ base::Time last_modified,
+ base::Value* value);
// Deletes the map entry for the given |primary_pattern|,
// |secondary_pattern|, |content_type|, |resource_identifier| tuple.
diff --git a/chromium/components/content_settings/core/browser/content_settings_policy_provider.cc b/chromium/components/content_settings/core/browser/content_settings_policy_provider.cc
index c2967aa41a6..d9b8cfa9806 100644
--- a/chromium/components/content_settings/core/browser/content_settings_policy_provider.cc
+++ b/chromium/components/content_settings/core/browser/content_settings_policy_provider.cc
@@ -13,6 +13,8 @@
#include "base/json/json_reader.h"
#include "base/macros.h"
#include "base/values.h"
+#include "components/content_settings/core/browser/content_settings_info.h"
+#include "components/content_settings/core/browser/content_settings_registry.h"
#include "components/content_settings/core/browser/content_settings_rule.h"
#include "components/content_settings/core/browser/content_settings_utils.h"
#include "components/content_settings/core/common/content_settings_pattern.h"
@@ -235,9 +237,10 @@ void PolicyProvider::GetContentSettingsFromPreferences(
VLOG_IF(2, !pattern_pair.second.IsValid())
<< "Replacing invalid secondary pattern '"
<< pattern_pair.second.ToString() << "' with wildcard";
+ // Don't set a timestamp for policy settings.
value_map->SetValue(
pattern_pair.first, secondary_pattern, content_type,
- ResourceIdentifier(),
+ ResourceIdentifier(), base::Time(),
new base::Value(kPrefsForManagedContentSettingsMap[i].setting));
}
}
@@ -319,11 +322,10 @@ void PolicyProvider::GetAutoSelectCertificateSettingsFromPreferences(
// Don't pass removed values from |value|, because base::Values read with
// JSONReader use a shared string buffer. Instead, DeepCopy here.
- value_map->SetValue(pattern,
- ContentSettingsPattern::Wildcard(),
+ // Don't set a timestamp for policy settings.
+ value_map->SetValue(pattern, ContentSettingsPattern::Wildcard(),
CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE,
- std::string(),
- cert_filter->DeepCopy());
+ std::string(), base::Time(), cert_filter->DeepCopy());
}
}
@@ -334,6 +336,13 @@ void PolicyProvider::ReadManagedDefaultSettings() {
void PolicyProvider::UpdateManagedDefaultSetting(
const PrefsForManagedDefaultMapEntry& entry) {
+ // Not all managed default types are registered on every platform. If they're
+ // not registered, don't update them.
+ const ContentSettingsInfo* info =
+ ContentSettingsRegistry::GetInstance()->Get(entry.content_type);
+ if (!info)
+ return;
+
// If a pref to manage a default-content-setting was not set (NOTICE:
// "HasPrefPath" returns false if no value was set for a registered pref) then
// the default value of the preference is used. The default value of a
@@ -355,10 +364,11 @@ void PolicyProvider::UpdateManagedDefaultSetting(
value_map_.DeleteValue(ContentSettingsPattern::Wildcard(),
ContentSettingsPattern::Wildcard(),
entry.content_type, std::string());
- } else {
+ } else if (info->IsSettingValid(IntToContentSetting(setting))) {
+ // Don't set a timestamp for policy settings.
value_map_.SetValue(ContentSettingsPattern::Wildcard(),
ContentSettingsPattern::Wildcard(), entry.content_type,
- std::string(), new base::Value(setting));
+ std::string(), base::Time(), new base::Value(setting));
}
}
diff --git a/chromium/components/content_settings/core/browser/content_settings_pref.cc b/chromium/components/content_settings/core/browser/content_settings_pref.cc
index f32e3018b4c..99e132b8151 100644
--- a/chromium/components/content_settings/core/browser/content_settings_pref.cc
+++ b/chromium/components/content_settings/core/browser/content_settings_pref.cc
@@ -8,7 +8,9 @@
#include "base/auto_reset.h"
#include "base/bind.h"
+#include "base/memory/ptr_util.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"
@@ -19,11 +21,14 @@
#include "components/content_settings/core/common/content_settings_pattern.h"
#include "components/content_settings/core/common/pref_names.h"
#include "components/prefs/scoped_user_pref_update.h"
+#include "services/preferences/public/cpp/dictionary_value_update.h"
+#include "services/preferences/public/cpp/scoped_pref_update.h"
#include "url/gurl.h"
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 +56,17 @@ bool IsValueAllowedForType(const base::Value* value, ContentSettingsType type) {
return value->GetType() == base::Value::Type::DICTIONARY;
}
+// Extract a timestamp from |dictionary[kLastModifiedPath]|.
+// Will return base::Time() if no timestamp exists.
+base::Time GetTimeStamp(const base::DictionaryValue* dictionary) {
+ std::string timestamp_str;
+ dictionary->GetStringWithoutPathExpansion(kLastModifiedPath, &timestamp_str);
+ int64_t timestamp = 0;
+ base::StringToInt64(timestamp_str, &timestamp);
+ base::Time last_modified = base::Time::FromInternalValue(timestamp);
+ return last_modified;
+}
+
} // namespace
namespace content_settings {
@@ -95,6 +111,7 @@ bool ContentSettingsPref::SetWebsiteSetting(
const ContentSettingsPattern& primary_pattern,
const ContentSettingsPattern& secondary_pattern,
const ResourceIdentifier& resource_identifier,
+ base::Time modified_time,
base::Value* in_value) {
DCHECK(!in_value || IsValueAllowedForType(in_value, content_type_));
DCHECK(thread_checker_.CalledOnValidThread());
@@ -114,12 +131,9 @@ bool ContentSettingsPref::SetWebsiteSetting(
{
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 +144,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 +154,19 @@ bool ContentSettingsPref::SetWebsiteSetting(
return true;
}
+base::Time ContentSettingsPref::GetWebsiteSettingLastModified(
+ const ContentSettingsPattern& primary_pattern,
+ const ContentSettingsPattern& secondary_pattern,
+ const ResourceIdentifier& resource_identifier) {
+ 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_, resource_identifier);
+ return last_modified;
+}
+
void ContentSettingsPref::ClearPref() {
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(prefs_);
@@ -153,9 +178,8 @@ void ContentSettingsPref::ClearPref() {
{
base::AutoReset<bool> auto_reset(&updating_preferences_, true);
- DictionaryPrefUpdate update(prefs_, pref_name_);
- base::DictionaryValue* pattern_pairs_settings = update.Get();
- pattern_pairs_settings->Clear();
+ prefs::ScopedDictionaryPrefUpdate update(prefs_, pref_name_);
+ update->Clear();
}
}
@@ -188,13 +212,13 @@ bool ContentSettingsPref::TryLockForTesting() const {
}
void ContentSettingsPref::ReadContentSettingsFromPref() {
- // |DictionaryPrefUpdate| sends out notifications when destructed. This
+ // |ScopedDictionaryPrefUpdate| sends out notifications when destructed. This
// construction order ensures |AutoLock| gets destroyed first and |lock_| is
// not held when the notifications are sent. Also, |auto_reset| must be still
// valid when the notifications are sent, so that |Observe| skips the
// notification.
base::AutoReset<bool> auto_reset(&updating_preferences_, true);
- DictionaryPrefUpdate update(prefs_, pref_name_);
+ prefs::ScopedDictionaryPrefUpdate update(prefs_, pref_name_);
base::AutoLock auto_lock(lock_);
const base::DictionaryValue* all_settings_dictionary =
@@ -202,27 +226,31 @@ void ContentSettingsPref::ReadContentSettingsFromPref() {
value_map_.clear();
- // Careful: The returned value could be NULL if the pref has never been set.
+ // Careful: The returned value could be nullptr if the pref has never been
+ // set.
if (!all_settings_dictionary)
return;
- base::DictionaryValue* mutable_settings;
- std::unique_ptr<base::DictionaryValue> mutable_settings_scope;
+ const base::DictionaryValue* settings;
if (!is_incognito_) {
- mutable_settings = update.Get();
+ // Convert all Unicode patterns into punycode form, then read.
+ auto mutable_settings = update.Get();
+ CanonicalizeContentSettingsExceptions(mutable_settings.get());
+ settings = mutable_settings->AsConstDictionary();
} else {
- // Create copy as we do not want to persist anything in incognito prefs.
- mutable_settings = all_settings_dictionary->DeepCopy();
- mutable_settings_scope.reset(mutable_settings);
+ // Canonicalization is unnecessary when |is_incognito_|. Both incognito and
+ // non-incognito read from the same pref and non-incognito reads occur
+ // before incognito reads. Thus, by the time the incognito call to
+ // ReadContentSettingsFromPref() occurs, the non-incognito call will have
+ // canonicalized the stored pref data.
+ settings = all_settings_dictionary;
}
- // Convert all Unicode patterns into punycode form, then read.
- CanonicalizeContentSettingsExceptions(mutable_settings);
size_t cookies_block_exception_count = 0;
size_t cookies_allow_exception_count = 0;
size_t cookies_session_only_exception_count = 0;
- for (base::DictionaryValue::Iterator i(*mutable_settings); !i.IsAtEnd();
+ for (base::DictionaryValue::Iterator i(*settings); !i.IsAtEnd();
i.Advance()) {
const std::string& pattern_str(i.key());
std::pair<ContentSettingsPattern, ContentSettingsPattern> pattern_pair =
@@ -236,14 +264,15 @@ void ContentSettingsPref::ReadContentSettingsFromPref() {
// Get settings dictionary for the current pattern string, and read
// settings from the dictionary.
- const base::DictionaryValue* settings_dictionary = NULL;
+ const base::DictionaryValue* settings_dictionary = nullptr;
bool is_dictionary = i.value().GetAsDictionary(&settings_dictionary);
DCHECK(is_dictionary);
if (SupportsResourceIdentifiers(content_type_)) {
- const base::DictionaryValue* resource_dictionary = NULL;
+ const base::DictionaryValue* resource_dictionary = nullptr;
if (settings_dictionary->GetDictionary(
kPerResourceIdentifierPrefName, &resource_dictionary)) {
+ base::Time last_modified = GetTimeStamp(settings_dictionary);
for (base::DictionaryValue::Iterator j(*resource_dictionary);
!j.IsAtEnd();
j.Advance()) {
@@ -253,10 +282,10 @@ 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,
+ DCHECK(IsValueAllowedForType(setting_ptr.get(), content_type_));
+ // Per resource settings store a single timestamps for all resources.
+ value_map_.SetValue(pattern_pair.first, pattern_pair.second,
+ content_type_, resource_identifier, last_modified,
setting_ptr->DeepCopy());
}
}
@@ -264,13 +293,11 @@ void ContentSettingsPref::ReadContentSettingsFromPref() {
const base::Value* value = nullptr;
settings_dictionary->GetWithoutPathExpansion(kSettingPath, &value);
-
if (value) {
+ base::Time last_modified = GetTimeStamp(settings_dictionary);
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,67 +348,82 @@ 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|).
+ // send out notifications (by |~ScopedDictionaryPrefUpdate|).
AssertLockNotHeld();
base::AutoReset<bool> auto_reset(&updating_preferences_, true);
{
- DictionaryPrefUpdate update(prefs_, pref_name_);
- base::DictionaryValue* pattern_pairs_settings = update.Get();
+ prefs::ScopedDictionaryPrefUpdate update(prefs_, pref_name_);
+ std::unique_ptr<prefs::DictionaryValueUpdate> pattern_pairs_settings =
+ update.Get();
// Get settings dictionary for the given patterns.
std::string pattern_str(CreatePatternString(primary_pattern,
secondary_pattern));
- base::DictionaryValue* settings_dictionary = NULL;
+ std::unique_ptr<prefs::DictionaryValueUpdate> settings_dictionary;
bool found = pattern_pairs_settings->GetDictionaryWithoutPathExpansion(
pattern_str, &settings_dictionary);
if (!found && value) {
- settings_dictionary = new base::DictionaryValue;
- pattern_pairs_settings->SetWithoutPathExpansion(
- pattern_str, settings_dictionary);
+ settings_dictionary =
+ pattern_pairs_settings->SetDictionaryWithoutPathExpansion(
+ pattern_str, base::MakeUnique<base::DictionaryValue>());
}
if (settings_dictionary) {
if (SupportsResourceIdentifiers(content_type_) &&
!resource_identifier.empty()) {
- base::DictionaryValue* resource_dictionary = NULL;
+ std::unique_ptr<prefs::DictionaryValueUpdate> resource_dictionary;
found = settings_dictionary->GetDictionary(
kPerResourceIdentifierPrefName, &resource_dictionary);
if (!found) {
- if (value == NULL)
+ if (value == nullptr)
return; // Nothing to remove. Exit early.
- resource_dictionary = new base::DictionaryValue;
- settings_dictionary->Set(
- kPerResourceIdentifierPrefName, resource_dictionary);
+ resource_dictionary =
+ settings_dictionary->SetDictionaryWithoutPathExpansion(
+ kPerResourceIdentifierPrefName,
+ base::MakeUnique<base::DictionaryValue>());
}
// Update resource dictionary.
- if (value == NULL) {
+ if (value == nullptr) {
resource_dictionary->RemoveWithoutPathExpansion(resource_identifier,
- NULL);
+ nullptr);
if (resource_dictionary->empty()) {
settings_dictionary->RemoveWithoutPathExpansion(
- kPerResourceIdentifierPrefName, NULL);
+ kPerResourceIdentifierPrefName, nullptr);
+ settings_dictionary->RemoveWithoutPathExpansion(kLastModifiedPath,
+ nullptr);
}
} else {
- resource_dictionary->SetWithoutPathExpansion(
- resource_identifier, value->DeepCopy());
+ resource_dictionary->SetWithoutPathExpansion(resource_identifier,
+ value->CreateDeepCopy());
+ // 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);
+ if (value == nullptr) {
+ settings_dictionary->RemoveWithoutPathExpansion(kSettingPath,
+ nullptr);
+ settings_dictionary->RemoveWithoutPathExpansion(kLastModifiedPath,
+ nullptr);
} else {
- settings_dictionary->SetWithoutPathExpansion(
- kSettingPath, value->DeepCopy());
+ settings_dictionary->SetWithoutPathExpansion(kSettingPath,
+ value->CreateDeepCopy());
+ settings_dictionary->SetStringWithoutPathExpansion(
+ kLastModifiedPath,
+ base::Int64ToString(last_modified.ToInternalValue()));
}
}
// Remove the settings dictionary if it is empty.
if (settings_dictionary->empty()) {
- pattern_pairs_settings->RemoveWithoutPathExpansion(
- pattern_str, NULL);
+ pattern_pairs_settings->RemoveWithoutPathExpansion(pattern_str,
+ nullptr);
}
}
}
@@ -389,14 +431,14 @@ void ContentSettingsPref::UpdatePref(
// static
void ContentSettingsPref::CanonicalizeContentSettingsExceptions(
- base::DictionaryValue* all_settings_dictionary) {
+ prefs::DictionaryValueUpdate* all_settings_dictionary) {
DCHECK(all_settings_dictionary);
std::vector<std::string> remove_items;
base::StringPairs move_items;
- for (base::DictionaryValue::Iterator i(*all_settings_dictionary);
- !i.IsAtEnd();
- i.Advance()) {
+ for (base::DictionaryValue::Iterator i(
+ *all_settings_dictionary->AsConstDictionary());
+ !i.IsAtEnd(); i.Advance()) {
const std::string& pattern_str(i.key());
std::pair<ContentSettingsPattern, ContentSettingsPattern> pattern_pair =
ParsePatternString(pattern_str);
@@ -415,7 +457,7 @@ void ContentSettingsPref::CanonicalizeContentSettingsExceptions(
}
// Clear old pattern if prefs already have canonicalized pattern.
- const base::DictionaryValue* new_pattern_settings_dictionary = NULL;
+ const base::DictionaryValue* new_pattern_settings_dictionary = nullptr;
if (all_settings_dictionary->GetDictionaryWithoutPathExpansion(
canonicalized_pattern_str, &new_pattern_settings_dictionary)) {
remove_items.push_back(pattern_str);
@@ -423,7 +465,7 @@ void ContentSettingsPref::CanonicalizeContentSettingsExceptions(
}
// Move old pattern to canonicalized pattern.
- const base::DictionaryValue* old_pattern_settings_dictionary = NULL;
+ const base::DictionaryValue* old_pattern_settings_dictionary = nullptr;
if (i.value().GetAsDictionary(&old_pattern_settings_dictionary)) {
move_items.push_back(
std::make_pair(pattern_str, canonicalized_pattern_str));
@@ -431,7 +473,8 @@ void ContentSettingsPref::CanonicalizeContentSettingsExceptions(
}
for (size_t i = 0; i < remove_items.size(); ++i) {
- all_settings_dictionary->RemoveWithoutPathExpansion(remove_items[i], NULL);
+ all_settings_dictionary->RemoveWithoutPathExpansion(remove_items[i],
+ nullptr);
}
for (size_t i = 0; i < move_items.size(); ++i) {
@@ -439,7 +482,7 @@ void ContentSettingsPref::CanonicalizeContentSettingsExceptions(
all_settings_dictionary->RemoveWithoutPathExpansion(
move_items[i].first, &pattern_settings_dictionary);
all_settings_dictionary->SetWithoutPathExpansion(
- move_items[i].second, pattern_settings_dictionary.release());
+ move_items[i].second, std::move(pattern_settings_dictionary));
}
}
diff --git a/chromium/components/content_settings/core/browser/content_settings_pref.h b/chromium/components/content_settings/core/browser/content_settings_pref.h
index 77c6d031fb1..3139fc4aecb 100644
--- a/chromium/components/content_settings/core/browser/content_settings_pref.h
+++ b/chromium/components/content_settings/core/browser/content_settings_pref.h
@@ -13,6 +13,7 @@
#include "base/macros.h"
#include "base/synchronization/lock.h"
#include "base/threading/thread_checker.h"
+#include "base/time/time.h"
#include "base/values.h"
#include "components/content_settings/core/browser/content_settings_origin_identifier_value_map.h"
#include "components/content_settings/core/browser/content_settings_provider.h"
@@ -22,8 +23,8 @@
class PrefService;
class PrefChangeRegistrar;
-namespace base {
-class DictionaryValue;
+namespace prefs {
+class DictionaryValueUpdate;
}
namespace content_settings {
@@ -54,8 +55,15 @@ class ContentSettingsPref {
bool SetWebsiteSetting(const ContentSettingsPattern& primary_pattern,
const ContentSettingsPattern& secondary_pattern,
const ResourceIdentifier& resource_identifier,
+ base::Time modified_time,
base::Value* value);
+ // Returns the |last_modified| date of a setting.
+ base::Time GetWebsiteSettingLastModified(
+ const ContentSettingsPattern& primary_pattern,
+ const ContentSettingsPattern& secondary_pattern,
+ const ResourceIdentifier& resource_identifier);
+
void ClearPref();
void ClearAllContentSettingsRules();
@@ -77,14 +85,14 @@ class ContentSettingsPref {
// value to the obsolete preference. When calling this function, |lock_|
// should not be held, since this function will send out notifications of
// preference changes.
- void UpdatePref(
- const ContentSettingsPattern& primary_pattern,
- const ContentSettingsPattern& secondary_pattern,
- const ResourceIdentifier& resource_identifier,
- const base::Value* value);
+ void UpdatePref(const ContentSettingsPattern& primary_pattern,
+ const ContentSettingsPattern& secondary_pattern,
+ const ResourceIdentifier& resource_identifier,
+ const base::Time last_modified,
+ const base::Value* value);
static void CanonicalizeContentSettingsExceptions(
- base::DictionaryValue* all_settings_dictionary);
+ prefs::DictionaryValueUpdate* all_settings_dictionary);
// In the debug mode, asserts that |lock_| is not held by this thread. It's
// ok if some other thread holds |lock_|, as long as it will eventually
diff --git a/chromium/components/content_settings/core/browser/content_settings_pref_provider.cc b/chromium/components/content_settings/core/browser/content_settings_pref_provider.cc
index 3bd173ebe0a..fc1d59bb35c 100644
--- a/chromium/components/content_settings/core/browser/content_settings_pref_provider.cc
+++ b/chromium/components/content_settings/core/browser/content_settings_pref_provider.cc
@@ -15,6 +15,7 @@
#include "base/bind.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
+#include "base/time/default_clock.h"
#include "components/content_settings/core/browser/content_settings_pref.h"
#include "components/content_settings/core/browser/content_settings_rule.h"
#include "components/content_settings/core/browser/content_settings_utils.h"
@@ -28,6 +29,8 @@
#include "components/prefs/pref_registry.h"
#include "components/prefs/pref_service.h"
#include "components/prefs/scoped_user_pref_update.h"
+#include "services/preferences/public/cpp/dictionary_value_update.h"
+#include "services/preferences/public/cpp/scoped_pref_update.h"
namespace content_settings {
@@ -80,9 +83,13 @@ void PrefProvider::RegisterProfilePrefs(
#endif // !defined(OS_IOS)
}
-PrefProvider::PrefProvider(PrefService* prefs, bool incognito)
+PrefProvider::PrefProvider(PrefService* prefs,
+ bool incognito,
+ bool store_last_modified)
: prefs_(prefs),
- is_incognito_(incognito) {
+ is_incognito_(incognito),
+ store_last_modified_(store_last_modified),
+ clock_(new base::DefaultClock) {
DCHECK(prefs_);
// Verify preferences version.
if (!prefs_->HasPrefPath(prefs::kContentSettingsVersion)) {
@@ -150,9 +157,25 @@ bool PrefProvider::SetWebsiteSetting(
return false;
}
+ base::Time modified_time =
+ store_last_modified_ ? clock_->Now() : base::Time();
+
return GetPref(content_type)
->SetWebsiteSetting(primary_pattern, secondary_pattern,
- resource_identifier, in_value);
+ resource_identifier, modified_time, in_value);
+}
+
+base::Time PrefProvider::GetWebsiteSettingLastModified(
+ const ContentSettingsPattern& primary_pattern,
+ const ContentSettingsPattern& secondary_pattern,
+ ContentSettingsType content_type,
+ const ResourceIdentifier& resource_identifier) {
+ DCHECK(CalledOnValidThread());
+ DCHECK(prefs_);
+
+ return GetPref(content_type)
+ ->GetWebsiteSettingLastModified(primary_pattern, secondary_pattern,
+ resource_identifier);
}
void PrefProvider::ClearAllContentSettingsRules(
@@ -197,6 +220,8 @@ void PrefProvider::Notify(
}
void PrefProvider::DiscardObsoletePreferences() {
+ if (is_incognito_)
+ return;
// These prefs were never stored on iOS/Android so they don't need to be
// deleted.
#if !defined(OS_IOS)
@@ -236,11 +261,11 @@ void PrefProvider::DiscardObsoletePreferences() {
if (!prefs_->GetDictionary(info->pref_name()))
continue;
- DictionaryPrefUpdate update(prefs_, info->pref_name());
- base::DictionaryValue* all_settings = update.Get();
+ prefs::ScopedDictionaryPrefUpdate update(prefs_, info->pref_name());
+ auto all_settings = update.Get();
std::vector<std::string> values_to_clean;
- for (base::DictionaryValue::Iterator i(*all_settings); !i.IsAtEnd();
- i.Advance()) {
+ for (base::DictionaryValue::Iterator i(*all_settings->AsConstDictionary());
+ !i.IsAtEnd(); i.Advance()) {
const base::DictionaryValue* pattern_settings = nullptr;
bool is_dictionary = i.value().GetAsDictionary(&pattern_settings);
DCHECK(is_dictionary);
@@ -249,7 +274,7 @@ void PrefProvider::DiscardObsoletePreferences() {
}
for (const std::string& key : values_to_clean) {
- base::DictionaryValue* pattern_settings = nullptr;
+ std::unique_ptr<prefs::DictionaryValueUpdate> pattern_settings;
all_settings->GetDictionaryWithoutPathExpansion(key, &pattern_settings);
pattern_settings->RemoveWithoutPathExpansion(kObsoleteLastUsed, nullptr);
if (pattern_settings->empty())
@@ -258,4 +283,8 @@ void PrefProvider::DiscardObsoletePreferences() {
}
}
+void PrefProvider::SetClockForTesting(std::unique_ptr<base::Clock> clock) {
+ clock_ = std::move(clock);
+}
+
} // namespace content_settings
diff --git a/chromium/components/content_settings/core/browser/content_settings_pref_provider.h b/chromium/components/content_settings/core/browser/content_settings_pref_provider.h
index 9f33e158f6e..124ac9b840f 100644
--- a/chromium/components/content_settings/core/browser/content_settings_pref_provider.h
+++ b/chromium/components/content_settings/core/browser/content_settings_pref_provider.h
@@ -18,6 +18,10 @@
class PrefService;
+namespace base {
+class Clock;
+}
+
namespace user_prefs {
class PrefRegistrySyncable;
}
@@ -32,7 +36,7 @@ class PrefProvider : public ObservableProvider {
public:
static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
- PrefProvider(PrefService* prefs, bool incognito);
+ PrefProvider(PrefService* prefs, bool incognito, bool store_last_modified);
~PrefProvider() override;
// ProviderInterface implementations.
@@ -47,6 +51,13 @@ class PrefProvider : public ObservableProvider {
const ResourceIdentifier& resource_identifier,
base::Value* value) override;
+ // Returns the |last_modified| date of a setting.
+ base::Time GetWebsiteSettingLastModified(
+ const ContentSettingsPattern& primary_pattern,
+ const ContentSettingsPattern& secondary_pattern,
+ ContentSettingsType content_type,
+ const ResourceIdentifier& resource_identifier);
+
void ClearAllContentSettingsRules(ContentSettingsType content_type) override;
void ShutdownOnUIThread() override;
@@ -55,6 +66,8 @@ class PrefProvider : public ObservableProvider {
ContentSettingsPref* GetPref(ContentSettingsType type) const;
+ void SetClockForTesting(std::unique_ptr<base::Clock> clock);
+
private:
friend class DeadlockCheckerObserver; // For testing.
@@ -71,6 +84,8 @@ class PrefProvider : public ObservableProvider {
const bool is_incognito_;
+ bool store_last_modified_;
+
PrefChangeRegistrar pref_change_registrar_;
std::map<ContentSettingsType, std::unique_ptr<ContentSettingsPref>>
@@ -78,6 +93,8 @@ class PrefProvider : public ObservableProvider {
base::ThreadChecker thread_checker_;
+ std::unique_ptr<base::Clock> clock_;
+
DISALLOW_COPY_AND_ASSIGN(PrefProvider);
};
diff --git a/chromium/components/content_settings/core/browser/content_settings_registry.cc b/chromium/components/content_settings/core/browser/content_settings_registry.cc
index b782ec64617..6b18f449543 100644
--- a/chromium/components/content_settings/core/browser/content_settings_registry.cc
+++ b/chromium/components/content_settings/core/browser/content_settings_registry.cc
@@ -250,7 +250,8 @@ void ContentSettingsRegistry::Init() {
Register(CONTENT_SETTINGS_TYPE_DURABLE_STORAGE, "durable-storage",
CONTENT_SETTING_ASK, WebsiteSettingsInfo::UNSYNCABLE,
WhitelistedSchemes(),
- ValidSettings(CONTENT_SETTING_ALLOW, CONTENT_SETTING_BLOCK),
+ ValidSettings(CONTENT_SETTING_ALLOW, CONTENT_SETTING_BLOCK,
+ CONTENT_SETTING_ASK),
WebsiteSettingsInfo::REQUESTING_ORIGIN_ONLY_SCOPE,
WebsiteSettingsRegistry::DESKTOP |
WebsiteSettingsRegistry::PLATFORM_ANDROID,
@@ -274,8 +275,8 @@ void ContentSettingsRegistry::Init() {
ContentSettingsInfo::INHERIT_IF_LESS_PERMISSIVE);
Register(CONTENT_SETTINGS_TYPE_SUBRESOURCE_FILTER, "subresource-filter",
- CONTENT_SETTING_ALLOW,
- WebsiteSettingsInfo::UNSYNCABLE, WhitelistedSchemes(),
+ CONTENT_SETTING_BLOCK, WebsiteSettingsInfo::UNSYNCABLE,
+ WhitelistedSchemes(),
ValidSettings(CONTENT_SETTING_ALLOW, CONTENT_SETTING_BLOCK),
WebsiteSettingsInfo::REQUESTING_ORIGIN_ONLY_SCOPE,
WebsiteSettingsRegistry::DESKTOP |
diff --git a/chromium/components/content_settings/core/browser/content_settings_registry_unittest.cc b/chromium/components/content_settings/core/browser/content_settings_registry_unittest.cc
index d63d180e0bf..db419b6e434 100644
--- a/chromium/components/content_settings/core/browser/content_settings_registry_unittest.cc
+++ b/chromium/components/content_settings/core/browser/content_settings_registry_unittest.cc
@@ -124,4 +124,23 @@ TEST_F(ContentSettingsRegistryTest, Iteration) {
EXPECT_TRUE(cookies_found);
}
+TEST_F(ContentSettingsRegistryTest, IsDefaultSettingValid) {
+ const ContentSettingsInfo* info =
+ registry()->Get(CONTENT_SETTINGS_TYPE_COOKIES);
+ EXPECT_TRUE(info->IsDefaultSettingValid(CONTENT_SETTING_ALLOW));
+
+#if !defined(OS_IOS)
+ info = registry()->Get(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC);
+ EXPECT_FALSE(info->IsDefaultSettingValid(CONTENT_SETTING_ALLOW));
+
+ info = registry()->Get(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA);
+ EXPECT_FALSE(info->IsDefaultSettingValid(CONTENT_SETTING_ALLOW));
+#endif
+
+#if defined(OS_ANDROID) || defined(OS_CHROMEOS)
+ info = registry()->Get(CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER);
+ EXPECT_FALSE(info->IsDefaultSettingValid(CONTENT_SETTING_ALLOW));
+#endif
+}
+
} // namespace content_settings
diff --git a/chromium/components/content_settings/core/browser/cookie_settings_unittest.cc b/chromium/components/content_settings/core/browser/cookie_settings_unittest.cc
index 1d16b2fec5f..f606004be5e 100644
--- a/chromium/components/content_settings/core/browser/cookie_settings_unittest.cc
+++ b/chromium/components/content_settings/core/browser/cookie_settings_unittest.cc
@@ -31,7 +31,8 @@ class CookieSettingsTest : public testing::Test {
CookieSettings::RegisterProfilePrefs(prefs_.registry());
HostContentSettingsMap::RegisterProfilePrefs(prefs_.registry());
settings_map_ = new HostContentSettingsMap(
- &prefs_, false /* incognito_profile */, false /* guest_profile */);
+ &prefs_, false /* incognito_profile */, false /* guest_profile */,
+ false /* store_last_modified */);
cookie_settings_ =
new CookieSettings(settings_map_.get(), &prefs_, "chrome-extension");
}
diff --git a/chromium/components/content_settings/core/browser/host_content_settings_map.cc b/chromium/components/content_settings/core/browser/host_content_settings_map.cc
index 3879f3096c0..52a6708ea74 100644
--- a/chromium/components/content_settings/core/browser/host_content_settings_map.cc
+++ b/chromium/components/content_settings/core/browser/host_content_settings_map.cc
@@ -178,13 +178,15 @@ content_settings::PatternPair GetPatternsForContentSettingsType(
HostContentSettingsMap::HostContentSettingsMap(PrefService* prefs,
bool is_incognito_profile,
- bool is_guest_profile)
+ bool is_guest_profile,
+ bool store_last_modified)
: RefcountedKeyedService(base::ThreadTaskRunnerHandle::Get()),
#ifndef NDEBUG
used_from_thread_id_(base::PlatformThread::CurrentId()),
#endif
prefs_(prefs),
is_incognito_(is_incognito_profile || is_guest_profile),
+ store_last_modified_(store_last_modified),
weak_ptr_factory_(this) {
DCHECK(!(is_incognito_profile && is_guest_profile));
@@ -194,8 +196,8 @@ HostContentSettingsMap::HostContentSettingsMap(PrefService* prefs,
base::WrapUnique(policy_provider);
policy_provider->AddObserver(this);
- pref_provider_ =
- new content_settings::PrefProvider(prefs_, is_incognito_);
+ pref_provider_ = new content_settings::PrefProvider(prefs_, is_incognito_,
+ store_last_modified_);
content_settings_providers_[PREF_PROVIDER] = base::WrapUnique(pref_provider_);
pref_provider_->AddObserver(this);
@@ -347,7 +349,9 @@ void HostContentSettingsMap::SetDefaultContentSetting(
std::unique_ptr<base::Value> value;
// A value of CONTENT_SETTING_DEFAULT implies deleting the content setting.
if (setting != CONTENT_SETTING_DEFAULT) {
- DCHECK(IsDefaultSettingAllowedForType(setting, content_type));
+ DCHECK(content_settings::ContentSettingsRegistry::GetInstance()
+ ->Get(content_type)
+ ->IsDefaultSettingValid(setting));
value.reset(new base::Value(setting));
}
SetWebsiteSettingCustomScope(ContentSettingsPattern::Wildcard(),
@@ -656,57 +660,41 @@ void HostContentSettingsMap::ClearSettingsForOneType(
FlushLossyWebsiteSettings();
}
+base::Time HostContentSettingsMap::GetSettingLastModifiedDate(
+ const ContentSettingsPattern& primary_pattern,
+ const ContentSettingsPattern& secondary_pattern,
+ ContentSettingsType content_type) const {
+ return pref_provider_->GetWebsiteSettingLastModified(
+ primary_pattern, secondary_pattern, content_type, std::string());
+}
+
void HostContentSettingsMap::ClearSettingsForOneTypeWithPredicate(
ContentSettingsType content_type,
- const base::Callback<bool(const ContentSettingsPattern& primary_pattern,
- const ContentSettingsPattern& secondary_pattern)>&
- pattern_predicate) {
- if (pattern_predicate.is_null()) {
+ base::Time begin_time,
+ const PatternSourcePredicate& pattern_predicate) {
+ if (pattern_predicate.is_null() && begin_time.is_null()) {
ClearSettingsForOneType(content_type);
return;
}
-
+ UsedContentSettingsProviders();
ContentSettingsForOneType settings;
GetSettingsForOneType(content_type, std::string(), &settings);
for (const ContentSettingPatternSource& setting : settings) {
- if (pattern_predicate.Run(setting.primary_pattern,
+ if (pattern_predicate.is_null() ||
+ pattern_predicate.Run(setting.primary_pattern,
setting.secondary_pattern)) {
- SetWebsiteSettingCustomScope(setting.primary_pattern,
- setting.secondary_pattern, content_type,
- std::string(), nullptr);
+ base::Time last_modified = pref_provider_->GetWebsiteSettingLastModified(
+ setting.primary_pattern, setting.secondary_pattern, content_type,
+ std::string());
+ if (last_modified >= begin_time) {
+ pref_provider_->SetWebsiteSetting(setting.primary_pattern,
+ setting.secondary_pattern,
+ content_type, std::string(), nullptr);
+ }
}
}
}
-// TODO(raymes): Remove this function. Consider making it a property of
-// ContentSettingsInfo or removing it altogether (it's unclear whether we should
-// be restricting allowed default values at this layer).
-// static
-bool HostContentSettingsMap::IsDefaultSettingAllowedForType(
- ContentSetting setting,
- ContentSettingsType content_type) {
-#if defined(OS_ANDROID) || defined(OS_CHROMEOS)
- // Don't support ALLOW for protected media default setting until migration.
- if (content_type == CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER &&
- setting == CONTENT_SETTING_ALLOW) {
- return false;
- }
-#endif
-
- // Don't support ALLOW for the default media settings.
- if ((content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA ||
- content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC) &&
- setting == CONTENT_SETTING_ALLOW) {
- return false;
- }
-
- const content_settings::ContentSettingsInfo* info =
- content_settings::ContentSettingsRegistry::GetInstance()->Get(
- content_type);
- DCHECK(info);
- return info->IsSettingValid(setting);
-}
-
void HostContentSettingsMap::OnContentSettingChanged(
const ContentSettingsPattern& primary_pattern,
const ContentSettingsPattern& secondary_pattern,
@@ -806,11 +794,8 @@ std::unique_ptr<base::Value> HostContentSettingsMap::GetWebsiteSetting(
}
}
- return GetWebsiteSettingInternal(primary_url,
- secondary_url,
- content_type,
- resource_identifier,
- info);
+ return GetWebsiteSettingInternal(primary_url, secondary_url, content_type,
+ resource_identifier, info);
}
// static
@@ -921,3 +906,8 @@ HostContentSettingsMap::GetContentSettingValueAndPatterns(
}
return std::unique_ptr<base::Value>();
}
+
+void HostContentSettingsMap::SetClockForTesting(
+ std::unique_ptr<base::Clock> clock) {
+ pref_provider_->SetClockForTesting(std::move(clock));
+} \ No newline at end of file
diff --git a/chromium/components/content_settings/core/browser/host_content_settings_map.h b/chromium/components/content_settings/core/browser/host_content_settings_map.h
index eadf365cfbd..b5c7798b02f 100644
--- a/chromium/components/content_settings/core/browser/host_content_settings_map.h
+++ b/chromium/components/content_settings/core/browser/host_content_settings_map.h
@@ -31,6 +31,7 @@ class PrefService;
namespace base {
class Value;
+class Clock;
}
namespace content_settings {
@@ -66,7 +67,8 @@ class HostContentSettingsMap : public content_settings::Observer,
// |is_incognito_profile| and |is_guest_profile| should be true.
HostContentSettingsMap(PrefService* prefs,
bool is_incognito_profile,
- bool is_guest_profile);
+ bool is_guest_profile,
+ bool store_last_modified);
static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
@@ -217,16 +219,27 @@ class HostContentSettingsMap : public content_settings::Observer,
// This should only be called on the UI thread.
void ClearSettingsForOneType(ContentSettingsType content_type);
+ // Return the |last_modified| date of a content setting. This will only return
+ // valid values for settings from the PreferenceProvider. Settings from other
+ // providers will return base::Time().
+ //
+ // This may be called on any thread.
+ base::Time GetSettingLastModifiedDate(
+ const ContentSettingsPattern& primary_pattern,
+ const ContentSettingsPattern& secondary_pattern,
+ ContentSettingsType content_type) const;
+
+ using PatternSourcePredicate =
+ base::Callback<bool(const ContentSettingsPattern& primary_pattern,
+ const ContentSettingsPattern& secondary_pattern)>;
+
// If |pattern_predicate| is null, this method is equivalent to the above.
- // Otherwise, it only deletes exceptions matched by |pattern_predicate|.
+ // Otherwise, it only deletes exceptions matched by |pattern_predicate| that
+ // were modified at or after |begin_time|.
void ClearSettingsForOneTypeWithPredicate(
ContentSettingsType content_type,
- const base::Callback<bool(
- const ContentSettingsPattern& primary_pattern,
- const ContentSettingsPattern& secondary_pattern)>& pattern_predicate);
-
- static bool IsDefaultSettingAllowedForType(ContentSetting setting,
- ContentSettingsType content_type);
+ base::Time begin_time,
+ const PatternSourcePredicate& pattern_predicate);
// RefcountedKeyedService implementation.
void ShutdownOnUIThread() override;
@@ -267,6 +280,10 @@ class HostContentSettingsMap : public content_settings::Observer,
base::WeakPtr<HostContentSettingsMap> GetWeakPtr();
+ // Injects a clock into the PrefProvider to allow control over the
+ // |last_modified| timestamp.
+ void SetClockForTesting(std::unique_ptr<base::Clock> clock);
+
private:
friend class base::RefCountedThreadSafe<HostContentSettingsMap>;
@@ -358,6 +375,10 @@ class HostContentSettingsMap : public content_settings::Observer,
// Whether this settings map is for an incognito session.
bool is_incognito_;
+ // Whether ContentSettings in the PrefProvider will store a last_modified
+ // timestamp.
+ bool store_last_modified_;
+
// Content setting providers. This is only modified at construction
// time and by RegisterExtensionService, both of which should happen
// before any other uses of it.
diff --git a/chromium/components/content_settings/core/browser/website_settings_registry.cc b/chromium/components/content_settings/core/browser/website_settings_registry.cc
index 1cfb5441383..4d49cef938c 100644
--- a/chromium/components/content_settings/core/browser/website_settings_registry.cc
+++ b/chromium/components/content_settings/core/browser/website_settings_registry.cc
@@ -165,6 +165,14 @@ void WebsiteSettingsRegistry::Init() {
WebsiteSettingsInfo::UNSYNCABLE, WebsiteSettingsInfo::NOT_LOSSY,
WebsiteSettingsInfo::REQUESTING_ORIGIN_ONLY_SCOPE,
DESKTOP | PLATFORM_ANDROID, WebsiteSettingsInfo::INHERIT_IN_INCOGNITO);
+ // Set when an origin is activated for subresource filtering and the
+ // associated UI is shown to the user. Cleared when a site is de-activated or
+ // the first URL matching the origin is removed from history.
+ Register(
+ CONTENT_SETTINGS_TYPE_SUBRESOURCE_FILTER_DATA, "subresource-filter-data",
+ nullptr, WebsiteSettingsInfo::UNSYNCABLE, WebsiteSettingsInfo::NOT_LOSSY,
+ WebsiteSettingsInfo::REQUESTING_ORIGIN_ONLY_SCOPE,
+ DESKTOP | PLATFORM_ANDROID, WebsiteSettingsInfo::INHERIT_IN_INCOGNITO);
}
} // namespace content_settings
diff --git a/chromium/components/content_settings/core/common/content_settings.cc b/chromium/components/content_settings/core/common/content_settings.cc
index ec1621532d9..4cf2d132898 100644
--- a/chromium/components/content_settings/core/common/content_settings.cc
+++ b/chromium/components/content_settings/core/common/content_settings.cc
@@ -16,50 +16,47 @@ ContentSetting IntToContentSetting(int content_setting) {
CONTENT_SETTING_DEFAULT : static_cast<ContentSetting>(content_setting);
}
-// WARNING: This array should not be reordered or removed as it is used for
-// histogram values. If a ContentSettingsType value has been removed, the entry
-// must be replaced by a placeholder. It should correspond directly to the
-// ContentType enum in histograms.xml.
+struct HistogramValue {
+ ContentSettingsType type;
+ int value;
+};
+
+// WARNING: The value specified here for a type should match exactly the value
+// specified in the ContentType enum in histograms.xml. Since these values are
+// used for histograms, please do not reuse the same value for a different
+// content setting. Always append to the end and increment.
// TODO(raymes): We should use a sparse histogram here on the hash of the
// content settings type name instead.
-ContentSettingsType kHistogramOrder[] = {
- CONTENT_SETTINGS_TYPE_COOKIES,
- CONTENT_SETTINGS_TYPE_IMAGES,
- CONTENT_SETTINGS_TYPE_JAVASCRIPT,
- CONTENT_SETTINGS_TYPE_PLUGINS,
- CONTENT_SETTINGS_TYPE_POPUPS,
- CONTENT_SETTINGS_TYPE_GEOLOCATION,
- CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
- CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE,
- CONTENT_SETTINGS_TYPE_DEFAULT, // FULLSCREEN (removed).
- CONTENT_SETTINGS_TYPE_DEFAULT, // MOUSELOCK (removed).
- CONTENT_SETTINGS_TYPE_MIXEDSCRIPT,
- CONTENT_SETTINGS_TYPE_DEFAULT, // MEDIASTREAM (removed).
- CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
- CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA,
- CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS,
- CONTENT_SETTINGS_TYPE_PPAPI_BROKER,
- CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS,
- CONTENT_SETTINGS_TYPE_MIDI_SYSEX,
- CONTENT_SETTINGS_TYPE_DEFAULT, // PUSH_MESSAGING (removed).
- CONTENT_SETTINGS_TYPE_SSL_CERT_DECISIONS,
- CONTENT_SETTINGS_TYPE_DEFAULT, // METRO_SWITCH_TO_DESKTOP (removed).
+HistogramValue kHistogramValue[] = {
+ {CONTENT_SETTINGS_TYPE_COOKIES, 0},
+ {CONTENT_SETTINGS_TYPE_IMAGES, 1},
+ {CONTENT_SETTINGS_TYPE_JAVASCRIPT, 2},
+ {CONTENT_SETTINGS_TYPE_PLUGINS, 3},
+ {CONTENT_SETTINGS_TYPE_POPUPS, 4},
+ {CONTENT_SETTINGS_TYPE_GEOLOCATION, 5},
+ {CONTENT_SETTINGS_TYPE_NOTIFICATIONS, 6},
+ {CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE, 7},
+ {CONTENT_SETTINGS_TYPE_MIXEDSCRIPT, 10},
+ {CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, 12},
+ {CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, 13},
+ {CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS, 14},
+ {CONTENT_SETTINGS_TYPE_PPAPI_BROKER, 15},
+ {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, 16},
+ {CONTENT_SETTINGS_TYPE_MIDI_SYSEX, 17},
+ {CONTENT_SETTINGS_TYPE_SSL_CERT_DECISIONS, 19},
#if defined(OS_ANDROID) || defined(OS_CHROMEOS)
- CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER,
-#else
- CONTENT_SETTINGS_TYPE_DEFAULT, // PROTECTED_MEDIA_IDENTIFIER (mobile only).
+ {CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER, 21},
#endif
- CONTENT_SETTINGS_TYPE_APP_BANNER,
- CONTENT_SETTINGS_TYPE_SITE_ENGAGEMENT,
- CONTENT_SETTINGS_TYPE_DURABLE_STORAGE,
- CONTENT_SETTINGS_TYPE_DEFAULT, // KEYGEN (removed).
- CONTENT_SETTINGS_TYPE_BLUETOOTH_GUARD,
- CONTENT_SETTINGS_TYPE_BACKGROUND_SYNC,
- CONTENT_SETTINGS_TYPE_AUTOPLAY,
- CONTENT_SETTINGS_TYPE_DEFAULT, // PROMPT_NO_DECISION_COUNT (migrated).
- CONTENT_SETTINGS_TYPE_IMPORTANT_SITE_INFO,
- CONTENT_SETTINGS_TYPE_PERMISSION_AUTOBLOCKER_DATA,
- CONTENT_SETTINGS_TYPE_SUBRESOURCE_FILTER,
+ {CONTENT_SETTINGS_TYPE_APP_BANNER, 22},
+ {CONTENT_SETTINGS_TYPE_SITE_ENGAGEMENT, 23},
+ {CONTENT_SETTINGS_TYPE_DURABLE_STORAGE, 24},
+ {CONTENT_SETTINGS_TYPE_BLUETOOTH_GUARD, 26},
+ {CONTENT_SETTINGS_TYPE_BACKGROUND_SYNC, 27},
+ {CONTENT_SETTINGS_TYPE_AUTOPLAY, 28},
+ {CONTENT_SETTINGS_TYPE_IMPORTANT_SITE_INFO, 30},
+ {CONTENT_SETTINGS_TYPE_PERMISSION_AUTOBLOCKER_DATA, 31},
+ {CONTENT_SETTINGS_TYPE_SUBRESOURCE_FILTER, 32},
+ {CONTENT_SETTINGS_TYPE_SUBRESOURCE_FILTER_DATA, 33},
};
int ContentSettingTypeToHistogramValue(ContentSettingsType content_setting,
@@ -68,14 +65,12 @@ int ContentSettingTypeToHistogramValue(ContentSettingsType content_setting,
typedef base::hash_map<int, int> Map;
CR_DEFINE_STATIC_LOCAL(Map, kMap, ());
if (kMap.empty()) {
- for (size_t i = 0; i < arraysize(kHistogramOrder); ++i) {
- if (kHistogramOrder[i] != CONTENT_SETTINGS_TYPE_DEFAULT)
- kMap[kHistogramOrder[i]] = static_cast<int>(i);
- }
+ for (const HistogramValue& histogram_value : kHistogramValue)
+ kMap[histogram_value.type] = histogram_value.value;
}
DCHECK(base::ContainsKey(kMap, content_setting));
- *num_values = arraysize(kHistogramOrder);
+ *num_values = arraysize(kHistogramValue);
return kMap[content_setting];
}
diff --git a/chromium/components/content_settings/core/common/content_settings_types.h b/chromium/components/content_settings/core/common/content_settings_types.h
index d7584141be5..580a94ac8c6 100644
--- a/chromium/components/content_settings/core/common/content_settings_types.h
+++ b/chromium/components/content_settings/core/common/content_settings_types.h
@@ -50,6 +50,10 @@ enum ContentSettingsType {
CONTENT_SETTINGS_TYPE_PERMISSION_AUTOBLOCKER_DATA,
CONTENT_SETTINGS_TYPE_SUBRESOURCE_FILTER,
+ // Website setting which stores metadata for the subresource filter to aid in
+ // decisions for whether or not to show the UI.
+ CONTENT_SETTINGS_TYPE_SUBRESOURCE_FILTER_DATA,
+
// This is special-cased in the permissions layer to always allow, and as
// such doesn't have associated prefs data.
CONTENT_SETTINGS_TYPE_MIDI,