summaryrefslogtreecommitdiffstats
path: root/chrome/browser/geolocation
diff options
context:
space:
mode:
authorbulach@chromium.org <bulach@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-11 13:28:16 +0000
committerbulach@chromium.org <bulach@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-11 13:28:16 +0000
commit777a7b66c0a16a8917b29af3ea6d2e440bc5371b (patch)
tree6a48fb9ecc0355a29405f3b6e0bfd2c455de8849 /chrome/browser/geolocation
parent8b4b84eee1eaa6a77c34f66f7278039004657896 (diff)
downloadchromium_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')
-rw-r--r--chrome/browser/geolocation/geolocation_browsertest.cc15
-rw-r--r--chrome/browser/geolocation/geolocation_permission_context_unittest.cc17
-rw-r--r--chrome/browser/geolocation/geolocation_settings_state.cc81
-rw-r--r--chrome/browser/geolocation/geolocation_settings_state.h65
-rw-r--r--chrome/browser/geolocation/geolocation_settings_state_unittest.cc122
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