Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(154)

Unified Diff: chrome/browser/extensions/extension_settings_frontend.cc

Issue 8177022: Add onChanged events to the extension settings API, both from sync and between (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: comments Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/extensions/extension_settings_frontend.cc
diff --git a/chrome/browser/extensions/extension_settings_frontend.cc b/chrome/browser/extensions/extension_settings_frontend.cc
index 4963e927ae92c67c77fb084f76387cce05297626..eca0f967803f42aec6de0c5e6c73fa9936f1dc0a 100644
--- a/chrome/browser/extensions/extension_settings_frontend.cc
+++ b/chrome/browser/extensions/extension_settings_frontend.cc
@@ -6,20 +6,114 @@
#include "base/bind.h"
#include "base/file_path.h"
+#include "chrome/browser/extensions/extension_event_names.h"
+#include "chrome/browser/extensions/extension_event_router.h"
+#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_settings_backend.h"
+#include "chrome/browser/profiles/profile.h"
#include "content/browser/browser_thread.h"
-ExtensionSettingsFrontend::ExtensionSettingsFrontend(
- const FilePath& base_path)
- : core_(new ExtensionSettingsFrontend::Core()) {
+// Observer which sends events to a target profile iff the profile isn't the
+// originating profile for the event.
+class ExtensionSettingsFrontend::DefaultObserver
+ : public ExtensionSettingsObserver {
+ public:
+ explicit DefaultObserver(Profile* profile) : target_profile_(profile) {}
+ virtual ~DefaultObserver() {}
+
+ virtual void OnSettingsChanged(
+ const Profile* origin_profile,
+ const std::string& extension_id,
+ const ExtensionSettingChanges& changes) OVERRIDE {
+ if (origin_profile != target_profile_) {
+ target_profile_->GetExtensionEventRouter()->DispatchEventToExtension(
+ extension_id,
+ extension_event_names::kOnSettingsChanged,
+ // This is the list of function arguments to pass to the onChanged
+ // handler of extensions, a single argument with the list of changes.
+ std::string("[") + changes.ToJson() + "]",
+ target_profile_,
+ GURL());
+ }
+ }
+
+ private:
+ Profile* target_profile_;
+};
+
+// Ref-counted container for the ExtensionSettingsBackend object.
+class ExtensionSettingsFrontend::Core
+ : public base::RefCountedThreadSafe<Core> {
+ public:
+ explicit Core(
+ const scoped_refptr<ObserverListThreadSafe<ExtensionSettingsObserver> >&
+ observers)
+ : observers_(observers), backend_(NULL) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ }
+
+ // Does any FILE thread specific initialization, such as construction of
+ // |backend_|. Must be called before any call to
+ // RunWithBackendOnFileThread().
+ void InitOnFileThread(const FilePath& base_path) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ DCHECK(!backend_);
+ backend_ = new ExtensionSettingsBackend(base_path, observers_);
+ }
+
+ // Runs |callback| with the extension backend.
+ void RunWithBackendOnFileThread(const BackendCallback& callback) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ DCHECK(backend_);
+ callback.Run(backend_);
+ }
+
+ private:
+ virtual ~Core() {
+ if (BrowserThread::CurrentlyOn(BrowserThread::FILE)) {
+ delete backend_;
+ } else if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
+ BrowserThread::DeleteSoon(BrowserThread::FILE, FROM_HERE, backend_);
+ } else {
+ NOTREACHED();
+ }
+ }
+
+ friend class base::RefCountedThreadSafe<Core>;
+
+ // Observers to settings changes (thread safe).
+ scoped_refptr<ObserverListThreadSafe<ExtensionSettingsObserver> >
+ observers_;
+
+ // Lives on the FILE thread.
+ ExtensionSettingsBackend* backend_;
+
+ DISALLOW_COPY_AND_ASSIGN(Core);
+};
+
+ExtensionSettingsFrontend::ExtensionSettingsFrontend(Profile* profile)
+ : observers_(new ObserverListThreadSafe<ExtensionSettingsObserver>()),
+ core_(new ExtensionSettingsFrontend::Core(observers_.get())) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ registrar_.Add(this, chrome::NOTIFICATION_PROFILE_CREATED,
akalin 2011/10/18 19:00:04 Wait, you're listening to creation of *any* profil
not at google - send to devlin 2011/10/19 03:14:32 Thanks, fixed.
+ NotificationService::AllBrowserContextsAndSources());
+ registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED,
+ NotificationService::AllBrowserContextsAndSources());
+ OnProfileCreated(profile);
+
BrowserThread::PostTask(
BrowserThread::FILE,
FROM_HERE,
base::Bind(
&ExtensionSettingsFrontend::Core::InitOnFileThread,
core_.get(),
- base_path));
+ profile->GetPath().AppendASCII(
+ ExtensionService::kSettingsDirectoryName)));
+}
+
+ExtensionSettingsFrontend::~ExtensionSettingsFrontend() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
}
void ExtensionSettingsFrontend::RunWithBackend(
@@ -34,34 +128,45 @@ void ExtensionSettingsFrontend::RunWithBackend(
callback));
}
-ExtensionSettingsFrontend::~ExtensionSettingsFrontend() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+void ExtensionSettingsFrontend::AddObserver(
+ ExtensionSettingsObserver* observer) {
+ observers_->AddObserver(observer);
}
-ExtensionSettingsFrontend::Core::Core() : backend_(NULL) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+void ExtensionSettingsFrontend::RemoveObserver(
+ ExtensionSettingsObserver* observer) {
+ observers_->RemoveObserver(observer);
}
-void ExtensionSettingsFrontend::Core::InitOnFileThread(
- const FilePath& base_path) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
- DCHECK(!backend_);
- backend_ = new ExtensionSettingsBackend(base_path);
+void ExtensionSettingsFrontend::Observe(
+ int type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ switch (type) {
+ case chrome::NOTIFICATION_PROFILE_CREATED:
+ OnProfileCreated(Source<Profile>(source).ptr());
+ break;
+ case chrome::NOTIFICATION_PROFILE_DESTROYED:
+ OnProfileDestroyed(Source<Profile>(source).ptr());
+ break;
+ default:
+ NOTREACHED();
+ }
}
-void ExtensionSettingsFrontend::Core::RunWithBackendOnFileThread(
- const BackendCallback& callback) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
- DCHECK(backend_);
- callback.Run(backend_);
+void ExtensionSettingsFrontend::OnProfileCreated(Profile* new_profile) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK(profile_observers_.find(new_profile) == profile_observers_.end());
+ linked_ptr<DefaultObserver> new_observer(new DefaultObserver(new_profile));
+ profile_observers_[new_profile] = new_observer;
+ AddObserver(new_observer.get());
}
-ExtensionSettingsFrontend::Core::~Core() {
- if (BrowserThread::CurrentlyOn(BrowserThread::FILE)) {
- delete backend_;
- } else if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- BrowserThread::DeleteSoon(BrowserThread::FILE, FROM_HERE, backend_);
- } else {
- NOTREACHED();
- }
+void ExtensionSettingsFrontend::OnProfileDestroyed(Profile* old_profile) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ linked_ptr<DefaultObserver> old_observer = profile_observers_[old_profile];
+ DCHECK(old_observer.get());
+ profile_observers_.erase(old_profile);
+ RemoveObserver(old_observer.get());
}

Powered by Google App Engine
This is Rietveld 408576698