Index: chrome/browser/extensions/api/preference/chrome_direct_setting_api.cc |
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 0000000000000000000000000000000000000000..9584ff6bd08ffb40e4c54c976b3cb0ecab959e30 |
--- /dev/null |
+++ b/chrome/browser/extensions/api/preference/chrome_direct_setting_api.cc |
@@ -0,0 +1,154 @@ |
+// Copyright (c) 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_, |
+ ®istrar_, |
+ 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 |
+ |