| Index: chrome/browser/sync/glue/chrome_sync_notification_bridge.cc
|
| diff --git a/chrome/browser/sync/glue/chrome_sync_notification_bridge.cc b/chrome/browser/sync/glue/chrome_sync_notification_bridge.cc
|
| index 9936fa08f020e93b0eff6fe86a1dcbecc3f81db8..78212d21b3f69bce073b10f088aaf66194effaaa 100644
|
| --- a/chrome/browser/sync/glue/chrome_sync_notification_bridge.cc
|
| +++ b/chrome/browser/sync/glue/chrome_sync_notification_bridge.cc
|
| @@ -4,6 +4,9 @@
|
|
|
| #include "chrome/browser/sync/glue/chrome_sync_notification_bridge.h"
|
|
|
| +#include "base/bind.h"
|
| +#include "base/location.h"
|
| +#include "base/observer_list.h"
|
| #include "chrome/common/chrome_notification_types.h"
|
| #include "content/public/browser/browser_thread.h"
|
| #include "content/public/browser/notification_service.h"
|
| @@ -13,10 +16,73 @@ using content::BrowserThread;
|
|
|
| namespace browser_sync {
|
|
|
| +class ChromeSyncNotificationBridge::Core
|
| + : public base::RefCountedThreadSafe<Core> {
|
| + public:
|
| + // Created on UI thread.
|
| + explicit Core(
|
| + const scoped_refptr<base::SequencedTaskRunner>& sync_task_runner);
|
| +
|
| + // All member functions below must be called on the sync task runner.
|
| +
|
| + void AddObserver(syncer::SyncNotifierObserver* observer);
|
| + void RemoveObserver(syncer::SyncNotifierObserver* observer);
|
| +
|
| + void EmitNotification(
|
| + syncer::ModelTypePayloadMap payload_map,
|
| + syncer::IncomingNotificationSource notification_source);
|
| +
|
| + private:
|
| + friend class base::RefCountedThreadSafe<Core>;
|
| +
|
| + // Destroyed on the UI thread or on |sync_task_runner_|.
|
| + ~Core();
|
| +
|
| + const scoped_refptr<base::SequencedTaskRunner> sync_task_runner_;
|
| +
|
| + // Used only on |sync_task_runner_|.
|
| + syncer::ModelTypeSet enabled_types_;
|
| + ObserverList<syncer::SyncNotifierObserver> observers_;
|
| +};
|
| +
|
| +ChromeSyncNotificationBridge::Core::Core(
|
| + const scoped_refptr<base::SequencedTaskRunner>& sync_task_runner)
|
| + : sync_task_runner_(sync_task_runner) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + DCHECK(sync_task_runner_.get());
|
| +}
|
| +
|
| +ChromeSyncNotificationBridge::Core::~Core() {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) ||
|
| + sync_task_runner_->RunsTasksOnCurrentThread());
|
| +}
|
| +
|
| +void ChromeSyncNotificationBridge::Core::AddObserver(
|
| + syncer::SyncNotifierObserver* observer) {
|
| + DCHECK(sync_task_runner_->RunsTasksOnCurrentThread());
|
| + observers_.AddObserver(observer);
|
| +}
|
| +
|
| +void ChromeSyncNotificationBridge::Core::RemoveObserver(
|
| + syncer::SyncNotifierObserver* observer) {
|
| + DCHECK(sync_task_runner_->RunsTasksOnCurrentThread());
|
| + observers_.RemoveObserver(observer);
|
| +}
|
| +
|
| +void ChromeSyncNotificationBridge::Core::EmitNotification(
|
| + syncer::ModelTypePayloadMap payload_map,
|
| + syncer::IncomingNotificationSource notification_source) {
|
| + DCHECK(sync_task_runner_->RunsTasksOnCurrentThread());
|
| + FOR_EACH_OBSERVER(
|
| + syncer::SyncNotifierObserver, observers_,
|
| + OnIncomingNotification(payload_map, notification_source));
|
| +}
|
| +
|
| ChromeSyncNotificationBridge::ChromeSyncNotificationBridge(
|
| - const Profile* profile)
|
| - : observers_(
|
| - new ObserverListThreadSafe<syncer::SyncNotifierObserver>()) {
|
| + const Profile* profile,
|
| + const scoped_refptr<base::SequencedTaskRunner>& sync_task_runner)
|
| + : sync_task_runner_(sync_task_runner),
|
| + core_(new Core(sync_task_runner_)) {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| DCHECK(profile);
|
| registrar_.Add(this, chrome::NOTIFICATION_SYNC_REFRESH_LOCAL,
|
| @@ -35,12 +101,14 @@ void ChromeSyncNotificationBridge::UpdateEnabledTypes(
|
|
|
| void ChromeSyncNotificationBridge::AddObserver(
|
| syncer::SyncNotifierObserver* observer) {
|
| - observers_->AddObserver(observer);
|
| + DCHECK(sync_task_runner_->RunsTasksOnCurrentThread());
|
| + core_->AddObserver(observer);
|
| }
|
|
|
| void ChromeSyncNotificationBridge::RemoveObserver(
|
| syncer::SyncNotifierObserver* observer) {
|
| - observers_->RemoveObserver(observer);
|
| + DCHECK(sync_task_runner_->RunsTasksOnCurrentThread());
|
| + core_->RemoveObserver(observer);
|
| }
|
|
|
| void ChromeSyncNotificationBridge::Observe(
|
| @@ -55,7 +123,7 @@ void ChromeSyncNotificationBridge::Observe(
|
| } else if (type == chrome::NOTIFICATION_SYNC_REFRESH_REMOTE) {
|
| notification_source = syncer::REMOTE_NOTIFICATION;
|
| } else {
|
| - NOTREACHED() << "Unexpected notification type:" << type;
|
| + NOTREACHED() << "Unexpected notification type: " << type;
|
| return;
|
| }
|
|
|
| @@ -69,9 +137,10 @@ void ChromeSyncNotificationBridge::Observe(
|
| syncer::ModelTypePayloadMapFromEnumSet(enabled_types_, std::string());
|
| }
|
|
|
| - observers_->Notify(
|
| - &syncer::SyncNotifierObserver::OnIncomingNotification,
|
| - payload_map, notification_source);
|
| + sync_task_runner_->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&Core::EmitNotification,
|
| + core_, payload_map, notification_source));
|
| }
|
|
|
| } // namespace browser_sync
|
|
|