diff options
author | pkasting@chromium.org <pkasting@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-19 01:52:45 +0000 |
---|---|---|
committer | pkasting@chromium.org <pkasting@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-19 01:52:45 +0000 |
commit | aee541ebc97e1ff2c8bb43e4375913f582931d40 (patch) | |
tree | 49e6735353739bef26d1e960738470247ffa0dc8 /chrome/browser/geolocation | |
parent | 470ad82d83b7773ed5c791a1f3b612087b980eee (diff) | |
download | chromium_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
Diffstat (limited to 'chrome/browser/geolocation')
3 files changed, 555 insertions, 0 deletions
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 |