summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcmp@chromium.org <cmp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-10 01:46:50 +0000
committercmp@chromium.org <cmp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-10 01:46:50 +0000
commitbfc2b4cbaa865df05976d73b989d321277b757aa (patch)
treea1f39f532ac30a15954cdfc56b5c980b2c268884
parent063b841e1b7462f9af20d8a5e1613c0effe97a72 (diff)
downloadchromium_src-bfc2b4cbaa865df05976d73b989d321277b757aa.zip
chromium_src-bfc2b4cbaa865df05976d73b989d321277b757aa.tar.gz
chromium_src-bfc2b4cbaa865df05976d73b989d321277b757aa.tar.bz2
Revert 109228 - ContentSettingsObserver (+ related classes) cleanup.
<cmp> This CL needs to be reverted before we revert 109213, which we speculate caused some performance regressions. Per-page content settings and default content settings are no longer needed, since the renderer stores the content setting rules for images and scripts. BUG=102662 TEST=NONE Review URL: http://codereview.chromium.org/8498007 TBR=marja@chromium.org Review URL: http://codereview.chromium.org/8497062 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@109360 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/content_settings/content_settings_default_provider.cc33
-rw-r--r--chrome/browser/content_settings/content_settings_default_provider.h4
-rw-r--r--chrome/browser/content_settings/content_settings_pref_provider_unittest.cc9
-rw-r--r--chrome/browser/content_settings/host_content_settings_map.cc27
-rw-r--r--chrome/browser/content_settings/host_content_settings_map.h13
-rw-r--r--chrome/browser/content_settings/host_content_settings_map_unittest.cc145
-rw-r--r--chrome/browser/content_settings/mock_settings_observer.cc3
-rw-r--r--chrome/browser/content_settings/tab_specific_content_settings.cc17
-rw-r--r--chrome/browser/content_settings/tab_specific_content_settings.h1
-rw-r--r--chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc10
-rw-r--r--chrome/common/content_settings.cc10
-rw-r--r--chrome/common/content_settings.h8
-rw-r--r--chrome/common/render_messages.cc20
-rw-r--r--chrome/common/render_messages.h27
-rw-r--r--chrome/renderer/chrome_content_renderer_client.cc2
-rw-r--r--chrome/renderer/chrome_render_process_observer.cc45
-rw-r--r--chrome/renderer/chrome_render_process_observer.h6
-rw-r--r--chrome/renderer/content_settings_observer.cc73
-rw-r--r--chrome/renderer/content_settings_observer.h28
-rw-r--r--chrome/renderer/content_settings_observer_browsertest.cc7
20 files changed, 404 insertions, 84 deletions
diff --git a/chrome/browser/content_settings/content_settings_default_provider.cc b/chrome/browser/content_settings/content_settings_default_provider.cc
index d70a4d0..d1ff977 100644
--- a/chrome/browser/content_settings/content_settings_default_provider.cc
+++ b/chrome/browser/content_settings/content_settings_default_provider.cc
@@ -109,7 +109,7 @@ DefaultProvider::DefaultProvider(PrefService* prefs, bool incognito)
// Read global defaults.
ReadDefaultSettings(true);
- if (default_content_settings_[CONTENT_SETTINGS_TYPE_COOKIES] ==
+ if (default_content_settings_.settings[CONTENT_SETTINGS_TYPE_COOKIES] ==
CONTENT_SETTING_BLOCK) {
UserMetrics::RecordAction(
UserMetricsAction("CookieBlockingEnabledPerDefault"));
@@ -161,12 +161,12 @@ void DefaultProvider::SetContentSetting(
base::AutoLock lock(lock_);
if (setting == CONTENT_SETTING_DEFAULT ||
setting == kDefaultSettings[content_type]) {
- default_content_settings_[content_type] =
+ default_content_settings_.settings[content_type] =
kDefaultSettings[content_type];
default_settings_dictionary->RemoveWithoutPathExpansion(dictionary_path,
NULL);
} else {
- default_content_settings_[content_type] = setting;
+ default_content_settings_.settings[content_type] = setting;
default_settings_dictionary->SetWithoutPathExpansion(
dictionary_path, Value::CreateIntegerValue(setting));
}
@@ -194,7 +194,7 @@ RuleIterator* DefaultProvider::GetRuleIterator(
base::AutoLock lock(lock_);
if (resource_identifier.empty()) {
return new DefaultRuleIterator(
- default_content_settings_[content_type]);
+ default_content_settings_.settings[content_type]);
} else {
return new EmptyRuleIterator();
}
@@ -254,29 +254,27 @@ void DefaultProvider::ReadDefaultSettings(bool overwrite) {
const DictionaryValue* default_settings_dictionary =
prefs_->GetDictionary(prefs::kDefaultContentSettings);
- if (overwrite) {
- for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i)
- default_content_settings_[i] = CONTENT_SETTING_DEFAULT;
- }
+ if (overwrite)
+ default_content_settings_ = ContentSettings();
// Careful: The returned value could be NULL if the pref has never been set.
if (default_settings_dictionary) {
GetSettingsFromDictionary(default_settings_dictionary,
- default_content_settings_);
+ &default_content_settings_);
}
ForceDefaultsToBeExplicit();
}
void DefaultProvider::ForceDefaultsToBeExplicit() {
for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) {
- if (default_content_settings_[i] == CONTENT_SETTING_DEFAULT)
- default_content_settings_[i] = kDefaultSettings[i];
+ if (default_content_settings_.settings[i] == CONTENT_SETTING_DEFAULT)
+ default_content_settings_.settings[i] = kDefaultSettings[i];
}
}
void DefaultProvider::GetSettingsFromDictionary(
const DictionaryValue* dictionary,
- ContentSetting* settings) {
+ ContentSettings* settings) {
for (DictionaryValue::key_iterator i(dictionary->begin_keys());
i != dictionary->end_keys(); ++i) {
const std::string& content_type(*i);
@@ -286,18 +284,19 @@ void DefaultProvider::GetSettingsFromDictionary(
bool found = dictionary->GetIntegerWithoutPathExpansion(content_type,
&setting);
DCHECK(found);
- settings[type] = IntToContentSetting(setting);
+ settings->settings[type] = IntToContentSetting(setting);
break;
}
}
}
// Migrate obsolete cookie prompt mode/
- if (settings[CONTENT_SETTINGS_TYPE_COOKIES] == CONTENT_SETTING_ASK)
- settings[CONTENT_SETTINGS_TYPE_COOKIES] = CONTENT_SETTING_BLOCK;
+ if (settings->settings[CONTENT_SETTINGS_TYPE_COOKIES] ==
+ CONTENT_SETTING_ASK)
+ settings->settings[CONTENT_SETTINGS_TYPE_COOKIES] = CONTENT_SETTING_BLOCK;
- settings[CONTENT_SETTINGS_TYPE_PLUGINS] =
+ settings->settings[CONTENT_SETTINGS_TYPE_PLUGINS] =
ClickToPlayFixup(CONTENT_SETTINGS_TYPE_PLUGINS,
- settings[CONTENT_SETTINGS_TYPE_PLUGINS]);
+ settings->settings[CONTENT_SETTINGS_TYPE_PLUGINS]);
}
void DefaultProvider::MigrateObsoleteNotificationPref() {
diff --git a/chrome/browser/content_settings/content_settings_default_provider.h b/chrome/browser/content_settings/content_settings_default_provider.h
index f9ddaff..f4a9c34 100644
--- a/chrome/browser/content_settings/content_settings_default_provider.h
+++ b/chrome/browser/content_settings/content_settings_default_provider.h
@@ -57,7 +57,7 @@ class DefaultProvider : public ObservableProvider,
private:
// Sets the fields of |settings| based on the values in |dictionary|.
void GetSettingsFromDictionary(const base::DictionaryValue* dictionary,
- ContentSetting* settings);
+ ContentSettings* settings);
// Forces the default settings to be explicitly set instead of themselves
// being CONTENT_SETTING_DEFAULT.
@@ -71,7 +71,7 @@ class DefaultProvider : public ObservableProvider,
void MigrateObsoleteGeolocationPref();
// Copies of the pref data, so that we can read it on the IO thread.
- ContentSetting default_content_settings_[CONTENT_SETTINGS_NUM_TYPES];
+ ContentSettings default_content_settings_;
PrefService* prefs_;
diff --git a/chrome/browser/content_settings/content_settings_pref_provider_unittest.cc b/chrome/browser/content_settings/content_settings_pref_provider_unittest.cc
index edefe97..50e56ff 100644
--- a/chrome/browser/content_settings/content_settings_pref_provider_unittest.cc
+++ b/chrome/browser/content_settings/content_settings_pref_provider_unittest.cc
@@ -53,6 +53,15 @@ void ExpectObsoleteGeolocationSetting(
namespace content_settings {
+bool SettingsEqual(const ContentSettings& settings1,
+ const ContentSettings& settings2) {
+ for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) {
+ if (settings1.settings[i] != settings2.settings[i])
+ return false;
+ }
+ return true;
+}
+
class DeadlockCheckerThread : public base::PlatformThread::Delegate {
public:
explicit DeadlockCheckerThread(PrefProvider* provider)
diff --git a/chrome/browser/content_settings/host_content_settings_map.cc b/chrome/browser/content_settings/host_content_settings_map.cc
index 2c09ad2..b0baa04 100644
--- a/chrome/browser/content_settings/host_content_settings_map.cc
+++ b/chrome/browser/content_settings/host_content_settings_map.cc
@@ -163,6 +163,16 @@ ContentSetting HostContentSettingsMap::GetDefaultContentSetting(
return CONTENT_SETTING_DEFAULT;
}
+ContentSettings HostContentSettingsMap::GetDefaultContentSettings() const {
+ ContentSettings output(CONTENT_SETTING_DEFAULT);
+ for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) {
+ if (!ContentTypeHasCompoundValue(ContentSettingsType(i)))
+ output.settings[i] = GetDefaultContentSetting(ContentSettingsType(i),
+ NULL);
+ }
+ return output;
+}
+
ContentSetting HostContentSettingsMap::GetContentSetting(
const GURL& primary_url,
const GURL& secondary_url,
@@ -173,6 +183,23 @@ ContentSetting HostContentSettingsMap::GetContentSetting(
return content_settings::ValueToContentSetting(value.get());
}
+ContentSettings HostContentSettingsMap::GetContentSettings(
+ const GURL& primary_url) const {
+ ContentSettings output;
+ // If we require a resource identifier, set the content settings to default,
+ // otherwise make the defaults explicit. Values for content type
+ // CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE can't be mapped to the type
+ // |ContentSetting|. So we ignore them here.
+ for (int j = 0; j < CONTENT_SETTINGS_NUM_TYPES; ++j) {
+ ContentSettingsType type = ContentSettingsType(j);
+ if (!ContentTypeHasCompoundValue(type)) {
+ output.settings[j] = GetContentSetting(
+ primary_url, primary_url, ContentSettingsType(j), std::string());
+ }
+ }
+ return output;
+}
+
void HostContentSettingsMap::GetSettingsForOneType(
ContentSettingsType content_type,
const std::string& resource_identifier,
diff --git a/chrome/browser/content_settings/host_content_settings_map.h b/chrome/browser/content_settings/host_content_settings_map.h
index a6f8700..7c91008 100644
--- a/chrome/browser/content_settings/host_content_settings_map.h
+++ b/chrome/browser/content_settings/host_content_settings_map.h
@@ -60,6 +60,11 @@ class HostContentSettingsMap
ContentSetting GetDefaultContentSetting(ContentSettingsType content_type,
std::string* provider_id) const;
+ // Returns the default settings for all content types.
+ //
+ // This may be called on any thread.
+ ContentSettings GetDefaultContentSettings() const;
+
// Returns a single |ContentSetting| which applies to the given URLs. Note
// that certain internal schemes are whitelisted. For |CONTENT_TYPE_COOKIES|,
// |CookieSettings| should be used instead. For content types that can't be
@@ -93,6 +98,14 @@ class HostContentSettingsMap
const std::string& resource_identifier,
content_settings::SettingInfo* info) const;
+ // Returns all ContentSettings which apply to the given |primary_url|. For
+ // content setting types that require an additional resource identifier, the
+ // default content setting is returned.
+ //
+ // This may be called on any thread.
+ ContentSettings GetContentSettings(
+ const GURL& primary_url) const;
+
// For a given content type, returns all patterns with a non-default setting,
// mapped to their actual settings, in the precedence order of the rules.
// |settings| must be a non-NULL outparam.
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 44fd8db..0965bc3 100644
--- a/chrome/browser/content_settings/host_content_settings_map_unittest.cc
+++ b/chrome/browser/content_settings/host_content_settings_map_unittest.cc
@@ -26,6 +26,23 @@ using content::BrowserThread;
using ::testing::_;
+namespace {
+
+bool SettingsEqual(const ContentSettings& settings1,
+ const ContentSettings& settings2) {
+ for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) {
+ if (settings1.settings[i] != settings2.settings[i]) {
+ LOG(ERROR) << "type: " << i
+ << " [expected: " << settings1.settings[i]
+ << " actual: " << settings2.settings[i] << "]";
+ return false;
+ }
+ }
+ return true;
+}
+
+} // namespace
+
class HostContentSettingsMapTest : public testing::Test {
public:
HostContentSettingsMapTest() : ui_thread_(BrowserThread::UI, &message_loop_) {
@@ -109,51 +126,48 @@ TEST_F(HostContentSettingsMapTest, IndividualSettings) {
host, host, CONTENT_SETTINGS_TYPE_PLUGINS, ""));
// Check returning all settings for a host.
+ ContentSettings desired_settings;
+ desired_settings.settings[CONTENT_SETTINGS_TYPE_COOKIES] =
+ CONTENT_SETTING_ALLOW;
host_content_settings_map->SetContentSetting(
pattern,
ContentSettingsPattern::Wildcard(),
CONTENT_SETTINGS_TYPE_IMAGES,
std::string(),
CONTENT_SETTING_DEFAULT);
- EXPECT_EQ(CONTENT_SETTING_ALLOW,
- host_content_settings_map->GetContentSetting(
- host, host, CONTENT_SETTINGS_TYPE_IMAGES, ""));
+ desired_settings.settings[CONTENT_SETTINGS_TYPE_IMAGES] =
+ CONTENT_SETTING_ALLOW;
host_content_settings_map->SetContentSetting(
pattern,
ContentSettingsPattern::Wildcard(),
CONTENT_SETTINGS_TYPE_JAVASCRIPT,
std::string(),
CONTENT_SETTING_BLOCK);
- EXPECT_EQ(CONTENT_SETTING_BLOCK,
- host_content_settings_map->GetContentSetting(
- host, host, CONTENT_SETTINGS_TYPE_JAVASCRIPT, ""));
+ desired_settings.settings[CONTENT_SETTINGS_TYPE_JAVASCRIPT] =
+ CONTENT_SETTING_BLOCK;
host_content_settings_map->SetContentSetting(
pattern,
ContentSettingsPattern::Wildcard(),
CONTENT_SETTINGS_TYPE_PLUGINS,
std::string(),
CONTENT_SETTING_ALLOW);
- EXPECT_EQ(CONTENT_SETTING_ALLOW,
- host_content_settings_map->GetContentSetting(
- host, host, CONTENT_SETTINGS_TYPE_PLUGINS, ""));
- EXPECT_EQ(CONTENT_SETTING_BLOCK,
- host_content_settings_map->GetContentSetting(
- host, host, CONTENT_SETTINGS_TYPE_POPUPS, ""));
- EXPECT_EQ(CONTENT_SETTING_ASK,
- host_content_settings_map->GetContentSetting(
- host, host, CONTENT_SETTINGS_TYPE_GEOLOCATION, ""));
- EXPECT_EQ(CONTENT_SETTING_ASK,
- host_content_settings_map->GetContentSetting(
- host, host, CONTENT_SETTINGS_TYPE_NOTIFICATIONS, ""));
- EXPECT_EQ(CONTENT_SETTING_ASK,
- host_content_settings_map->GetContentSetting(
- host, host, CONTENT_SETTINGS_TYPE_INTENTS, ""));
- EXPECT_EQ(CONTENT_SETTING_ASK,
- host_content_settings_map->GetContentSetting(
- host, host, CONTENT_SETTINGS_TYPE_FULLSCREEN, ""));
- EXPECT_EQ(CONTENT_SETTING_ASK,
- host_content_settings_map->GetContentSetting(
- host, host, CONTENT_SETTINGS_TYPE_MOUSELOCK, ""));
+ desired_settings.settings[CONTENT_SETTINGS_TYPE_PLUGINS] =
+ CONTENT_SETTING_ALLOW;
+ desired_settings.settings[CONTENT_SETTINGS_TYPE_POPUPS] =
+ CONTENT_SETTING_BLOCK;
+ desired_settings.settings[CONTENT_SETTINGS_TYPE_GEOLOCATION] =
+ CONTENT_SETTING_ASK;
+ desired_settings.settings[CONTENT_SETTINGS_TYPE_NOTIFICATIONS] =
+ CONTENT_SETTING_ASK;
+ desired_settings.settings[CONTENT_SETTINGS_TYPE_INTENTS] =
+ CONTENT_SETTING_ASK;
+ desired_settings.settings[CONTENT_SETTINGS_TYPE_FULLSCREEN] =
+ CONTENT_SETTING_ASK;
+ desired_settings.settings[CONTENT_SETTINGS_TYPE_MOUSELOCK] =
+ CONTENT_SETTING_ASK;
+ ContentSettings settings =
+ host_content_settings_map->GetContentSettings(host);
+ EXPECT_TRUE(SettingsEqual(desired_settings, settings));
// Check returning all hosts for a setting.
ContentSettingsPattern pattern2 =
@@ -589,36 +603,48 @@ TEST_F(HostContentSettingsMapTest, NestedSettings) {
host_content_settings_map->SetDefaultContentSetting(
CONTENT_SETTINGS_TYPE_JAVASCRIPT, CONTENT_SETTING_BLOCK);
- EXPECT_EQ(CONTENT_SETTING_BLOCK,
- host_content_settings_map->GetContentSetting(
- host, host, CONTENT_SETTINGS_TYPE_COOKIES, ""));
- EXPECT_EQ(CONTENT_SETTING_BLOCK,
- host_content_settings_map->GetContentSetting(
- host, host, CONTENT_SETTINGS_TYPE_IMAGES, ""));
- EXPECT_EQ(CONTENT_SETTING_BLOCK,
- host_content_settings_map->GetContentSetting(
- host, host, CONTENT_SETTINGS_TYPE_JAVASCRIPT, ""));
- EXPECT_EQ(CONTENT_SETTING_BLOCK,
- host_content_settings_map->GetContentSetting(
- host, host, CONTENT_SETTINGS_TYPE_PLUGINS, ""));
- EXPECT_EQ(CONTENT_SETTING_BLOCK,
- host_content_settings_map->GetContentSetting(
- host, host, CONTENT_SETTINGS_TYPE_POPUPS, ""));
- EXPECT_EQ(CONTENT_SETTING_ASK,
- host_content_settings_map->GetContentSetting(
- host, host, CONTENT_SETTINGS_TYPE_GEOLOCATION, ""));
- EXPECT_EQ(CONTENT_SETTING_ASK,
- host_content_settings_map->GetContentSetting(
- host, host, CONTENT_SETTINGS_TYPE_NOTIFICATIONS, ""));
- EXPECT_EQ(CONTENT_SETTING_ASK,
- host_content_settings_map->GetContentSetting(
- host, host, CONTENT_SETTINGS_TYPE_INTENTS, ""));
- EXPECT_EQ(CONTENT_SETTING_ASK,
- host_content_settings_map->GetContentSetting(
- host, host, CONTENT_SETTINGS_TYPE_FULLSCREEN, ""));
- EXPECT_EQ(CONTENT_SETTING_ASK,
- host_content_settings_map->GetContentSetting(
- host, host, CONTENT_SETTINGS_TYPE_MOUSELOCK, ""));
+ ContentSettings desired_settings;
+ desired_settings.settings[CONTENT_SETTINGS_TYPE_COOKIES] =
+ CONTENT_SETTING_BLOCK;
+ desired_settings.settings[CONTENT_SETTINGS_TYPE_IMAGES] =
+ CONTENT_SETTING_BLOCK;
+ desired_settings.settings[CONTENT_SETTINGS_TYPE_JAVASCRIPT] =
+ CONTENT_SETTING_BLOCK;
+ desired_settings.settings[CONTENT_SETTINGS_TYPE_PLUGINS] =
+ CONTENT_SETTING_BLOCK;
+ desired_settings.settings[CONTENT_SETTINGS_TYPE_POPUPS] =
+ CONTENT_SETTING_BLOCK;
+ desired_settings.settings[CONTENT_SETTINGS_TYPE_GEOLOCATION] =
+ CONTENT_SETTING_ASK;
+ desired_settings.settings[CONTENT_SETTINGS_TYPE_NOTIFICATIONS] =
+ CONTENT_SETTING_ASK;
+ desired_settings.settings[CONTENT_SETTINGS_TYPE_INTENTS] =
+ CONTENT_SETTING_ASK;
+ desired_settings.settings[CONTENT_SETTINGS_TYPE_FULLSCREEN] =
+ CONTENT_SETTING_ASK;
+ desired_settings.settings[CONTENT_SETTINGS_TYPE_MOUSELOCK] =
+ CONTENT_SETTING_ASK;
+ ContentSettings settings =
+ host_content_settings_map->GetContentSettings(host);
+ EXPECT_TRUE(SettingsEqual(desired_settings, settings));
+ EXPECT_EQ(desired_settings.settings[CONTENT_SETTINGS_TYPE_COOKIES],
+ settings.settings[CONTENT_SETTINGS_TYPE_COOKIES]);
+ EXPECT_EQ(desired_settings.settings[CONTENT_SETTINGS_TYPE_IMAGES],
+ settings.settings[CONTENT_SETTINGS_TYPE_IMAGES]);
+ EXPECT_EQ(desired_settings.settings[CONTENT_SETTINGS_TYPE_PLUGINS],
+ settings.settings[CONTENT_SETTINGS_TYPE_PLUGINS]);
+ EXPECT_EQ(desired_settings.settings[CONTENT_SETTINGS_TYPE_POPUPS],
+ settings.settings[CONTENT_SETTINGS_TYPE_POPUPS]);
+ EXPECT_EQ(desired_settings.settings[CONTENT_SETTINGS_TYPE_GEOLOCATION],
+ settings.settings[CONTENT_SETTINGS_TYPE_GEOLOCATION]);
+ EXPECT_EQ(desired_settings.settings[CONTENT_SETTINGS_TYPE_COOKIES],
+ settings.settings[CONTENT_SETTINGS_TYPE_COOKIES]);
+ EXPECT_EQ(desired_settings.settings[CONTENT_SETTINGS_TYPE_INTENTS],
+ settings.settings[CONTENT_SETTINGS_TYPE_INTENTS]);
+ EXPECT_EQ(desired_settings.settings[CONTENT_SETTINGS_TYPE_FULLSCREEN],
+ settings.settings[CONTENT_SETTINGS_TYPE_FULLSCREEN]);
+ EXPECT_EQ(desired_settings.settings[CONTENT_SETTINGS_TYPE_MOUSELOCK],
+ settings.settings[CONTENT_SETTINGS_TYPE_MOUSELOCK]);
}
TEST_F(HostContentSettingsMapTest, OffTheRecord) {
@@ -788,9 +814,10 @@ TEST_F(HostContentSettingsMapTest, ResourceIdentifier) {
ContentSetting default_plugin_setting =
host_content_settings_map->GetDefaultContentSetting(
CONTENT_SETTINGS_TYPE_PLUGINS, NULL);
+ ContentSettings settings =
+ host_content_settings_map->GetContentSettings(host);
EXPECT_EQ(default_plugin_setting,
- host_content_settings_map->GetContentSetting(
- host, host, CONTENT_SETTINGS_TYPE_PLUGINS, ""));
+ settings.settings[CONTENT_SETTINGS_TYPE_PLUGINS]);
// If no resource-specific content settings are defined, the setting should be
// DEFAULT.
diff --git a/chrome/browser/content_settings/mock_settings_observer.cc b/chrome/browser/content_settings/mock_settings_observer.cc
index a281a1d..a0cc5b1 100644
--- a/chrome/browser/content_settings/mock_settings_observer.cc
+++ b/chrome/browser/content_settings/mock_settings_observer.cc
@@ -34,6 +34,5 @@ void MockSettingsObserver::Observe(
settings_details->update_all());
// This checks that calling a Get function from an observer doesn't
// deadlock.
- GURL url("http://random-hostname.com/");
- map->GetContentSetting(url, url, CONTENT_SETTINGS_TYPE_IMAGES, "");
+ map->GetContentSettings(GURL("http://random-hostname.com/"));
}
diff --git a/chrome/browser/content_settings/tab_specific_content_settings.cc b/chrome/browser/content_settings/tab_specific_content_settings.cc
index fda4042..91948d5 100644
--- a/chrome/browser/content_settings/tab_specific_content_settings.cc
+++ b/chrome/browser/content_settings/tab_specific_content_settings.cc
@@ -431,6 +431,15 @@ void TabSpecificContentSettings::DidNavigateMainFramePostCommit(
}
}
+void TabSpecificContentSettings::RenderViewCreated(
+ RenderViewHost* render_view_host) {
+ Profile* profile =
+ Profile::FromBrowserContext(tab_contents()->browser_context());
+ HostContentSettingsMap* map = profile->GetHostContentSettingsMap();
+ render_view_host->Send(new ChromeViewMsg_SetDefaultContentSettings(
+ map->GetDefaultContentSettings()));
+}
+
void TabSpecificContentSettings::DidStartProvisionalLoadForFrame(
int64 frame_id,
bool is_main_frame,
@@ -477,9 +486,13 @@ void TabSpecificContentSettings::Observe(
settings_details.ptr()->primary_pattern().Matches(entry_url)) {
Profile* profile =
Profile::FromBrowserContext(tab_contents()->browser_context());
+ HostContentSettingsMap* map = profile->GetHostContentSettingsMap();
+ Send(new ChromeViewMsg_SetDefaultContentSettings(
+ map->GetDefaultContentSettings()));
+ Send(new ChromeViewMsg_SetContentSettingsForCurrentURL(
+ entry_url, map->GetContentSettings(entry_url)));
RendererContentSettingRules rules;
- GetRendererContentSettingRules(profile->GetHostContentSettingsMap(),
- &rules);
+ GetRendererContentSettingRules(map, &rules);
Send(new ChromeViewMsg_SetContentSettingRules(rules));
}
}
diff --git a/chrome/browser/content_settings/tab_specific_content_settings.h b/chrome/browser/content_settings/tab_specific_content_settings.h
index cef428d..c240759 100644
--- a/chrome/browser/content_settings/tab_specific_content_settings.h
+++ b/chrome/browser/content_settings/tab_specific_content_settings.h
@@ -163,6 +163,7 @@ class TabSpecificContentSettings : public TabContentsObserver,
virtual void DidNavigateMainFramePostCommit(
const content::LoadCommittedDetails& details,
const ViewHostMsg_FrameNavigate_Params& params) OVERRIDE;
+ virtual void RenderViewCreated(RenderViewHost* render_view_host) OVERRIDE;
virtual void DidStartProvisionalLoadForFrame(
int64 frame_id,
bool is_main_frame,
diff --git a/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc b/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc
index 3d86c7c..35231bb 100644
--- a/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc
+++ b/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc
@@ -333,6 +333,16 @@ void ChromeResourceDispatcherHostDelegate::OnResponseStarted(
}
}
+ // We must send the content settings for the URL before sending response
+ // headers to the renderer.
+ const content::ResourceContext& resource_context = filter->resource_context();
+ ProfileIOData* io_data =
+ reinterpret_cast<ProfileIOData*>(resource_context.GetUserData(NULL));
+ HostContentSettingsMap* map = io_data->GetHostContentSettingsMap();
+ filter->Send(new ChromeViewMsg_SetContentSettingsForLoadingURL(
+ info->route_id(), request->url(),
+ map->GetContentSettings(request->url())));
+
// See if the response contains the X-Auto-Login header. If so, this was
// a request for a login page, and the server is allowing the browser to
// suggest auto-login, if available.
diff --git a/chrome/common/content_settings.cc b/chrome/common/content_settings.cc
index 8b28f4b..cd30d6c 100644
--- a/chrome/common/content_settings.cc
+++ b/chrome/common/content_settings.cc
@@ -10,6 +10,16 @@ ContentSetting IntToContentSetting(int content_setting) {
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,
diff --git a/chrome/common/content_settings.h b/chrome/common/content_settings.h
index 0c44417..cff4102 100644
--- a/chrome/common/content_settings.h
+++ b/chrome/common/content_settings.h
@@ -27,6 +27,14 @@ enum ContentSetting {
// prefs off disk.
ContentSetting IntToContentSetting(int content_setting);
+// Aggregates the permissions for the different content types.
+struct ContentSettings {
+ ContentSettings();
+ explicit ContentSettings(ContentSetting default_setting);
+
+ ContentSetting settings[CONTENT_SETTINGS_NUM_TYPES];
+};
+
struct ContentSettingPatternSource {
ContentSettingPatternSource(const ContentSettingsPattern& primary_pattern,
const ContentSettingsPattern& secondary_patttern,
diff --git a/chrome/common/render_messages.cc b/chrome/common/render_messages.cc
index 726f082..39c6705 100644
--- a/chrome/common/render_messages.cc
+++ b/chrome/common/render_messages.cc
@@ -6,6 +6,26 @@
namespace IPC {
+void ParamTraits<ContentSettings>::Write(
+ Message* m, const ContentSettings& settings) {
+ for (size_t i = 0; i < arraysize(settings.settings); ++i)
+ WriteParam(m, settings.settings[i]);
+}
+
+bool ParamTraits<ContentSettings>::Read(
+ const Message* m, void** iter, ContentSettings* r) {
+ for (size_t i = 0; i < arraysize(r->settings); ++i) {
+ if (!ReadParam(m, iter, &r->settings[i]))
+ return false;
+ }
+ return true;
+}
+
+void ParamTraits<ContentSettings>::Log(
+ const ContentSettings& p, std::string* l) {
+ l->append("<ContentSettings>");
+}
+
void ParamTraits<ContentSettingsPattern>::Write(
Message* m, const ContentSettingsPattern& pattern) {
pattern.WriteToMessage(m);
diff --git a/chrome/common/render_messages.h b/chrome/common/render_messages.h
index 54b5be3..89e395e 100644
--- a/chrome/common/render_messages.h
+++ b/chrome/common/render_messages.h
@@ -98,6 +98,14 @@ struct ParamTraits<gfx::NativeView> {
#endif // defined(OS_POSIX) && !defined(USE_AURA)
template <>
+struct ParamTraits<ContentSettings> {
+ typedef ContentSettings param_type;
+ static void Write(Message* m, const param_type& p);
+ static bool Read(const Message* m, void** iter, param_type* r);
+ static void Log(const param_type& p, std::string* l);
+};
+
+template <>
struct ParamTraits<ContentSettingsPattern> {
typedef ContentSettingsPattern param_type;
static void Write(Message* m, const param_type& p);
@@ -223,6 +231,25 @@ IPC_MESSAGE_CONTROL1(ChromeViewMsg_VisitedLink_Add, std::vector<uint64>)
// re-calculated.
IPC_MESSAGE_CONTROL0(ChromeViewMsg_VisitedLink_Reset)
+// Set the content settings for a particular url that the renderer is in the
+// process of loading. This will be stored, to be used if the load commits
+// and ignored otherwise.
+IPC_MESSAGE_ROUTED2(ChromeViewMsg_SetContentSettingsForLoadingURL,
+ GURL /* url */,
+ ContentSettings /* content_settings */)
+
+// Set the content settings for a particular url, so all render views
+// displaying this host url update their content settings to match.
+IPC_MESSAGE_CONTROL2(ChromeViewMsg_SetContentSettingsForCurrentURL,
+ GURL /* url */,
+ ContentSettings /* content_settings */)
+
+// Set the content settings for a particular url that the renderer is in the
+// process of loading. This will be stored, to be used if the load commits
+// and ignored otherwise.
+IPC_MESSAGE_CONTROL1(ChromeViewMsg_SetDefaultContentSettings,
+ ContentSettings /* content_settings */)
+
// Set the content setting rules stored by the renderer.
IPC_MESSAGE_CONTROL1(ChromeViewMsg_SetContentSettingRules,
RendererContentSettingRules /* rules */)
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc
index 841772c..7cf200c 100644
--- a/chrome/renderer/chrome_content_renderer_client.cc
+++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -217,6 +217,8 @@ void ChromeContentRendererClient::RenderViewCreated(
ContentSettingsObserver* content_settings =
new ContentSettingsObserver(render_view);
if (chrome_observer_.get()) {
+ content_settings->SetDefaultContentSettings(
+ chrome_observer_->default_content_settings());
content_settings->SetContentSettingRules(
chrome_observer_->content_setting_rules());
}
diff --git a/chrome/renderer/chrome_render_process_observer.cc b/chrome/renderer/chrome_render_process_observer.cc
index c1ff810..0b2fd95 100644
--- a/chrome/renderer/chrome_render_process_observer.cc
+++ b/chrome/renderer/chrome_render_process_observer.cc
@@ -106,6 +106,30 @@ class RendererResourceDelegate : public content::ResourceDispatcherDelegate {
DISALLOW_COPY_AND_ASSIGN(RendererResourceDelegate);
};
+class RenderViewContentSettingsSetter : public content::RenderViewVisitor {
+ public:
+ RenderViewContentSettingsSetter(const GURL& url,
+ const ContentSettings& content_settings)
+ : url_(url),
+ content_settings_(content_settings) {
+ }
+
+ virtual bool Visit(content::RenderView* render_view) {
+ if (GURL(render_view->GetWebView()->mainFrame()->document().url()) ==
+ url_) {
+ ContentSettingsObserver::Get(render_view)->SetContentSettings(
+ content_settings_);
+ }
+ return true;
+ }
+
+ private:
+ GURL url_;
+ ContentSettings content_settings_;
+
+ DISALLOW_COPY_AND_ASSIGN(RenderViewContentSettingsSetter);
+};
+
#if defined(OS_WIN)
static base::win::IATPatchFunction g_iat_patch_createdca;
HDC WINAPI CreateDCAPatch(LPCSTR driver_name,
@@ -239,6 +263,10 @@ bool ChromeRenderProcessObserver::OnControlMessageReceived(
IPC_BEGIN_MESSAGE_MAP(ChromeRenderProcessObserver, message)
IPC_MESSAGE_HANDLER(ChromeViewMsg_SetIsIncognitoProcess,
OnSetIsIncognitoProcess)
+ IPC_MESSAGE_HANDLER(ChromeViewMsg_SetDefaultContentSettings,
+ OnSetDefaultContentSettings)
+ IPC_MESSAGE_HANDLER(ChromeViewMsg_SetContentSettingsForCurrentURL,
+ OnSetContentSettingsForCurrentURL)
IPC_MESSAGE_HANDLER(ChromeViewMsg_SetContentSettingRules,
OnSetContentSettingRules)
IPC_MESSAGE_HANDLER(ChromeViewMsg_SetCacheCapacities, OnSetCacheCapacities)
@@ -270,6 +298,18 @@ void ChromeRenderProcessObserver::OnSetIsIncognitoProcess(
is_incognito_process_ = is_incognito_process;
}
+void ChromeRenderProcessObserver::OnSetContentSettingsForCurrentURL(
+ const GURL& url,
+ const ContentSettings& content_settings) {
+ RenderViewContentSettingsSetter setter(url, content_settings);
+ content::RenderView::ForEach(&setter);
+}
+
+void ChromeRenderProcessObserver::OnSetDefaultContentSettings(
+ const ContentSettings& content_settings) {
+ default_content_settings_ = content_settings;
+}
+
void ChromeRenderProcessObserver::OnSetContentSettingRules(
const RendererContentSettingRules& rules) {
content_setting_rules_ = rules;
@@ -394,3 +434,8 @@ const RendererContentSettingRules*
ChromeRenderProcessObserver::content_setting_rules() const {
return &content_setting_rules_;
}
+
+const ContentSettings*
+ChromeRenderProcessObserver::default_content_settings() const {
+ return &default_content_settings_;
+}
diff --git a/chrome/renderer/chrome_render_process_observer.h b/chrome/renderer/chrome_render_process_observer.h
index ed4805e..74ab740 100644
--- a/chrome/renderer/chrome_render_process_observer.h
+++ b/chrome/renderer/chrome_render_process_observer.h
@@ -41,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 default content settings owned by
+ // |ChromeRenderProcessObserver|.
+ const ContentSettings* default_content_settings() const;
+
// Returns a pointer to the content setting rules owned by
// |ChromeRenderProcessObserver|.
const RendererContentSettingRules* content_setting_rules() const;
@@ -53,6 +57,7 @@ class ChromeRenderProcessObserver : public content::RenderProcessObserver {
void OnSetIsIncognitoProcess(bool is_incognito_process);
void OnSetContentSettingsForCurrentURL(
const GURL& url, const ContentSettings& content_settings);
+ void OnSetDefaultContentSettings(const ContentSettings& content_settings);
void OnSetContentSettingRules(const RendererContentSettingRules& rules);
void OnSetCacheCapacities(size_t min_dead_capacity,
size_t max_dead_capacity,
@@ -74,6 +79,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_;
+ ContentSettings default_content_settings_;
RendererContentSettingRules content_setting_rules_;
DISALLOW_COPY_AND_ASSIGN(ChromeRenderProcessObserver);
diff --git a/chrome/renderer/content_settings_observer.cc b/chrome/renderer/content_settings_observer.cc
index dda5235..3d1bfac 100644
--- a/chrome/renderer/content_settings_observer.cc
+++ b/chrome/renderer/content_settings_observer.cc
@@ -80,6 +80,7 @@ ContentSettingsObserver::ContentSettingsObserver(
content::RenderView* render_view)
: content::RenderViewObserver(render_view),
content::RenderViewObserverTracker<ContentSettingsObserver>(render_view),
+ default_content_settings_(NULL),
content_setting_rules_(NULL),
plugins_temporarily_allowed_(false) {
ClearBlockedContentSettings();
@@ -88,11 +89,28 @@ ContentSettingsObserver::ContentSettingsObserver(
ContentSettingsObserver::~ContentSettingsObserver() {
}
+void ContentSettingsObserver::SetContentSettings(
+ const ContentSettings& settings) {
+ current_content_settings_ = settings;
+}
+
+void ContentSettingsObserver::SetDefaultContentSettings(
+ const ContentSettings* settings) {
+ default_content_settings_ = settings;
+}
+
void ContentSettingsObserver::SetContentSettingRules(
const RendererContentSettingRules* content_setting_rules) {
content_setting_rules_ = content_setting_rules;
}
+ContentSetting ContentSettingsObserver::GetContentSetting(
+ ContentSettingsType type) {
+ // Don't call this for plug-ins.
+ DCHECK_NE(CONTENT_SETTINGS_TYPE_PLUGINS, type);
+ return current_content_settings_.settings[type];
+}
+
void ContentSettingsObserver::DidBlockContentType(
ContentSettingsType settings_type,
const std::string& resource_identifier) {
@@ -114,6 +132,8 @@ bool ContentSettingsObserver::OnMessageReceived(const IPC::Message& message) {
// blocked plugin.
IPC_MESSAGE_HANDLER_GENERIC(ChromeViewMsg_LoadBlockedPlugins,
OnLoadBlockedPlugins(); handled = false)
+ IPC_MESSAGE_HANDLER(ChromeViewMsg_SetContentSettingsForLoadingURL,
+ OnSetContentSettingsForLoadingURL)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
@@ -136,10 +156,46 @@ void ContentSettingsObserver::DidCommitProvisionalLoad(
}
GURL url = frame->document().url();
+
+ if (frame->document().securityOrigin().toString() == "null" &&
+ !url.SchemeIs(chrome::kFileScheme)) {
+ // The Frame has a unique security origin. Instead of granting the frame
+ // privileges based on it's URL, we fall back to the default content
+ // settings.
+
+ // We exempt file URLs here because we sandbox them by default, but folks
+ // might reasonably want to supply non-default content settings for various
+ // file URLs.
+ if (default_content_settings_)
+ SetContentSettings(*default_content_settings_);
+ return;
+ }
+
// If we start failing this DCHECK, please makes sure we don't regress
// this bug: http://code.google.com/p/chromium/issues/detail?id=79304
- DCHECK(frame->document().securityOrigin().toString() == "null" ||
- !url.SchemeIs(chrome::kDataScheme));
+ DCHECK(!url.SchemeIs(chrome::kDataScheme));
+
+ // Set content settings. Default them from the parent window if one exists.
+ // This makes sure about:blank windows work as expected.
+ HostContentSettings::iterator host_content_settings =
+ host_content_settings_.find(url);
+ if (host_content_settings != host_content_settings_.end()) {
+ SetContentSettings(host_content_settings->second);
+
+ // These content settings were merely recorded transiently for this load.
+ // We can erase them now. If at some point we reload this page, the
+ // browser will send us new, up-to-date content settings.
+ host_content_settings_.erase(host_content_settings);
+ } else if (frame->opener()) {
+ // The opener's view is not guaranteed to be non-null (it could be
+ // detached from its page but not yet destructed).
+ if (WebView* opener_view = frame->opener()->view()) {
+ content::RenderView* opener =
+ content::RenderView::FromWebView(opener_view);
+ ContentSettingsObserver* observer = ContentSettingsObserver::Get(opener);
+ SetContentSettings(observer->current_content_settings_);
+ }
+ }
}
bool ContentSettingsObserver::AllowDatabase(WebFrame* frame,
@@ -276,10 +332,23 @@ void ContentSettingsObserver::DidNotAllowScript(WebFrame* frame) {
DidBlockContentType(CONTENT_SETTINGS_TYPE_JAVASCRIPT, std::string());
}
+void ContentSettingsObserver::OnSetContentSettingsForLoadingURL(
+ const GURL& url,
+ const ContentSettings& content_settings) {
+ host_content_settings_[url] = content_settings;
+}
+
void ContentSettingsObserver::OnLoadBlockedPlugins() {
plugins_temporarily_allowed_ = true;
}
+bool ContentSettingsObserver::AllowContentType(
+ ContentSettingsType settings_type) {
+ // CONTENT_SETTING_ASK is only valid for cookies.
+ return current_content_settings_.settings[settings_type] !=
+ CONTENT_SETTING_BLOCK;
+}
+
void ContentSettingsObserver::ClearBlockedContentSettings() {
for (size_t i = 0; i < arraysize(content_blocked_); ++i)
content_blocked_[i] = false;
diff --git a/chrome/renderer/content_settings_observer.h b/chrome/renderer/content_settings_observer.h
index 6c3d3f5..dd9c7b9 100644
--- a/chrome/renderer/content_settings_observer.h
+++ b/chrome/renderer/content_settings_observer.h
@@ -27,12 +27,22 @@ class ContentSettingsObserver
explicit ContentSettingsObserver(content::RenderView* render_view);
virtual ~ContentSettingsObserver();
+ // Sets the content settings that back allowScripts() and allowPlugins().
+ void SetContentSettings(const ContentSettings& settings);
+
+ // Sets the default content settings that back allowScripts() and
+ // allowPlugins().
+ void SetDefaultContentSettings(const ContentSettings* settings);
+
// Sets the content setting rules which back |AllowImage()|, |AllowScript()|,
// and |AllowScriptFromSource()|. |content_setting_rules| must outlive this
// |ContentSettingsObserver|.
void SetContentSettingRules(
const RendererContentSettingRules* content_setting_rules);
+ // Returns the setting for the given type.
+ ContentSetting GetContentSetting(ContentSettingsType type);
+
bool plugins_temporarily_allowed() {
return plugins_temporarily_allowed_;
}
@@ -71,11 +81,29 @@ class ContentSettingsObserver
bool is_new_navigation);
// Message handlers.
+ void OnSetContentSettingsForLoadingURL(
+ const GURL& url,
+ const ContentSettings& content_settings);
void OnLoadBlockedPlugins();
+ // Helper method that returns if the user wants to block content of type
+ // |content_type|.
+ bool AllowContentType(ContentSettingsType settings_type);
+
// Resets the |content_blocked_| array.
void ClearBlockedContentSettings();
+ typedef std::map<GURL, ContentSettings> HostContentSettings;
+ HostContentSettings host_content_settings_;
+
+ // A pointer to the most up-to-date view of the default content
+ // settings. Normally, they are owned by |ChromeRenderProcessObserver|. In the
+ // tests they are owned by the caller of |SetDefaultContentSettings|.
+ const ContentSettings* default_content_settings_;
+
+ // Stores if loading of scripts and plugins is allowed.
+ ContentSettings current_content_settings_;
+
// A pointer to content setting rules stored by the renderer. Normally, the
// |RendererContentSettingRules| object is owned by
// |ChromeRenderProcessObserver|. In the tests it is owned by the caller of
diff --git a/chrome/renderer/content_settings_observer_browsertest.cc b/chrome/renderer/content_settings_observer_browsertest.cc
index eb9d337..78c7d21 100644
--- a/chrome/renderer/content_settings_observer_browsertest.cc
+++ b/chrome/renderer/content_settings_observer_browsertest.cc
@@ -149,7 +149,14 @@ TEST_F(ChromeRenderViewTest, PluginsTemporarilyAllowed) {
// Load some HTML.
LoadHTML("<html>Foo</html>");
+ // Block plugins.
+ ContentSettings settings;
+ for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i)
+ settings.settings[i] = CONTENT_SETTING_ALLOW;
+ settings.settings[CONTENT_SETTINGS_TYPE_PLUGINS] = CONTENT_SETTING_BLOCK;
ContentSettingsObserver* observer = ContentSettingsObserver::Get(view_);
+ observer->SetContentSettings(settings);
+ observer->SetDefaultContentSettings(&settings);
EXPECT_FALSE(observer->plugins_temporarily_allowed());
// Temporarily allow plugins.