summaryrefslogtreecommitdiffstats
path: root/chrome/browser/content_settings
diff options
context:
space:
mode:
authorKristian Monsen <kristianm@google.com>2011-06-09 11:47:42 +0100
committerKristian Monsen <kristianm@google.com>2011-06-29 14:33:03 +0100
commitdc0f95d653279beabeb9817299e2902918ba123e (patch)
tree32eb121cd532053a5b9cb0c390331349af8d6baa /chrome/browser/content_settings
parentba160cd4054d13d0cb0b1b46e61c3bed67095811 (diff)
downloadexternal_chromium-dc0f95d653279beabeb9817299e2902918ba123e.zip
external_chromium-dc0f95d653279beabeb9817299e2902918ba123e.tar.gz
external_chromium-dc0f95d653279beabeb9817299e2902918ba123e.tar.bz2
Merge Chromium at r11.0.696.0: Initial merge by git
Change-Id: I273dde2843af0839dfc08b419bb443fbd449532d
Diffstat (limited to 'chrome/browser/content_settings')
-rw-r--r--chrome/browser/content_settings/content_settings_base_provider.cc255
-rw-r--r--chrome/browser/content_settings/content_settings_base_provider.h134
-rw-r--r--chrome/browser/content_settings/content_settings_mock_provider.cc (renamed from chrome/browser/content_settings/mock_content_settings_provider.cc)18
-rw-r--r--chrome/browser/content_settings/content_settings_mock_provider.h (renamed from chrome/browser/content_settings/mock_content_settings_provider.h)32
-rw-r--r--chrome/browser/content_settings/content_settings_pattern.cc19
-rw-r--r--chrome/browser/content_settings/content_settings_pattern_unittest.cc19
-rw-r--r--chrome/browser/content_settings/content_settings_policy_provider.cc482
-rw-r--r--chrome/browser/content_settings/content_settings_policy_provider.h (renamed from chrome/browser/content_settings/policy_content_settings_provider.h)79
-rw-r--r--chrome/browser/content_settings/content_settings_policy_provider_unittest.cc185
-rw-r--r--chrome/browser/content_settings/content_settings_pref_provider.cc (renamed from chrome/browser/content_settings/pref_content_settings_provider.cc)316
-rw-r--r--chrome/browser/content_settings/content_settings_pref_provider.h (renamed from chrome/browser/content_settings/pref_content_settings_provider.h)59
-rw-r--r--chrome/browser/content_settings/content_settings_pref_provider_unittest.cc (renamed from chrome/browser/content_settings/pref_content_settings_provider_unittest.cc)24
-rw-r--r--chrome/browser/content_settings/content_settings_provider.h5
-rw-r--r--chrome/browser/content_settings/content_settings_provider_unittest.cc4
-rw-r--r--chrome/browser/content_settings/host_content_settings_map.cc37
-rw-r--r--chrome/browser/content_settings/host_content_settings_map.h8
-rw-r--r--chrome/browser/content_settings/host_content_settings_map_unittest.cc7
-rw-r--r--chrome/browser/content_settings/policy_content_settings_provider.cc198
-rw-r--r--chrome/browser/content_settings/policy_content_settings_provider_unittest.cc83
19 files changed, 1330 insertions, 634 deletions
diff --git a/chrome/browser/content_settings/content_settings_base_provider.cc b/chrome/browser/content_settings/content_settings_base_provider.cc
new file mode 100644
index 0000000..b0e7ced
--- /dev/null
+++ b/chrome/browser/content_settings/content_settings_base_provider.cc
@@ -0,0 +1,255 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+#include "chrome/browser/content_settings/content_settings_base_provider.h"
+
+#include "base/command_line.h"
+#include "base/logging.h"
+#include "chrome/common/chrome_switches.h"
+#include "googleurl/src/gurl.h"
+#include "net/base/net_util.h"
+
+namespace {
+
+// True if a given content settings type requires additional resource
+// identifiers.
+const bool kRequiresResourceIdentifier[CONTENT_SETTINGS_NUM_TYPES] = {
+ false, // CONTENT_SETTINGS_TYPE_COOKIES
+ false, // CONTENT_SETTINGS_TYPE_IMAGES
+ false, // CONTENT_SETTINGS_TYPE_JAVASCRIPT
+ true, // CONTENT_SETTINGS_TYPE_PLUGINS
+ false, // CONTENT_SETTINGS_TYPE_POPUPS
+ false, // Not used for Geolocation
+ false, // Not used for Notifications
+};
+
+} // namespace
+
+namespace content_settings {
+
+ExtendedContentSettings::ExtendedContentSettings() {}
+
+ExtendedContentSettings::ExtendedContentSettings(
+ const ExtendedContentSettings& rhs)
+ : content_settings(rhs.content_settings),
+ content_settings_for_resources(rhs.content_settings_for_resources) {
+}
+
+ExtendedContentSettings::~ExtendedContentSettings() {}
+
+BaseProvider::BaseProvider(bool is_otr)
+ : is_off_the_record_(is_otr) {
+}
+
+BaseProvider::~BaseProvider() {}
+
+bool BaseProvider::RequiresResourceIdentifier(
+ ContentSettingsType content_type) const {
+ if (CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableResourceContentSettings)) {
+ return kRequiresResourceIdentifier[content_type];
+ } else {
+ return false;
+ }
+}
+
+bool BaseProvider::AllDefault(
+ const ExtendedContentSettings& settings) const {
+ for (size_t i = 0; i < arraysize(settings.content_settings.settings); ++i) {
+ if (settings.content_settings.settings[i] != CONTENT_SETTING_DEFAULT)
+ return false;
+ }
+ return settings.content_settings_for_resources.empty();
+}
+
+ContentSetting BaseProvider::GetContentSetting(
+ const GURL& requesting_url,
+ const GURL& embedding_url,
+ ContentSettingsType content_type,
+ const ResourceIdentifier& resource_identifier) const {
+ // Support for embedding_patterns is not implemented yet.
+ DCHECK(requesting_url == embedding_url);
+
+ if (!RequiresResourceIdentifier(content_type) ||
+ (RequiresResourceIdentifier(content_type) && resource_identifier.empty()))
+ return GetNonDefaultContentSettings(requesting_url).settings[content_type];
+
+ // Resolve content settings with resource identifier.
+ // 1. Check for pattern that exactly match the url/host
+ // 1.1 In the content-settings-map
+ // 1.2 In the off_the_record content-settings-map
+ // 3. Shorten the url subdomain by subdomain and try to find a pattern in
+ // 3.1 OTR content-settings-map
+ // 3.2 content-settings-map
+ base::AutoLock auto_lock(lock_);
+ const std::string host(net::GetHostOrSpecFromURL(requesting_url));
+ ContentSettingsTypeResourceIdentifierPair
+ requested_setting(content_type, resource_identifier);
+
+ // Check for exact matches first.
+ HostContentSettings::const_iterator i(host_content_settings_.find(host));
+ if (i != host_content_settings_.end() &&
+ i->second.content_settings_for_resources.find(requested_setting) !=
+ i->second.content_settings_for_resources.end()) {
+ return i->second.content_settings_for_resources.find(
+ requested_setting)->second;
+ }
+
+ // If this map is not for an off-the-record profile, these searches will never
+ // match. The additional off-the-record exceptions always overwrite the
+ // regular ones.
+ i = off_the_record_settings_.find(host);
+ if (i != off_the_record_settings_.end() &&
+ i->second.content_settings_for_resources.find(requested_setting) !=
+ i->second.content_settings_for_resources.end()) {
+ return i->second.content_settings_for_resources.find(
+ requested_setting)->second;
+ }
+
+ // Match patterns starting with the most concrete pattern match.
+ for (std::string key =
+ std::string(ContentSettingsPattern::kDomainWildcard) + host; ; ) {
+ HostContentSettings::const_iterator i(off_the_record_settings_.find(key));
+ if (i != off_the_record_settings_.end() &&
+ i->second.content_settings_for_resources.find(requested_setting) !=
+ i->second.content_settings_for_resources.end()) {
+ return i->second.content_settings_for_resources.find(
+ requested_setting)->second;
+ }
+
+ i = host_content_settings_.find(key);
+ if (i != host_content_settings_.end() &&
+ i->second.content_settings_for_resources.find(requested_setting) !=
+ i->second.content_settings_for_resources.end()) {
+ return i->second.content_settings_for_resources.find(
+ requested_setting)->second;
+ }
+
+ const size_t next_dot =
+ key.find('.', ContentSettingsPattern::kDomainWildcardLength);
+ if (next_dot == std::string::npos)
+ break;
+ key.erase(ContentSettingsPattern::kDomainWildcardLength,
+ next_dot - ContentSettingsPattern::kDomainWildcardLength + 1);
+ }
+
+ return CONTENT_SETTING_DEFAULT;
+}
+
+void BaseProvider::GetAllContentSettingsRules(
+ ContentSettingsType content_type,
+ const ResourceIdentifier& resource_identifier,
+ Rules* content_setting_rules) const {
+ DCHECK(content_setting_rules);
+ content_setting_rules->clear();
+
+ const HostContentSettings* map_to_return =
+ is_off_the_record_ ? &off_the_record_settings_ : &host_content_settings_;
+ ContentSettingsTypeResourceIdentifierPair requested_setting(
+ content_type, resource_identifier);
+
+ base::AutoLock auto_lock(lock_);
+ for (HostContentSettings::const_iterator i(map_to_return->begin());
+ i != map_to_return->end(); ++i) {
+ ContentSetting setting;
+ if (RequiresResourceIdentifier(content_type)) {
+ if (i->second.content_settings_for_resources.find(requested_setting) !=
+ i->second.content_settings_for_resources.end()) {
+ setting = i->second.content_settings_for_resources.find(
+ requested_setting)->second;
+ } else {
+ setting = CONTENT_SETTING_DEFAULT;
+ }
+ } else {
+ setting = i->second.content_settings.settings[content_type];
+ }
+ if (setting != CONTENT_SETTING_DEFAULT) {
+ // Use of push_back() relies on the map iterator traversing in order of
+ // ascending keys.
+ content_setting_rules->push_back(Rule(ContentSettingsPattern(i->first),
+ ContentSettingsPattern(i->first),
+ setting));
+ }
+ }
+}
+
+ContentSettings BaseProvider::GetNonDefaultContentSettings(
+ const GURL& url) const {
+ base::AutoLock auto_lock(lock_);
+
+ const std::string host(net::GetHostOrSpecFromURL(url));
+ ContentSettings output;
+ for (int j = 0; j < CONTENT_SETTINGS_NUM_TYPES; ++j)
+ output.settings[j] = CONTENT_SETTING_DEFAULT;
+
+ // Check for exact matches first.
+ HostContentSettings::const_iterator i(host_content_settings_.find(host));
+ if (i != host_content_settings_.end())
+ output = i->second.content_settings;
+
+ // If this map is not for an off-the-record profile, these searches will never
+ // match. The additional off-the-record exceptions always overwrite the
+ // regular ones.
+ i = off_the_record_settings_.find(host);
+ if (i != off_the_record_settings_.end()) {
+ for (int j = 0; j < CONTENT_SETTINGS_NUM_TYPES; ++j)
+ if (i->second.content_settings.settings[j] != CONTENT_SETTING_DEFAULT)
+ output.settings[j] = i->second.content_settings.settings[j];
+ }
+
+ // Match patterns starting with the most concrete pattern match.
+ for (std::string key =
+ std::string(ContentSettingsPattern::kDomainWildcard) + host; ; ) {
+ HostContentSettings::const_iterator i(off_the_record_settings_.find(key));
+ if (i != off_the_record_settings_.end()) {
+ for (int j = 0; j < CONTENT_SETTINGS_NUM_TYPES; ++j) {
+ if (output.settings[j] == CONTENT_SETTING_DEFAULT)
+ output.settings[j] = i->second.content_settings.settings[j];
+ }
+ }
+ i = host_content_settings_.find(key);
+ if (i != host_content_settings_.end()) {
+ for (int j = 0; j < CONTENT_SETTINGS_NUM_TYPES; ++j) {
+ if (output.settings[j] == CONTENT_SETTING_DEFAULT)
+ output.settings[j] = i->second.content_settings.settings[j];
+ }
+ }
+ const size_t next_dot =
+ key.find('.', ContentSettingsPattern::kDomainWildcardLength);
+ if (next_dot == std::string::npos)
+ break;
+ key.erase(ContentSettingsPattern::kDomainWildcardLength,
+ next_dot - ContentSettingsPattern::kDomainWildcardLength + 1);
+ }
+
+ return output;
+}
+
+void BaseProvider::UpdateContentSettingsMap(
+ const ContentSettingsPattern& requesting_pattern,
+ const ContentSettingsPattern& embedding_pattern,
+ ContentSettingsType content_type,
+ const ResourceIdentifier& resource_identifier,
+ ContentSetting content_setting) {
+ std::string pattern_str(requesting_pattern.CanonicalizePattern());
+ HostContentSettings* content_settings_map = host_content_settings();
+ ExtendedContentSettings& extended_settings =
+ (*content_settings_map)[pattern_str];
+ extended_settings.content_settings.settings[content_type] = content_setting;
+}
+
+// static
+ContentSetting BaseProvider::ClickToPlayFixup(ContentSettingsType content_type,
+ ContentSetting setting) {
+ if (setting == CONTENT_SETTING_ASK &&
+ content_type == CONTENT_SETTINGS_TYPE_PLUGINS &&
+ !CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableClickToPlay)) {
+ return CONTENT_SETTING_BLOCK;
+ }
+ return setting;
+}
+
+} // namespace content_settings
diff --git a/chrome/browser/content_settings/content_settings_base_provider.h b/chrome/browser/content_settings/content_settings_base_provider.h
new file mode 100644
index 0000000..1e6c9e4
--- /dev/null
+++ b/chrome/browser/content_settings/content_settings_base_provider.h
@@ -0,0 +1,134 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CONTENT_SETTINGS_CONTENT_SETTINGS_BASE_PROVIDER_H_
+#define CHROME_BROWSER_CONTENT_SETTINGS_CONTENT_SETTINGS_BASE_PROVIDER_H_
+#pragma once
+
+#include <map>
+#include <string>
+#include <utility>
+
+#include "base/synchronization/lock.h"
+#include "chrome/browser/content_settings/content_settings_provider.h"
+
+namespace content_settings {
+
+typedef std::pair<ContentSettingsType, std::string>
+ ContentSettingsTypeResourceIdentifierPair;
+typedef std::map<ContentSettingsTypeResourceIdentifierPair, ContentSetting>
+ ResourceContentSettings;
+
+struct ExtendedContentSettings {
+ ExtendedContentSettings();
+ ExtendedContentSettings(const ExtendedContentSettings& rhs);
+ ~ExtendedContentSettings();
+
+ ContentSettings content_settings;
+ ResourceContentSettings content_settings_for_resources;
+};
+
+// Map for ContentSettings.
+typedef std::map<std::string, ExtendedContentSettings> HostContentSettings;
+
+// BaseProvider is the abstract base class for all content-settings-provider
+// classes.
+class BaseProvider : public ProviderInterface {
+ public:
+ // Maps CONTENT_SETTING_ASK for the CONTENT_SETTINGS_TYPE_PLUGINS to
+ // CONTENT_SETTING_BLOCK if click-to-play is not enabled.
+ static ContentSetting ClickToPlayFixup(ContentSettingsType content_type,
+ ContentSetting setting);
+
+ explicit BaseProvider(bool is_otr);
+ virtual ~BaseProvider();
+
+
+ // Initializes the Provider.
+ virtual void Init() = 0;
+
+ // ProviderInterface Implementation
+ virtual bool ContentSettingsTypeIsManaged(
+ ContentSettingsType content_type) = 0;
+
+ virtual ContentSetting GetContentSetting(
+ const GURL& requesting_url,
+ const GURL& embedding_url,
+ ContentSettingsType content_type,
+ const ResourceIdentifier& resource_identifier) const;
+
+ virtual void SetContentSetting(
+ const ContentSettingsPattern& requesting_pattern,
+ const ContentSettingsPattern& embedding_pattern,
+ ContentSettingsType content_type,
+ const ResourceIdentifier& resource_identifier,
+ ContentSetting content_setting) = 0;
+
+ virtual void GetAllContentSettingsRules(
+ ContentSettingsType content_type,
+ const ResourceIdentifier& resource_identifier,
+ Rules* content_setting_rules) const;
+
+ virtual void ClearAllContentSettingsRules(
+ ContentSettingsType content_type) = 0;
+
+ virtual void ResetToDefaults() = 0;
+
+ protected:
+ // Returns true if the |content_type| requires a resource identifier.
+ bool RequiresResourceIdentifier(
+ ContentSettingsType content_type) const;
+
+ // Returns true if the passed |settings| object contains only
+ // CONTENT_SETTING_DEFAULT values.
+ bool AllDefault(const ExtendedContentSettings& settings) const;
+
+ void UpdateContentSettingsMap(
+ const ContentSettingsPattern& requesting_pattern,
+ const ContentSettingsPattern& embedding_pattern,
+ ContentSettingsType content_type,
+ const ResourceIdentifier& resource_identifier,
+ ContentSetting content_setting);
+
+ // TODO(markusheintz): LEGACY method. Will be removed in a future re-factoring
+ // step.
+ ContentSettings GetNonDefaultContentSettings(const GURL& url) const;
+
+ // Accessors
+ HostContentSettings* host_content_settings() {
+ return &host_content_settings_;
+ }
+
+ HostContentSettings* off_the_record_settings() {
+ return &off_the_record_settings_;
+ }
+
+ base::Lock& lock() const {
+ return lock_;
+ }
+
+ bool is_off_the_record() const {
+ return is_off_the_record_;
+ }
+
+ private:
+ // Copies of the pref data, so that we can read it on threads other than the
+ // UI thread.
+ HostContentSettings host_content_settings_;
+
+ // Whether this settings map is for an OTR session.
+ bool is_off_the_record_;
+
+ // Differences to the preference-stored host content settings for
+ // off-the-record settings.
+ HostContentSettings off_the_record_settings_;
+
+ // Used around accesses to the content_settings_ object to guarantee
+ // thread safety.
+ mutable base::Lock lock_;
+};
+
+} // namespace content_settings
+
+#endif // CHROME_BROWSER_CONTENT_SETTINGS_CONTENT_SETTINGS_BASE_PROVIDER_H_
diff --git a/chrome/browser/content_settings/mock_content_settings_provider.cc b/chrome/browser/content_settings/content_settings_mock_provider.cc
index f73280f..c166dd6 100644
--- a/chrome/browser/content_settings/mock_content_settings_provider.cc
+++ b/chrome/browser/content_settings/content_settings_mock_provider.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "chrome/browser/content_settings/mock_content_settings_provider.h"
+#include "chrome/browser/content_settings/content_settings_mock_provider.h"
namespace content_settings {
@@ -46,20 +46,23 @@ MockProvider::MockProvider()
content_type_(CONTENT_SETTINGS_TYPE_COOKIES),
resource_identifier_(""),
setting_(CONTENT_SETTING_DEFAULT),
- read_only_(false) {}
+ read_only_(false),
+ is_managed_(false) {}
MockProvider::MockProvider(ContentSettingsPattern requesting_url_pattern,
ContentSettingsPattern embedding_url_pattern,
ContentSettingsType content_type,
ResourceIdentifier resource_identifier,
ContentSetting setting,
- bool read_only)
+ bool read_only,
+ bool is_managed)
: requesting_url_pattern_(requesting_url_pattern),
embedding_url_pattern_(embedding_url_pattern),
content_type_(content_type),
resource_identifier_(resource_identifier),
setting_(setting),
- read_only_(read_only) {}
+ read_only_(read_only),
+ is_managed_(is_managed) {}
MockProvider::~MockProvider() {}
@@ -91,4 +94,11 @@ void MockProvider::SetContentSetting(
setting_ = content_setting;
}
+bool MockProvider::ContentSettingsTypeIsManaged(ContentSettingsType type) {
+ if (type == content_type_) {
+ return is_managed_;
+ }
+ return false;
+}
+
} // namespace content_settings
diff --git a/chrome/browser/content_settings/mock_content_settings_provider.h b/chrome/browser/content_settings/content_settings_mock_provider.h
index 4393868..17ced25 100644
--- a/chrome/browser/content_settings/mock_content_settings_provider.h
+++ b/chrome/browser/content_settings/content_settings_mock_provider.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CHROME_BROWSER_CONTENT_SETTINGS_MOCK_CONTENT_SETTINGS_PROVIDER_H_
-#define CHROME_BROWSER_CONTENT_SETTINGS_MOCK_CONTENT_SETTINGS_PROVIDER_H_
+#ifndef CHROME_BROWSER_CONTENT_SETTINGS_CONTENT_SETTINGS_MOCK_PROVIDER_H_
+#define CHROME_BROWSER_CONTENT_SETTINGS_CONTENT_SETTINGS_MOCK_PROVIDER_H_
#pragma once
#include "base/basictypes.h"
@@ -49,9 +49,12 @@ class MockProvider : public ProviderInterface {
ContentSettingsType content_type,
ResourceIdentifier resource_identifier,
ContentSetting setting,
- bool read_only);
+ bool read_only,
+ bool is_managed);
virtual ~MockProvider();
+ virtual bool ContentSettingsTypeIsManaged(ContentSettingsType type);
+
// ProviderInterface implementation
virtual ContentSetting GetContentSetting(
const GURL& requesting_url,
@@ -83,7 +86,7 @@ class MockProvider : public ProviderInterface {
requesting_url_pattern_ = pattern;
}
- ContentSettingsPattern requesting_url_pattern() {
+ ContentSettingsPattern requesting_url_pattern() const {
return requesting_url_pattern_;
}
@@ -91,7 +94,7 @@ class MockProvider : public ProviderInterface {
embedding_url_pattern_ = pattern;
}
- ContentSettingsPattern embedding_url_pattern() {
+ ContentSettingsPattern embedding_url_pattern() const {
return embedding_url_pattern_;
}
@@ -99,7 +102,7 @@ class MockProvider : public ProviderInterface {
content_type_ = content_type;
}
- ContentSettingsType content_type() {
+ ContentSettingsType content_type() const {
return content_type_;
}
@@ -107,7 +110,7 @@ class MockProvider : public ProviderInterface {
resource_identifier_ = resource_identifier;
}
- ResourceIdentifier resource_identifier() {
+ ResourceIdentifier resource_identifier() const {
return resource_identifier_;
}
@@ -115,7 +118,7 @@ class MockProvider : public ProviderInterface {
setting_ = setting;
}
- ContentSetting setting() {
+ ContentSetting setting() const {
return setting_;
}
@@ -123,10 +126,18 @@ class MockProvider : public ProviderInterface {
read_only_ = read_only;
}
- bool read_only() {
+ bool read_only() const {
return read_only_;
}
+ void set_is_managed(bool is_managed) {
+ is_managed_ = is_managed;
+ }
+
+ bool is_managed() const {
+ return is_managed_;
+ }
+
private:
ContentSettingsPattern requesting_url_pattern_;
ContentSettingsPattern embedding_url_pattern_;
@@ -134,10 +145,11 @@ class MockProvider : public ProviderInterface {
ResourceIdentifier resource_identifier_;
ContentSetting setting_;
bool read_only_;
+ bool is_managed_;
DISALLOW_COPY_AND_ASSIGN(MockProvider);
};
} // namespace content_settings
-#endif // CHROME_BROWSER_CONTENT_SETTINGS_MOCK_CONTENT_SETTINGS_PROVIDER_H_
+#endif // CHROME_BROWSER_CONTENT_SETTINGS_CONTENT_SETTINGS_MOCK_PROVIDER_H_
diff --git a/chrome/browser/content_settings/content_settings_pattern.cc b/chrome/browser/content_settings/content_settings_pattern.cc
index ba93ff4..ef759a8 100644
--- a/chrome/browser/content_settings/content_settings_pattern.cc
+++ b/chrome/browser/content_settings/content_settings_pattern.cc
@@ -5,10 +5,20 @@
#include "chrome/browser/content_settings/content_settings_pattern.h"
#include "base/string_util.h"
+#include "chrome/common/url_constants.h"
#include "net/base/net_util.h"
#include "googleurl/src/gurl.h"
#include "googleurl/src/url_canon.h"
+namespace {
+bool IsValidHostlessPattern(const std::string& pattern) {
+ std::string file_scheme_plus_separator(chrome::kFileScheme);
+ file_scheme_plus_separator += chrome::kStandardSchemeSeparator;
+
+ return StartsWithASCII(pattern, file_scheme_plus_separator, false);
+}
+} // namespace
+
// The version of the pattern format implemented. Version 1 includes the
// following patterns:
// - [*.]domain.tld (matches domain.tld and all sub-domains)
@@ -40,6 +50,9 @@ bool ContentSettingsPattern::IsValid() const {
if (pattern_.empty())
return false;
+ if (IsValidHostlessPattern(pattern_))
+ return true;
+
const std::string host(pattern_.length() > kDomainWildcardLength &&
StartsWithASCII(pattern_, kDomainWildcard, false) ?
pattern_.substr(kDomainWildcardLength) :
@@ -67,9 +80,11 @@ bool ContentSettingsPattern::Matches(const GURL& url) const {
}
std::string ContentSettingsPattern::CanonicalizePattern() const {
- if (!IsValid()) {
+ if (!IsValid())
return "";
- }
+
+ if (IsValidHostlessPattern(pattern_))
+ return GURL(pattern_).spec();
bool starts_with_wildcard = pattern_.length() > kDomainWildcardLength &&
StartsWithASCII(pattern_, kDomainWildcard, false);
diff --git a/chrome/browser/content_settings/content_settings_pattern_unittest.cc b/chrome/browser/content_settings/content_settings_pattern_unittest.cc
index 88b42dc..4882e34 100644
--- a/chrome/browser/content_settings/content_settings_pattern_unittest.cc
+++ b/chrome/browser/content_settings/content_settings_pattern_unittest.cc
@@ -14,6 +14,7 @@ TEST(ContentSettingsPatternTest, PatternSupport) {
EXPECT_TRUE(ContentSettingsPattern("example.com").IsValid());
EXPECT_TRUE(ContentSettingsPattern("192.168.0.1").IsValid());
EXPECT_TRUE(ContentSettingsPattern("[::1]").IsValid());
+ EXPECT_TRUE(ContentSettingsPattern("file:///tmp/test.html").IsValid());
EXPECT_FALSE(ContentSettingsPattern("*example.com").IsValid());
EXPECT_FALSE(ContentSettingsPattern("example.*").IsValid());
EXPECT_FALSE(ContentSettingsPattern("http://example.com").IsValid());
@@ -24,12 +25,18 @@ TEST(ContentSettingsPatternTest, PatternSupport) {
GURL("http://www.example.com/")));
EXPECT_TRUE(ContentSettingsPattern("www.example.com").Matches(
GURL("http://www.example.com/")));
+ EXPECT_TRUE(ContentSettingsPattern("file:///tmp/test.html").Matches(
+ GURL("file:///tmp/test.html")));
EXPECT_FALSE(ContentSettingsPattern("").Matches(
GURL("http://www.example.com/")));
EXPECT_FALSE(ContentSettingsPattern("[*.]example.com").Matches(
GURL("http://example.org/")));
EXPECT_FALSE(ContentSettingsPattern("example.com").Matches(
GURL("http://example.org/")));
+ EXPECT_FALSE(ContentSettingsPattern("file:///tmp/test.html").Matches(
+ GURL("file:///tmp/other.html")));
+ EXPECT_FALSE(ContentSettingsPattern("file:///tmp/test.html").Matches(
+ GURL("http://example.org/")));
}
TEST(ContentSettingsPatternTest, CanonicalizePattern) {
@@ -42,19 +49,21 @@ TEST(ContentSettingsPatternTest, CanonicalizePattern) {
.CanonicalizePattern().c_str());
EXPECT_STREQ("[::1]", ContentSettingsPattern("[::1]")
.CanonicalizePattern().c_str());
- // IsValid returns false for file:/// patterns.
- EXPECT_STREQ("", ContentSettingsPattern(
- "file:///temp/file.html").CanonicalizePattern().c_str());
+ EXPECT_STREQ("file:///tmp/file.html", ContentSettingsPattern(
+ "file:///tmp/file.html").CanonicalizePattern().c_str());
// UTF-8 patterns.
EXPECT_STREQ("[*.]xn--ira-ppa.com", ContentSettingsPattern(
"[*.]\xC4\x87ira.com").CanonicalizePattern().c_str());
EXPECT_STREQ("xn--ira-ppa.com", ContentSettingsPattern(
"\xC4\x87ira.com").CanonicalizePattern().c_str());
- // IsValid returns false for file:/// patterns.
- EXPECT_STREQ("", ContentSettingsPattern(
+ EXPECT_STREQ("file:///%C4%87ira.html", ContentSettingsPattern(
"file:///\xC4\x87ira.html").CanonicalizePattern().c_str());
+ // file:/// normalization.
+ EXPECT_STREQ("file:///tmp/test.html", ContentSettingsPattern(
+ "file:///tmp/bar/../test.html").CanonicalizePattern().c_str());
+
// Invalid patterns.
EXPECT_STREQ("", ContentSettingsPattern(
"*example.com").CanonicalizePattern().c_str());
diff --git a/chrome/browser/content_settings/content_settings_policy_provider.cc b/chrome/browser/content_settings/content_settings_policy_provider.cc
new file mode 100644
index 0000000..a8ab96a
--- /dev/null
+++ b/chrome/browser/content_settings/content_settings_policy_provider.cc
@@ -0,0 +1,482 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/content_settings/content_settings_policy_provider.h"
+
+#include <string>
+#include <vector>
+
+#include "base/command_line.h"
+#include "chrome/browser/content_settings/content_settings_details.h"
+#include "chrome/browser/content_settings/content_settings_pattern.h"
+#include "chrome/browser/prefs/pref_service.h"
+#include "chrome/browser/prefs/scoped_user_pref_update.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/common/notification_details.h"
+#include "chrome/common/notification_service.h"
+#include "chrome/common/notification_source.h"
+#include "chrome/common/pref_names.h"
+#include "content/browser/browser_thread.h"
+#include "webkit/plugins/npapi/plugin_group.h"
+#include "webkit/plugins/npapi/plugin_list.h"
+
+namespace {
+
+// Base pref path of the prefs that contain the managed default content
+// settings values.
+const std::string kManagedSettings =
+ "profile.managed_default_content_settings";
+
+// The preferences used to manage ContentSettingsTypes.
+const char* kPrefToManageType[CONTENT_SETTINGS_NUM_TYPES] = {
+ prefs::kManagedDefaultCookiesSetting,
+ prefs::kManagedDefaultImagesSetting,
+ prefs::kManagedDefaultJavaScriptSetting,
+ prefs::kManagedDefaultPluginsSetting,
+ prefs::kManagedDefaultPopupsSetting,
+ NULL, // Not used for Geolocation
+ NULL, // Not used for Notifications
+};
+
+struct PrefsForManagedContentSettingsMapEntry {
+ const char* pref_name;
+ ContentSettingsType content_type;
+ ContentSetting setting;
+};
+
+const PrefsForManagedContentSettingsMapEntry
+ kPrefsForManagedContentSettingsMap[] = {
+ {
+ prefs::kManagedCookiesAllowedForUrls,
+ CONTENT_SETTINGS_TYPE_COOKIES,
+ CONTENT_SETTING_ALLOW
+ }, {
+ prefs::kManagedCookiesSessionOnlyForUrls,
+ CONTENT_SETTINGS_TYPE_COOKIES,
+ CONTENT_SETTING_SESSION_ONLY
+ }, {
+ prefs::kManagedCookiesBlockedForUrls,
+ CONTENT_SETTINGS_TYPE_COOKIES,
+ CONTENT_SETTING_BLOCK
+ }, {
+ prefs::kManagedImagesAllowedForUrls,
+ CONTENT_SETTINGS_TYPE_IMAGES,
+ CONTENT_SETTING_ALLOW
+ }, {
+ prefs::kManagedImagesBlockedForUrls,
+ CONTENT_SETTINGS_TYPE_IMAGES,
+ CONTENT_SETTING_BLOCK
+ }, {
+ prefs::kManagedJavaScriptAllowedForUrls,
+ CONTENT_SETTINGS_TYPE_JAVASCRIPT,
+ CONTENT_SETTING_ALLOW
+ }, {
+ prefs::kManagedJavaScriptBlockedForUrls,
+ CONTENT_SETTINGS_TYPE_JAVASCRIPT,
+ CONTENT_SETTING_BLOCK
+ }, {
+ prefs::kManagedPluginsAllowedForUrls,
+ CONTENT_SETTINGS_TYPE_PLUGINS,
+ CONTENT_SETTING_ALLOW
+ }, {
+ prefs::kManagedPluginsBlockedForUrls,
+ CONTENT_SETTINGS_TYPE_PLUGINS,
+ CONTENT_SETTING_BLOCK
+ }, {
+ prefs::kManagedPopupsAllowedForUrls,
+ CONTENT_SETTINGS_TYPE_POPUPS,
+ CONTENT_SETTING_ALLOW
+ }, {
+ prefs::kManagedPopupsBlockedForUrls,
+ CONTENT_SETTINGS_TYPE_POPUPS,
+ CONTENT_SETTING_BLOCK
+ }
+};
+
+const std::string NO_IDENTIFIER = "";
+
+} // namespace
+
+namespace content_settings {
+
+PolicyDefaultProvider::PolicyDefaultProvider(Profile* profile)
+ : profile_(profile),
+ is_off_the_record_(profile_->IsOffTheRecord()) {
+ PrefService* prefs = profile->GetPrefs();
+
+ // Read global defaults.
+ DCHECK_EQ(arraysize(kPrefToManageType),
+ static_cast<size_t>(CONTENT_SETTINGS_NUM_TYPES));
+ ReadManagedDefaultSettings();
+
+ pref_change_registrar_.Init(prefs);
+ // The following preferences are only used to indicate if a
+ // default-content-setting is managed and to hold the managed default-setting
+ // value. If the value for any of the following perferences is set then the
+ // corresponding default-content-setting is managed. These preferences exist
+ // in parallel to the preference default-content-settings. If a
+ // default-content-settings-type is managed any user defined excpetions
+ // (patterns) for this type are ignored.
+ pref_change_registrar_.Add(prefs::kManagedDefaultCookiesSetting, this);
+ pref_change_registrar_.Add(prefs::kManagedDefaultImagesSetting, this);
+ pref_change_registrar_.Add(prefs::kManagedDefaultJavaScriptSetting, this);
+ pref_change_registrar_.Add(prefs::kManagedDefaultPluginsSetting, this);
+ pref_change_registrar_.Add(prefs::kManagedDefaultPopupsSetting, this);
+ notification_registrar_.Add(this, NotificationType::PROFILE_DESTROYED,
+ Source<Profile>(profile_));
+}
+
+PolicyDefaultProvider::~PolicyDefaultProvider() {
+ UnregisterObservers();
+}
+
+ContentSetting PolicyDefaultProvider::ProvideDefaultSetting(
+ ContentSettingsType content_type) const {
+ base::AutoLock auto_lock(lock_);
+ return managed_default_content_settings_.settings[content_type];
+}
+
+void PolicyDefaultProvider::UpdateDefaultSetting(
+ ContentSettingsType content_type,
+ ContentSetting setting) {
+}
+
+bool PolicyDefaultProvider::DefaultSettingIsManaged(
+ ContentSettingsType content_type) const {
+ base::AutoLock lock(lock_);
+ if (managed_default_content_settings_.settings[content_type] !=
+ CONTENT_SETTING_DEFAULT) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+void PolicyDefaultProvider::ResetToDefaults() {
+}
+
+void PolicyDefaultProvider::Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ if (type == NotificationType::PREF_CHANGED) {
+ DCHECK_EQ(profile_->GetPrefs(), Source<PrefService>(source).ptr());
+ std::string* name = Details<std::string>(details).ptr();
+ if (*name == prefs::kManagedDefaultCookiesSetting) {
+ UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_COOKIES);
+ } else if (*name == prefs::kManagedDefaultImagesSetting) {
+ UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_IMAGES);
+ } else if (*name == prefs::kManagedDefaultJavaScriptSetting) {
+ UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_JAVASCRIPT);
+ } else if (*name == prefs::kManagedDefaultPluginsSetting) {
+ UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_PLUGINS);
+ } else if (*name == prefs::kManagedDefaultPopupsSetting) {
+ UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_POPUPS);
+ } else {
+ NOTREACHED() << "Unexpected preference observed";
+ return;
+ }
+
+ if (!is_off_the_record_) {
+ NotifyObservers(ContentSettingsDetails(
+ ContentSettingsPattern(), CONTENT_SETTINGS_TYPE_DEFAULT, ""));
+ }
+ } else if (type == NotificationType::PROFILE_DESTROYED) {
+ DCHECK_EQ(profile_, Source<Profile>(source).ptr());
+ UnregisterObservers();
+ } else {
+ NOTREACHED() << "Unexpected notification";
+ }
+}
+
+void PolicyDefaultProvider::UnregisterObservers() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ if (!profile_)
+ return;
+ pref_change_registrar_.RemoveAll();
+ notification_registrar_.Remove(this, NotificationType::PROFILE_DESTROYED,
+ Source<Profile>(profile_));
+ profile_ = NULL;
+}
+
+
+void PolicyDefaultProvider::NotifyObservers(
+ const ContentSettingsDetails& details) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ if (profile_ == NULL)
+ return;
+ NotificationService::current()->Notify(
+ NotificationType::CONTENT_SETTINGS_CHANGED,
+ Source<HostContentSettingsMap>(profile_->GetHostContentSettingsMap()),
+ Details<const ContentSettingsDetails>(&details));
+}
+
+void PolicyDefaultProvider::ReadManagedDefaultSettings() {
+ for (size_t type = 0; type < arraysize(kPrefToManageType); ++type) {
+ if (kPrefToManageType[type] == NULL) {
+ continue;
+ }
+ UpdateManagedDefaultSetting(ContentSettingsType(type));
+ }
+}
+
+void PolicyDefaultProvider::UpdateManagedDefaultSetting(
+ ContentSettingsType type) {
+ // 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
+ // preference to manage a default-content-settings is CONTENT_SETTING_DEFAULT.
+ // This indicates that no managed value is set. If a pref was set, than it
+ // MUST be managed.
+ PrefService* prefs = profile_->GetPrefs();
+ DCHECK(!prefs->HasPrefPath(kPrefToManageType[type]) ||
+ prefs->IsManagedPreference(kPrefToManageType[type]));
+ base::AutoLock auto_lock(lock_);
+ managed_default_content_settings_.settings[type] = IntToContentSetting(
+ prefs->GetInteger(kPrefToManageType[type]));
+}
+
+// static
+void PolicyDefaultProvider::RegisterUserPrefs(PrefService* prefs) {
+ // Preferences for default content setting policies. A policy is not set of
+ // the corresponding preferences below is set to CONTENT_SETTING_DEFAULT.
+ prefs->RegisterIntegerPref(prefs::kManagedDefaultCookiesSetting,
+ CONTENT_SETTING_DEFAULT);
+ prefs->RegisterIntegerPref(prefs::kManagedDefaultImagesSetting,
+ CONTENT_SETTING_DEFAULT);
+ prefs->RegisterIntegerPref(prefs::kManagedDefaultJavaScriptSetting,
+ CONTENT_SETTING_DEFAULT);
+ prefs->RegisterIntegerPref(prefs::kManagedDefaultPluginsSetting,
+ CONTENT_SETTING_DEFAULT);
+ prefs->RegisterIntegerPref(prefs::kManagedDefaultPopupsSetting,
+ CONTENT_SETTING_DEFAULT);
+}
+
+// ////////////////////////////////////////////////////////////////////////////
+// PolicyProvider
+
+// static
+void PolicyProvider::RegisterUserPrefs(PrefService* prefs) {
+ prefs->RegisterListPref(prefs::kManagedCookiesAllowedForUrls);
+ prefs->RegisterListPref(prefs::kManagedCookiesBlockedForUrls);
+ prefs->RegisterListPref(prefs::kManagedCookiesSessionOnlyForUrls);
+ prefs->RegisterListPref(prefs::kManagedImagesAllowedForUrls);
+ prefs->RegisterListPref(prefs::kManagedImagesBlockedForUrls);
+ prefs->RegisterListPref(prefs::kManagedJavaScriptAllowedForUrls);
+ prefs->RegisterListPref(prefs::kManagedJavaScriptBlockedForUrls);
+ prefs->RegisterListPref(prefs::kManagedPluginsAllowedForUrls);
+ prefs->RegisterListPref(prefs::kManagedPluginsBlockedForUrls);
+ prefs->RegisterListPref(prefs::kManagedPopupsAllowedForUrls);
+ prefs->RegisterListPref(prefs::kManagedPopupsBlockedForUrls);
+}
+
+PolicyProvider::PolicyProvider(Profile* profile)
+ : BaseProvider(profile->IsOffTheRecord()),
+ profile_(profile) {
+ Init();
+}
+
+PolicyProvider::~PolicyProvider() {
+ UnregisterObservers();
+}
+
+void PolicyProvider::ReadManagedContentSettingsTypes(
+ ContentSettingsType content_type) {
+ PrefService* prefs = profile_->GetPrefs();
+ if (kPrefToManageType[content_type] == NULL) {
+ content_type_is_managed_[content_type] = false;
+ } else {
+ content_type_is_managed_[content_type] =
+ prefs->IsManagedPreference(kPrefToManageType[content_type]);
+ }
+}
+
+void PolicyProvider::Init() {
+ PrefService* prefs = profile_->GetPrefs();
+
+ ReadManagedContentSettings(false);
+ for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i)
+ ReadManagedContentSettingsTypes(ContentSettingsType(i));
+
+ pref_change_registrar_.Init(prefs);
+ pref_change_registrar_.Add(prefs::kManagedCookiesBlockedForUrls, this);
+ pref_change_registrar_.Add(prefs::kManagedCookiesAllowedForUrls, this);
+ pref_change_registrar_.Add(prefs::kManagedCookiesSessionOnlyForUrls, this);
+ pref_change_registrar_.Add(prefs::kManagedImagesBlockedForUrls, this);
+ pref_change_registrar_.Add(prefs::kManagedImagesAllowedForUrls, this);
+ pref_change_registrar_.Add(prefs::kManagedJavaScriptBlockedForUrls, this);
+ pref_change_registrar_.Add(prefs::kManagedJavaScriptAllowedForUrls, this);
+ pref_change_registrar_.Add(prefs::kManagedPluginsBlockedForUrls, this);
+ pref_change_registrar_.Add(prefs::kManagedPluginsAllowedForUrls, this);
+ pref_change_registrar_.Add(prefs::kManagedPopupsBlockedForUrls, this);
+ pref_change_registrar_.Add(prefs::kManagedPopupsAllowedForUrls, this);
+
+ pref_change_registrar_.Add(prefs::kManagedDefaultCookiesSetting, this);
+ pref_change_registrar_.Add(prefs::kManagedDefaultImagesSetting, this);
+ pref_change_registrar_.Add(prefs::kManagedDefaultJavaScriptSetting, this);
+ pref_change_registrar_.Add(prefs::kManagedDefaultPluginsSetting, this);
+ pref_change_registrar_.Add(prefs::kManagedDefaultPopupsSetting, this);
+
+ notification_registrar_.Add(this, NotificationType::PROFILE_DESTROYED,
+ Source<Profile>(profile_));
+}
+
+bool PolicyProvider::ContentSettingsTypeIsManaged(
+ ContentSettingsType content_type) {
+ return content_type_is_managed_[content_type];
+}
+
+void PolicyProvider::GetContentSettingsFromPreferences(
+ PrefService* prefs,
+ ContentSettingsRules* rules) {
+ for (size_t i = 0; i < arraysize(kPrefsForManagedContentSettingsMap); ++i) {
+ const char* pref_name = kPrefsForManagedContentSettingsMap[i].pref_name;
+ // Skip unset policies.
+ if (!prefs->HasPrefPath(pref_name)) {
+ VLOG(2) << "Skipping unset preference: " << pref_name;
+ continue;
+ }
+
+ const PrefService::Preference* pref = prefs->FindPreference(pref_name);
+ DCHECK(pref->IsManaged());
+ DCHECK_EQ(Value::TYPE_LIST, pref->GetType());
+
+ const ListValue* pattern_str_list =
+ static_cast<const ListValue*>(pref->GetValue());
+ for (size_t j = 0; j < pattern_str_list->GetSize(); ++j) {
+ std::string original_pattern_str;
+ pattern_str_list->GetString(j, &original_pattern_str);
+ ContentSettingsPattern pattern(original_pattern_str);
+ // Ignore invalid patterns.
+ if (!pattern.IsValid()) {
+ VLOG(1) << "Ignoring invalid content settings pattern: " <<
+ pattern.AsString();
+ continue;
+ }
+ rules->push_back(MakeTuple(
+ pattern,
+ pattern,
+ kPrefsForManagedContentSettingsMap[i].content_type,
+ NO_IDENTIFIER,
+ kPrefsForManagedContentSettingsMap[i].setting));
+ }
+ }
+}
+
+void PolicyProvider::ReadManagedContentSettings(bool overwrite) {
+ ContentSettingsRules rules;
+ PrefService* prefs = profile_->GetPrefs();
+ GetContentSettingsFromPreferences(prefs, &rules);
+ {
+ base::AutoLock auto_lock(lock());
+ HostContentSettings* content_settings_map = host_content_settings();
+ if (overwrite)
+ content_settings_map->clear();
+ for (ContentSettingsRules::iterator rule = rules.begin();
+ rule != rules.end();
+ ++rule) {
+ DispatchToMethod(this, &PolicyProvider::UpdateContentSettingsMap, *rule);
+ }
+ }
+}
+
+// Since the PolicyProvider is a read only content settings provider, all
+// methodes of the ProviderInterface that set or delete any settings do nothing.
+void PolicyProvider::SetContentSetting(
+ const ContentSettingsPattern& requesting_pattern,
+ const ContentSettingsPattern& embedding_pattern,
+ ContentSettingsType content_type,
+ const ResourceIdentifier& resource_identifier,
+ ContentSetting content_setting) {
+}
+
+ContentSetting PolicyProvider::GetContentSetting(
+ const GURL& requesting_url,
+ const GURL& embedding_url,
+ ContentSettingsType content_type,
+ const ResourceIdentifier& resource_identifier) const {
+ return BaseProvider::GetContentSetting(
+ requesting_url,
+ embedding_url,
+ content_type,
+ NO_IDENTIFIER);
+}
+
+void PolicyProvider::ClearAllContentSettingsRules(
+ ContentSettingsType content_type) {
+}
+
+void PolicyProvider::ResetToDefaults() {
+}
+
+void PolicyProvider::UnregisterObservers() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ if (!profile_)
+ return;
+ pref_change_registrar_.RemoveAll();
+ notification_registrar_.Remove(this, NotificationType::PROFILE_DESTROYED,
+ Source<Profile>(profile_));
+ profile_ = NULL;
+}
+
+void PolicyProvider::NotifyObservers(
+ const ContentSettingsDetails& details) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ if (profile_ == NULL)
+ return;
+ NotificationService::current()->Notify(
+ NotificationType::CONTENT_SETTINGS_CHANGED,
+ Source<HostContentSettingsMap>(profile_->GetHostContentSettingsMap()),
+ Details<const ContentSettingsDetails>(&details));
+}
+
+void PolicyProvider::Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ if (type == NotificationType::PREF_CHANGED) {
+ DCHECK_EQ(profile_->GetPrefs(), Source<PrefService>(source).ptr());
+ std::string* name = Details<std::string>(details).ptr();
+ if (*name == prefs::kManagedCookiesAllowedForUrls ||
+ *name == prefs::kManagedCookiesBlockedForUrls ||
+ *name == prefs::kManagedCookiesSessionOnlyForUrls ||
+ *name == prefs::kManagedImagesAllowedForUrls ||
+ *name == prefs::kManagedImagesBlockedForUrls ||
+ *name == prefs::kManagedJavaScriptAllowedForUrls ||
+ *name == prefs::kManagedJavaScriptBlockedForUrls ||
+ *name == prefs::kManagedPluginsAllowedForUrls ||
+ *name == prefs::kManagedPluginsBlockedForUrls ||
+ *name == prefs::kManagedPopupsAllowedForUrls ||
+ *name == prefs::kManagedPopupsBlockedForUrls) {
+ ReadManagedContentSettings(true);
+ NotifyObservers(ContentSettingsDetails(
+ ContentSettingsPattern(), CONTENT_SETTINGS_TYPE_DEFAULT, ""));
+ // We do not want to sent a notification when managed default content
+ // settings change. The DefaultProvider will take care of that. We are
+ // only a passive observer.
+ // TODO(markusheintz): NOTICE: This is still work in progress and part of
+ // a larger refactoring. The code will change and be much cleaner and
+ // clearer in the end.
+ } else if (*name == prefs::kManagedDefaultCookiesSetting) {
+ ReadManagedContentSettingsTypes(CONTENT_SETTINGS_TYPE_COOKIES);
+ } else if (*name == prefs::kManagedDefaultImagesSetting) {
+ ReadManagedContentSettingsTypes(CONTENT_SETTINGS_TYPE_IMAGES);
+ } else if (*name == prefs::kManagedDefaultJavaScriptSetting) {
+ ReadManagedContentSettingsTypes(CONTENT_SETTINGS_TYPE_JAVASCRIPT);
+ } else if (*name == prefs::kManagedDefaultPluginsSetting) {
+ ReadManagedContentSettingsTypes(CONTENT_SETTINGS_TYPE_PLUGINS);
+ } else if (*name == prefs::kManagedDefaultPopupsSetting) {
+ ReadManagedContentSettingsTypes(CONTENT_SETTINGS_TYPE_POPUPS);
+ }
+ } else if (type == NotificationType::PROFILE_DESTROYED) {
+ DCHECK_EQ(profile_, Source<Profile>(source).ptr());
+ UnregisterObservers();
+ } else {
+ NOTREACHED() << "Unexpected notification";
+ }
+}
+
+} // namespace content_settings
diff --git a/chrome/browser/content_settings/policy_content_settings_provider.h b/chrome/browser/content_settings/content_settings_policy_provider.h
index b63e19b..96dd115 100644
--- a/chrome/browser/content_settings/policy_content_settings_provider.h
+++ b/chrome/browser/content_settings/content_settings_policy_provider.h
@@ -2,15 +2,19 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CHROME_BROWSER_CONTENT_SETTINGS_POLICY_CONTENT_SETTINGS_PROVIDER_H_
-#define CHROME_BROWSER_CONTENT_SETTINGS_POLICY_CONTENT_SETTINGS_PROVIDER_H_
+#ifndef CHROME_BROWSER_CONTENT_SETTINGS_CONTENT_SETTINGS_POLICY_PROVIDER_H_
+#define CHROME_BROWSER_CONTENT_SETTINGS_CONTENT_SETTINGS_POLICY_PROVIDER_H_
#pragma once
// A content settings provider that takes its settings out of policies.
+#include <vector>
+
#include "base/basictypes.h"
#include "base/synchronization/lock.h"
+#include "base/tuple.h"
#include "chrome/browser/content_settings/content_settings_provider.h"
+#include "chrome/browser/content_settings/content_settings_base_provider.h"
#include "chrome/browser/prefs/pref_change_registrar.h"
#include "chrome/common/notification_observer.h"
#include "chrome/common/notification_registrar.h"
@@ -76,6 +80,75 @@ class PolicyDefaultProvider : public DefaultProviderInterface,
DISALLOW_COPY_AND_ASSIGN(PolicyDefaultProvider);
};
+// PolicyProvider that provider managed content-settings.
+class PolicyProvider : public BaseProvider,
+ public NotificationObserver {
+ public:
+ explicit PolicyProvider(Profile* profile);
+ ~PolicyProvider();
+ static void RegisterUserPrefs(PrefService* prefs);
+
+ // BaseProvider Implementation
+ virtual void Init();
+
+ // ProviderInterface Implementation
+ virtual bool ContentSettingsTypeIsManaged(
+ ContentSettingsType content_type);
+
+ virtual void SetContentSetting(
+ const ContentSettingsPattern& requesting_pattern,
+ const ContentSettingsPattern& embedding_pattern,
+ ContentSettingsType content_type,
+ const ResourceIdentifier& resource_identifier,
+ ContentSetting content_setting);
+
+ virtual ContentSetting GetContentSetting(
+ const GURL& requesting_url,
+ const GURL& embedding_url,
+ ContentSettingsType content_type,
+ const ResourceIdentifier& resource_identifier) const;
+
+ virtual void ClearAllContentSettingsRules(
+ ContentSettingsType content_type);
+
+ virtual void ResetToDefaults();
+
+ // NotificationObserver implementation.
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
+ private:
+ typedef Tuple5<
+ ContentSettingsPattern,
+ ContentSettingsPattern,
+ ContentSettingsType,
+ content_settings::ProviderInterface::ResourceIdentifier,
+ ContentSetting> ContentSettingsRule;
+
+ typedef std::vector<ContentSettingsRule> ContentSettingsRules;
+
+ void ReadManagedContentSettings(bool overwrite);
+
+ void GetContentSettingsFromPreferences(PrefService* prefs,
+ ContentSettingsRules* rules);
+
+ void ReadManagedContentSettingsTypes(
+ ContentSettingsType content_type);
+
+ void NotifyObservers(const ContentSettingsDetails& details);
+
+ void UnregisterObservers();
+
+ Profile* profile_;
+
+ bool content_type_is_managed_[CONTENT_SETTINGS_NUM_TYPES];
+
+ PrefChangeRegistrar pref_change_registrar_;
+ NotificationRegistrar notification_registrar_;
+
+ DISALLOW_COPY_AND_ASSIGN(PolicyProvider);
+};
+
} // namespace content_settings
-#endif // CHROME_BROWSER_CONTENT_SETTINGS_POLICY_CONTENT_SETTINGS_PROVIDER_H_
+#endif // CHROME_BROWSER_CONTENT_SETTINGS_CONTENT_SETTINGS_POLICY_PROVIDER_H_
diff --git a/chrome/browser/content_settings/content_settings_policy_provider_unittest.cc b/chrome/browser/content_settings/content_settings_policy_provider_unittest.cc
new file mode 100644
index 0000000..1d1053c
--- /dev/null
+++ b/chrome/browser/content_settings/content_settings_policy_provider_unittest.cc
@@ -0,0 +1,185 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/content_settings/content_settings_policy_provider.h"
+
+#include "base/auto_reset.h"
+#include "base/command_line.h"
+#include "chrome/browser/content_settings/stub_settings_observer.h"
+#include "chrome/browser/prefs/pref_service.h"
+#include "chrome/common/chrome_switches.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/common/url_constants.h"
+#include "chrome/test/testing_browser_process_test.h"
+#include "chrome/test/testing_pref_service.h"
+#include "chrome/test/testing_profile.h"
+#include "content/browser/browser_thread.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "googleurl/src/gurl.h"
+
+namespace content_settings {
+
+class PolicyDefaultProviderTest : public TestingBrowserProcessTest {
+ public:
+ PolicyDefaultProviderTest()
+ : ui_thread_(BrowserThread::UI, &message_loop_) {
+ }
+
+ protected:
+ MessageLoop message_loop_;
+ BrowserThread ui_thread_;
+};
+
+TEST_F(PolicyDefaultProviderTest, DefaultValues) {
+ TestingProfile profile;
+ PolicyDefaultProvider provider(&profile);
+ TestingPrefService* prefs = profile.GetTestingPrefService();
+
+ // By default, policies should be off.
+ ASSERT_FALSE(
+ provider.DefaultSettingIsManaged(CONTENT_SETTINGS_TYPE_COOKIES));
+
+ // Set managed-default-content-setting through the coresponding preferences.
+ prefs->SetManagedPref(prefs::kManagedDefaultCookiesSetting,
+ Value::CreateIntegerValue(CONTENT_SETTING_BLOCK));
+ ASSERT_TRUE(
+ provider.DefaultSettingIsManaged(CONTENT_SETTINGS_TYPE_COOKIES));
+ ASSERT_EQ(CONTENT_SETTING_BLOCK,
+ provider.ProvideDefaultSetting(CONTENT_SETTINGS_TYPE_COOKIES));
+
+ // Remove managed-default-content-settings-preferences.
+ prefs->RemoveManagedPref(prefs::kManagedDefaultCookiesSetting);
+ ASSERT_FALSE(
+ provider.DefaultSettingIsManaged(CONTENT_SETTINGS_TYPE_COOKIES));
+}
+
+// When a default-content-setting is set to a managed setting a
+// CONTENT_SETTINGS_CHANGED notification should be fired. The same should happen
+// if the managed setting is removed.
+TEST_F(PolicyDefaultProviderTest, ObserveManagedSettingsChange) {
+ TestingProfile profile;
+ StubSettingsObserver observer;
+ // Make sure the content settings map exists.
+ profile.GetHostContentSettingsMap();
+ TestingPrefService* prefs = profile.GetTestingPrefService();
+
+ // Set the managed default-content-setting.
+ prefs->SetManagedPref(prefs::kManagedDefaultImagesSetting,
+ Value::CreateIntegerValue(CONTENT_SETTING_BLOCK));
+ EXPECT_EQ(profile.GetHostContentSettingsMap(), observer.last_notifier);
+ EXPECT_EQ(ContentSettingsPattern(), observer.last_pattern);
+ EXPECT_EQ(CONTENT_SETTINGS_TYPE_DEFAULT, observer.last_type);
+ EXPECT_TRUE(observer.last_update_all);
+ EXPECT_TRUE(observer.last_update_all_types);
+ EXPECT_EQ(1, observer.counter);
+
+ // Remove the managed default-content-setting.
+ prefs->RemoveManagedPref(prefs::kManagedDefaultImagesSetting);
+ EXPECT_EQ(profile.GetHostContentSettingsMap(), observer.last_notifier);
+ EXPECT_EQ(CONTENT_SETTINGS_TYPE_DEFAULT, observer.last_type);
+ EXPECT_EQ(ContentSettingsPattern(), observer.last_pattern);
+ EXPECT_TRUE(observer.last_update_all);
+ EXPECT_TRUE(observer.last_update_all_types);
+ EXPECT_EQ(2, observer.counter);
+}
+
+class PolicyProviderTest : public testing::Test {
+ public:
+ PolicyProviderTest()
+ : ui_thread_(BrowserThread::UI, &message_loop_) {
+ }
+
+ protected:
+ // TODO(markusheintz): Check if it's possible to derive the provider class
+ // from NonThreadSafe and to use native thread identifiers instead of
+ // BrowserThread IDs. Then we could get rid of the message_loop and ui_thread
+ // fields.
+ MessageLoop message_loop_;
+ BrowserThread ui_thread_;
+};
+
+TEST_F(PolicyProviderTest, Default) {
+ TestingProfile profile;
+ TestingPrefService* prefs = profile.GetTestingPrefService();
+
+ ListValue* value = new ListValue();
+ value->Append(Value::CreateStringValue("[*.]google.com"));
+ prefs->SetManagedPref(prefs::kManagedImagesBlockedForUrls,
+ value);
+
+ PolicyProvider provider(static_cast<Profile*>(&profile));
+
+ ContentSettingsPattern yt_url_pattern("www.youtube.com");
+ GURL youtube_url("http://www.youtube.com");
+ GURL google_url("http://mail.google.com");
+
+ EXPECT_EQ(CONTENT_SETTING_DEFAULT,
+ provider.GetContentSetting(
+ youtube_url, youtube_url, CONTENT_SETTINGS_TYPE_COOKIES, ""));
+ EXPECT_EQ(CONTENT_SETTING_BLOCK,
+ provider.GetContentSetting(
+ google_url, google_url, CONTENT_SETTINGS_TYPE_IMAGES, ""));
+
+ provider.SetContentSetting(
+ yt_url_pattern,
+ yt_url_pattern,
+ CONTENT_SETTINGS_TYPE_COOKIES,
+ "",
+ CONTENT_SETTING_BLOCK);
+ EXPECT_EQ(CONTENT_SETTING_DEFAULT,
+ provider.GetContentSetting(
+ youtube_url, youtube_url, CONTENT_SETTINGS_TYPE_COOKIES, ""));
+}
+
+TEST_F(PolicyProviderTest, ResourceIdentifier) {
+ CommandLine* cmd = CommandLine::ForCurrentProcess();
+ AutoReset<CommandLine> auto_reset(cmd, *cmd);
+ cmd->AppendSwitch(switches::kEnableResourceContentSettings);
+
+ TestingProfile profile;
+ TestingPrefService* prefs = profile.GetTestingPrefService();
+
+ ListValue* value = new ListValue();
+ value->Append(Value::CreateStringValue("[*.]google.com"));
+ prefs->SetManagedPref(prefs::kManagedPluginsAllowedForUrls,
+ value);
+
+ PolicyProvider provider(static_cast<Profile*>(&profile));
+
+ GURL youtube_url("http://www.youtube.com");
+ GURL google_url("http://mail.google.com");
+
+ EXPECT_EQ(CONTENT_SETTING_DEFAULT,
+ provider.GetContentSetting(
+ youtube_url,
+ youtube_url,
+ CONTENT_SETTINGS_TYPE_PLUGINS,
+ "someplugin"));
+
+ // There is no policy support for resource content settings until the feature
+ // is enabled by default. Resource identifiers are simply ignored by the
+ // PolicyProvider.
+ EXPECT_EQ(CONTENT_SETTING_ALLOW,
+ provider.GetContentSetting(
+ google_url,
+ google_url,
+ CONTENT_SETTINGS_TYPE_PLUGINS,
+ ""));
+
+ EXPECT_EQ(CONTENT_SETTING_ALLOW,
+ provider.GetContentSetting(
+ google_url,
+ google_url,
+ CONTENT_SETTINGS_TYPE_PLUGINS,
+ "someplugin"));
+
+ EXPECT_EQ(CONTENT_SETTING_ALLOW,
+ provider.GetContentSetting(
+ google_url,
+ google_url,
+ CONTENT_SETTINGS_TYPE_PLUGINS,
+ "anotherplugin"));
+}
+
+} // namespace content_settings
diff --git a/chrome/browser/content_settings/pref_content_settings_provider.cc b/chrome/browser/content_settings/content_settings_pref_provider.cc
index bb6360e..aee1513 100644
--- a/chrome/browser/content_settings/pref_content_settings_provider.cc
+++ b/chrome/browser/content_settings/content_settings_pref_provider.cc
@@ -2,18 +2,17 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "chrome/browser/content_settings/pref_content_settings_provider.h"
+#include "chrome/browser/content_settings/content_settings_pref_provider.h"
#include <string>
#include <vector>
#include <utility>
#include "base/command_line.h"
-#include "chrome/browser/browser_thread.h"
#include "chrome/browser/content_settings/content_settings_details.h"
#include "chrome/browser/content_settings/content_settings_pattern.h"
#include "chrome/browser/prefs/pref_service.h"
-#include "chrome/browser/prefs/scoped_pref_update.h"
+#include "chrome/browser/prefs/scoped_user_pref_update.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/content_settings.h"
@@ -21,6 +20,7 @@
#include "chrome/common/notification_service.h"
#include "chrome/common/notification_source.h"
#include "chrome/common/pref_names.h"
+#include "content/browser/browser_thread.h"
#include "googleurl/src/gurl.h"
#include "net/base/net_util.h"
@@ -28,7 +28,7 @@ namespace {
// The preference keys where resource identifiers are stored for
// ContentSettingsType values that support resource identifiers.
-const char* kResourceTypeNames[CONTENT_SETTINGS_NUM_TYPES] = {
+const char* kResourceTypeNames[] = {
NULL,
NULL,
NULL,
@@ -36,10 +36,13 @@ const char* kResourceTypeNames[CONTENT_SETTINGS_NUM_TYPES] = {
NULL,
NULL, // Not used for Geolocation
NULL, // Not used for Notifications
+ NULL, // Not used for Prerender.
};
+COMPILE_ASSERT(arraysize(kResourceTypeNames) == CONTENT_SETTINGS_NUM_TYPES,
+ resource_type_names_incorrect_size);
// The default setting for each content type.
-const ContentSetting kDefaultSettings[CONTENT_SETTINGS_NUM_TYPES] = {
+const ContentSetting kDefaultSettings[] = {
CONTENT_SETTING_ALLOW, // CONTENT_SETTINGS_TYPE_COOKIES
CONTENT_SETTING_ALLOW, // CONTENT_SETTINGS_TYPE_IMAGES
CONTENT_SETTING_ALLOW, // CONTENT_SETTINGS_TYPE_JAVASCRIPT
@@ -47,10 +50,13 @@ const ContentSetting kDefaultSettings[CONTENT_SETTINGS_NUM_TYPES] = {
CONTENT_SETTING_BLOCK, // CONTENT_SETTINGS_TYPE_POPUPS
CONTENT_SETTING_ASK, // Not used for Geolocation
CONTENT_SETTING_ASK, // Not used for Notifications
+ CONTENT_SETTING_ALLOW, // CONTENT_SETTINGS_TYPE_PRERENDER
};
+COMPILE_ASSERT(arraysize(kDefaultSettings) == CONTENT_SETTINGS_NUM_TYPES,
+ default_settings_incorrect_size);
// The names of the ContentSettingsType values, for use with dictionary prefs.
-const char* kTypeNames[CONTENT_SETTINGS_NUM_TYPES] = {
+const char* kTypeNames[] = {
"cookies",
"images",
"javascript",
@@ -58,42 +64,15 @@ const char* kTypeNames[CONTENT_SETTINGS_NUM_TYPES] = {
"popups",
NULL, // Not used for Geolocation
NULL, // Not used for Notifications
+ NULL, // Not used for Prerender
};
-
-// True if a given content settings type requires additional resource
-// identifiers.
-const bool kRequiresResourceIdentifier[CONTENT_SETTINGS_NUM_TYPES] = {
- false, // CONTENT_SETTINGS_TYPE_COOKIES
- false, // CONTENT_SETTINGS_TYPE_IMAGES
- false, // CONTET_SETTINGS_TYPE_JAVASCRIPT
- true, // CONTENT_SETTINGS_TYPE_PLUGINS
- false, // CONTENT_SETTINGS_TYPE_POPUPS
- false, // Not used for Geolocation
- false, // Not used for Notifications
-};
-
-// Map ASK for the plugins content type to BLOCK if click-to-play is
-// not enabled.
-ContentSetting ClickToPlayFixup(ContentSettingsType content_type,
- ContentSetting setting) {
- if (setting == CONTENT_SETTING_ASK &&
- content_type == CONTENT_SETTINGS_TYPE_PLUGINS &&
- !CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableClickToPlay)) {
- return CONTENT_SETTING_BLOCK;
- }
- return setting;
-}
+COMPILE_ASSERT(arraysize(kTypeNames) == CONTENT_SETTINGS_NUM_TYPES,
+ type_names_incorrect_size);
} // namespace
namespace content_settings {
-struct PrefProvider::ExtendedContentSettings {
- ContentSettings content_settings;
- ResourceContentSettings content_settings_for_resources;
-};
-
PrefDefaultProvider::PrefDefaultProvider(Profile* profile)
: profile_(profile),
is_off_the_record_(profile_->IsOffTheRecord()),
@@ -144,7 +123,7 @@ void PrefDefaultProvider::UpdateDefaultSetting(
updating_preferences_ = true;
{
base::AutoLock lock(lock_);
- ScopedPrefUpdate update(prefs, prefs::kDefaultContentSettings);
+ ScopedUserPrefUpdate update(prefs, prefs::kDefaultContentSettings);
if ((setting == CONTENT_SETTING_DEFAULT) ||
(setting == kDefaultSettings[content_type])) {
default_content_settings_.settings[content_type] =
@@ -273,8 +252,9 @@ void PrefDefaultProvider::GetSettingsFromDictionary(
settings->settings[CONTENT_SETTINGS_TYPE_COOKIES] = CONTENT_SETTING_BLOCK;
settings->settings[CONTENT_SETTINGS_TYPE_PLUGINS] =
- ClickToPlayFixup(CONTENT_SETTINGS_TYPE_PLUGINS,
- settings->settings[CONTENT_SETTINGS_TYPE_PLUGINS]);
+ BaseProvider::ClickToPlayFixup(
+ CONTENT_SETTINGS_TYPE_PLUGINS,
+ settings->settings[CONTENT_SETTINGS_TYPE_PLUGINS]);
}
void PrefDefaultProvider::NotifyObservers(
@@ -288,14 +268,13 @@ void PrefDefaultProvider::NotifyObservers(
Details<const ContentSettingsDetails>(&details));
}
-
// static
void PrefDefaultProvider::RegisterUserPrefs(PrefService* prefs) {
prefs->RegisterDictionaryPref(prefs::kDefaultContentSettings);
}
// ////////////////////////////////////////////////////////////////////////////
-// PrefProvider::
+// PrefProvider:
//
// static
@@ -310,9 +289,13 @@ void PrefProvider::RegisterUserPrefs(PrefService* prefs) {
}
PrefProvider::PrefProvider(Profile* profile)
- : profile_(profile),
- is_off_the_record_(profile_->IsOffTheRecord()),
+ : BaseProvider(profile->IsOffTheRecord()),
+ profile_(profile),
updating_preferences_(false) {
+ Init();
+}
+
+void PrefProvider::Init() {
initializing_ = true;
PrefService* prefs = profile_->GetPrefs();
@@ -347,81 +330,6 @@ bool PrefProvider::ContentSettingsTypeIsManaged(
return false;
}
-ContentSetting PrefProvider::GetContentSetting(
- const GURL& requesting_url,
- const GURL& embedding_url,
- ContentSettingsType content_type,
- const ResourceIdentifier& resource_identifier) const {
- // Support for embedding_patterns is not implemented yet.
- DCHECK(requesting_url == embedding_url);
-
- if (!RequiresResourceIdentifier(content_type))
- return GetNonDefaultContentSettings(requesting_url).settings[content_type];
-
- if (RequiresResourceIdentifier(content_type) && resource_identifier.empty())
- return CONTENT_SETTING_DEFAULT;
-
- if (CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableResourceContentSettings)) {
- DCHECK(!resource_identifier.empty());
- }
-
- base::AutoLock auto_lock(lock_);
-
- const std::string host(net::GetHostOrSpecFromURL(requesting_url));
- ContentSettingsTypeResourceIdentifierPair
- requested_setting(content_type, resource_identifier);
-
- // Check for exact matches first.
- HostContentSettings::const_iterator i(host_content_settings_.find(host));
- if (i != host_content_settings_.end() &&
- i->second.content_settings_for_resources.find(requested_setting) !=
- i->second.content_settings_for_resources.end()) {
- return i->second.content_settings_for_resources.find(
- requested_setting)->second;
- }
-
- // If this map is not for an off-the-record profile, these searches will never
- // match. The additional off-the-record exceptions always overwrite the
- // regular ones.
- i = off_the_record_settings_.find(host);
- if (i != off_the_record_settings_.end() &&
- i->second.content_settings_for_resources.find(requested_setting) !=
- i->second.content_settings_for_resources.end()) {
- return i->second.content_settings_for_resources.find(
- requested_setting)->second;
- }
-
- // Match patterns starting with the most concrete pattern match.
- for (std::string key =
- std::string(ContentSettingsPattern::kDomainWildcard) + host; ; ) {
- HostContentSettings::const_iterator i(off_the_record_settings_.find(key));
- if (i != off_the_record_settings_.end() &&
- i->second.content_settings_for_resources.find(requested_setting) !=
- i->second.content_settings_for_resources.end()) {
- return i->second.content_settings_for_resources.find(
- requested_setting)->second;
- }
-
- i = host_content_settings_.find(key);
- if (i != host_content_settings_.end() &&
- i->second.content_settings_for_resources.find(requested_setting) !=
- i->second.content_settings_for_resources.end()) {
- return i->second.content_settings_for_resources.find(
- requested_setting)->second;
- }
-
- const size_t next_dot =
- key.find('.', ContentSettingsPattern::kDomainWildcardLength);
- if (next_dot == std::string::npos)
- break;
- key.erase(ContentSettingsPattern::kDomainWildcardLength,
- next_dot - ContentSettingsPattern::kDomainWildcardLength + 1);
- }
-
- return CONTENT_SETTING_DEFAULT;
-}
-
void PrefProvider::SetContentSetting(
const ContentSettingsPattern& requesting_pattern,
const ContentSettingsPattern& embedding_pattern,
@@ -447,16 +355,20 @@ void PrefProvider::SetContentSetting(
std::string pattern_str(pattern.AsString());
PrefService* prefs = NULL;
DictionaryValue* all_settings_dictionary = NULL;
- HostContentSettings* map_to_modify = &off_the_record_settings_;
- if (!is_off_the_record_) {
+
+ // Select content-settings-map to write to.
+ HostContentSettings* map_to_modify = off_the_record_settings();
+ if (!is_off_the_record()) {
prefs = profile_->GetPrefs();
all_settings_dictionary =
prefs->GetMutableDictionary(prefs::kContentSettingsPatterns);
- map_to_modify = &host_content_settings_;
+
+ map_to_modify = host_content_settings();
}
+ // Update content-settings-map.
{
- base::AutoLock auto_lock(lock_);
+ base::AutoLock auto_lock(lock());
if (!map_to_modify->count(pattern_str))
(*map_to_modify)[pattern_str].content_settings = ContentSettings();
HostContentSettings::iterator i(
@@ -482,11 +394,12 @@ void PrefProvider::SetContentSetting(
all_settings_dictionary->RemoveWithoutPathExpansion(pattern_str, NULL);
// We can't just return because |NotifyObservers()| needs to be called,
- // without |lock_| being held.
+ // without lock() being held.
early_exit = true;
}
}
+ // Update the content_settings preference.
if (!early_exit && all_settings_dictionary) {
DictionaryValue* host_settings_dictionary = NULL;
bool found = all_settings_dictionary->GetDictionaryWithoutPathExpansion(
@@ -526,62 +439,23 @@ void PrefProvider::SetContentSetting(
}
updating_preferences_ = true;
- if (!is_off_the_record_)
- ScopedPrefUpdate update(prefs, prefs::kContentSettingsPatterns);
+ if (!is_off_the_record())
+ ScopedUserPrefUpdate update(prefs, prefs::kContentSettingsPatterns);
updating_preferences_ = false;
NotifyObservers(ContentSettingsDetails(pattern, content_type, ""));
}
-void PrefProvider::GetAllContentSettingsRules(
- ContentSettingsType content_type,
- const ResourceIdentifier& resource_identifier,
- Rules* content_setting_rules) const {
- DCHECK(RequiresResourceIdentifier(content_type) !=
- resource_identifier.empty());
- DCHECK(content_setting_rules);
- content_setting_rules->clear();
-
- const HostContentSettings* map_to_return =
- is_off_the_record_ ? &off_the_record_settings_ : &host_content_settings_;
- ContentSettingsTypeResourceIdentifierPair requested_setting(
- content_type, resource_identifier);
-
- base::AutoLock auto_lock(lock_);
- for (HostContentSettings::const_iterator i(map_to_return->begin());
- i != map_to_return->end(); ++i) {
- ContentSetting setting;
- if (RequiresResourceIdentifier(content_type)) {
- if (i->second.content_settings_for_resources.find(requested_setting) !=
- i->second.content_settings_for_resources.end()) {
- setting = i->second.content_settings_for_resources.find(
- requested_setting)->second;
- } else {
- setting = CONTENT_SETTING_DEFAULT;
- }
- } else {
- setting = i->second.content_settings.settings[content_type];
- }
- if (setting != CONTENT_SETTING_DEFAULT) {
- // Use of push_back() relies on the map iterator traversing in order of
- // ascending keys.
- content_setting_rules->push_back(Rule(ContentSettingsPattern(i->first),
- ContentSettingsPattern(i->first),
- setting));
- }
- }
-}
-
void PrefProvider::ResetToDefaults() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
{
- base::AutoLock auto_lock(lock_);
- host_content_settings_.clear();
- off_the_record_settings_.clear();
+ base::AutoLock auto_lock(lock());
+ host_content_settings()->clear();
+ off_the_record_settings()->clear();
}
- if (!is_off_the_record_) {
+ if (!is_off_the_record()) {
PrefService* prefs = profile_->GetPrefs();
updating_preferences_ = true;
prefs->ClearPref(prefs::kContentSettingsPatterns);
@@ -595,22 +469,22 @@ void PrefProvider::ClearAllContentSettingsRules(
PrefService* prefs = NULL;
DictionaryValue* all_settings_dictionary = NULL;
- HostContentSettings* map_to_modify = &off_the_record_settings_;
+ HostContentSettings* map_to_modify = off_the_record_settings();
- if (!is_off_the_record_) {
+ if (!is_off_the_record()) {
prefs = profile_->GetPrefs();
all_settings_dictionary =
prefs->GetMutableDictionary(prefs::kContentSettingsPatterns);
- map_to_modify = &host_content_settings_;
+ map_to_modify = host_content_settings();
}
{
- base::AutoLock auto_lock(lock_);
+ base::AutoLock auto_lock(lock());
for (HostContentSettings::iterator i(map_to_modify->begin());
i != map_to_modify->end(); ) {
if (RequiresResourceIdentifier(content_type) ||
i->second.content_settings.settings[content_type] !=
- CONTENT_SETTING_DEFAULT) {
+ CONTENT_SETTING_DEFAULT) {
if (RequiresResourceIdentifier(content_type))
i->second.content_settings_for_resources.clear();
i->second.content_settings.settings[content_type] =
@@ -637,8 +511,8 @@ void PrefProvider::ClearAllContentSettingsRules(
}
updating_preferences_ = true;
- if (!is_off_the_record_)
- ScopedPrefUpdate update(prefs, prefs::kContentSettingsPatterns);
+ if (!is_off_the_record())
+ ScopedUserPrefUpdate update(prefs, prefs::kContentSettingsPatterns);
updating_preferences_ = false;
NotifyObservers(
@@ -664,7 +538,7 @@ void PrefProvider::Observe(
return;
}
- if (!is_off_the_record_) {
+ if (!is_off_the_record()) {
NotifyObservers(ContentSettingsDetails(ContentSettingsPattern(),
CONTENT_SETTINGS_TYPE_DEFAULT,
""));
@@ -684,34 +558,15 @@ PrefProvider::~PrefProvider() {
// ////////////////////////////////////////////////////////////////////////////
// Private
-bool PrefProvider::RequiresResourceIdentifier(
- ContentSettingsType content_type) const {
- if (CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableResourceContentSettings)) {
- return kRequiresResourceIdentifier[content_type];
- } else {
- return false;
- }
-}
-
-bool PrefProvider::AllDefault(
- const ExtendedContentSettings& settings) const {
- for (size_t i = 0; i < arraysize(settings.content_settings.settings); ++i) {
- if (settings.content_settings.settings[i] != CONTENT_SETTING_DEFAULT)
- return false;
- }
- return settings.content_settings_for_resources.empty();
-}
-
void PrefProvider::ReadExceptions(bool overwrite) {
- base::AutoLock lock(lock_);
+ base::AutoLock auto_lock(lock());
PrefService* prefs = profile_->GetPrefs();
DictionaryValue* all_settings_dictionary =
prefs->GetMutableDictionary(prefs::kContentSettingsPatterns);
if (overwrite)
- host_content_settings_.clear();
+ host_content_settings()->clear();
// Careful: The returned value could be NULL if the pref has never been set.
if (all_settings_dictionary != NULL) {
@@ -727,12 +582,15 @@ void PrefProvider::ReadExceptions(bool overwrite) {
bool found = all_settings_dictionary->GetDictionaryWithoutPathExpansion(
pattern, &pattern_settings_dictionary);
DCHECK(found);
- ContentSettings settings;
- GetSettingsFromDictionary(pattern_settings_dictionary, &settings);
- host_content_settings_[pattern].content_settings = settings;
+
+ ExtendedContentSettings extended_settings;
+ GetSettingsFromDictionary(pattern_settings_dictionary,
+ &extended_settings.content_settings);
GetResourceSettingsFromDictionary(
pattern_settings_dictionary,
- &host_content_settings_[pattern].content_settings_for_resources);
+ &extended_settings.content_settings_for_resources);
+
+ (*host_content_settings())[pattern] = extended_settings;
}
}
}
@@ -911,60 +769,4 @@ void PrefProvider::MigrateObsoletePopupsPref(PrefService* prefs) {
}
}
-// ////////////////////////////////////////////////////////////////////////////
-// LEGACY TBR
-//
-
-ContentSettings PrefProvider::GetNonDefaultContentSettings(
- const GURL& url) const {
- base::AutoLock auto_lock(lock_);
-
- const std::string host(net::GetHostOrSpecFromURL(url));
- ContentSettings output;
- for (int j = 0; j < CONTENT_SETTINGS_NUM_TYPES; ++j)
- output.settings[j] = CONTENT_SETTING_DEFAULT;
-
- // Check for exact matches first.
- HostContentSettings::const_iterator i(host_content_settings_.find(host));
- if (i != host_content_settings_.end())
- output = i->second.content_settings;
-
- // If this map is not for an off-the-record profile, these searches will never
- // match. The additional off-the-record exceptions always overwrite the
- // regular ones.
- i = off_the_record_settings_.find(host);
- if (i != off_the_record_settings_.end()) {
- for (int j = 0; j < CONTENT_SETTINGS_NUM_TYPES; ++j)
- if (i->second.content_settings.settings[j] != CONTENT_SETTING_DEFAULT)
- output.settings[j] = i->second.content_settings.settings[j];
- }
-
- // Match patterns starting with the most concrete pattern match.
- for (std::string key =
- std::string(ContentSettingsPattern::kDomainWildcard) + host; ; ) {
- HostContentSettings::const_iterator i(off_the_record_settings_.find(key));
- if (i != off_the_record_settings_.end()) {
- for (int j = 0; j < CONTENT_SETTINGS_NUM_TYPES; ++j) {
- if (output.settings[j] == CONTENT_SETTING_DEFAULT)
- output.settings[j] = i->second.content_settings.settings[j];
- }
- }
- i = host_content_settings_.find(key);
- if (i != host_content_settings_.end()) {
- for (int j = 0; j < CONTENT_SETTINGS_NUM_TYPES; ++j) {
- if (output.settings[j] == CONTENT_SETTING_DEFAULT)
- output.settings[j] = i->second.content_settings.settings[j];
- }
- }
- const size_t next_dot =
- key.find('.', ContentSettingsPattern::kDomainWildcardLength);
- if (next_dot == std::string::npos)
- break;
- key.erase(ContentSettingsPattern::kDomainWildcardLength,
- next_dot - ContentSettingsPattern::kDomainWildcardLength + 1);
- }
-
- return output;
-}
-
} // namespace content_settings
diff --git a/chrome/browser/content_settings/pref_content_settings_provider.h b/chrome/browser/content_settings/content_settings_pref_provider.h
index b4631b8..95a4e75 100644
--- a/chrome/browser/content_settings/pref_content_settings_provider.h
+++ b/chrome/browser/content_settings/content_settings_pref_provider.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CHROME_BROWSER_CONTENT_SETTINGS_PREF_CONTENT_SETTINGS_PROVIDER_H_
-#define CHROME_BROWSER_CONTENT_SETTINGS_PREF_CONTENT_SETTINGS_PROVIDER_H_
+#ifndef CHROME_BROWSER_CONTENT_SETTINGS_CONTENT_SETTINGS_PREF_PROVIDER_H_
+#define CHROME_BROWSER_CONTENT_SETTINGS_CONTENT_SETTINGS_PREF_PROVIDER_H_
#pragma once
// A content settings provider that takes its settings out of the pref service.
@@ -14,6 +14,7 @@
#include "base/basictypes.h"
#include "base/synchronization/lock.h"
+#include "chrome/browser/content_settings/content_settings_base_provider.h"
#include "chrome/browser/content_settings/content_settings_provider.h"
#include "chrome/browser/prefs/pref_change_registrar.h"
#include "chrome/common/notification_observer.h"
@@ -90,7 +91,9 @@ class PrefDefaultProvider : public DefaultProviderInterface,
DISALLOW_COPY_AND_ASSIGN(PrefDefaultProvider);
};
-class PrefProvider : public ProviderInterface,
+// Content settings provider that provides content settings from the user
+// preference.
+class PrefProvider : public BaseProvider,
public NotificationObserver {
public:
static void RegisterUserPrefs(PrefService* prefs);
@@ -102,12 +105,6 @@ class PrefProvider : public ProviderInterface,
virtual bool ContentSettingsTypeIsManaged(
ContentSettingsType content_type);
- virtual ContentSetting GetContentSetting(
- const GURL& requesting_url,
- const GURL& embedding_url,
- ContentSettingsType content_type,
- const ResourceIdentifier& resource_identifier) const;
-
virtual void SetContentSetting(
const ContentSettingsPattern& requesting_pattern,
const ContentSettingsPattern& embedding_pattern,
@@ -115,43 +112,27 @@ class PrefProvider : public ProviderInterface,
const ResourceIdentifier& resource_identifier,
ContentSetting content_setting);
- virtual void GetAllContentSettingsRules(
- ContentSettingsType content_type,
- const ResourceIdentifier& resource_identifier,
- Rules* content_setting_rules) const;
-
virtual void ClearAllContentSettingsRules(
ContentSettingsType content_type);
virtual void ResetToDefaults();
+ // BaseProvider implementations.
+ virtual void Init();
+
// NotificationObserver implementation.
virtual void Observe(NotificationType type,
const NotificationSource& source,
const NotificationDetails& details);
private:
- typedef std::pair<ContentSettingsType, std::string>
- ContentSettingsTypeResourceIdentifierPair;
- typedef std::map<ContentSettingsTypeResourceIdentifierPair, ContentSetting>
- ResourceContentSettings;
-
- struct ExtendedContentSettings;
-
- typedef std::map<std::string, ExtendedContentSettings> HostContentSettings;
+ void ReadExceptions(bool overwrite);
// Various migration methods (old cookie, popup and per-host data gets
// migrated to the new format).
void MigrateObsoletePerhostPref(PrefService* prefs);
void MigrateObsoletePopupsPref(PrefService* prefs);
- bool AllDefault(const ExtendedContentSettings& settings) const;
-
- void ReadExceptions(bool overwrite);
-
- bool RequiresResourceIdentifier(
- ContentSettingsType content_type) const;
-
void CanonicalizeContentSettingsExceptions(
DictionaryValue* all_settings_dictionary);
@@ -169,24 +150,9 @@ class PrefProvider : public ProviderInterface,
Profile* profile_;
- // Whether this settings map is for an OTR session.
- bool is_off_the_record_;
-
- // Used around accesses to the content_settings_ object to guarantee
- // thread safety.
- mutable base::Lock lock_;
-
PrefChangeRegistrar pref_change_registrar_;
NotificationRegistrar notification_registrar_;
- // Copies of the pref data, so that we can read it on threads other than the
- // UI thread.
- HostContentSettings host_content_settings_;
-
- // Differences to the preference-stored host content settings for
- // off-the-record settings.
- HostContentSettings off_the_record_settings_;
-
// Whether we are currently updating preferences, this is used to ignore
// notifications from the preferences service that we triggered ourself.
bool updating_preferences_;
@@ -194,12 +160,9 @@ class PrefProvider : public ProviderInterface,
// Do not fire any Notifications as long as we are in the constructor.
bool initializing_;
- // LEGACY: TBR
- ContentSettings GetNonDefaultContentSettings(const GURL& url) const;
-
DISALLOW_COPY_AND_ASSIGN(PrefProvider);
};
} // namespace content_settings
-#endif // CHROME_BROWSER_CONTENT_SETTINGS_PREF_CONTENT_SETTINGS_PROVIDER_H_
+#endif // CHROME_BROWSER_CONTENT_SETTINGS_CONTENT_SETTINGS_PREF_PROVIDER_H_
diff --git a/chrome/browser/content_settings/pref_content_settings_provider_unittest.cc b/chrome/browser/content_settings/content_settings_pref_provider_unittest.cc
index 80b62c3..fda116d 100644
--- a/chrome/browser/content_settings/pref_content_settings_provider_unittest.cc
+++ b/chrome/browser/content_settings/content_settings_pref_provider_unittest.cc
@@ -2,24 +2,25 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "chrome/browser/content_settings/pref_content_settings_provider.h"
+#include "chrome/browser/content_settings/content_settings_pref_provider.h"
#include "base/auto_reset.h"
#include "base/command_line.h"
-#include "chrome/browser/browser_thread.h"
#include "chrome/browser/content_settings/stub_settings_observer.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
+#include "chrome/test/testing_browser_process_test.h"
#include "chrome/test/testing_pref_service.h"
#include "chrome/test/testing_profile.h"
+#include "content/browser/browser_thread.h"
#include "googleurl/src/gurl.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace content_settings {
-class PrefDefaultProviderTest : public testing::Test {
+class PrefDefaultProviderTest : public TestingBrowserProcessTest {
public:
PrefDefaultProviderTest()
: ui_thread_(BrowserThread::UI, &message_loop_) {
@@ -136,7 +137,7 @@ bool SettingsEqual(const ContentSettings& settings1,
return true;
}
-class PrefProviderTest : public testing::Test {
+class PrefProviderTest : public TestingBrowserProcessTest {
public:
PrefProviderTest() : ui_thread_(
BrowserThread::UI, &message_loop_) {
@@ -175,8 +176,10 @@ TEST_F(PrefProviderTest, Patterns) {
GURL host1("http://example.com/");
GURL host2("http://www.example.com/");
GURL host3("http://example.org/");
+ GURL host4("file:///tmp/test.html");
ContentSettingsPattern pattern1("[*.]example.com");
ContentSettingsPattern pattern2("example.org");
+ ContentSettingsPattern pattern3("file:///tmp/test.html");
EXPECT_EQ(CONTENT_SETTING_DEFAULT,
pref_content_settings_provider.GetContentSetting(
@@ -206,6 +209,19 @@ TEST_F(PrefProviderTest, Patterns) {
EXPECT_EQ(CONTENT_SETTING_BLOCK,
pref_content_settings_provider.GetContentSetting(
host3, host3, CONTENT_SETTINGS_TYPE_IMAGES, ""));
+
+ EXPECT_EQ(CONTENT_SETTING_DEFAULT,
+ pref_content_settings_provider.GetContentSetting(
+ host4, host4, CONTENT_SETTINGS_TYPE_IMAGES, ""));
+ pref_content_settings_provider.SetContentSetting(
+ pattern3,
+ pattern3,
+ CONTENT_SETTINGS_TYPE_IMAGES,
+ "",
+ CONTENT_SETTING_BLOCK);
+ EXPECT_EQ(CONTENT_SETTING_BLOCK,
+ pref_content_settings_provider.GetContentSetting(
+ host4, host4, CONTENT_SETTINGS_TYPE_IMAGES, ""));
}
TEST_F(PrefProviderTest, ResourceIdentifier) {
diff --git a/chrome/browser/content_settings/content_settings_provider.h b/chrome/browser/content_settings/content_settings_provider.h
index 621c522..eff1443 100644
--- a/chrome/browser/content_settings/content_settings_provider.h
+++ b/chrome/browser/content_settings/content_settings_provider.h
@@ -65,6 +65,11 @@ class ProviderInterface {
virtual ~ProviderInterface() {}
+ // Returns true whether the content settings provider manages the
+ // |content_type|.
+ virtual bool ContentSettingsTypeIsManaged(
+ ContentSettingsType content_type) = 0;
+
// Returns a single ContentSetting which applies to a given |requesting_url|,
// |embedding_url| pair or CONTENT_SETTING_DEFAULT, if no rule applies. For
// ContentSettingsTypes that require a resource identifier to be specified,
diff --git a/chrome/browser/content_settings/content_settings_provider_unittest.cc b/chrome/browser/content_settings/content_settings_provider_unittest.cc
index 71cded4..11c0284 100644
--- a/chrome/browser/content_settings/content_settings_provider_unittest.cc
+++ b/chrome/browser/content_settings/content_settings_provider_unittest.cc
@@ -4,7 +4,7 @@
#include "testing/gtest/include/gtest/gtest.h"
-#include "chrome/browser/content_settings/mock_content_settings_provider.h"
+#include "chrome/browser/content_settings/content_settings_mock_provider.h"
#include "googleurl/src/gurl.h"
namespace content_settings {
@@ -34,7 +34,9 @@ TEST(ContentSettingsProviderTest, Mock) {
CONTENT_SETTINGS_TYPE_PLUGINS,
"java_plugin",
CONTENT_SETTING_BLOCK,
+ false,
false);
+
EXPECT_EQ(CONTENT_SETTING_BLOCK, mock_provider.GetContentSetting(
url, url, CONTENT_SETTINGS_TYPE_PLUGINS, "java_plugin"));
EXPECT_EQ(CONTENT_SETTING_DEFAULT, mock_provider.GetContentSetting(
diff --git a/chrome/browser/content_settings/host_content_settings_map.cc b/chrome/browser/content_settings/host_content_settings_map.cc
index bcdd538..93dac5f 100644
--- a/chrome/browser/content_settings/host_content_settings_map.cc
+++ b/chrome/browser/content_settings/host_content_settings_map.cc
@@ -7,21 +7,21 @@
#include "base/command_line.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
-#include "chrome/browser/browser_thread.h"
#include "chrome/browser/content_settings/content_settings_details.h"
#include "chrome/browser/content_settings/content_settings_provider.h"
-#include "chrome/browser/content_settings/policy_content_settings_provider.h"
-#include "chrome/browser/content_settings/pref_content_settings_provider.h"
+#include "chrome/browser/content_settings/content_settings_policy_provider.h"
+#include "chrome/browser/content_settings/content_settings_pref_provider.h"
#include "chrome/browser/metrics/user_metrics.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/prefs/scoped_pref_update.h"
+#include "chrome/browser/prefs/scoped_user_pref_update.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/notification_source.h"
#include "chrome/common/notification_type.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
+#include "content/browser/browser_thread.h"
#include "googleurl/src/gurl.h"
#include "net/base/net_util.h"
#include "net/base/static_cookie_policy.h"
@@ -100,8 +100,10 @@ HostContentSettingsMap::HostContentSettingsMap(Profile* profile)
// The order in which the content settings providers are created is critical,
// as providers that are further up in the list (i.e. added earlier) override
// providers further down.
- content_settings_providers_.push_back(ProviderPtr(
- new content_settings::PrefProvider(profile)));
+ content_settings_providers_.push_back(
+ make_linked_ptr(new content_settings::PolicyProvider(profile)));
+ content_settings_providers_.push_back(
+ make_linked_ptr(new content_settings::PrefProvider(profile)));
pref_change_registrar_.Init(prefs);
pref_change_registrar_.Add(prefs::kBlockThirdPartyCookies, this);
@@ -124,6 +126,7 @@ void HostContentSettingsMap::RegisterUserPrefs(PrefService* prefs) {
content_settings::PrefDefaultProvider::RegisterUserPrefs(prefs);
content_settings::PolicyDefaultProvider::RegisterUserPrefs(prefs);
content_settings::PrefProvider::RegisterUserPrefs(prefs);
+ content_settings::PolicyProvider::RegisterUserPrefs(prefs);
}
ContentSetting HostContentSettingsMap::GetDefaultContentSetting(
@@ -151,10 +154,8 @@ ContentSetting HostContentSettingsMap::GetContentSetting(
ContentSetting setting = GetNonDefaultContentSetting(url,
content_type,
resource_identifier);
- if (setting == CONTENT_SETTING_DEFAULT ||
- IsDefaultContentSettingManaged(content_type)) {
+ if (setting == CONTENT_SETTING_DEFAULT)
return GetDefaultContentSetting(content_type);
- }
return setting;
}
@@ -173,8 +174,9 @@ ContentSetting HostContentSettingsMap::GetNonDefaultContentSetting(
++provider) {
provided_setting = (*provider)->GetContentSetting(
url, url, content_type, resource_identifier);
- if (provided_setting != CONTENT_SETTING_DEFAULT)
- break;
+ bool isManaged = (*provider)->ContentSettingsTypeIsManaged(content_type);
+ if (provided_setting != CONTENT_SETTING_DEFAULT || isManaged)
+ return provided_setting;
}
return provided_setting;
}
@@ -188,9 +190,8 @@ ContentSettings HostContentSettingsMap::GetContentSettings(
for (int j = 0; j < CONTENT_SETTINGS_NUM_TYPES; ++j) {
// A managed default content setting has the highest priority and hence
// will overwrite any previously set value.
- if ((output.settings[j] == CONTENT_SETTING_DEFAULT &&
- j != CONTENT_SETTINGS_TYPE_PLUGINS) ||
- IsDefaultContentSettingManaged(ContentSettingsType(j))) {
+ if (output.settings[j] == CONTENT_SETTING_DEFAULT &&
+ j != CONTENT_SETTINGS_TYPE_PLUGINS) {
output.settings[j] = GetDefaultContentSetting(ContentSettingsType(j));
}
}
@@ -225,8 +226,14 @@ void HostContentSettingsMap::GetSettingsForOneType(
++provider) {
// TODO(markusheintz): Only the rules that are applied should be collected.
// Merge rules.
+ // TODO(markusheintz): GetAllContentSettingsRules should maybe not clear the
+ // passed vector in case rule sets are just unified.
+ Rules rules;
(*provider)->GetAllContentSettingsRules(
- content_type, resource_identifier, &content_settings_rules);
+ content_type, resource_identifier, &rules);
+ content_settings_rules.insert(content_settings_rules.end(),
+ rules.begin(),
+ rules.end());
}
// convert Rules to SettingsForOneType
diff --git a/chrome/browser/content_settings/host_content_settings_map.h b/chrome/browser/content_settings/host_content_settings_map.h
index c2658e8..cf326d7 100644
--- a/chrome/browser/content_settings/host_content_settings_map.h
+++ b/chrome/browser/content_settings/host_content_settings_map.h
@@ -18,12 +18,12 @@
#include "base/linked_ptr.h"
#include "base/ref_counted.h"
#include "base/synchronization/lock.h"
-#include "chrome/browser/browser_thread.h"
#include "chrome/browser/content_settings/content_settings_pattern.h"
#include "chrome/browser/prefs/pref_change_registrar.h"
#include "chrome/common/content_settings.h"
#include "chrome/common/notification_observer.h"
#include "chrome/common/notification_registrar.h"
+#include "content/browser/browser_thread.h"
namespace content_settings {
class DefaultProviderInterface;
@@ -45,7 +45,6 @@ class HostContentSettingsMap
typedef std::vector<PatternSettingPair> SettingsForOneType;
explicit HostContentSettingsMap(Profile* profile);
- ~HostContentSettingsMap();
static void RegisterUserPrefs(PrefService* prefs);
@@ -171,7 +170,10 @@ class HostContentSettingsMap
const NotificationDetails& details);
private:
- friend class base::RefCountedThreadSafe<HostContentSettingsMap>;
+ friend struct BrowserThread::DeleteOnThread<BrowserThread::UI>;
+ friend class DeleteTask<HostContentSettingsMap>;
+
+ ~HostContentSettingsMap();
// Informs observers that content settings have changed. Make sure that
// |lock_| is not held when calling this, as listeners will usually call one
diff --git a/chrome/browser/content_settings/host_content_settings_map_unittest.cc b/chrome/browser/content_settings/host_content_settings_map_unittest.cc
index 7de163d..7748406 100644
--- a/chrome/browser/content_settings/host_content_settings_map_unittest.cc
+++ b/chrome/browser/content_settings/host_content_settings_map_unittest.cc
@@ -13,6 +13,7 @@
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
+#include "chrome/test/testing_browser_process_test.h"
#include "chrome/test/testing_pref_service.h"
#include "chrome/test/testing_profile.h"
#include "googleurl/src/gurl.h"
@@ -30,7 +31,7 @@ bool SettingsEqual(const ContentSettings& settings1,
return true;
}
-class HostContentSettingsMapTest : public testing::Test {
+class HostContentSettingsMapTest : public TestingBrowserProcessTest {
public:
HostContentSettingsMapTest() : ui_thread_(BrowserThread::UI, &message_loop_) {
}
@@ -121,6 +122,8 @@ TEST_F(HostContentSettingsMapTest, DefaultValues) {
CONTENT_SETTING_ASK;
desired_settings.settings[CONTENT_SETTINGS_TYPE_NOTIFICATIONS] =
CONTENT_SETTING_ASK;
+ desired_settings.settings[CONTENT_SETTINGS_TYPE_PRERENDER] =
+ CONTENT_SETTING_ALLOW;
ContentSettings settings =
host_content_settings_map->GetContentSettings(host);
EXPECT_TRUE(SettingsEqual(desired_settings, settings));
@@ -422,6 +425,8 @@ TEST_F(HostContentSettingsMapTest, NestedSettings) {
CONTENT_SETTING_ASK;
desired_settings.settings[CONTENT_SETTINGS_TYPE_NOTIFICATIONS] =
CONTENT_SETTING_ASK;
+ desired_settings.settings[CONTENT_SETTINGS_TYPE_PRERENDER] =
+ CONTENT_SETTING_ALLOW;
ContentSettings settings =
host_content_settings_map->GetContentSettings(host);
EXPECT_TRUE(SettingsEqual(desired_settings, settings));
diff --git a/chrome/browser/content_settings/policy_content_settings_provider.cc b/chrome/browser/content_settings/policy_content_settings_provider.cc
deleted file mode 100644
index d39acef..0000000
--- a/chrome/browser/content_settings/policy_content_settings_provider.cc
+++ /dev/null
@@ -1,198 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/content_settings/policy_content_settings_provider.h"
-
-#include <string>
-
-#include "base/command_line.h"
-#include "chrome/browser/browser_thread.h"
-#include "chrome/browser/content_settings/content_settings_details.h"
-#include "chrome/browser/content_settings/content_settings_pattern.h"
-#include "chrome/browser/prefs/pref_service.h"
-#include "chrome/browser/prefs/scoped_pref_update.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/common/notification_details.h"
-#include "chrome/common/notification_service.h"
-#include "chrome/common/notification_source.h"
-#include "chrome/common/pref_names.h"
-
-namespace {
-
-// Base pref path of the prefs that contain the managed default content
-// settings values.
-const std::string kManagedSettings =
- "profile.managed_default_content_settings";
-
-// The preferences used to manage ContentSettingsTypes.
-const char* kPrefToManageType[CONTENT_SETTINGS_NUM_TYPES] = {
- prefs::kManagedDefaultCookiesSetting,
- prefs::kManagedDefaultImagesSetting,
- prefs::kManagedDefaultJavaScriptSetting,
- prefs::kManagedDefaultPluginsSetting,
- prefs::kManagedDefaultPopupsSetting,
- NULL, // Not used for Geolocation
- NULL, // Not used for Notifications
-};
-
-} // namespace
-
-namespace content_settings {
-
-PolicyDefaultProvider::PolicyDefaultProvider(Profile* profile)
- : profile_(profile),
- is_off_the_record_(profile_->IsOffTheRecord()) {
- PrefService* prefs = profile->GetPrefs();
-
- // Read global defaults.
- DCHECK_EQ(arraysize(kPrefToManageType),
- static_cast<size_t>(CONTENT_SETTINGS_NUM_TYPES));
- ReadManagedDefaultSettings();
-
- pref_change_registrar_.Init(prefs);
- // The following preferences are only used to indicate if a
- // default-content-setting is managed and to hold the managed default-setting
- // value. If the value for any of the following perferences is set then the
- // corresponding default-content-setting is managed. These preferences exist
- // in parallel to the preference default-content-settings. If a
- // default-content-settings-type is managed any user defined excpetions
- // (patterns) for this type are ignored.
- pref_change_registrar_.Add(prefs::kManagedDefaultCookiesSetting, this);
- pref_change_registrar_.Add(prefs::kManagedDefaultImagesSetting, this);
- pref_change_registrar_.Add(prefs::kManagedDefaultJavaScriptSetting, this);
- pref_change_registrar_.Add(prefs::kManagedDefaultPluginsSetting, this);
- pref_change_registrar_.Add(prefs::kManagedDefaultPopupsSetting, this);
- notification_registrar_.Add(this, NotificationType::PROFILE_DESTROYED,
- Source<Profile>(profile_));
-}
-
-PolicyDefaultProvider::~PolicyDefaultProvider() {
- UnregisterObservers();
-}
-
-ContentSetting PolicyDefaultProvider::ProvideDefaultSetting(
- ContentSettingsType content_type) const {
- base::AutoLock auto_lock(lock_);
- return managed_default_content_settings_.settings[content_type];
-}
-
-void PolicyDefaultProvider::UpdateDefaultSetting(
- ContentSettingsType content_type,
- ContentSetting setting) {
-}
-
-bool PolicyDefaultProvider::DefaultSettingIsManaged(
- ContentSettingsType content_type) const {
- base::AutoLock lock(lock_);
- if (managed_default_content_settings_.settings[content_type] !=
- CONTENT_SETTING_DEFAULT) {
- return true;
- } else {
- return false;
- }
-}
-
-void PolicyDefaultProvider::ResetToDefaults() {
-}
-
-void PolicyDefaultProvider::Observe(NotificationType type,
- const NotificationSource& source,
- const NotificationDetails& details) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
- if (type == NotificationType::PREF_CHANGED) {
- DCHECK_EQ(profile_->GetPrefs(), Source<PrefService>(source).ptr());
- std::string* name = Details<std::string>(details).ptr();
- if (*name == prefs::kManagedDefaultCookiesSetting) {
- UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_COOKIES);
- } else if (*name == prefs::kManagedDefaultImagesSetting) {
- UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_IMAGES);
- } else if (*name == prefs::kManagedDefaultJavaScriptSetting) {
- UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_JAVASCRIPT);
- } else if (*name == prefs::kManagedDefaultPluginsSetting) {
- UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_PLUGINS);
- } else if (*name == prefs::kManagedDefaultPopupsSetting) {
- UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_POPUPS);
- } else {
- NOTREACHED() << "Unexpected preference observed";
- return;
- }
-
- if (!is_off_the_record_) {
- NotifyObservers(ContentSettingsDetails(
- ContentSettingsPattern(), CONTENT_SETTINGS_TYPE_DEFAULT, ""));
- }
- } else if (type == NotificationType::PROFILE_DESTROYED) {
- DCHECK_EQ(profile_, Source<Profile>(source).ptr());
- UnregisterObservers();
- } else {
- NOTREACHED() << "Unexpected notification";
- }
-}
-
-void PolicyDefaultProvider::UnregisterObservers() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- if (!profile_)
- return;
- pref_change_registrar_.RemoveAll();
- notification_registrar_.Remove(this, NotificationType::PROFILE_DESTROYED,
- Source<Profile>(profile_));
- profile_ = NULL;
-}
-
-
-void PolicyDefaultProvider::NotifyObservers(
- const ContentSettingsDetails& details) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- if (profile_ == NULL)
- return;
- NotificationService::current()->Notify(
- NotificationType::CONTENT_SETTINGS_CHANGED,
- Source<HostContentSettingsMap>(profile_->GetHostContentSettingsMap()),
- Details<const ContentSettingsDetails>(&details));
-}
-
-void PolicyDefaultProvider::ReadManagedDefaultSettings() {
- for (size_t type = 0; type < arraysize(kPrefToManageType); ++type) {
- if (kPrefToManageType[type] == NULL) {
- // TODO(markusheintz): Handle Geolocation and notification separately.
- continue;
- }
- UpdateManagedDefaultSetting(ContentSettingsType(type));
- }
-}
-
-void PolicyDefaultProvider::UpdateManagedDefaultSetting(
- ContentSettingsType type) {
- // 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
- // preference to manage a default-content-settings is CONTENT_SETTING_DEFAULT.
- // This indicates that no managed value is set. If a pref was set, than it
- // MUST be managed.
- PrefService* prefs = profile_->GetPrefs();
- DCHECK(!prefs->HasPrefPath(kPrefToManageType[type]) ||
- prefs->IsManagedPreference(kPrefToManageType[type]));
- base::AutoLock auto_lock(lock_);
- managed_default_content_settings_.settings[type] = IntToContentSetting(
- prefs->GetInteger(kPrefToManageType[type]));
-}
-
-// static
-void PolicyDefaultProvider::RegisterUserPrefs(PrefService* prefs) {
- // Preferences for default content setting policies. A policy is not set of
- // the corresponding preferences below is set to CONTENT_SETTING_DEFAULT.
- prefs->RegisterIntegerPref(prefs::kManagedDefaultCookiesSetting,
- CONTENT_SETTING_DEFAULT);
- prefs->RegisterIntegerPref(prefs::kManagedDefaultImagesSetting,
- CONTENT_SETTING_DEFAULT);
- prefs->RegisterIntegerPref(prefs::kManagedDefaultJavaScriptSetting,
- CONTENT_SETTING_DEFAULT);
- prefs->RegisterIntegerPref(prefs::kManagedDefaultPluginsSetting,
- CONTENT_SETTING_DEFAULT);
- prefs->RegisterIntegerPref(prefs::kManagedDefaultPopupsSetting,
- CONTENT_SETTING_DEFAULT);
-}
-
-} // namespace content_settings
diff --git a/chrome/browser/content_settings/policy_content_settings_provider_unittest.cc b/chrome/browser/content_settings/policy_content_settings_provider_unittest.cc
deleted file mode 100644
index 6aa9a88..0000000
--- a/chrome/browser/content_settings/policy_content_settings_provider_unittest.cc
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/content_settings/policy_content_settings_provider.h"
-
-#include "chrome/browser/browser_thread.h"
-#include "chrome/browser/content_settings/stub_settings_observer.h"
-#include "chrome/browser/prefs/pref_service.h"
-#include "chrome/common/pref_names.h"
-#include "chrome/common/url_constants.h"
-#include "chrome/test/testing_pref_service.h"
-#include "chrome/test/testing_profile.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-
-namespace content_settings {
-
-class PolicyDefaultProviderTest : public testing::Test {
- public:
- PolicyDefaultProviderTest()
- : ui_thread_(BrowserThread::UI, &message_loop_) {
- }
-
- protected:
- MessageLoop message_loop_;
- BrowserThread ui_thread_;
-};
-
-TEST_F(PolicyDefaultProviderTest, DefaultValues) {
- TestingProfile profile;
- PolicyDefaultProvider provider(&profile);
- TestingPrefService* prefs = profile.GetTestingPrefService();
-
- // By default, policies should be off.
- ASSERT_FALSE(
- provider.DefaultSettingIsManaged(CONTENT_SETTINGS_TYPE_COOKIES));
-
- // Set managed-default-content-setting through the coresponding preferences.
- prefs->SetManagedPref(prefs::kManagedDefaultCookiesSetting,
- Value::CreateIntegerValue(CONTENT_SETTING_BLOCK));
- ASSERT_TRUE(
- provider.DefaultSettingIsManaged(CONTENT_SETTINGS_TYPE_COOKIES));
- ASSERT_EQ(CONTENT_SETTING_BLOCK,
- provider.ProvideDefaultSetting(CONTENT_SETTINGS_TYPE_COOKIES));
-
- // Remove managed-default-content-settings-preferences.
- prefs->RemoveManagedPref(prefs::kManagedDefaultCookiesSetting);
- ASSERT_FALSE(
- provider.DefaultSettingIsManaged(CONTENT_SETTINGS_TYPE_COOKIES));
-}
-
-// When a default-content-setting is set to a managed setting a
-// CONTENT_SETTINGS_CHANGED notification should be fired. The same should happen
-// if the managed setting is removed.
-TEST_F(PolicyDefaultProviderTest, ObserveManagedSettingsChange) {
- TestingProfile profile;
- StubSettingsObserver observer;
- // Make sure the content settings map exists.
- profile.GetHostContentSettingsMap();
- TestingPrefService* prefs = profile.GetTestingPrefService();
-
- // Set the managed default-content-setting.
- prefs->SetManagedPref(prefs::kManagedDefaultImagesSetting,
- Value::CreateIntegerValue(CONTENT_SETTING_BLOCK));
- EXPECT_EQ(profile.GetHostContentSettingsMap(), observer.last_notifier);
- EXPECT_EQ(ContentSettingsPattern(), observer.last_pattern);
- EXPECT_EQ(CONTENT_SETTINGS_TYPE_DEFAULT, observer.last_type);
- EXPECT_TRUE(observer.last_update_all);
- EXPECT_TRUE(observer.last_update_all_types);
- EXPECT_EQ(1, observer.counter);
-
- // Remove the managed default-content-setting.
- prefs->RemoveManagedPref(prefs::kManagedDefaultImagesSetting);
- EXPECT_EQ(profile.GetHostContentSettingsMap(), observer.last_notifier);
- EXPECT_EQ(CONTENT_SETTINGS_TYPE_DEFAULT, observer.last_type);
- EXPECT_EQ(ContentSettingsPattern(), observer.last_pattern);
- EXPECT_TRUE(observer.last_update_all);
- EXPECT_TRUE(observer.last_update_all_types);
- EXPECT_EQ(2, observer.counter);
-}
-
-} // namespace content_settings