diff options
-rw-r--r-- | chrome/browser/content_setting_bubble_model.cc | 39 | ||||
-rw-r--r-- | chrome/browser/content_setting_bubble_model_unittest.cc | 73 |
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); +} |