summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/content_setting_bubble_model.cc39
-rw-r--r--chrome/browser/content_setting_bubble_model_unittest.cc73
2 files changed, 99 insertions, 13 deletions
diff --git a/chrome/browser/content_setting_bubble_model.cc b/chrome/browser/content_setting_bubble_model.cc
index 01d4d22..573111a 100644
--- a/chrome/browser/content_setting_bubble_model.cc
+++ b/chrome/browser/content_setting_bubble_model.cc
@@ -172,8 +172,7 @@ class ContentSettingDomainListBubbleModel
: ContentSettingTitleAndLinkModel(tab_contents, profile, content_type) {
DCHECK_EQ(CONTENT_SETTINGS_TYPE_GEOLOCATION, content_type) <<
"SetDomains currently only supports geolocation content type";
- SetDomains();
- SetClearLink();
+ SetDomainsAndClearLink();
}
private:
@@ -183,24 +182,52 @@ class ContentSettingDomainListBubbleModel
add_domain_list(*domain_list);
}
}
- void SetDomains() {
+ void SetDomainsAndClearLink() {
const TabContents::GeolocationContentSettings& settings =
tab_contents()->geolocation_content_settings();
+ const GURL& embedder_url = tab_contents()->GetURL();
+ const GeolocationContentSettingsMap* settings_map =
+ profile()->GetGeolocationContentSettingsMap();
+ const ContentSetting default_setting =
+ settings_map->GetDefaultContentSetting();
+ // Will be true if the current page permission state does not
+ // match that in the content map (i.e. if a reload will yield a different
+ // permission state).
+ bool needs_reload = false;
+ // Will be true if there are any exceptions in the content map
+ // (i.e. non-default entries) for the frames using geolocaiton on this page.
+ bool has_exception = false;
// Divide the tab's current geolocation users into sets according to their
// permission state.
DomainList domains[CONTENT_SETTING_NUM_SETTINGS];
for (TabContents::GeolocationContentSettings::const_iterator it =
settings.begin(); it != settings.end(); ++it) {
domains[it->second].hosts.insert(it->first.host());
+ const ContentSetting saved_setting =
+ settings_map->GetContentSetting(it->first, embedder_url);
+ if (saved_setting != default_setting)
+ has_exception = true;
+ if (saved_setting != it->second)
+ needs_reload = true;
}
MaybeAddDomainList(&domains[CONTENT_SETTING_ALLOW],
IDS_GEOLOCATION_BUBBLE_SECTION_ALLOWED);
MaybeAddDomainList(&domains[CONTENT_SETTING_BLOCK],
IDS_GEOLOCATION_BUBBLE_SECTION_DENIED);
- }
- void SetClearLink() {
- set_clear_link(l10n_util::GetStringUTF8(IDS_GEOLOCATION_BUBBLE_CLEAR_LINK));
+ if (has_exception) {
+ set_clear_link(
+ l10n_util::GetStringUTF8(IDS_GEOLOCATION_BUBBLE_CLEAR_LINK));
+ } else if (needs_reload) {
+ // It is a slight abuse of the domain list field to use it for the reload
+ // hint, but works fine for now. TODO(joth): If we need to style it
+ // differently, consider adding an explicit field, or generalize the
+ // domain list to be a flat list of style formatted lines.
+ DomainList reload_section;
+ reload_section.title = l10n_util::GetStringUTF8(
+ IDS_GEOLOCATION_BUBBLE_REQUIRE_RELOAD_TO_CLEAR);
+ add_domain_list(reload_section);
+ }
}
virtual void OnClearLinkClicked() {
if (!tab_contents())
diff --git a/chrome/browser/content_setting_bubble_model_unittest.cc b/chrome/browser/content_setting_bubble_model_unittest.cc
index d75ceff..d6555014 100644
--- a/chrome/browser/content_setting_bubble_model_unittest.cc
+++ b/chrome/browser/content_setting_bubble_model_unittest.cc
@@ -10,16 +10,45 @@
#include "chrome/test/testing_profile.h"
#include "testing/gtest/include/gtest/gtest.h"
-typedef RenderViewHostTestHarness ContentSettingBubbleModelTest;
+class ContentSettingBubbleModelTest : public RenderViewHostTestHarness {
+ protected:
+ ContentSettingBubbleModelTest()
+ : ui_thread_(ChromeThread::UI, MessageLoop::current()) {
+ }
+
+ void CheckGeolocationBubble(size_t expected_domains,
+ bool expect_clear_link,
+ bool expect_reload_hint) {
+ scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model(
+ ContentSettingBubbleModel::CreateContentSettingBubbleModel(
+ contents(), profile_.get(), CONTENT_SETTINGS_TYPE_GEOLOCATION));
+ const ContentSettingBubbleModel::BubbleContent& bubble_content =
+ content_setting_bubble_model->bubble_content();
+ EXPECT_EQ(0U, bubble_content.popup_items.size());
+ EXPECT_EQ(0U, bubble_content.radio_groups.size());
+ // The reload hint is currently implemented as a tacked on domain title, so
+ // account for this.
+ if (expect_reload_hint)
+ ++expected_domains;
+ EXPECT_EQ(expected_domains, bubble_content.domain_lists.size());
+ if (expect_clear_link)
+ EXPECT_NE(std::string(), bubble_content.clear_link);
+ else
+ EXPECT_EQ(std::string(), bubble_content.clear_link);
+ EXPECT_NE(std::string(), bubble_content.manage_link);
+ EXPECT_EQ(std::string(), bubble_content.title);
+ }
+
+ ChromeThread ui_thread_;
+};
TEST_F(ContentSettingBubbleModelTest, ImageRadios) {
- TestTabContents tab_contents(profile_.get(), NULL);
- RenderViewHostDelegate::Resource* render_view_host_delegate = &tab_contents;
+ RenderViewHostDelegate::Resource* render_view_host_delegate = contents();
render_view_host_delegate->OnContentBlocked(CONTENT_SETTINGS_TYPE_IMAGES);
scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model(
ContentSettingBubbleModel::CreateContentSettingBubbleModel(
- &tab_contents, profile_.get(), CONTENT_SETTINGS_TYPE_IMAGES));
+ contents(), profile_.get(), CONTENT_SETTINGS_TYPE_IMAGES));
const ContentSettingBubbleModel::BubbleContent& bubble_content =
content_setting_bubble_model->bubble_content();
EXPECT_EQ(1U, bubble_content.radio_groups.size());
@@ -30,16 +59,46 @@ TEST_F(ContentSettingBubbleModelTest, ImageRadios) {
}
TEST_F(ContentSettingBubbleModelTest, Cookies) {
- TestTabContents tab_contents(profile_.get(), NULL);
- RenderViewHostDelegate::Resource* render_view_host_delegate = &tab_contents;
+ RenderViewHostDelegate::Resource* render_view_host_delegate = contents();
render_view_host_delegate->OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES);
scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model(
ContentSettingBubbleModel::CreateContentSettingBubbleModel(
- &tab_contents, profile_.get(), CONTENT_SETTINGS_TYPE_COOKIES));
+ contents(), profile_.get(), CONTENT_SETTINGS_TYPE_COOKIES));
const ContentSettingBubbleModel::BubbleContent& bubble_content =
content_setting_bubble_model->bubble_content();
EXPECT_EQ(0U, bubble_content.radio_groups.size());
EXPECT_NE(std::string(), bubble_content.manage_link);
EXPECT_NE(std::string(), bubble_content.title);
}
+
+TEST_F(ContentSettingBubbleModelTest, Geolocation) {
+ const GURL page_url("http://toplevel.example/");
+ const GURL frame1_url("http://host1.example/");
+ const GURL frame2_url("http://host2.example:999/");
+
+ NavigateAndCommit(page_url);
+ RenderViewHostDelegate::Resource* render_view_host_delegate = contents();
+
+ // One permitted frame, but not in the content map: requires reload.
+ render_view_host_delegate->OnGeolocationPermissionSet(frame1_url, true);
+ CheckGeolocationBubble(1, false, true);
+
+ // Add it to the content map, should now have a clear link.
+ GeolocationContentSettingsMap* setting_map =
+ profile_->GetGeolocationContentSettingsMap();
+ setting_map->SetContentSetting(frame1_url, page_url, CONTENT_SETTING_ALLOW);
+ CheckGeolocationBubble(1, true, false);
+
+ // Change the default to allow: no message needed.
+ setting_map->SetDefaultContentSetting(CONTENT_SETTING_ALLOW);
+ CheckGeolocationBubble(1, false, false);
+
+ // Second frame denied, but not stored in the content map: requires reload.
+ render_view_host_delegate->OnGeolocationPermissionSet(frame2_url, false);
+ CheckGeolocationBubble(2, false, true);
+
+ // Change the default to block: offer a clear link for the persisted frame 1.
+ setting_map->SetDefaultContentSetting(CONTENT_SETTING_BLOCK);
+ CheckGeolocationBubble(2, true, false);
+}