summaryrefslogtreecommitdiffstats
path: root/chrome/browser/extensions/api/preference
diff options
context:
space:
mode:
authorrobliao@chromium.org <robliao@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-07-18 09:40:47 +0000
committerrobliao@chromium.org <robliao@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-07-18 09:40:47 +0000
commit4ad4ce089223e144fb240751ba7a48f7c9064d27 (patch)
tree1c9cb30afd770376443e67c97a79a968ba7531f5 /chrome/browser/extensions/api/preference
parente631a5f7df3aceff6307e04d36073f01412fbb3c (diff)
downloadchromium_src-4ad4ce089223e144fb240751ba7a48f7c9064d27.zip
chromium_src-4ad4ce089223e144fb240751ba7a48f7c9064d27.tar.gz
chromium_src-4ad4ce089223e144fb240751ba7a48f7c9064d27.tar.bz2
Implemented types.private.ChromeDirectSetting.onChange
This delta links up the onChange event machinery to the property change notification machinery. It follows a pattern established in PreferencesAPI and the PreferenceEventRouter. * Given a list of preferences, register event listener added observers to each preference. * On the first added event listener, unregister all observers and register all property change listeners. * On property changes, forward an event to each component extension that has a property listener added. BUG=164227 Review URL: https://chromiumcodereview.appspot.com/18100007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@212307 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/extensions/api/preference')
-rw-r--r--chrome/browser/extensions/api/preference/chrome_direct_setting.cc41
-rw-r--r--chrome/browser/extensions/api/preference/chrome_direct_setting.h3
-rw-r--r--chrome/browser/extensions/api/preference/chrome_direct_setting_api.cc154
-rw-r--r--chrome/browser/extensions/api/preference/chrome_direct_setting_api.h60
4 files changed, 222 insertions, 36 deletions
diff --git a/chrome/browser/extensions/api/preference/chrome_direct_setting.cc b/chrome/browser/extensions/api/preference/chrome_direct_setting.cc
index 161ef9b..6d1bd76 100644
--- a/chrome/browser/extensions/api/preference/chrome_direct_setting.cc
+++ b/chrome/browser/extensions/api/preference/chrome_direct_setting.cc
@@ -5,39 +5,16 @@
#include "chrome/browser/extensions/api/preference/chrome_direct_setting.h"
#include "base/containers/hash_tables.h"
+#include "base/lazy_instance.h"
#include "base/prefs/pref_service.h"
#include "base/values.h"
+#include "chrome/browser/extensions/api/preference/chrome_direct_setting_api.h"
#include "chrome/browser/extensions/api/preference/preference_api_constants.h"
#include "chrome/browser/profiles/profile.h"
namespace extensions {
namespace chromedirectsetting {
-namespace {
-
-class PreferenceWhitelist {
- public:
- PreferenceWhitelist() {
- whitelist_.insert("googlegeolocationaccess.enabled");
- }
-
- ~PreferenceWhitelist() {}
-
- bool IsPreferenceOnWhitelist(const std::string& pref_key){
- return whitelist_.find(pref_key) != whitelist_.end();
- }
-
- private:
- base::hash_set<std::string> whitelist_;
-
- DISALLOW_COPY_AND_ASSIGN(PreferenceWhitelist);
-};
-
-static base::LazyInstance<PreferenceWhitelist> preference_whitelist_ =
- LAZY_INSTANCE_INITIALIZER;
-
-} // namespace
-
DirectSettingFunctionBase::DirectSettingFunctionBase() {}
DirectSettingFunctionBase::~DirectSettingFunctionBase() {}
@@ -50,11 +27,6 @@ bool DirectSettingFunctionBase::IsCalledFromComponentExtension() {
return GetExtension()->location() == Manifest::COMPONENT;
}
-bool DirectSettingFunctionBase::IsPreferenceOnWhitelist(
- const std::string& pref_key) {
- return preference_whitelist_.Get().IsPreferenceOnWhitelist(pref_key);
-}
-
GetDirectSettingFunction::GetDirectSettingFunction() {}
bool GetDirectSettingFunction::RunImpl() {
@@ -62,7 +34,8 @@ bool GetDirectSettingFunction::RunImpl() {
std::string pref_key;
EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &pref_key));
- EXTENSION_FUNCTION_VALIDATE(IsPreferenceOnWhitelist(pref_key));
+ EXTENSION_FUNCTION_VALIDATE(
+ ChromeDirectSettingAPI::Get(profile())->IsPreferenceOnWhitelist(pref_key));
const PrefService::Preference* preference =
GetPrefService()->FindPreference(pref_key.c_str());
@@ -85,7 +58,8 @@ bool SetDirectSettingFunction::RunImpl() {
std::string pref_key;
EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &pref_key));
- EXTENSION_FUNCTION_VALIDATE(IsPreferenceOnWhitelist(pref_key));
+ EXTENSION_FUNCTION_VALIDATE(
+ ChromeDirectSettingAPI::Get(profile())->IsPreferenceOnWhitelist(pref_key));
DictionaryValue* details = NULL;
EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &details));
@@ -115,7 +89,8 @@ bool ClearDirectSettingFunction::RunImpl() {
std::string pref_key;
EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &pref_key));
- EXTENSION_FUNCTION_VALIDATE(IsPreferenceOnWhitelist(pref_key));
+ EXTENSION_FUNCTION_VALIDATE(
+ ChromeDirectSettingAPI::Get(profile())->IsPreferenceOnWhitelist(pref_key));
GetPrefService()->ClearPref(pref_key.c_str());
return true;
diff --git a/chrome/browser/extensions/api/preference/chrome_direct_setting.h b/chrome/browser/extensions/api/preference/chrome_direct_setting.h
index 1a8164b..7e36344 100644
--- a/chrome/browser/extensions/api/preference/chrome_direct_setting.h
+++ b/chrome/browser/extensions/api/preference/chrome_direct_setting.h
@@ -25,9 +25,6 @@ class DirectSettingFunctionBase : public SyncExtensionFunction {
// Returns true if the caller is a component extension.
bool IsCalledFromComponentExtension();
- // Returns true if the preference is on the whitelist.
- bool IsPreferenceOnWhitelist(const std::string& pref_key);
-
private:
DISALLOW_COPY_AND_ASSIGN(DirectSettingFunctionBase);
};
diff --git a/chrome/browser/extensions/api/preference/chrome_direct_setting_api.cc b/chrome/browser/extensions/api/preference/chrome_direct_setting_api.cc
new file mode 100644
index 0000000..04b4307
--- /dev/null
+++ b/chrome/browser/extensions/api/preference/chrome_direct_setting_api.cc
@@ -0,0 +1,154 @@
+// Copyright 2013 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/extensions/api/preference/chrome_direct_setting_api.h"
+
+#include "base/bind.h"
+#include "base/containers/hash_tables.h"
+#include "base/lazy_instance.h"
+#include "base/prefs/pref_change_registrar.h"
+#include "base/prefs/pref_service.h"
+#include "base/strings/stringprintf.h"
+#include "chrome/browser/extensions/api/preference/preference_api_constants.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/profiles/profile.h"
+
+namespace extensions {
+namespace chromedirectsetting {
+
+const char kOnPrefChangeFormat[] =
+ "types.private.ChromeDirectSetting.%s.onChange";
+
+class PreferenceWhitelist {
+ public:
+ PreferenceWhitelist() {
+ whitelist_.insert("googlegeolocationaccess.enabled");
+ }
+
+ ~PreferenceWhitelist() {}
+
+ bool IsPreferenceOnWhitelist(const std::string& pref_key){
+ return whitelist_.find(pref_key) != whitelist_.end();
+ }
+
+ void RegisterEventListeners(
+ Profile* profile,
+ EventRouter::Observer* observer) {
+ for (base::hash_set<std::string>::iterator iter = whitelist_.begin();
+ iter != whitelist_.end();
+ iter++) {
+ std::string event_name = base::StringPrintf(
+ kOnPrefChangeFormat,
+ (*iter).c_str());
+ ExtensionSystem::Get(profile)->event_router()->RegisterObserver(
+ observer,
+ event_name);
+ }
+ }
+
+ void RegisterPropertyListeners(
+ Profile* profile,
+ PrefChangeRegistrar* registrar,
+ const base::Callback<void(const std::string&)>& callback) {
+ for (base::hash_set<std::string>::iterator iter = whitelist_.begin();
+ iter != whitelist_.end();
+ iter++) {
+ const char* pref_key = (*iter).c_str();
+ std::string event_name = base::StringPrintf(
+ kOnPrefChangeFormat,
+ pref_key);
+ registrar->Add(pref_key, callback);
+ }
+ }
+
+ private:
+ base::hash_set<std::string> whitelist_;
+
+ DISALLOW_COPY_AND_ASSIGN(PreferenceWhitelist);
+};
+
+base::LazyInstance<PreferenceWhitelist> preference_whitelist =
+ LAZY_INSTANCE_INITIALIZER;
+
+static base::LazyInstance<ProfileKeyedAPIFactory<ChromeDirectSettingAPI> >
+ g_factory = LAZY_INSTANCE_INITIALIZER;
+
+ChromeDirectSettingAPI::ChromeDirectSettingAPI(Profile* profile)
+ : profile_(profile) {
+ preference_whitelist.Get().RegisterEventListeners(profile, this);
+}
+
+ChromeDirectSettingAPI::~ChromeDirectSettingAPI() {}
+
+// BrowserContextKeyedService implementation.
+void ChromeDirectSettingAPI::Shutdown() {}
+
+// ProfileKeyedAPI implementation.
+ProfileKeyedAPIFactory<ChromeDirectSettingAPI>*
+ ChromeDirectSettingAPI::GetFactoryInstance() {
+ return &g_factory.Get();
+}
+
+// EventRouter::Observer implementation.
+void ChromeDirectSettingAPI::OnListenerAdded(const EventListenerInfo& details) {
+ ExtensionSystem::Get(profile_)->event_router()->UnregisterObserver(this);
+ registrar_.Init(profile_->GetPrefs());
+ preference_whitelist.Get().RegisterPropertyListeners(
+ profile_,
+ &registrar_,
+ base::Bind(&ChromeDirectSettingAPI::OnPrefChanged,
+ base::Unretained(this),
+ registrar_.prefs()));
+}
+
+bool ChromeDirectSettingAPI::IsPreferenceOnWhitelist(
+ const std::string& pref_key) {
+ return preference_whitelist.Get().IsPreferenceOnWhitelist(pref_key);
+}
+
+ChromeDirectSettingAPI* ChromeDirectSettingAPI::Get(Profile* profile) {
+ return
+ ProfileKeyedAPIFactory<ChromeDirectSettingAPI>::GetForProfile(profile);
+}
+
+// ProfileKeyedAPI implementation.
+const char* ChromeDirectSettingAPI::service_name() {
+ return "ChromeDirectSettingAPI";
+}
+
+void ChromeDirectSettingAPI::OnPrefChanged(
+ PrefService* pref_service, const std::string& pref_key) {
+ std::string event_name = base::StringPrintf(kOnPrefChangeFormat,
+ pref_key.c_str());
+ EventRouter* router = ExtensionSystem::Get(profile_)->event_router();
+ if (router && router->HasEventListener(event_name)) {
+ const PrefService::Preference* preference =
+ profile_->GetPrefs()->FindPreference(pref_key.c_str());
+ const base::Value* value = preference->GetValue();
+
+ scoped_ptr<DictionaryValue> result(new DictionaryValue);
+ result->Set(preference_api_constants::kValue, value->DeepCopy());
+ base::ListValue args;
+ args.Append(result.release());
+
+ ExtensionService* extension_service =
+ ExtensionSystem::Get(profile_)->extension_service();
+ const ExtensionSet* extensions = extension_service->extensions();
+ for (ExtensionSet::const_iterator it = extensions->begin();
+ it != extensions->end(); ++it) {
+ if ((*it)->location() == Manifest::COMPONENT) {
+ std::string extension_id = (*it)->id();
+ if (router->ExtensionHasEventListener(extension_id, event_name)) {
+ scoped_ptr<base::ListValue> args_copy(args.DeepCopy());
+ scoped_ptr<Event> event(new Event(event_name, args_copy.Pass()));
+ router->DispatchEventToExtension(extension_id, event.Pass());
+ }
+ }
+ }
+ }
+}
+
+} // namespace chromedirectsetting
+} // namespace extensions
+
diff --git a/chrome/browser/extensions/api/preference/chrome_direct_setting_api.h b/chrome/browser/extensions/api/preference/chrome_direct_setting_api.h
new file mode 100644
index 0000000..0fd6207
--- /dev/null
+++ b/chrome/browser/extensions/api/preference/chrome_direct_setting_api.h
@@ -0,0 +1,60 @@
+// Copyright 2013 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_EXTENSIONS_API_PREFERENCE_CHROME_DIRECT_SETTING_API_H__
+#define CHROME_BROWSER_EXTENSIONS_API_PREFERENCE_CHROME_DIRECT_SETTING_API_H__
+
+#include "chrome/browser/extensions/api/profile_keyed_api_factory.h"
+#include "chrome/browser/extensions/event_router.h"
+
+class PrefChangeRegistrar;
+class Profile;
+
+namespace extensions {
+namespace chromedirectsetting {
+
+class ChromeDirectSettingAPI : public ProfileKeyedAPI,
+ public EventRouter::Observer {
+ public:
+ explicit ChromeDirectSettingAPI(Profile* profile);
+
+ virtual ~ChromeDirectSettingAPI();
+
+ // BrowserContextKeyedService implementation.
+ virtual void Shutdown() OVERRIDE;
+
+ // ProfileKeyedAPI implementation.
+ static ProfileKeyedAPIFactory<ChromeDirectSettingAPI>* GetFactoryInstance();
+
+ // EventRouter::Observer implementation.
+ virtual void OnListenerAdded(const EventListenerInfo& details) OVERRIDE;
+
+ // Returns true if the preference is on the whitelist.
+ bool IsPreferenceOnWhitelist(const std::string& pref_key);
+
+ // Convenience method to get the ChromeDirectSettingAPI for a profile.
+ static ChromeDirectSettingAPI* Get(Profile* profile);
+
+ private:
+ friend class ProfileKeyedAPIFactory<ChromeDirectSettingAPI>;
+
+ // ProfileKeyedAPI implementation.
+ static const char* service_name();
+
+ void OnPrefChanged(PrefService* pref_service, const std::string& pref_key);
+
+ static const bool kServiceIsNULLWhileTesting = true;
+ static const bool kServiceRedirectedInIncognito = false;
+
+ PrefChangeRegistrar registrar_;
+ Profile* profile_;
+
+ DISALLOW_COPY_AND_ASSIGN(ChromeDirectSettingAPI);
+};
+
+} // namespace chromedirectsetting
+} // namespace extensions
+
+#endif // CHROME_BROWSER_EXTENSIONS_API_PREFERENCE_CHROME_DIRECT_SETTING_API_H__
+