summaryrefslogtreecommitdiffstats
path: root/chrome/browser/geolocation
diff options
context:
space:
mode:
authormarkusheintz@chromium.org <markusheintz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-12-20 14:30:40 +0000
committermarkusheintz@chromium.org <markusheintz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-12-20 14:30:40 +0000
commit026d4fdde11afb8107b6a092cc2d6dbae6f230c5 (patch)
treea62cab017ae6fade2159586b3bfb5699af7df33e /chrome/browser/geolocation
parentcca1200a6e6ddae53a089bdac7bed22bbda4ca94 (diff)
downloadchromium_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')
-rw-r--r--chrome/browser/geolocation/geolocation_content_settings_map.cc70
-rw-r--r--chrome/browser/geolocation/geolocation_content_settings_map.h26
-rw-r--r--chrome/browser/geolocation/geolocation_content_settings_map_unittest.cc66
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