diff options
author | bulach@chromium.org <bulach@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-11 13:28:16 +0000 |
---|---|---|
committer | bulach@chromium.org <bulach@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-11 13:28:16 +0000 |
commit | 777a7b66c0a16a8917b29af3ea6d2e440bc5371b (patch) | |
tree | 6a48fb9ecc0355a29405f3b6e0bfd2c455de8849 /chrome/browser/geolocation | |
parent | 8b4b84eee1eaa6a77c34f66f7278039004657896 (diff) | |
download | chromium_src-777a7b66c0a16a8917b29af3ea6d2e440bc5371b.zip chromium_src-777a7b66c0a16a8917b29af3ea6d2e440bc5371b.tar.gz chromium_src-777a7b66c0a16a8917b29af3ea6d2e440bc5371b.tar.bz2 |
Adds GeolocationSettingsState
TEST=geolocation_settings_state_unittest.cc
Review URL: http://codereview.chromium.org/1540034
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@46911 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/geolocation')
5 files changed, 283 insertions, 17 deletions
diff --git a/chrome/browser/geolocation/geolocation_browsertest.cc b/chrome/browser/geolocation/geolocation_browsertest.cc index b8667c8..9bfbae7 100644 --- a/chrome/browser/geolocation/geolocation_browsertest.cc +++ b/chrome/browser/geolocation/geolocation_browsertest.cc @@ -9,6 +9,7 @@ #include "chrome/browser/browser_list.h" #include "chrome/browser/dom_operation_notification_details.h" #include "chrome/browser/geolocation/geolocation_content_settings_map.h" +#include "chrome/browser/geolocation/geolocation_settings_state.h" #include "chrome/browser/geolocation/location_arbitrator.h" #include "chrome/browser/geolocation/location_provider.h" #include "chrome/browser/geolocation/mock_location_provider.h" @@ -266,9 +267,9 @@ class GeolocationBrowserTest : public InProcessBrowserTest { void SetInfobarResponse(const GURL& requesting_url, bool allowed) { TabContents* tab_contents = current_browser_->GetSelectedTabContents(); - TabContents::GeolocationContentSettings content_settings = - tab_contents->geolocation_content_settings(); - size_t settings_size = content_settings.size(); + const GeolocationSettingsState& settings_state = + tab_contents->geolocation_settings_state(); + size_t state_map_size = settings_state.state_map().size(); ASSERT_TRUE(infobar_); LOG(WARNING) << "will set infobar response"; if (allowed) @@ -279,13 +280,13 @@ class GeolocationBrowserTest : public InProcessBrowserTest { tab_contents->RemoveInfoBar(infobar_); LOG(WARNING) << "infobar response set"; infobar_ = NULL; - content_settings = tab_contents->geolocation_content_settings(); - EXPECT_GT(content_settings.size(), settings_size); + EXPECT_GT(settings_state.state_map().size(), state_map_size); GURL requesting_origin = requesting_url.GetOrigin(); - EXPECT_EQ(1U, content_settings.count(requesting_origin)); + EXPECT_EQ(1U, settings_state.state_map().count(requesting_origin)); ContentSetting expected_setting = allowed ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK; - EXPECT_EQ(expected_setting, content_settings[requesting_origin]); + EXPECT_EQ(expected_setting, + settings_state.state_map().find(requesting_origin)->second); } void WaitForJSPrompt() { diff --git a/chrome/browser/geolocation/geolocation_permission_context_unittest.cc b/chrome/browser/geolocation/geolocation_permission_context_unittest.cc index e8d631d..1124648 100644 --- a/chrome/browser/geolocation/geolocation_permission_context_unittest.cc +++ b/chrome/browser/geolocation/geolocation_permission_context_unittest.cc @@ -130,16 +130,13 @@ class GeolocationPermissionContextTests : public RenderViewHostTestHarness { void CheckTabContentsState(const GURL& requesting_frame, ContentSetting expected_content_setting) { - EXPECT_EQ(1U, - contents()->geolocation_content_settings().count( - requesting_frame.GetOrigin())); - EXPECT_EQ(0U, - contents()->geolocation_content_settings().count( - requesting_frame)); - TabContents::GeolocationContentSettings::const_iterator settings = - contents()->geolocation_content_settings().find( - requesting_frame.GetOrigin()); - ASSERT_FALSE(settings == contents()->geolocation_content_settings().end()) + const GeolocationSettingsState::StateMap& state_map = + contents()->geolocation_settings_state().state_map(); + EXPECT_EQ(1U, state_map.count(requesting_frame.GetOrigin())); + EXPECT_EQ(0U, state_map.count(requesting_frame)); + GeolocationSettingsState::StateMap::const_iterator settings = + state_map.find(requesting_frame.GetOrigin()); + ASSERT_FALSE(settings == state_map.end()) << "geolocation state not found " << requesting_frame; EXPECT_EQ(expected_content_setting, settings->second); } diff --git a/chrome/browser/geolocation/geolocation_settings_state.cc b/chrome/browser/geolocation/geolocation_settings_state.cc new file mode 100644 index 0000000..a045d6d --- /dev/null +++ b/chrome/browser/geolocation/geolocation_settings_state.cc @@ -0,0 +1,81 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/geolocation/geolocation_settings_state.h" + +#include "base/utf_string_conversions.h" +#include "chrome/browser/geolocation/geolocation_content_settings_map.h" +#include "chrome/browser/pref_service.h" +#include "chrome/browser/profile.h" +#include "chrome/browser/tab_contents/navigation_entry.h" +#include "chrome/common/pref_names.h" +#include "net/base/net_util.h" + +GeolocationSettingsState::GeolocationSettingsState(Profile* profile) + : profile_(profile) { +} + +GeolocationSettingsState::~GeolocationSettingsState() { +} + +void GeolocationSettingsState::OnGeolocationPermissionSet( + const GURL& requesting_origin, bool allowed) { + state_map_[requesting_origin] = + allowed ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK; +} + +void GeolocationSettingsState::DidNavigate( + const NavigationController::LoadCommittedDetails& details) { + if (details.entry) + embedder_url_ = details.entry->url(); + if (state_map_.empty()) + return; + if (!details.entry || + details.previous_url.GetOrigin() != details.entry->url().GetOrigin()) { + state_map_.clear(); + return; + } + // We're in the same origin, check if there's any icon to be displayed. + unsigned int tab_state_flags = 0; + GetDetailedInfo(NULL, &tab_state_flags); + if (!(tab_state_flags & TABSTATE_HAS_ANY_ICON)) + state_map_.clear(); +} + +void GeolocationSettingsState::GetDetailedInfo( + FormattedHostsPerState* formatted_hosts_per_state, + unsigned int* tab_state_flags) const { + DCHECK(tab_state_flags); + DCHECK(embedder_url_.is_valid()); + const ContentSetting default_setting = + profile_->GetGeolocationContentSettingsMap()->GetDefaultContentSetting(); + for (StateMap::const_iterator i(state_map_.begin()); + i != state_map_.end(); ++i) { + if (i->second == CONTENT_SETTING_ALLOW) + *tab_state_flags |= TABSTATE_HAS_ANY_ALLOWED; + if (formatted_hosts_per_state) { + (*formatted_hosts_per_state)[i->second].insert( + GURLToFormattedHost(i->first)); + } + + const ContentSetting saved_setting = + profile_->GetGeolocationContentSettingsMap()->GetContentSetting( + i->first, embedder_url_); + if (saved_setting != default_setting) + *tab_state_flags |= TABSTATE_HAS_EXCEPTION; + if (saved_setting != i->second) + *tab_state_flags |= TABSTATE_HAS_CHANGED; + if (saved_setting != CONTENT_SETTING_ASK) + *tab_state_flags |= TABSTATE_HAS_ANY_ICON; + } +} + +std::string GeolocationSettingsState::GURLToFormattedHost( + const GURL& url) const { + std::wstring display_host_wide; + net::AppendFormattedHost( + url, profile_->GetPrefs()->GetString(prefs::kAcceptLanguages), + &display_host_wide, NULL, NULL); + return WideToUTF8(display_host_wide); +} diff --git a/chrome/browser/geolocation/geolocation_settings_state.h b/chrome/browser/geolocation/geolocation_settings_state.h new file mode 100644 index 0000000..fe3b7b74 --- /dev/null +++ b/chrome/browser/geolocation/geolocation_settings_state.h @@ -0,0 +1,65 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_GEOLOCATION_GEOLOCATION_SETTINGS_STATE_H_ +#define CHROME_BROWSER_GEOLOCATION_GEOLOCATION_SETTINGS_STATE_H_ + +#include <map> +#include <set> + +#include "chrome/browser/tab_contents/navigation_controller.h" +#include "chrome/common/content_settings.h" + +class GeolocationContentSettingsMap; + +// This class manages the geolocation state per tab, and provides information +// and presentation data about the geolocation usage. +class GeolocationSettingsState { + public: + explicit GeolocationSettingsState(Profile* profile); + virtual ~GeolocationSettingsState(); + + typedef std::map<GURL, ContentSetting> StateMap; + const StateMap& state_map() const { + return state_map_; + } + + // Sets the state for |requesting_origin|. + void OnGeolocationPermissionSet(const GURL& requesting_origin, bool allowed); + + // Delegated by TabContents to indicate a navigation has happened and we + // may need to clear our settings. + void DidNavigate(const NavigationController::LoadCommittedDetails& details); + + enum TabState { + TABSTATE_NONE = 0, + // There's at least one entry with non-default setting. + TABSTATE_HAS_EXCEPTION = 1 << 1, + // There's at least one entry with a non-ASK setting. + TABSTATE_HAS_ANY_ICON = 1 << 2, + // There's at least one entry with ALLOWED setting. + TABSTATE_HAS_ANY_ALLOWED = 1 << 3, + // There's at least one entry that doesn't match the saved setting. + TABSTATE_HAS_CHANGED = 1 << 4, + }; + + // Maps ContentSetting to a set of hosts formatted for presentation. + typedef std::map<ContentSetting, std::set<std::string> > + FormattedHostsPerState; + + // Returns an (optional) |formatted_hosts_per_state| and a mask of TabState. + void GetDetailedInfo(FormattedHostsPerState* formatted_hosts_per_state, + unsigned int* tab_state_flags) const; + + private: + std::string GURLToFormattedHost(const GURL& url) const; + + Profile* profile_; + StateMap state_map_; + GURL embedder_url_; + + DISALLOW_COPY_AND_ASSIGN(GeolocationSettingsState); +}; + +#endif // CHROME_BROWSER_GEOLOCATION_GEOLOCATION_SETTINGS_STATE_H_ diff --git a/chrome/browser/geolocation/geolocation_settings_state_unittest.cc b/chrome/browser/geolocation/geolocation_settings_state_unittest.cc new file mode 100644 index 0000000..f7c9c17 --- /dev/null +++ b/chrome/browser/geolocation/geolocation_settings_state_unittest.cc @@ -0,0 +1,122 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/geolocation/geolocation_settings_state.h" + +#include "chrome/browser/geolocation/geolocation_content_settings_map.h" +#include "chrome/browser/tab_contents/navigation_entry.h" +#include "chrome/test/testing_profile.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +class GeolocationSettingsStateTests : public testing::Test { + public: + GeolocationSettingsStateTests() + : ui_thread_(ChromeThread::UI, &message_loop_) { + } + + protected: + MessageLoop message_loop_; + ChromeThread ui_thread_; +}; + +TEST_F(GeolocationSettingsStateTests, ClearOnNewOrigin) { + TestingProfile profile; + GeolocationSettingsState state(&profile); + GURL url_0("http://www.example.com"); + + NavigationEntry entry; + entry.set_url(url_0); + NavigationController::LoadCommittedDetails load_committed_details; + load_committed_details.entry = &entry; + state.DidNavigate(load_committed_details); + + profile.GetGeolocationContentSettingsMap()->SetContentSetting( + url_0, url_0, CONTENT_SETTING_ALLOW); + state.OnGeolocationPermissionSet(url_0, true); + + GURL url_1("http://www.example1.com"); + profile.GetGeolocationContentSettingsMap()->SetContentSetting( + url_1, url_0, CONTENT_SETTING_BLOCK); + state.OnGeolocationPermissionSet(url_1, false); + + GeolocationSettingsState::StateMap state_map = + state.state_map(); + EXPECT_EQ(2U, state_map.size()); + + GeolocationSettingsState::FormattedHostsPerState formatted_host_per_state; + unsigned int tab_state_flags = 0; + state.GetDetailedInfo(&formatted_host_per_state, &tab_state_flags); + EXPECT_TRUE(tab_state_flags & + GeolocationSettingsState::TABSTATE_HAS_ANY_ALLOWED) + << tab_state_flags; + EXPECT_TRUE(tab_state_flags & + GeolocationSettingsState::TABSTATE_HAS_EXCEPTION) + << tab_state_flags; + EXPECT_FALSE(tab_state_flags & + GeolocationSettingsState::TABSTATE_HAS_CHANGED) + << tab_state_flags; + EXPECT_TRUE(tab_state_flags & + GeolocationSettingsState::TABSTATE_HAS_ANY_ICON) + << tab_state_flags; + EXPECT_EQ(1U, formatted_host_per_state[CONTENT_SETTING_ALLOW].size()); + EXPECT_EQ(1U, + formatted_host_per_state[CONTENT_SETTING_ALLOW].count( + url_0.host())); + + EXPECT_EQ(1U, formatted_host_per_state[CONTENT_SETTING_BLOCK].size()); + EXPECT_EQ(1U, + formatted_host_per_state[CONTENT_SETTING_BLOCK].count( + url_1.host())); + + state.OnGeolocationPermissionSet(url_0, false); + + formatted_host_per_state.clear(); + tab_state_flags = 0; + state.GetDetailedInfo(&formatted_host_per_state, &tab_state_flags); + EXPECT_FALSE(tab_state_flags & + GeolocationSettingsState::TABSTATE_HAS_ANY_ALLOWED) + << tab_state_flags; + EXPECT_TRUE(tab_state_flags & + GeolocationSettingsState::TABSTATE_HAS_EXCEPTION) + << tab_state_flags; + EXPECT_TRUE(tab_state_flags & + GeolocationSettingsState::TABSTATE_HAS_CHANGED) + << tab_state_flags; + EXPECT_TRUE(tab_state_flags & + GeolocationSettingsState::TABSTATE_HAS_ANY_ICON) + << tab_state_flags; + EXPECT_EQ(0U, formatted_host_per_state[CONTENT_SETTING_ALLOW].size()); + EXPECT_EQ(2U, formatted_host_per_state[CONTENT_SETTING_BLOCK].size()); + EXPECT_EQ(1U, + formatted_host_per_state[CONTENT_SETTING_BLOCK].count( + url_0.host())); + EXPECT_EQ(1U, + formatted_host_per_state[CONTENT_SETTING_BLOCK].count( + url_1.host())); + + state.OnGeolocationPermissionSet(url_0, true); + + load_committed_details.previous_url = url_0; + state.DidNavigate(load_committed_details); + + GeolocationSettingsState::StateMap new_state_map = + state.state_map(); + EXPECT_EQ(state_map.size(), new_state_map.size()); + + GURL different_url("http://foo.com"); + entry.set_url(different_url); + state.DidNavigate(load_committed_details); + + EXPECT_TRUE(state.state_map().empty()); + + formatted_host_per_state.clear(); + tab_state_flags = 0; + state.GetDetailedInfo(&formatted_host_per_state, &tab_state_flags); + EXPECT_TRUE(formatted_host_per_state.empty()); + EXPECT_EQ(0U, tab_state_flags); +} + +} // namespace |