diff options
author | markusheintz@chromium.org <markusheintz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-12-20 14:30:40 +0000 |
---|---|---|
committer | markusheintz@chromium.org <markusheintz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-12-20 14:30:40 +0000 |
commit | 026d4fdde11afb8107b6a092cc2d6dbae6f230c5 (patch) | |
tree | a62cab017ae6fade2159586b3bfb5699af7df33e /chrome/browser/geolocation | |
parent | cca1200a6e6ddae53a089bdac7bed22bbda4ca94 (diff) | |
download | chromium_src-026d4fdde11afb8107b6a092cc2d6dbae6f230c5.zip chromium_src-026d4fdde11afb8107b6a092cc2d6dbae6f230c5.tar.gz chromium_src-026d4fdde11afb8107b6a092cc2d6dbae6f230c5.tar.bz2 |
Allow default desktop content settings and default geolocation settings to be managed via policy. (Support for the Cocoa UI will be added via a separate CL)
BUG=63190,63187, 63180
TEST=none
Review URL: http://codereview.chromium.org/5398001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@69707 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/geolocation')
3 files changed, 158 insertions, 4 deletions
diff --git a/chrome/browser/geolocation/geolocation_content_settings_map.cc b/chrome/browser/geolocation/geolocation_content_settings_map.cc index 40b1462..5c67523 100644 --- a/chrome/browser/geolocation/geolocation_content_settings_map.cc +++ b/chrome/browser/geolocation/geolocation_content_settings_map.cc @@ -20,9 +20,13 @@ #include "base/string_piece.h" #include "base/utf_string_conversions.h" #include "chrome/browser/browser_thread.h" +#include "chrome/browser/content_settings/content_settings_details.h" +#include "chrome/browser/content_settings/content_settings_pattern.h" #include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/prefs/scoped_pref_update.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/common/notification_service.h" +#include "chrome/common/notification_source.h" #include "chrome/common/notification_type.h" #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" @@ -36,6 +40,11 @@ const ContentSetting GeolocationContentSettingsMap::GeolocationContentSettingsMap(Profile* profile) : profile_(profile) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + prefs_registrar_.Init(profile_->GetPrefs()); + prefs_registrar_.Add(prefs::kGeolocationDefaultContentSetting, this); + prefs_registrar_.Add(prefs::kGeolocationContentSettings, this); + notification_registrar_.Add(this, NotificationType::PROFILE_DESTROYED, + Source<Profile>(profile_)); } // static @@ -47,6 +56,9 @@ void GeolocationContentSettingsMap::RegisterUserPrefs(PrefService* prefs) { ContentSetting GeolocationContentSettingsMap::GetDefaultContentSetting() const { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + // If the profile is destroyed (and set to NULL) return CONTENT_SETTING_BLOCK. + if (!profile_) + return CONTENT_SETTING_BLOCK; const PrefService* prefs = profile_->GetPrefs(); const ContentSetting default_content_setting = IntToContentSetting( prefs->GetInteger(prefs::kGeolocationDefaultContentSetting)); @@ -54,6 +66,15 @@ ContentSetting GeolocationContentSettingsMap::GetDefaultContentSetting() const { kDefaultSetting : default_content_setting; } +bool GeolocationContentSettingsMap::IsDefaultContentSettingManaged() const { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + // If the profile is destroyed (and set to NULL) return true. + if (!profile_) + return true; + return profile_->GetPrefs()->IsManagedPreference( + prefs::kGeolocationDefaultContentSetting); +} + ContentSetting GeolocationContentSettingsMap::GetContentSetting( const GURL& requesting_url, const GURL& embedding_url) const { @@ -62,7 +83,9 @@ ContentSetting GeolocationContentSettingsMap::GetContentSetting( GURL requesting_origin(requesting_url.GetOrigin()); GURL embedding_origin(embedding_url.GetOrigin()); DCHECK(requesting_origin.is_valid() && embedding_origin.is_valid()); - + // If the profile is destroyed (and set to NULL) return CONTENT_SETTING_BLOCK. + if (!profile_) + return CONTENT_SETTING_BLOCK; const DictionaryValue* all_settings_dictionary = profile_->GetPrefs()->GetDictionary(prefs::kGeolocationContentSettings); // Careful: The returned value could be NULL if the pref has never been set. @@ -115,6 +138,8 @@ GeolocationContentSettingsMap::AllOriginsSettings void GeolocationContentSettingsMap::SetDefaultContentSetting( ContentSetting setting) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + if (!profile_) + return; profile_->GetPrefs()->SetInteger(prefs::kGeolocationDefaultContentSetting, setting == CONTENT_SETTING_DEFAULT ? kDefaultSetting : setting); @@ -131,6 +156,8 @@ void GeolocationContentSettingsMap::SetContentSetting( GURL embedding_origin(embedding_url.GetOrigin()); DCHECK(requesting_origin.is_valid()); DCHECK(embedding_origin.is_valid() || embedding_url.is_empty()); + if (!profile_) + return; PrefService* prefs = profile_->GetPrefs(); DictionaryValue* all_settings_dictionary = prefs->GetMutableDictionary( prefs::kGeolocationContentSettings); @@ -162,13 +189,52 @@ void GeolocationContentSettingsMap::SetContentSetting( void GeolocationContentSettingsMap::ResetToDefault() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - + if (!profile_) + return; PrefService* prefs = profile_->GetPrefs(); prefs->ClearPref(prefs::kGeolocationDefaultContentSetting); prefs->ClearPref(prefs::kGeolocationContentSettings); } +void GeolocationContentSettingsMap::NotifyObservers( + const ContentSettingsDetails& details) { + NotificationService::current()->Notify( + NotificationType::GEOLOCATION_SETTINGS_CHANGED, + Source<GeolocationContentSettingsMap>(this), + Details<const ContentSettingsDetails>(&details)); +} + +void GeolocationContentSettingsMap::Observe( + NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + if (type == NotificationType::PREF_CHANGED) { + const std::string& name = *Details<std::string>(details).ptr(); + if (name == prefs::kGeolocationDefaultContentSetting) { + NotifyObservers(ContentSettingsDetails( + ContentSettingsPattern(), + CONTENT_SETTINGS_TYPE_DEFAULT, + "")); + } + } else if (NotificationType::PROFILE_DESTROYED == type) { + UnregisterObservers(); + } else { + NOTREACHED(); + } +} + +void GeolocationContentSettingsMap::UnregisterObservers() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + if (!profile_) + return; + prefs_registrar_.RemoveAll(); + notification_registrar_.Remove(this, NotificationType::PROFILE_DESTROYED, + Source<Profile>(profile_)); + profile_ = NULL; +} + GeolocationContentSettingsMap::~GeolocationContentSettingsMap() { + UnregisterObservers(); } // static diff --git a/chrome/browser/geolocation/geolocation_content_settings_map.h b/chrome/browser/geolocation/geolocation_content_settings_map.h index ae56044..74a74fa 100644 --- a/chrome/browser/geolocation/geolocation_content_settings_map.h +++ b/chrome/browser/geolocation/geolocation_content_settings_map.h @@ -17,21 +17,28 @@ #include "base/basictypes.h" #include "base/ref_counted.h" +#include "chrome/browser/prefs/pref_change_registrar.h" #include "chrome/common/content_settings.h" +#include "chrome/common/notification_observer.h" +#include "chrome/common/notification_registrar.h" #include "googleurl/src/gurl.h" +class ContentSettingsDetails; class DictionaryValue; class PrefService; class Profile; class GeolocationContentSettingsMap - : public base::RefCountedThreadSafe<GeolocationContentSettingsMap> { + : public base::RefCountedThreadSafe<GeolocationContentSettingsMap>, + public NotificationObserver { public: typedef std::map<GURL, ContentSetting> OneOriginSettings; typedef std::map<GURL, OneOriginSettings> AllOriginsSettings; explicit GeolocationContentSettingsMap(Profile* profile); + virtual ~GeolocationContentSettingsMap(); + static void RegisterUserPrefs(PrefService* prefs); // Returns the default setting. @@ -39,6 +46,9 @@ class GeolocationContentSettingsMap // This should only be called on the UI thread. ContentSetting GetDefaultContentSetting() const; + // Returns true if the content setting is managed (set by a policy). + bool IsDefaultContentSettingManaged() 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, @@ -80,13 +90,21 @@ class GeolocationContentSettingsMap // This should only be called on the UI thread. void ResetToDefault(); + // NotificationObserver implementation. + virtual void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details); + private: friend class base::RefCountedThreadSafe<GeolocationContentSettingsMap>; // The default setting. static const ContentSetting kDefaultSetting; - ~GeolocationContentSettingsMap(); + // Sends a CONTENT_SETTINGS_CHANGED notification. + void NotifyObservers(const ContentSettingsDetails& details); + + void UnregisterObservers(); // Sets the fields of |one_origin_settings| based on the values in // |dictionary|. @@ -97,6 +115,10 @@ class GeolocationContentSettingsMap // The profile we're associated with. Profile* profile_; + // Registrar to register for PREF_CHANGED notifications. + PrefChangeRegistrar prefs_registrar_; + NotificationRegistrar notification_registrar_; + DISALLOW_COPY_AND_ASSIGN(GeolocationContentSettingsMap); }; diff --git a/chrome/browser/geolocation/geolocation_content_settings_map_unittest.cc b/chrome/browser/geolocation/geolocation_content_settings_map_unittest.cc index 2ed941d..0177f0f 100644 --- a/chrome/browser/geolocation/geolocation_content_settings_map_unittest.cc +++ b/chrome/browser/geolocation/geolocation_content_settings_map_unittest.cc @@ -6,7 +6,10 @@ #include "base/message_loop.h" #include "chrome/browser/browser_thread.h" +#include "chrome/browser/content_settings/content_settings_details.h" #include "chrome/browser/prefs/pref_service.h" +#include "chrome/common/notification_registrar.h" +#include "chrome/common/notification_service.h" #include "chrome/common/pref_names.h" #include "chrome/test/testing_profile.h" #include "testing/gtest/include/gtest/gtest.h" @@ -14,6 +17,41 @@ namespace { +class StubSettingsObserver : public NotificationObserver { + public: + StubSettingsObserver() : last_notifier(NULL), counter(0) { + registrar_.Add(this, NotificationType::GEOLOCATION_SETTINGS_CHANGED, + NotificationService::AllSources()); + } + + virtual void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + ++counter; + Source<GeolocationContentSettingsMap> content_settings(source); + Details<ContentSettingsDetails> settings_details(details); + last_notifier = content_settings.ptr(); + last_pattern = settings_details.ptr()->pattern(); + last_update_all = settings_details.ptr()->update_all(); + last_update_all_types = settings_details.ptr()->update_all_types(); + last_type = settings_details.ptr()->type(); + // This checks that calling a Get function from an observer doesn't + // deadlock. + last_notifier->GetContentSetting(GURL("http://random-hostname.com/"), + GURL("http://foo.random-hostname.com/")); + } + + GeolocationContentSettingsMap* last_notifier; + ContentSettingsPattern last_pattern; + bool last_update_all; + bool last_update_all_types; + int counter; + ContentSettingsType last_type; + + private: + NotificationRegistrar registrar_; +}; + class GeolocationContentSettingsMapTests : public testing::Test { public: GeolocationContentSettingsMapTests() @@ -241,4 +279,32 @@ TEST_F(GeolocationContentSettingsMapTests, IgnoreInvalidURLsInPrefs) { GURL("http://b/"))); } +TEST_F(GeolocationContentSettingsMapTests, Observe) { + TestingProfile profile; + GeolocationContentSettingsMap* map = + profile.GetGeolocationContentSettingsMap(); + StubSettingsObserver observer; + + EXPECT_EQ(CONTENT_SETTING_ASK, map->GetDefaultContentSetting()); + + // Test if a CONTENT_SETTING_CHANGE notification is sent after the geolocation + // default content setting was changed through calling the + // SetDefaultContentSetting method. + map->SetDefaultContentSetting(CONTENT_SETTING_BLOCK); + EXPECT_EQ(map, observer.last_notifier); + EXPECT_EQ(CONTENT_SETTINGS_TYPE_DEFAULT, observer.last_type); + EXPECT_EQ(1, observer.counter); + + + // Test if a CONTENT_SETTING_CHANGE notification is sent after the preference + // GeolocationDefaultContentSetting was changed. + PrefService* prefs = profile.GetPrefs(); + prefs->SetInteger(prefs::kGeolocationDefaultContentSetting, + CONTENT_SETTING_ALLOW); + EXPECT_EQ(2, observer.counter); + EXPECT_EQ(map, observer.last_notifier); + EXPECT_EQ(CONTENT_SETTINGS_TYPE_DEFAULT, observer.last_type); + EXPECT_EQ(CONTENT_SETTING_ALLOW, map->GetDefaultContentSetting()); +} + } // namespace |