summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpkasting@chromium.org <pkasting@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-19 01:52:45 +0000
committerpkasting@chromium.org <pkasting@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-19 01:52:45 +0000
commitaee541ebc97e1ff2c8bb43e4375913f582931d40 (patch)
tree49e6735353739bef26d1e960738470247ffa0dc8
parent470ad82d83b7773ed5c791a1f3b612087b980eee (diff)
downloadchromium_src-aee541ebc97e1ff2c8bb43e4375913f582931d40.zip
chromium_src-aee541ebc97e1ff2c8bb43e4375913f582931d40.tar.gz
chromium_src-aee541ebc97e1ff2c8bb43e4375913f582931d40.tar.bz2
Add GeolocationContentSettingsMap, a geolocation-specific variant of HostContentSettingsMap.
This was originally written by bulach and posted at http://codereview.chromium.org/1033004 ; modified and landed by me. BUG=37206 TEST=Tested by unittests TBR=bulach,joth Review URL: http://codereview.chromium.org/1084005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@42064 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/browser_prefs.cc2
-rwxr-xr-xchrome/browser/geolocation/geolocation_content_settings_map.cc203
-rwxr-xr-xchrome/browser/geolocation/geolocation_content_settings_map.h121
-rwxr-xr-xchrome/browser/geolocation/geolocation_content_settings_map_unittest.cc231
-rw-r--r--chrome/browser/host_content_settings_map.cc2
-rw-r--r--chrome/browser/profile.cc11
-rw-r--r--chrome/browser/profile.h7
-rwxr-xr-xchrome/chrome_browser.gypi2
-rw-r--r--chrome/chrome_common.gypi5
-rw-r--r--chrome/chrome_tests.gypi1
-rw-r--r--chrome/common/content_settings.cc11
-rw-r--r--chrome/common/content_settings.h4
-rw-r--r--chrome/common/pref_names.cc7
-rw-r--r--chrome/common/pref_names.h2
-rw-r--r--chrome/test/testing_profile.h10
15 files changed, 616 insertions, 3 deletions
diff --git a/chrome/browser/browser_prefs.cc b/chrome/browser/browser_prefs.cc
index 85eac53..187201a 100644
--- a/chrome/browser/browser_prefs.cc
+++ b/chrome/browser/browser_prefs.cc
@@ -16,6 +16,7 @@
#include "chrome/browser/extensions/extension_prefs.h"
#include "chrome/browser/extensions/extensions_ui.h"
#include "chrome/browser/external_protocol_handler.h"
+#include "chrome/browser/geolocation/geolocation_content_settings_map.h"
#include "chrome/browser/geolocation/geolocation_prefs.h"
#include "chrome/browser/google_url_tracker.h"
#include "chrome/browser/host_content_settings_map.h"
@@ -102,6 +103,7 @@ void RegisterUserPrefs(PrefService* user_prefs) {
Blacklist::RegisterUserPrefs(user_prefs);
PinnedTabCodec::RegisterUserPrefs(user_prefs);
ExtensionPrefs::RegisterUserPrefs(user_prefs);
+ GeolocationContentSettingsMap::RegisterUserPrefs(user_prefs);
#if defined(TOOLKIT_VIEWS)
BrowserActionsContainer::RegisterUserPrefs(user_prefs);
#elif defined(TOOLKIT_GTK)
diff --git a/chrome/browser/geolocation/geolocation_content_settings_map.cc b/chrome/browser/geolocation/geolocation_content_settings_map.cc
new file mode 100755
index 0000000..3f88fb2
--- /dev/null
+++ b/chrome/browser/geolocation/geolocation_content_settings_map.cc
@@ -0,0 +1,203 @@
+// 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_content_settings_map.h"
+
+#include "base/utf_string_conversions.h"
+#include "chrome/browser/chrome_thread.h"
+#include "chrome/browser/pref_service.h"
+#include "chrome/browser/profile.h"
+#include "chrome/common/notification_service.h"
+#include "chrome/common/notification_type.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/common/url_constants.h"
+#include "net/base/dns_util.h"
+#include "net/base/static_cookie_policy.h"
+
+// static
+const ContentSetting
+ GeolocationContentSettingsMap::kDefaultSetting = CONTENT_SETTING_ASK;
+
+GeolocationContentSettingsMap::GeolocationContentSettingsMap(Profile* profile)
+ : profile_(profile) {
+ PrefService* prefs = profile_->GetPrefs();
+
+ // Read global defaults.
+ default_content_setting_ = IntToContentSetting(
+ prefs->GetInteger(prefs::kGeolocationDefaultContentSetting));
+ if (default_content_setting_ == CONTENT_SETTING_DEFAULT)
+ default_content_setting_ = kDefaultSetting;
+
+ // Read exceptions.
+ const DictionaryValue* all_settings_dictionary =
+ prefs->GetDictionary(prefs::kGeolocationContentSettings);
+ // Careful: The returned value could be NULL if the pref has never been set.
+ if (all_settings_dictionary != NULL) {
+ for (DictionaryValue::key_iterator i(all_settings_dictionary->begin_keys());
+ i != all_settings_dictionary->end_keys(); ++i) {
+ const std::wstring& wide_origin(*i);
+ DictionaryValue* requesting_origin_settings_dictionary = NULL;
+ bool found = all_settings_dictionary->GetDictionaryWithoutPathExpansion(
+ wide_origin, &requesting_origin_settings_dictionary);
+ DCHECK(found);
+ OneOriginSettings* requesting_origin_settings =
+ &content_settings_[GURL(WideToUTF8(wide_origin))];
+ GetOneOriginSettingsFromDictionary(requesting_origin_settings_dictionary,
+ requesting_origin_settings);
+ }
+ }
+}
+
+// static
+void GeolocationContentSettingsMap::RegisterUserPrefs(PrefService* prefs) {
+ prefs->RegisterIntegerPref(prefs::kGeolocationDefaultContentSetting,
+ CONTENT_SETTING_ASK);
+ prefs->RegisterDictionaryPref(prefs::kGeolocationContentSettings);
+}
+
+ContentSetting GeolocationContentSettingsMap::GetDefaultContentSetting() const {
+ AutoLock auto_lock(lock_);
+ return default_content_setting_;
+}
+
+ContentSetting GeolocationContentSettingsMap::GetContentSetting(
+ const GURL& requesting_url,
+ const GURL& embedding_url) const {
+ DCHECK(requesting_url.is_valid() && embedding_url.is_valid());
+ GURL requesting_origin(requesting_url.GetOrigin());
+ GURL embedding_origin(embedding_url.GetOrigin());
+ DCHECK(requesting_origin.is_valid() && embedding_origin.is_valid());
+ AutoLock auto_lock(lock_);
+ AllOriginsSettings::const_iterator i(content_settings_.find(
+ requesting_origin));
+ if (i != content_settings_.end()) {
+ OneOriginSettings::const_iterator j(i->second.find(embedding_origin));
+ if (j != i->second.end())
+ return j->second;
+ if (requesting_origin != embedding_origin) {
+ OneOriginSettings::const_iterator any_embedder(i->second.find(GURL()));
+ if (any_embedder != i->second.end())
+ return any_embedder->second;
+ }
+ }
+ return default_content_setting_;
+}
+
+GeolocationContentSettingsMap::AllOriginsSettings
+ GeolocationContentSettingsMap::GetAllOriginsSettings() const {
+ AutoLock auto_lock(lock_);
+ return content_settings_;
+}
+
+void GeolocationContentSettingsMap::SetDefaultContentSetting(
+ ContentSetting setting) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
+ {
+ AutoLock auto_lock(lock_);
+ default_content_setting_ =
+ (setting == CONTENT_SETTING_DEFAULT) ? kDefaultSetting : setting;
+ }
+ profile_->GetPrefs()->SetInteger(prefs::kGeolocationDefaultContentSetting,
+ default_content_setting_);
+}
+
+void GeolocationContentSettingsMap::SetContentSetting(
+ const GURL& requesting_url,
+ const GURL& embedding_url,
+ ContentSetting setting) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
+ DCHECK(requesting_url.is_valid() &&
+ (embedding_url.is_valid() || embedding_url.is_empty()));
+ GURL requesting_origin(requesting_url.GetOrigin());
+ GURL embedding_origin(embedding_url.GetOrigin());
+ DCHECK(requesting_origin.is_valid() &&
+ (embedding_origin.is_valid() || embedding_url.is_empty()));
+ std::wstring wide_requesting_origin(UTF8ToWide(requesting_origin.spec()));
+ std::wstring wide_embedding_origin(UTF8ToWide(embedding_origin.spec()));
+ DictionaryValue* all_settings_dictionary =
+ profile_->GetPrefs()->GetMutableDictionary(
+ prefs::kGeolocationContentSettings);
+
+ AutoLock auto_lock(lock_);
+ DictionaryValue* requesting_origin_settings_dictionary;
+ all_settings_dictionary->GetDictionaryWithoutPathExpansion(
+ wide_requesting_origin, &requesting_origin_settings_dictionary);
+ if (setting == CONTENT_SETTING_DEFAULT) {
+ if (!content_settings_.count(requesting_origin) ||
+ !content_settings_[requesting_origin].count(embedding_origin))
+ return;
+ if (content_settings_[requesting_origin].size() == 1) {
+ all_settings_dictionary->RemoveWithoutPathExpansion(
+ wide_requesting_origin, NULL);
+ content_settings_.erase(requesting_origin);
+ return;
+ }
+ requesting_origin_settings_dictionary->RemoveWithoutPathExpansion(
+ wide_embedding_origin, NULL);
+ content_settings_[requesting_origin].erase(embedding_origin);
+ return;
+ }
+
+ if (!content_settings_.count(requesting_origin)) {
+ requesting_origin_settings_dictionary = new DictionaryValue;
+ all_settings_dictionary->SetWithoutPathExpansion(
+ wide_requesting_origin, requesting_origin_settings_dictionary);
+ }
+ content_settings_[requesting_origin][embedding_origin] = setting;
+ DCHECK(requesting_origin_settings_dictionary);
+ requesting_origin_settings_dictionary->SetWithoutPathExpansion(
+ wide_embedding_origin, Value::CreateIntegerValue(setting));
+}
+
+void GeolocationContentSettingsMap::ClearOneRequestingOrigin(
+ const GURL& requesting_origin) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
+ DCHECK(requesting_origin.is_valid());
+
+ {
+ AutoLock auto_lock(lock_);
+ AllOriginsSettings::iterator i(content_settings_.find(requesting_origin));
+ if (i == content_settings_.end())
+ return;
+ content_settings_.erase(i);
+ }
+
+ DictionaryValue* all_settings_dictionary =
+ profile_->GetPrefs()->GetMutableDictionary(
+ prefs::kGeolocationContentSettings);
+ all_settings_dictionary->RemoveWithoutPathExpansion(
+ UTF8ToWide(requesting_origin.spec()), NULL);
+}
+
+void GeolocationContentSettingsMap::ResetToDefault() {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
+
+ {
+ AutoLock auto_lock(lock_);
+ default_content_setting_ = kDefaultSetting;
+ content_settings_.clear();
+ }
+
+ PrefService* prefs = profile_->GetPrefs();
+ prefs->ClearPref(prefs::kGeolocationDefaultContentSetting);
+ prefs->ClearPref(prefs::kGeolocationContentSettings);
+}
+
+GeolocationContentSettingsMap::~GeolocationContentSettingsMap() {
+}
+
+// static
+void GeolocationContentSettingsMap::GetOneOriginSettingsFromDictionary(
+ const DictionaryValue* dictionary,
+ OneOriginSettings* one_origin_settings) {
+ for (DictionaryValue::key_iterator i(dictionary->begin_keys());
+ i != dictionary->end_keys(); ++i) {
+ const std::wstring& target(*i);
+ int setting = kDefaultSetting;
+ bool found = dictionary->GetIntegerWithoutPathExpansion(target, &setting);
+ DCHECK(found);
+ (*one_origin_settings)[GURL(WideToUTF8(target))] =
+ IntToContentSetting(setting);
+ }
+}
diff --git a/chrome/browser/geolocation/geolocation_content_settings_map.h b/chrome/browser/geolocation/geolocation_content_settings_map.h
new file mode 100755
index 0000000..df9d953
--- /dev/null
+++ b/chrome/browser/geolocation/geolocation_content_settings_map.h
@@ -0,0 +1,121 @@
+// 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.
+
+// Maps [requesting_origin, embedder] to content settings. Written on the UI
+// thread and read on any thread. One instance per profile. This is based on
+// HostContentSettingsMap but differs significantly in two aspects:
+// - It maps [requesting_origin.GetOrigin(), embedder.GetOrigin()] => setting
+// rather than host => setting.
+// - It manages only Geolocation.
+
+#ifndef CHROME_BROWSER_GEOLOCATION_GEOLOCATION_CONTENT_SETTINGS_MAP_H_
+#define CHROME_BROWSER_GEOLOCATION_GEOLOCATION_CONTENT_SETTINGS_MAP_H_
+
+#include <map>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/lock.h"
+#include "base/ref_counted.h"
+#include "chrome/common/content_settings.h"
+#include "googleurl/src/gurl.h"
+
+class DictionaryValue;
+class PrefService;
+class Profile;
+
+class GeolocationContentSettingsMap
+ : public base::RefCountedThreadSafe<GeolocationContentSettingsMap> {
+ public:
+ typedef std::map<GURL, ContentSetting> OneOriginSettings;
+ typedef std::map<GURL, OneOriginSettings> AllOriginsSettings;
+
+ explicit GeolocationContentSettingsMap(Profile* profile);
+
+ static void RegisterUserPrefs(PrefService* prefs);
+
+ // Returns the default setting.
+ //
+ // This may be called on any thread.
+ ContentSetting GetDefaultContentSetting() const;
+
+ // Returns a single ContentSetting which applies to the given |requesting_url|
+ // when embedded in a top-level page from |embedding_url|. To determine the
+ // setting for a top-level page, as opposed to a frame embedded in a page,
+ // pass the page's URL for both arguments.
+ //
+ // This may be called on any thread. Both arguments should be valid GURLs.
+ ContentSetting GetContentSetting(const GURL& requesting_url,
+ const GURL& embedding_url) const;
+
+ // Returns the settings for all origins with any non-default settings.
+ //
+ // This may be called on any thread.
+ AllOriginsSettings GetAllOriginsSettings() const;
+
+ // Sets the default setting.
+ //
+ // This should only be called on the UI thread.
+ void SetDefaultContentSetting(ContentSetting setting);
+
+ // Sets the content setting for a particular (requesting origin, embedding
+ // origin) pair. If the embedding origin is the same as the requesting
+ // origin, this represents the setting used when the requesting origin is
+ // itself the top-level page. If |embedder| is the empty GURL, |setting|
+ // becomes the default setting for the requesting origin when embedded on any
+ // page that does not have an explicit setting. Passing
+ // CONTENT_SETTING_DEFAULT for |setting| effectively removes that setting and
+ // allows future requests to return the all-embedders or global defaults (as
+ // applicable).
+ //
+ // This should only be called on the UI thread. |requesting_url| should be
+ // a valid GURL, and |embedding_url| should be valid or empty.
+ void SetContentSetting(const GURL& requesting_url,
+ const GURL& embedding_url,
+ ContentSetting setting);
+
+ // Clears all settings for |requesting_origin|. Note: Unlike in the functions
+ // above, this is expected to be an origin, not some URL of which we'll take
+ // the origin; this is to prevent ambiguity where callers could think they're
+ // clearing something wider or narrower than they really are.
+ //
+ // This should only be called on the UI thread. |requesting_origin| should be
+ // a valid GURL.
+ void ClearOneRequestingOrigin(const GURL& requesting_origin);
+
+ // Resets all settings.
+ //
+ // This should only be called on the UI thread.
+ void ResetToDefault();
+
+ private:
+ friend class base::RefCountedThreadSafe<GeolocationContentSettingsMap>;
+
+ // The default setting.
+ static const ContentSetting kDefaultSetting;
+
+ ~GeolocationContentSettingsMap();
+
+ // Sets the fields of |one_origin_settings| based on the values in
+ // |dictionary|.
+ static void GetOneOriginSettingsFromDictionary(
+ const DictionaryValue* dictionary,
+ OneOriginSettings* one_origin_settings);
+
+ // The profile we're associated with.
+ Profile* profile_;
+
+ // Copies of the pref data, so that we can read it on the IO thread.
+ ContentSetting default_content_setting_;
+ AllOriginsSettings content_settings_;
+
+ // Used around accesses to the settings objects to guarantee thread safety.
+ mutable Lock lock_;
+
+ DISALLOW_COPY_AND_ASSIGN(GeolocationContentSettingsMap);
+};
+
+#endif // CHROME_BROWSER_GEOLOCATION_GEOLOCATION_CONTENT_SETTINGS_MAP_H_
diff --git a/chrome/browser/geolocation/geolocation_content_settings_map_unittest.cc b/chrome/browser/geolocation/geolocation_content_settings_map_unittest.cc
new file mode 100755
index 0000000..4219c6d
--- /dev/null
+++ b/chrome/browser/geolocation/geolocation_content_settings_map_unittest.cc
@@ -0,0 +1,231 @@
+// 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_content_settings_map.h"
+
+#include "chrome/test/testing_profile.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+
+namespace {
+
+class GeolocationContentSettingsMapTests : public testing::Test {
+ public:
+ GeolocationContentSettingsMapTests()
+ : ui_thread_(ChromeThread::UI, &message_loop_) {
+ }
+
+ protected:
+ MessageLoop message_loop_;
+ ChromeThread ui_thread_;
+};
+
+TEST_F(GeolocationContentSettingsMapTests, DefaultValues) {
+ TestingProfile profile;
+ GeolocationContentSettingsMap* map =
+ profile.GetGeolocationContentSettingsMap();
+
+ // Check setting defaults.
+ EXPECT_EQ(CONTENT_SETTING_ASK, map->GetDefaultContentSetting());
+ map->SetDefaultContentSetting(CONTENT_SETTING_BLOCK);
+ EXPECT_EQ(CONTENT_SETTING_BLOCK, map->GetDefaultContentSetting());
+}
+
+TEST_F(GeolocationContentSettingsMapTests, Embedder) {
+ TestingProfile profile;
+ GeolocationContentSettingsMap* map =
+ profile.GetGeolocationContentSettingsMap();
+ GURL top_level("http://www.toplevel0.com/foo/bar");
+ EXPECT_EQ(CONTENT_SETTING_ASK, map->GetContentSetting(top_level, top_level));
+ // Now set the permission for requester_0.
+ map->SetContentSetting(top_level, top_level, CONTENT_SETTING_ALLOW);
+ EXPECT_EQ(CONTENT_SETTING_ALLOW,
+ map->GetContentSetting(top_level, top_level));
+
+ GURL requester_0("http://www.frame0.com/foo/bar");
+ EXPECT_EQ(CONTENT_SETTING_ASK,
+ map->GetContentSetting(requester_0, top_level));
+ // Now set the permission for only requester_1.
+ map->SetContentSetting(requester_0, top_level, CONTENT_SETTING_ALLOW);
+ EXPECT_EQ(CONTENT_SETTING_ALLOW,
+ map->GetContentSetting(top_level, top_level));
+ EXPECT_EQ(CONTENT_SETTING_ALLOW,
+ map->GetContentSetting(requester_0, top_level));
+ // Block only requester_1.
+ map->SetContentSetting(requester_0, top_level, CONTENT_SETTING_BLOCK);
+ EXPECT_EQ(CONTENT_SETTING_BLOCK,
+ map->GetContentSetting(requester_0, top_level));
+ EXPECT_EQ(CONTENT_SETTING_ALLOW,
+ map->GetContentSetting(top_level, top_level));
+}
+
+TEST_F(GeolocationContentSettingsMapTests, MultipleEmbeddersAndOrigins) {
+ TestingProfile profile;
+ GeolocationContentSettingsMap* map =
+ profile.GetGeolocationContentSettingsMap();
+ GURL requester_0("http://www.iframe0.com/foo/bar");
+ GURL requester_1("http://www.iframe1.co.uk/bar/foo");
+ GURL embedder_0("http://www.toplevel0.com/foo/bar");
+ EXPECT_EQ(CONTENT_SETTING_ASK,
+ map->GetContentSetting(requester_0, embedder_0));
+ EXPECT_EQ(CONTENT_SETTING_ASK,
+ map->GetContentSetting(requester_1, embedder_0));
+ // Now set the permission for only one origin.
+ map->SetContentSetting(requester_0, embedder_0, CONTENT_SETTING_ALLOW);
+ EXPECT_EQ(CONTENT_SETTING_ALLOW,
+ map->GetContentSetting(requester_0, embedder_0));
+ EXPECT_EQ(CONTENT_SETTING_ASK,
+ map->GetContentSetting(requester_1, embedder_0));
+ // Set the permission for the other origin.
+ map->SetContentSetting(requester_1, embedder_0, CONTENT_SETTING_ALLOW);
+ EXPECT_EQ(CONTENT_SETTING_ALLOW,
+ map->GetContentSetting(requester_1, embedder_0));
+ // Check they're not allowed on a different embedder.
+ GURL embedder_1("http://www.toplevel1.com/foo/bar");
+ EXPECT_EQ(CONTENT_SETTING_ASK,
+ map->GetContentSetting(requester_0, embedder_1));
+ EXPECT_EQ(CONTENT_SETTING_ASK,
+ map->GetContentSetting(requester_1, embedder_1));
+ // Check all settings are valid.
+ GeolocationContentSettingsMap::AllOriginsSettings content_settings(
+ map->GetAllOriginsSettings());
+ EXPECT_EQ(0U, content_settings.count(requester_0));
+ EXPECT_EQ(1U, content_settings.count(requester_0.GetOrigin()));
+ GeolocationContentSettingsMap::OneOriginSettings one_origin_settings(
+ content_settings[requester_0.GetOrigin()]);
+ EXPECT_EQ(CONTENT_SETTING_ALLOW, one_origin_settings[embedder_0.GetOrigin()]);
+
+ EXPECT_EQ(0U, content_settings.count(requester_1));
+ EXPECT_EQ(1U, content_settings.count(requester_1.GetOrigin()));
+ one_origin_settings = content_settings[requester_1.GetOrigin()];
+ EXPECT_EQ(CONTENT_SETTING_ALLOW, one_origin_settings[embedder_0.GetOrigin()]);
+ // Block requester_1 on the first embedder and add it to the second.
+ map->SetContentSetting(requester_1, embedder_0, CONTENT_SETTING_BLOCK);
+ map->SetContentSetting(requester_1, embedder_1, CONTENT_SETTING_ALLOW);
+ EXPECT_EQ(CONTENT_SETTING_BLOCK,
+ map->GetContentSetting(requester_1, embedder_0));
+ EXPECT_EQ(CONTENT_SETTING_ALLOW,
+ map->GetContentSetting(requester_1, embedder_1));
+}
+
+TEST_F(GeolocationContentSettingsMapTests, SetContentSettingDefault) {
+ TestingProfile profile;
+ GeolocationContentSettingsMap* map =
+ profile.GetGeolocationContentSettingsMap();
+ GURL top_level("http://www.toplevel0.com/foo/bar");
+ map->SetContentSetting(top_level, top_level, CONTENT_SETTING_ALLOW);
+ EXPECT_EQ(CONTENT_SETTING_ALLOW,
+ map->GetContentSetting(top_level, top_level));
+ // Set to CONTENT_SETTING_DEFAULT and check the actual value has changed.
+ map->SetContentSetting(top_level, top_level, CONTENT_SETTING_DEFAULT);
+ EXPECT_EQ(CONTENT_SETTING_ASK, map->GetContentSetting(top_level, top_level));
+}
+
+TEST_F(GeolocationContentSettingsMapTests, ClearOneOrigin) {
+ TestingProfile profile;
+ GeolocationContentSettingsMap* map =
+ profile.GetGeolocationContentSettingsMap();
+ GURL requester_0("http://www.iframe0.com/foo/bar");
+ GURL requester_1("http://www.iframe1.com/foo/bar");
+ GURL embedder_0("http://www.toplevel0.com/foo/bar");
+ map->SetContentSetting(requester_0, embedder_0, CONTENT_SETTING_ALLOW);
+ map->SetContentSetting(requester_1, embedder_0, CONTENT_SETTING_ALLOW);
+ EXPECT_EQ(CONTENT_SETTING_ALLOW,
+ map->GetContentSetting(requester_0, embedder_0));
+ EXPECT_EQ(CONTENT_SETTING_ALLOW,
+ map->GetContentSetting(requester_1, embedder_0));
+
+ map->ClearOneRequestingOrigin(requester_0.GetOrigin());
+ EXPECT_EQ(CONTENT_SETTING_ASK,
+ map->GetContentSetting(requester_0, embedder_0));
+
+ // Passing a non-origin shouldn't do anything.
+ map->ClearOneRequestingOrigin(requester_1);
+ EXPECT_EQ(CONTENT_SETTING_ALLOW,
+ map->GetContentSetting(requester_1, embedder_0));
+}
+
+TEST_F(GeolocationContentSettingsMapTests, Reset) {
+ TestingProfile profile;
+ GeolocationContentSettingsMap* map =
+ profile.GetGeolocationContentSettingsMap();
+ GURL requester_0("http://www.iframe0.com/foo/bar");
+ GURL embedder_0("http://www.toplevel0.com/foo/bar");
+ map->SetContentSetting(requester_0, embedder_0, CONTENT_SETTING_ALLOW);
+ EXPECT_EQ(CONTENT_SETTING_ALLOW,
+ map->GetContentSetting(requester_0, embedder_0));
+ GeolocationContentSettingsMap::AllOriginsSettings content_settings(
+ map->GetAllOriginsSettings());
+ EXPECT_EQ(1U, content_settings.size());
+
+ // Set to CONTENT_SETTING_DEFAULT and check the actual value has changed.
+ map->SetContentSetting(requester_0, embedder_0, CONTENT_SETTING_DEFAULT);
+ EXPECT_EQ(CONTENT_SETTING_ASK,
+ map->GetContentSetting(requester_0, embedder_0));
+ content_settings = map->GetAllOriginsSettings();
+ EXPECT_TRUE(content_settings.empty());
+}
+
+TEST_F(GeolocationContentSettingsMapTests, ClearsWhenSettingBackToDefault) {
+ TestingProfile profile;
+ GeolocationContentSettingsMap* map =
+ profile.GetGeolocationContentSettingsMap();
+ GURL requester_0("http://www.iframe0.com/foo/bar");
+ GURL requester_1("http://www.iframe1.com/foo/bar");
+ GURL embedder_0("http://www.toplevel0.com/foo/bar");
+ map->SetContentSetting(requester_0, embedder_0, CONTENT_SETTING_ALLOW);
+ EXPECT_EQ(CONTENT_SETTING_ALLOW,
+ map->GetContentSetting(requester_0, embedder_0));
+ GeolocationContentSettingsMap::AllOriginsSettings content_settings(
+ map->GetAllOriginsSettings());
+ EXPECT_EQ(1U, content_settings.size());
+
+ map->SetContentSetting(requester_1, embedder_0, CONTENT_SETTING_ALLOW);
+ EXPECT_EQ(CONTENT_SETTING_ALLOW,
+ map->GetContentSetting(requester_1, embedder_0));
+ content_settings = map->GetAllOriginsSettings();
+ EXPECT_EQ(2U, content_settings.size());
+ EXPECT_EQ(1U, content_settings[requester_0.GetOrigin()].size());
+ EXPECT_EQ(1U, content_settings[requester_1.GetOrigin()].size());
+
+ // Set to default.
+ map->SetContentSetting(requester_0, embedder_0, CONTENT_SETTING_DEFAULT);
+ content_settings = map->GetAllOriginsSettings();
+ EXPECT_EQ(1U, content_settings.size());
+
+ map->SetContentSetting(requester_1, embedder_0, CONTENT_SETTING_DEFAULT);
+ content_settings = map->GetAllOriginsSettings();
+ EXPECT_TRUE(content_settings.empty());
+}
+
+TEST_F(GeolocationContentSettingsMapTests, WildCardForEmptyEmbedder) {
+ TestingProfile profile;
+ GeolocationContentSettingsMap* map =
+ profile.GetGeolocationContentSettingsMap();
+ GURL requester_0("http://www.iframe0.com/foo/bar");
+ GURL embedder_0("http://www.toplevel0.com/foo/bar");
+ GURL embedder_1("http://www.toplevel1.com/foo/bar");
+ GURL empty_url;
+ map->SetContentSetting(requester_0, embedder_0, CONTENT_SETTING_BLOCK);
+ map->SetContentSetting(requester_0, empty_url, CONTENT_SETTING_ALLOW);
+ EXPECT_EQ(CONTENT_SETTING_BLOCK,
+ map->GetContentSetting(requester_0, embedder_0));
+ EXPECT_EQ(CONTENT_SETTING_ALLOW,
+ map->GetContentSetting(requester_0, embedder_1));
+ EXPECT_EQ(CONTENT_SETTING_ASK,
+ map->GetContentSetting(requester_0, requester_0));
+
+ // Change the wildcard behavior.
+ map->SetContentSetting(requester_0, embedder_0, CONTENT_SETTING_ALLOW);
+ map->SetContentSetting(requester_0, empty_url, CONTENT_SETTING_BLOCK);
+ map->SetDefaultContentSetting(CONTENT_SETTING_ALLOW);
+ EXPECT_EQ(CONTENT_SETTING_ALLOW,
+ map->GetContentSetting(requester_0, embedder_0));
+ EXPECT_EQ(CONTENT_SETTING_BLOCK,
+ map->GetContentSetting(requester_0, embedder_1));
+ EXPECT_EQ(CONTENT_SETTING_ALLOW,
+ map->GetContentSetting(requester_0, requester_0));
+}
+
+} // namespace
diff --git a/chrome/browser/host_content_settings_map.cc b/chrome/browser/host_content_settings_map.cc
index 811836a..2508f6cc 100644
--- a/chrome/browser/host_content_settings_map.cc
+++ b/chrome/browser/host_content_settings_map.cc
@@ -352,7 +352,7 @@ void HostContentSettingsMap::GetSettingsFromDictionary(
DCHECK(found);
for (size_t type = 0; type < arraysize(kTypeNames); ++type) {
if (std::wstring(kTypeNames[type]) == content_type) {
- settings->settings[type] = static_cast<ContentSetting>(setting);
+ settings->settings[type] = IntToContentSetting(setting);
break;
}
}
diff --git a/chrome/browser/profile.cc b/chrome/browser/profile.cc
index c94b38c..802ad29 100644
--- a/chrome/browser/profile.cc
+++ b/chrome/browser/profile.cc
@@ -28,6 +28,7 @@
#include "chrome/browser/extensions/extensions_service.h"
#include "chrome/browser/extensions/user_script_master.h"
#include "chrome/browser/favicon_service.h"
+#include "chrome/browser/geolocation/geolocation_content_settings_map.h"
#include "chrome/browser/spellcheck_host.h"
#include "chrome/browser/transport_security_persister.h"
#include "chrome/browser/history/history.h"
@@ -408,6 +409,10 @@ class OffTheRecordProfileImpl : public Profile,
return profile_->GetHostZoomMap();
}
+ virtual GeolocationContentSettingsMap* GetGeolocationContentSettingsMap() {
+ return profile_->GetGeolocationContentSettingsMap();
+ }
+
virtual Blacklist* GetPrivacyBlacklist() {
return profile_->GetPrivacyBlacklist();
}
@@ -987,6 +992,12 @@ HostZoomMap* ProfileImpl::GetHostZoomMap() {
return host_zoom_map_.get();
}
+GeolocationContentSettingsMap* ProfileImpl::GetGeolocationContentSettingsMap() {
+ if (!geolocation_content_settings_map_.get())
+ geolocation_content_settings_map_ = new GeolocationContentSettingsMap(this);
+ return geolocation_content_settings_map_.get();
+}
+
Blacklist* ProfileImpl::GetPrivacyBlacklist() {
if (!CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnablePrivacyBlacklists))
diff --git a/chrome/browser/profile.h b/chrome/browser/profile.h
index de6ed47..9db5374 100644
--- a/chrome/browser/profile.h
+++ b/chrome/browser/profile.h
@@ -42,6 +42,7 @@ class ExtensionProcessManager;
class ExtensionMessageService;
class ExtensionsService;
class FaviconService;
+class GeolocationContentSettingsMap;
class HistoryService;
class HostContentSettingsMap;
class HostZoomMap;
@@ -298,6 +299,9 @@ class Profile {
// Returns the Hostname <-> Zoom Level map for this profile.
virtual HostZoomMap* GetHostZoomMap() = 0;
+ // Returns the geolocation settings map for this profile.
+ virtual GeolocationContentSettingsMap* GetGeolocationContentSettingsMap() = 0;
+
// Returns the Privacy Blacklist for this profile.
virtual Blacklist* GetPrivacyBlacklist() = 0;
@@ -471,6 +475,7 @@ class ProfileImpl : public Profile,
virtual net::SSLConfigService* GetSSLConfigService();
virtual HostContentSettingsMap* GetHostContentSettingsMap();
virtual HostZoomMap* GetHostZoomMap();
+ virtual GeolocationContentSettingsMap* GetGeolocationContentSettingsMap();
virtual Blacklist* GetPrivacyBlacklist();
virtual UserStyleSheetWatcher* GetUserStyleSheetWatcher();
virtual SessionService* GetSessionService();
@@ -558,6 +563,8 @@ class ProfileImpl : public Profile,
scoped_refptr<HostContentSettingsMap> host_content_settings_map_;
scoped_refptr<HostZoomMap> host_zoom_map_;
+ scoped_refptr<GeolocationContentSettingsMap>
+ geolocation_content_settings_map_;
scoped_refptr<Blacklist> privacy_blacklist_;
scoped_refptr<UserStyleSheetWatcher> user_style_sheet_watcher_;
scoped_refptr<DownloadManager> download_manager_;
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 730914a..a6f0e91 100755
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -1054,6 +1054,8 @@
'browser/geolocation/geolocation_permission_context.h',
'browser/geolocation/geolocation_prefs.cc',
'browser/geolocation/geolocation_prefs.h',
+ 'browser/geolocation/geolocation_content_settings_map.cc',
+ 'browser/geolocation/geolocation_content_settings_map.h',
'browser/geolocation/location_arbitrator.cc',
'browser/geolocation/location_arbitrator.h',
'browser/geolocation/location_provider.cc',
diff --git a/chrome/chrome_common.gypi b/chrome/chrome_common.gypi
index 4fb4c85..6a935e6 100644
--- a/chrome/chrome_common.gypi
+++ b/chrome/chrome_common.gypi
@@ -42,6 +42,9 @@
'common/chrome_counters.h',
'common/common_param_traits.cc',
'common/common_param_traits.h',
+ 'common/content_settings.cc',
+ 'common/content_settings.h',
+ 'common/content_settings_types.h',
'common/debug_flags.cc',
'common/debug_flags.h',
'common/devtools_messages.h',
@@ -196,8 +199,6 @@
'common/command_buffer_messages.h',
'common/command_buffer_messages_internal.h',
'common/common_glue.cc',
- 'common/content_settings.h'
- 'common/content_settings_types.h',
'common/css_colors.h',
'common/db_message_filter.cc',
'common/db_message_filter.h',
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index a465999..25e7e7c 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -752,6 +752,7 @@
'browser/file_watcher_unittest.cc',
'browser/find_backend_unittest.cc',
'browser/geolocation/fake_access_token_store.h',
+ 'browser/geolocation/geolocation_content_settings_map_unittest.cc',
'browser/geolocation/location_arbitrator_unittest.cc',
'browser/geolocation/network_location_provider_unittest.cc',
'browser/geolocation/wifi_data_provider_common_unittest.cc',
diff --git a/chrome/common/content_settings.cc b/chrome/common/content_settings.cc
new file mode 100644
index 0000000..89eaa59
--- /dev/null
+++ b/chrome/common/content_settings.cc
@@ -0,0 +1,11 @@
+// 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/common/content_settings.h"
+
+ContentSetting IntToContentSetting(int content_setting) {
+ return ((content_setting < 0) ||
+ (content_setting >= CONTENT_SETTING_NUM_SETTINGS)) ?
+ CONTENT_SETTING_DEFAULT : static_cast<ContentSetting>(content_setting);
+}
diff --git a/chrome/common/content_settings.h b/chrome/common/content_settings.h
index 63af52e..b077be2 100644
--- a/chrome/common/content_settings.h
+++ b/chrome/common/content_settings.h
@@ -17,6 +17,10 @@ enum ContentSetting {
CONTENT_SETTING_NUM_SETTINGS
};
+// Range-checked conversion of an int to a ContentSetting, for use when reading
+// prefs off disk.
+ContentSetting IntToContentSetting(int content_setting);
+
// Aggregates the permissions for the different content types.
struct ContentSettings {
ContentSettings() {
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index 24f5f67c..62486e3 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -351,6 +351,13 @@ const wchar_t kEnableTranslate[] = L"translate.enabled";
const wchar_t kPinnedTabs[] = L"pinned_tabs";
+// Integer containing the default Geolocation content setting.
+const wchar_t kGeolocationDefaultContentSetting[] =
+ L"geolocation.default_content_setting";
+
+// Dictionary that maps [frame, toplevel] to their Geolocation content setting.
+const wchar_t kGeolocationContentSettings[] = L"geolocation.content_settings";
+
// *************** LOCAL STATE ***************
// These are attached to the machine/installation
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index 1e0006f..a8b2de9 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -253,6 +253,8 @@ extern const wchar_t kWebAppCreateInAppsMenu[];
extern const wchar_t kWebAppCreateInQuickLaunchBar[];
extern const wchar_t kGeolocationAccessToken[];
+extern const wchar_t kGeolocationDefaultContentSetting[];
+extern const wchar_t kGeolocationContentSettings[];
} // namespace prefs
diff --git a/chrome/test/testing_profile.h b/chrome/test/testing_profile.h
index 82535c5..08e02b7 100644
--- a/chrome/test/testing_profile.h
+++ b/chrome/test/testing_profile.h
@@ -12,6 +12,7 @@
#include "chrome/browser/browser_prefs.h"
#include "chrome/browser/browser_theme_provider.h"
#include "chrome/browser/favicon_service.h"
+#include "chrome/browser/geolocation/geolocation_content_settings_map.h"
#include "chrome/browser/host_content_settings_map.h"
#include "chrome/browser/history/history.h"
#include "chrome/browser/in_process_webkit/webkit_context.h"
@@ -190,6 +191,13 @@ class TestingProfile : public Profile {
host_content_settings_map_ = new HostContentSettingsMap(this);
return host_content_settings_map_.get();
}
+ virtual GeolocationContentSettingsMap* GetGeolocationContentSettingsMap() {
+ if (!geolocation_content_settings_map_.get()) {
+ geolocation_content_settings_map_ =
+ new GeolocationContentSettingsMap(this);
+ }
+ return geolocation_content_settings_map_.get();
+ }
virtual HostZoomMap* GetHostZoomMap() { return NULL; }
void set_session_service(SessionService* session_service);
virtual SessionService* GetSessionService() { return session_service_.get(); }
@@ -315,6 +323,8 @@ class TestingProfile : public Profile {
scoped_refptr<WebKitContext> webkit_context_;
scoped_refptr<HostContentSettingsMap> host_content_settings_map_;
+ scoped_refptr<GeolocationContentSettingsMap>
+ geolocation_content_settings_map_;
};
// A profile that derives from another profile. This does not actually