summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormarja@chromium.org <marja@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-10-27 13:43:42 +0000
committermarja@chromium.org <marja@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-10-27 13:43:42 +0000
commitc144060968bce7873e4079bd2293272fe03b520f (patch)
tree6d1f7cc551e53d2626ff522ec46adb18da6c991c
parent78d4939cf2732a79ff823a0b00938e6aef77cf97 (diff)
downloadchromium_src-c144060968bce7873e4079bd2293272fe03b520f.zip
chromium_src-c144060968bce7873e4079bd2293272fe03b520f.tar.gz
chromium_src-c144060968bce7873e4079bd2293272fe03b520f.tar.bz2
Delegating the "are images allowed" decision to renderer.
This enables making the decision based on both image url and the page url. E.g., blocking third-party images. BUG=81179 TEST=RenderViewTest.ImagesBlockedByDefault, RenderViewTest.ImagesAllowedByDefault Review URL: http://codereview.chromium.org/7831075 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@107562 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/chrome_content_browser_client.cc4
-rw-r--r--chrome/browser/content_settings/host_content_settings_map.cc6
-rw-r--r--chrome/browser/content_settings/host_content_settings_map.h20
-rw-r--r--chrome/browser/content_settings/host_content_settings_map_unittest.cc4
-rw-r--r--chrome/browser/content_settings/tab_specific_content_settings.cc3
-rw-r--r--chrome/browser/extensions/extension_special_storage_policy.cc4
-rw-r--r--chrome/browser/notifications/desktop_notification_service.cc3
-rw-r--r--chrome/browser/notifications/desktop_notification_service.h4
-rw-r--r--chrome/browser/notifications/desktop_notification_service_unittest.cc23
-rw-r--r--chrome/browser/ui/webui/options/content_settings_handler.cc42
-rw-r--r--chrome/common/content_settings.cc26
-rw-r--r--chrome/common/content_settings.h33
-rw-r--r--chrome/common/extensions/api/extension_api.json2
-rw-r--r--chrome/common/extensions/docs/contentSettings.html2
-rw-r--r--chrome/common/render_messages.h13
-rw-r--r--chrome/renderer/chrome_content_renderer_client.cc4
-rw-r--r--chrome/renderer/chrome_render_process_observer.cc12
-rw-r--r--chrome/renderer/chrome_render_process_observer.h7
-rw-r--r--chrome/renderer/content_settings_observer.cc42
-rw-r--r--chrome/renderer/content_settings_observer.h21
-rw-r--r--chrome/renderer/content_settings_observer_browsertest.cc87
21 files changed, 277 insertions, 85 deletions
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index d1651a8..388a27c 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -286,6 +286,10 @@ void ChromeContentBrowserClient::BrowserRenderProcessHostCreated(
profile->IsOffTheRecord()));
SendExtensionWebRequestStatusToHost(host);
+ ContentSettingsForOneType settings;
+ HostContentSettingsMap* map = profile->GetHostContentSettingsMap();
+ map->GetSettingsForOneType(CONTENT_SETTINGS_TYPE_IMAGES, "", &settings);
+ host->Send(new ChromeViewMsg_SetImageSettingRules(settings));
}
void ChromeContentBrowserClient::PluginProcessHostCreated(
diff --git a/chrome/browser/content_settings/host_content_settings_map.cc b/chrome/browser/content_settings/host_content_settings_map.cc
index 5d76b92..c345ae2 100644
--- a/chrome/browser/content_settings/host_content_settings_map.cc
+++ b/chrome/browser/content_settings/host_content_settings_map.cc
@@ -316,7 +316,7 @@ ContentSettings HostContentSettingsMap::GetContentSettings(
void HostContentSettingsMap::GetSettingsForOneType(
ContentSettingsType content_type,
const std::string& resource_identifier,
- SettingsForOneType* settings) const {
+ ContentSettingsForOneType* settings) const {
DCHECK(content_settings::SupportsResourceIdentifier(content_type) ||
resource_identifier.empty());
DCHECK(settings);
@@ -552,7 +552,7 @@ void HostContentSettingsMap::AddSettingsForOneType(
ProviderType provider_type,
ContentSettingsType content_type,
const std::string& resource_identifier,
- SettingsForOneType* settings,
+ ContentSettingsForOneType* settings,
bool incognito) const {
scoped_ptr<content_settings::RuleIterator> rule_iterator(
provider->GetRuleIterator(content_type,
@@ -561,7 +561,7 @@ void HostContentSettingsMap::AddSettingsForOneType(
ContentSettingsPattern wildcard = ContentSettingsPattern::Wildcard();
while (rule_iterator->HasNext()) {
const content_settings::Rule& rule = rule_iterator->Next();
- settings->push_back(PatternSettingSourceTuple(
+ settings->push_back(ContentSettingPatternSource(
rule.primary_pattern, rule.secondary_pattern,
content_settings::ValueToContentSetting(rule.value.get()),
kProviderNames[provider_type],
diff --git a/chrome/browser/content_settings/host_content_settings_map.h b/chrome/browser/content_settings/host_content_settings_map.h
index 4c167b9..4980656 100644
--- a/chrome/browser/content_settings/host_content_settings_map.h
+++ b/chrome/browser/content_settings/host_content_settings_map.h
@@ -49,15 +49,6 @@ class HostContentSettingsMap
NUM_PROVIDER_TYPES,
};
- // TODO(markusheintz): I sold my soul to the devil on order to add this tuple.
- // I really want my soul back, so I really will change this ASAP.
- typedef Tuple5<ContentSettingsPattern,
- ContentSettingsPattern,
- ContentSetting,
- std::string,
- bool> PatternSettingSourceTuple;
- typedef std::vector<PatternSettingSourceTuple> SettingsForOneType;
-
HostContentSettingsMap(PrefService* prefs,
ExtensionService* extension_service,
bool incognito);
@@ -126,16 +117,13 @@ class HostContentSettingsMap
const GURL& secondary_url) const;
// For a given content type, returns all patterns with a non-default setting,
- // mapped to their actual settings, in lexicographical order. |settings|
- // must be a non-NULL outparam. If this map was created for the
- // incognito profile, it will only return those settings differing from
- // the main map. For ContentSettingsTypes that require an resource identifier
- // to be specified, the |resource_identifier| must be non-empty.
+ // mapped to their actual settings, in the precedence order of the rules.
+ // |settings| must be a non-NULL outparam.
//
// This may be called on any thread.
void GetSettingsForOneType(ContentSettingsType content_type,
const std::string& resource_identifier,
- SettingsForOneType* settings) const;
+ ContentSettingsForOneType* settings) const;
// Sets the default setting for a particular content type. This method must
// not be invoked on an incognito map.
@@ -236,7 +224,7 @@ class HostContentSettingsMap
ProviderType provider_type,
ContentSettingsType content_type,
const std::string& resource_identifier,
- SettingsForOneType* settings,
+ ContentSettingsForOneType* settings,
bool incognito) const;
// Weak; owned by the Profile.
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 208b8ba..6cd7e7c9 100644
--- a/chrome/browser/content_settings/host_content_settings_map_unittest.cc
+++ b/chrome/browser/content_settings/host_content_settings_map_unittest.cc
@@ -180,7 +180,7 @@ TEST_F(HostContentSettingsMapTest, IndividualSettings) {
CONTENT_SETTINGS_TYPE_PLUGINS,
std::string(),
CONTENT_SETTING_BLOCK);
- HostContentSettingsMap::SettingsForOneType host_settings;
+ ContentSettingsForOneType host_settings;
host_content_settings_map->GetSettingsForOneType(CONTENT_SETTINGS_TYPE_IMAGES,
"",
&host_settings);
@@ -233,7 +233,7 @@ TEST_F(HostContentSettingsMapTest, Clear) {
CONTENT_SETTING_BLOCK);
host_content_settings_map->ClearSettingsForOneType(
CONTENT_SETTINGS_TYPE_IMAGES);
- HostContentSettingsMap::SettingsForOneType host_settings;
+ ContentSettingsForOneType host_settings;
host_content_settings_map->GetSettingsForOneType(CONTENT_SETTINGS_TYPE_IMAGES,
"",
&host_settings);
diff --git a/chrome/browser/content_settings/tab_specific_content_settings.cc b/chrome/browser/content_settings/tab_specific_content_settings.cc
index 4e1a5c0..b15e1f7 100644
--- a/chrome/browser/content_settings/tab_specific_content_settings.cc
+++ b/chrome/browser/content_settings/tab_specific_content_settings.cc
@@ -489,6 +489,9 @@ void TabSpecificContentSettings::Observe(
map->GetDefaultContentSettings()));
Send(new ChromeViewMsg_SetContentSettingsForCurrentURL(
entry_url, map->GetContentSettings(entry_url, entry_url)));
+ ContentSettingsForOneType settings;
+ map->GetSettingsForOneType(CONTENT_SETTINGS_TYPE_IMAGES, "", &settings);
+ Send(new ChromeViewMsg_SetImageSettingRules(settings));
}
}
diff --git a/chrome/browser/extensions/extension_special_storage_policy.cc b/chrome/browser/extensions/extension_special_storage_policy.cc
index 2064f37..eddaedf 100644
--- a/chrome/browser/extensions/extension_special_storage_policy.cc
+++ b/chrome/browser/extensions/extension_special_storage_policy.cc
@@ -45,11 +45,11 @@ bool ExtensionSpecialStoragePolicy::HasSessionOnlyOrigins() {
if (host_content_settings_map_->GetDefaultContentSetting(
CONTENT_SETTINGS_TYPE_COOKIES, NULL) == CONTENT_SETTING_SESSION_ONLY)
return true;
- HostContentSettingsMap::SettingsForOneType entries;
+ ContentSettingsForOneType entries;
host_content_settings_map_->GetSettingsForOneType(
CONTENT_SETTINGS_TYPE_COOKIES, "", &entries);
for (size_t i = 0; i < entries.size(); ++i) {
- if (entries[i].c == CONTENT_SETTING_SESSION_ONLY)
+ if (entries[i].setting == CONTENT_SETTING_SESSION_ONLY)
return true;
}
return false;
diff --git a/chrome/browser/notifications/desktop_notification_service.cc b/chrome/browser/notifications/desktop_notification_service.cc
index ca4857d..4a43f94 100644
--- a/chrome/browser/notifications/desktop_notification_service.cc
+++ b/chrome/browser/notifications/desktop_notification_service.cc
@@ -23,6 +23,7 @@
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
#include "chrome/common/chrome_notification_types.h"
+#include "chrome/common/content_settings.h"
#include "chrome/common/content_settings_pattern.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
@@ -292,7 +293,7 @@ void DesktopNotificationService::ResetToDefaultContentSetting() {
}
void DesktopNotificationService::GetNotificationsSettings(
- HostContentSettingsMap::SettingsForOneType* settings) {
+ ContentSettingsForOneType* settings) {
profile_->GetHostContentSettingsMap()->GetSettingsForOneType(
CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
NO_RESOURCE_IDENTIFIER,
diff --git a/chrome/browser/notifications/desktop_notification_service.h b/chrome/browser/notifications/desktop_notification_service.h
index 8ab6b4c..eed1167 100644
--- a/chrome/browser/notifications/desktop_notification_service.h
+++ b/chrome/browser/notifications/desktop_notification_service.h
@@ -14,7 +14,6 @@
#include "base/memory/scoped_ptr.h"
#include "base/string16.h"
#include "chrome/browser/content_settings/content_settings_provider.h"
-#include "chrome/browser/content_settings/host_content_settings_map.h"
#include "chrome/browser/profiles/profile_keyed_service.h"
#include "chrome/common/content_settings.h"
#include "content/public/browser/notification_observer.h"
@@ -107,8 +106,7 @@ class DesktopNotificationService : public content::NotificationObserver,
// Returns all notifications settings. |settings| is cleared before
// notifications setting are passed to it.
- void GetNotificationsSettings(
- HostContentSettingsMap::SettingsForOneType* settings);
+ void GetNotificationsSettings(ContentSettingsForOneType* settings);
// Clears the notifications setting for the given pattern.
void ClearSetting(const ContentSettingsPattern& pattern);
diff --git a/chrome/browser/notifications/desktop_notification_service_unittest.cc b/chrome/browser/notifications/desktop_notification_service_unittest.cc
index c60e627..008589f 100644
--- a/chrome/browser/notifications/desktop_notification_service_unittest.cc
+++ b/chrome/browser/notifications/desktop_notification_service_unittest.cc
@@ -8,7 +8,6 @@
#include "base/memory/scoped_ptr.h"
#include "base/message_loop.h"
#include "base/synchronization/waitable_event.h"
-#include "chrome/browser/content_settings/host_content_settings_map.h"
#include "chrome/browser/notifications/desktop_notification_service_factory.h"
#include "chrome/test/base/chrome_render_view_host_test_harness.h"
#include "chrome/test/base/testing_profile.h"
@@ -162,33 +161,33 @@ TEST_F(DesktopNotificationServiceTest, GetNotificationsSettings) {
service_->DenyPermission(GURL("http://denied2.com"));
service_->DenyPermission(GURL("http://denied.com"));
- HostContentSettingsMap::SettingsForOneType settings;
+ ContentSettingsForOneType settings;
service_->GetNotificationsSettings(&settings);
// |settings| contains the default setting and 4 exceptions.
ASSERT_EQ(5u, settings.size());
EXPECT_EQ(ContentSettingsPattern::FromURLNoWildcard(
GURL("http://allowed.com")),
- settings[0].a);
+ settings[0].primary_pattern);
EXPECT_EQ(CONTENT_SETTING_ALLOW,
- settings[0].c);
+ settings[0].setting);
EXPECT_EQ(ContentSettingsPattern::FromURLNoWildcard(
GURL("http://allowed2.com")),
- settings[1].a);
+ settings[1].primary_pattern);
EXPECT_EQ(CONTENT_SETTING_ALLOW,
- settings[1].c);
+ settings[1].setting);
EXPECT_EQ(ContentSettingsPattern::FromURLNoWildcard(
GURL("http://denied.com")),
- settings[2].a);
+ settings[2].primary_pattern);
EXPECT_EQ(CONTENT_SETTING_BLOCK,
- settings[2].c);
+ settings[2].setting);
EXPECT_EQ(ContentSettingsPattern::FromURLNoWildcard(
GURL("http://denied2.com")),
- settings[3].a);
+ settings[3].primary_pattern);
EXPECT_EQ(CONTENT_SETTING_BLOCK,
- settings[3].c);
+ settings[3].setting);
EXPECT_EQ(ContentSettingsPattern::Wildcard(),
- settings[4].a);
+ settings[4].primary_pattern);
EXPECT_EQ(CONTENT_SETTING_ASK,
- settings[4].c);
+ settings[4].setting);
}
diff --git a/chrome/browser/ui/webui/options/content_settings_handler.cc b/chrome/browser/ui/webui/options/content_settings_handler.cc
index 3ccff843..7f6b9e09 100644
--- a/chrome/browser/ui/webui/options/content_settings_handler.cc
+++ b/chrome/browser/ui/webui/options/content_settings_handler.cc
@@ -24,6 +24,7 @@
#include "chrome/browser/ui/browser_list.h"
#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/chrome_switches.h"
+#include "chrome/common/content_settings.h"
#include "chrome/common/content_settings_pattern.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
@@ -468,7 +469,7 @@ void ContentSettingsHandler::UpdateGeolocationExceptionsView() {
Profile* profile = Profile::FromWebUI(web_ui_);
HostContentSettingsMap* map = profile->GetHostContentSettingsMap();
- HostContentSettingsMap::SettingsForOneType all_settings;
+ ContentSettingsForOneType all_settings;
map->GetSettingsForOneType(
CONTENT_SETTINGS_TYPE_GEOLOCATION,
std::string(),
@@ -476,11 +477,12 @@ void ContentSettingsHandler::UpdateGeolocationExceptionsView() {
// Group geolocation settings by primary_pattern.
AllPatternsSettings all_patterns_settings;
- for (HostContentSettingsMap::SettingsForOneType::iterator i =
+ for (ContentSettingsForOneType::iterator i =
all_settings.begin();
i != all_settings.end();
++i) {
- all_patterns_settings[i->a][i->b] = i->c;
+ all_patterns_settings[i->primary_pattern][i->secondary_pattern] =
+ i->setting;
}
ListValue exceptions;
@@ -528,17 +530,17 @@ void ContentSettingsHandler::UpdateNotificationExceptionsView() {
DesktopNotificationService* service =
DesktopNotificationServiceFactory::GetForProfile(profile);
- HostContentSettingsMap::SettingsForOneType settings;
+ ContentSettingsForOneType settings;
service->GetNotificationsSettings(&settings);
ListValue exceptions;
- for (HostContentSettingsMap::SettingsForOneType::const_iterator i =
+ for (ContentSettingsForOneType::const_iterator i =
settings.begin();
i != settings.end();
++i) {
- const HostContentSettingsMap::PatternSettingSourceTuple& tuple(*i);
exceptions.Append(
- GetNotificationExceptionForPage(tuple.a, tuple.c, tuple.d));
+ GetNotificationExceptionForPage(i->primary_pattern, i->setting,
+ i->source));
}
StringValue type_string(
@@ -553,16 +555,16 @@ void ContentSettingsHandler::UpdateNotificationExceptionsView() {
void ContentSettingsHandler::UpdateExceptionsViewFromHostContentSettingsMap(
ContentSettingsType type) {
- HostContentSettingsMap::SettingsForOneType entries;
+ ContentSettingsForOneType entries;
GetContentSettingsMap()->GetSettingsForOneType(type, "", &entries);
ListValue exceptions;
for (size_t i = 0; i < entries.size(); ++i) {
// Skip default settings from extensions and policy, and the default content
// settings; all of them will affect the default setting UI.
- if (entries[i].a == ContentSettingsPattern::Wildcard() &&
- entries[i].b == ContentSettingsPattern::Wildcard() &&
- entries[i].d != "preference") {
+ if (entries[i].primary_pattern == ContentSettingsPattern::Wildcard() &&
+ entries[i].secondary_pattern == ContentSettingsPattern::Wildcard() &&
+ entries[i].source != "preference") {
continue;
}
// The content settings UI does not support secondary content settings
@@ -571,9 +573,10 @@ void ContentSettingsHandler::UpdateExceptionsViewFromHostContentSettingsMap(
// able to modify content settings with a secondary pattern other than the
// wildcard pattern. So only show settings that the user is able to modify.
// TODO(bauerb): Support a read-only view for those patterns.
- if (entries[i].b == ContentSettingsPattern::Wildcard()) {
+ if (entries[i].secondary_pattern == ContentSettingsPattern::Wildcard()) {
exceptions.Append(
- GetExceptionForPage(entries[i].a, entries[i].c, entries[i].d));
+ GetExceptionForPage(entries[i].primary_pattern, entries[i].setting,
+ entries[i].source));
} else {
LOG(ERROR) << "Secondary content settings patterns are not "
<< "supported by the content settings UI";
@@ -597,7 +600,7 @@ void ContentSettingsHandler::UpdateExceptionsViewFromOTRHostContentSettingsMap(
if (!otr_settings_map)
return;
- HostContentSettingsMap::SettingsForOneType otr_entries;
+ ContentSettingsForOneType otr_entries;
otr_settings_map->GetSettingsForOneType(type, "", &otr_entries);
ListValue otr_exceptions;
@@ -605,7 +608,7 @@ void ContentSettingsHandler::UpdateExceptionsViewFromOTRHostContentSettingsMap(
// Off-the-record HostContentSettingsMap contains incognito content settings
// as well as normal content settings. Here, we use the incongnito settings
// only.
- if (!otr_entries[i].e)
+ if (!otr_entries[i].incognito)
continue;
// The content settings UI does not support secondary content settings
// pattern yet. For content settings set through the content settings UI the
@@ -613,11 +616,12 @@ void ContentSettingsHandler::UpdateExceptionsViewFromOTRHostContentSettingsMap(
// able to modify content settings with a secondary pattern other than the
// wildcard pattern. So only show settings that the user is able to modify.
// TODO(bauerb): Support a read-only view for those patterns.
- if (otr_entries[i].b == ContentSettingsPattern::Wildcard()) {
+ if (otr_entries[i].secondary_pattern ==
+ ContentSettingsPattern::Wildcard()) {
otr_exceptions.Append(
- GetExceptionForPage(otr_entries[i].a,
- otr_entries[i].c,
- otr_entries[i].d));
+ GetExceptionForPage(otr_entries[i].primary_pattern,
+ otr_entries[i].setting,
+ otr_entries[i].source));
} else {
LOG(ERROR) << "Secondary content settings patterns are not "
<< "supported by the content settings UI";
diff --git a/chrome/common/content_settings.cc b/chrome/common/content_settings.cc
index 89eaa59..ecf26f8 100644
--- a/chrome/common/content_settings.cc
+++ b/chrome/common/content_settings.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// 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.
@@ -9,3 +9,27 @@ ContentSetting IntToContentSetting(int content_setting) {
(content_setting >= CONTENT_SETTING_NUM_SETTINGS)) ?
CONTENT_SETTING_DEFAULT : static_cast<ContentSetting>(content_setting);
}
+
+ContentSettings::ContentSettings() {
+ for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i)
+ settings[i] = CONTENT_SETTING_DEFAULT;
+}
+
+ContentSettings::ContentSettings(ContentSetting default_setting) {
+ for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i)
+ settings[i] = default_setting;
+}
+
+ContentSettingPatternSource::ContentSettingPatternSource(
+ const ContentSettingsPattern& primary_pattern,
+ const ContentSettingsPattern& secondary_pattern,
+ ContentSetting setting,
+ const std::string& source,
+ bool incognito)
+ : primary_pattern(primary_pattern),
+ secondary_pattern(secondary_pattern),
+ setting(setting),
+ source(source),
+ incognito(incognito) {}
+
+ContentSettingPatternSource::ContentSettingPatternSource() {}
diff --git a/chrome/common/content_settings.h b/chrome/common/content_settings.h
index 4731263..2c7e5c2 100644
--- a/chrome/common/content_settings.h
+++ b/chrome/common/content_settings.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// 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.
@@ -6,6 +6,10 @@
#define CHROME_COMMON_CONTENT_SETTINGS_H_
#pragma once
+#include <string>
+#include <vector>
+
+#include "chrome/common/content_settings_pattern.h"
#include "chrome/common/content_settings_types.h"
// Different settings that can be assigned for a particular content type. We
@@ -25,17 +29,26 @@ ContentSetting IntToContentSetting(int content_setting);
// Aggregates the permissions for the different content types.
struct ContentSettings {
- ContentSettings() {
- for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i)
- settings[i] = CONTENT_SETTING_DEFAULT;
- }
-
- explicit ContentSettings(ContentSetting default_setting) {
- for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i)
- settings[i] = default_setting;
- }
+ ContentSettings();
+ explicit ContentSettings(ContentSetting default_setting);
ContentSetting settings[CONTENT_SETTINGS_NUM_TYPES];
};
+struct ContentSettingPatternSource {
+ ContentSettingPatternSource(const ContentSettingsPattern& primary_pattern,
+ const ContentSettingsPattern& secondary_patttern,
+ ContentSetting setting,
+ const std::string& source,
+ bool incognito);
+ ContentSettingPatternSource();
+ ContentSettingsPattern primary_pattern;
+ ContentSettingsPattern secondary_pattern;
+ ContentSetting setting;
+ std::string source;
+ bool incognito;
+};
+
+typedef std::vector<ContentSettingPatternSource> ContentSettingsForOneType;
+
#endif // CHROME_COMMON_CONTENT_SETTINGS_H_
diff --git a/chrome/common/extensions/api/extension_api.json b/chrome/common/extensions/api/extension_api.json
index 7745b84..9202df4 100644
--- a/chrome/common/extensions/api/extension_api.json
+++ b/chrome/common/extensions/api/extension_api.json
@@ -8380,7 +8380,7 @@
},
"images": {
"$ref": "ContentSetting",
- "description": "Whether to show images. One of<br><var>allow</var>: Show images,<br><var>block</var>: Don't show images. <br>Default is <var>allow</var>.<br>The primary URL is the main-frame URL. The secondary URL is not used.",
+ "description": "Whether to show images. One of<br><var>allow</var>: Show images,<br><var>block</var>: Don't show images. <br>Default is <var>allow</var>.<br>The primary URL is the main-frame URL. The secondary URL is the URL of the image.",
"value": [
"images",
{"type":"string", "enum": ["allow", "block"]}
diff --git a/chrome/common/extensions/docs/contentSettings.html b/chrome/common/extensions/docs/contentSettings.html
index ba82881..86ea6df 100644
--- a/chrome/common/extensions/docs/contentSettings.html
+++ b/chrome/common/extensions/docs/contentSettings.html
@@ -628,7 +628,7 @@ You can find samples of this API on the
<dd class="todo" style="display: none; ">
Undocumented.
</dd>
- <dd>Whether to show images. One of<br><var>allow</var>: Show images,<br><var>block</var>: Don't show images. <br>Default is <var>allow</var>.<br>The primary URL is the main-frame URL. The secondary URL is not used.</dd>
+ <dd>Whether to show images. One of<br><var>allow</var>: Show images,<br><var>block</var>: Don't show images. <br>Default is <var>allow</var>.<br>The primary URL is the main-frame URL. The secondary URL is the URL of the image.</dd>
<dd style="display: none; ">
This parameter was added in version
<b><span></span></b>.
diff --git a/chrome/common/render_messages.h b/chrome/common/render_messages.h
index b7af0d1..87822fb 100644
--- a/chrome/common/render_messages.h
+++ b/chrome/common/render_messages.h
@@ -17,6 +17,7 @@
#include "base/values.h"
#include "build/build_config.h"
#include "chrome/common/common_param_traits.h"
+#include "chrome/common/content_settings.h"
#include "chrome/common/content_settings_pattern.h"
#include "chrome/common/instant_types.h"
#include "chrome/common/nacl_types.h"
@@ -136,6 +137,14 @@ IPC_STRUCT_TRAITS_BEGIN(ContentSettingsPattern::PatternParts)
IPC_STRUCT_TRAITS_MEMBER(path)
IPC_STRUCT_TRAITS_END()
+IPC_STRUCT_TRAITS_BEGIN(ContentSettingPatternSource)
+ IPC_STRUCT_TRAITS_MEMBER(primary_pattern)
+ IPC_STRUCT_TRAITS_MEMBER(secondary_pattern)
+ IPC_STRUCT_TRAITS_MEMBER(setting)
+ IPC_STRUCT_TRAITS_MEMBER(source)
+ IPC_STRUCT_TRAITS_MEMBER(incognito)
+IPC_STRUCT_TRAITS_END()
+
IPC_STRUCT_TRAITS_BEGIN(ThumbnailScore)
IPC_STRUCT_TRAITS_MEMBER(boring_score)
IPC_STRUCT_TRAITS_MEMBER(good_clipping)
@@ -233,6 +242,10 @@ IPC_MESSAGE_CONTROL2(ChromeViewMsg_SetContentSettingsForCurrentURL,
IPC_MESSAGE_CONTROL1(ChromeViewMsg_SetDefaultContentSettings,
ContentSettings /* content_settings */)
+// Set the content settings for images.
+IPC_MESSAGE_CONTROL1(ChromeViewMsg_SetImageSettingRules,
+ ContentSettingsForOneType /* rules */)
+
// Tells the render view to load all blocked plugins.
IPC_MESSAGE_ROUTED0(ChromeViewMsg_LoadBlockedPlugins)
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc
index ec598ef..5c461a7 100644
--- a/chrome/renderer/chrome_content_renderer_client.cc
+++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -225,6 +225,10 @@ void ChromeContentRendererClient::RenderViewCreated(
content::RenderView* render_view) {
ContentSettingsObserver* content_settings =
new ContentSettingsObserver(render_view);
+ if (chrome_observer_.get()) {
+ content_settings->SetImageSettingRules(
+ chrome_observer_->image_setting_rules());
+ }
new ExtensionHelper(render_view, extension_dispatcher_.get());
new PageLoadHistograms(render_view, histogram_snapshots_.get());
new PrintWebViewHelper(render_view);
diff --git a/chrome/renderer/chrome_render_process_observer.cc b/chrome/renderer/chrome_render_process_observer.cc
index b642d61..41e6f97 100644
--- a/chrome/renderer/chrome_render_process_observer.cc
+++ b/chrome/renderer/chrome_render_process_observer.cc
@@ -267,6 +267,8 @@ bool ChromeRenderProcessObserver::OnControlMessageReceived(
OnSetDefaultContentSettings)
IPC_MESSAGE_HANDLER(ChromeViewMsg_SetContentSettingsForCurrentURL,
OnSetContentSettingsForCurrentURL)
+ IPC_MESSAGE_HANDLER(ChromeViewMsg_SetImageSettingRules,
+ OnSetImageSettingRules)
IPC_MESSAGE_HANDLER(ChromeViewMsg_SetCacheCapacities, OnSetCacheCapacities)
IPC_MESSAGE_HANDLER(ChromeViewMsg_ClearCache, OnClearCache)
IPC_MESSAGE_HANDLER(ChromeViewMsg_SetFieldTrialGroup, OnSetFieldTrialGroup)
@@ -308,6 +310,11 @@ void ChromeRenderProcessObserver::OnSetDefaultContentSettings(
ContentSettingsObserver::SetDefaultContentSettings(content_settings);
}
+void ChromeRenderProcessObserver::OnSetImageSettingRules(
+ const ContentSettingsForOneType& settings) {
+ image_setting_rules_ = settings;
+}
+
void ChromeRenderProcessObserver::OnSetCacheCapacities(size_t min_dead_capacity,
size_t max_dead_capacity,
size_t capacity) {
@@ -422,3 +429,8 @@ void ChromeRenderProcessObserver::ExecutePendingClearCache() {
WebCache::clear();
}
}
+
+const ContentSettingsForOneType*
+ChromeRenderProcessObserver::image_setting_rules() const {
+ return &image_setting_rules_;
+}
diff --git a/chrome/renderer/chrome_render_process_observer.h b/chrome/renderer/chrome_render_process_observer.h
index 7c14c24..44477b8 100644
--- a/chrome/renderer/chrome_render_process_observer.h
+++ b/chrome/renderer/chrome_render_process_observer.h
@@ -11,6 +11,7 @@
#include "base/compiler_specific.h"
#include "base/file_path.h"
#include "base/memory/scoped_ptr.h"
+#include "chrome/common/content_settings.h"
#include "content/public/renderer/render_process_observer.h"
class GURL;
@@ -40,6 +41,10 @@ class ChromeRenderProcessObserver : public content::RenderProcessObserver {
// any 'clear cache' commands that were delayed until the next navigation.
void ExecutePendingClearCache();
+ // Returns a pointer to the image setting rules owned by
+ // |ChromeRenderProcessObserver|.
+ const ContentSettingsForOneType* image_setting_rules() const;
+
private:
// RenderProcessObserver implementation.
virtual bool OnControlMessageReceived(const IPC::Message& message) OVERRIDE;
@@ -49,6 +54,7 @@ class ChromeRenderProcessObserver : public content::RenderProcessObserver {
void OnSetContentSettingsForCurrentURL(
const GURL& url, const ContentSettings& content_settings);
void OnSetDefaultContentSettings(const ContentSettings& content_settings);
+ void OnSetImageSettingRules(const ContentSettingsForOneType& settings);
void OnSetCacheCapacities(size_t min_dead_capacity,
size_t max_dead_capacity,
size_t capacity);
@@ -69,6 +75,7 @@ class ChromeRenderProcessObserver : public content::RenderProcessObserver {
chrome::ChromeContentRendererClient* client_;
// If true, the web cache shall be cleared before the next navigation event.
bool clear_cache_pending_;
+ ContentSettingsForOneType image_setting_rules_;
DISALLOW_COPY_AND_ASSIGN(ChromeRenderProcessObserver);
};
diff --git a/chrome/renderer/content_settings_observer.cc b/chrome/renderer/content_settings_observer.cc
index 94150e6..525159f 100644
--- a/chrome/renderer/content_settings_observer.cc
+++ b/chrome/renderer/content_settings_observer.cc
@@ -50,6 +50,15 @@ static bool IsWhitelistedForContentSettings(WebFrame* frame) {
return false;
}
+GURL GetOriginOrURL(const WebFrame* frame) {
+ WebString top_origin = frame->top()->document().securityOrigin().toString();
+ // The the |top_origin| is unique ("null") e.g., for file:// URLs. Use the
+ // document URL as the primary URL in those cases.
+ if (top_origin == "null")
+ return frame->document().url();
+ return GURL(top_origin);
+}
+
} // namespace
ContentSettings ContentSettingsObserver::default_settings_;
@@ -75,6 +84,11 @@ void ContentSettingsObserver::SetDefaultContentSettings(
default_settings_ = settings;
}
+void ContentSettingsObserver::SetImageSettingRules(
+ const ContentSettingsForOneType* image_setting_rules) {
+ image_setting_rules_ = image_setting_rules;
+}
+
ContentSetting ContentSettingsObserver::GetContentSetting(
ContentSettingsType type) {
// Don't call this for plug-ins.
@@ -118,7 +132,7 @@ void ContentSettingsObserver::DidCommitProvisionalLoad(
NavigationState* state = NavigationState::FromDataSource(frame->dataSource());
if (!state->was_within_same_page()) {
// Clear "block" flags for the new page. This needs to happen before any of
- // allowScripts(), allowImages(), allowPlugins() is called for the new page
+ // allowScripts(), allowImage(), allowPlugins() is called for the new page
// so that these functions can correctly detect that a piece of content
// flipped from "not blocked" to "blocked".
ClearBlockedContentSettings();
@@ -198,16 +212,28 @@ bool ContentSettingsObserver::AllowFileSystem(WebFrame* frame) {
bool ContentSettingsObserver::AllowImage(WebFrame* frame,
bool enabled_per_settings,
const WebURL& image_url) {
- if (enabled_per_settings &&
- AllowContentType(CONTENT_SETTINGS_TYPE_IMAGES)) {
- return true;
- }
-
if (IsWhitelistedForContentSettings(frame))
return true;
- DidBlockContentType(CONTENT_SETTINGS_TYPE_IMAGES, std::string());
- return false; // Other protocols fall through here.
+ bool allow = enabled_per_settings;
+ const GURL& primary_url = GetOriginOrURL(frame);
+ GURL secondary_url(image_url);
+ if (image_setting_rules_ &&
+ enabled_per_settings) {
+ ContentSettingsForOneType::const_iterator it;
+ for (it = image_setting_rules_->begin();
+ it != image_setting_rules_->end(); ++it) {
+ if (it->primary_pattern.Matches(primary_url) &&
+ it->secondary_pattern.Matches(secondary_url)) {
+ allow = (it->setting != CONTENT_SETTING_BLOCK);
+ break;
+ }
+ }
+ }
+
+ if (!allow)
+ DidBlockContentType(CONTENT_SETTINGS_TYPE_IMAGES, std::string());
+ return allow;
}
bool ContentSettingsObserver::AllowIndexedDB(WebFrame* frame,
diff --git a/chrome/renderer/content_settings_observer.h b/chrome/renderer/content_settings_observer.h
index 45f2125..3055caa 100644
--- a/chrome/renderer/content_settings_observer.h
+++ b/chrome/renderer/content_settings_observer.h
@@ -27,14 +27,19 @@ class ContentSettingsObserver
explicit ContentSettingsObserver(content::RenderView* render_view);
virtual ~ContentSettingsObserver();
- // Sets the content settings that back allowScripts(), allowImages(), and
- // allowPlugins().
+ // Sets the content settings that back allowScripts() and allowPlugins().
void SetContentSettings(const ContentSettings& settings);
- // Sets the default content settings that back allowScripts(),
- // allowImages(), and allowPlugins().
+ // Sets the default content settings that back allowScripts() and
+ // allowPlugins().
static void SetDefaultContentSettings(const ContentSettings& settings);
+ // Sets the image setting rules which back |allowImage()|. The
+ // |ContentSettingsForOneType| object must outlive this
+ // |ContentSettingsObserver|.
+ void SetImageSettingRules(
+ const ContentSettingsForOneType* image_setting_rules);
+
// Returns the setting for the given type.
ContentSetting GetContentSetting(ContentSettingsType type);
@@ -90,11 +95,17 @@ class ContentSettingsObserver
HostContentSettings host_content_settings_;
// Stores our most up-to-date view of the default content settings.
+ // TODO(marja): Store default settings in |ChromeRenderProcessObserver|.
static ContentSettings default_settings_;
- // Stores if loading of images, scripts, and plugins is allowed.
+ // Stores if loading of scripts and plugins is allowed.
ContentSettings current_content_settings_;
+ // Stores the rules for image content settings. Normally, they are owned by
+ // |ChromeRenderProcessObserver|; in the tests they are owned by the caller of
+ // |SetImageSettingRules|.
+ const ContentSettingsForOneType* image_setting_rules_;
+
// Stores if images, scripts, and plugins have actually been blocked.
bool content_blocked_[CONTENT_SETTINGS_NUM_TYPES];
diff --git a/chrome/renderer/content_settings_observer_browsertest.cc b/chrome/renderer/content_settings_observer_browsertest.cc
index ceaaee1..9326407 100644
--- a/chrome/renderer/content_settings_observer_browsertest.cc
+++ b/chrome/renderer/content_settings_observer_browsertest.cc
@@ -28,11 +28,15 @@ class MockContentSettingsObserver : public ContentSettingsObserver {
MOCK_METHOD5(OnAllowDOMStorage,
void(int, const GURL&, const GURL&, bool, IPC::Message*));
+ GURL image_url_;
+ std::string image_origin_;
};
MockContentSettingsObserver::MockContentSettingsObserver(
content::RenderView* render_view)
- : ContentSettingsObserver(render_view) {
+ : ContentSettingsObserver(render_view),
+ image_url_("http://www.foo.com/image.jpg"),
+ image_origin_("http://www.foo.com") {
}
bool MockContentSettingsObserver::Send(IPC::Message* message) {
@@ -162,3 +166,84 @@ TEST_F(ChromeRenderViewTest, PluginsTemporarilyAllowed) {
LoadHTML("<html>Bar</html>");
EXPECT_FALSE(observer->plugins_temporarily_allowed());
}
+
+TEST_F(ChromeRenderViewTest, ImagesBlockedByDefault) {
+ MockContentSettingsObserver mock_observer(view_);
+
+ // Load some HTML.
+ LoadHTML("<html>Foo</html>");
+
+ // Set the default image blocking setting.
+ ContentSettingsForOneType image_setting_rules;
+ image_setting_rules.push_back(
+ ContentSettingPatternSource(ContentSettingsPattern::Wildcard(),
+ ContentSettingsPattern::Wildcard(),
+ CONTENT_SETTING_BLOCK,
+ "",
+ false));
+
+ ContentSettingsObserver* observer = ContentSettingsObserver::Get(view_);
+ observer->SetImageSettingRules(&image_setting_rules);
+ EXPECT_CALL(mock_observer,
+ OnContentBlocked(CONTENT_SETTINGS_TYPE_IMAGES, std::string()));
+ EXPECT_FALSE(observer->AllowImage(GetMainFrame(),
+ true, mock_observer.image_url_));
+ ::testing::Mock::VerifyAndClearExpectations(&observer);
+
+ // Create an exception which allows the image.
+ image_setting_rules.insert(
+ image_setting_rules.begin(),
+ ContentSettingPatternSource(
+ ContentSettingsPattern::Wildcard(),
+ ContentSettingsPattern::FromString(mock_observer.image_origin_),
+ CONTENT_SETTING_ALLOW,
+ "",
+ false));
+
+ EXPECT_CALL(
+ mock_observer,
+ OnContentBlocked(CONTENT_SETTINGS_TYPE_IMAGES, std::string())).Times(0);
+ EXPECT_TRUE(observer->AllowImage(GetMainFrame(), true,
+ mock_observer.image_url_));
+ ::testing::Mock::VerifyAndClearExpectations(&observer);
+}
+
+TEST_F(ChromeRenderViewTest, ImagesAllowedByDefault) {
+ MockContentSettingsObserver mock_observer(view_);
+
+ // Load some HTML.
+ LoadHTML("<html>Foo</html>");
+
+ // Set the default image blocking setting.
+ ContentSettingsForOneType image_setting_rules;
+ image_setting_rules.push_back(
+ ContentSettingPatternSource(ContentSettingsPattern::Wildcard(),
+ ContentSettingsPattern::Wildcard(),
+ CONTENT_SETTING_ALLOW,
+ "",
+ false));
+
+ ContentSettingsObserver* observer = ContentSettingsObserver::Get(view_);
+ observer->SetImageSettingRules(&image_setting_rules);
+ EXPECT_CALL(
+ mock_observer,
+ OnContentBlocked(CONTENT_SETTINGS_TYPE_IMAGES, std::string())).Times(0);
+ EXPECT_TRUE(observer->AllowImage(GetMainFrame(), true,
+ mock_observer.image_url_));
+ ::testing::Mock::VerifyAndClearExpectations(&observer);
+
+ // Create an exception which blocks the image.
+ image_setting_rules.insert(
+ image_setting_rules.begin(),
+ ContentSettingPatternSource(
+ ContentSettingsPattern::Wildcard(),
+ ContentSettingsPattern::FromString(mock_observer.image_origin_),
+ CONTENT_SETTING_BLOCK,
+ "",
+ false));
+ EXPECT_CALL(mock_observer,
+ OnContentBlocked(CONTENT_SETTINGS_TYPE_IMAGES, std::string()));
+ EXPECT_FALSE(observer->AllowImage(GetMainFrame(),
+ true, mock_observer.image_url_));
+ ::testing::Mock::VerifyAndClearExpectations(&observer);
+}