diff options
author | maruel@chromium.org <maruel@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-07-26 12:34:36 +0000 |
---|---|---|
committer | maruel@chromium.org <maruel@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-07-26 12:34:36 +0000 |
commit | 4b773fc537e937aab56bc8754a77dc650684bfa7 (patch) | |
tree | 6773dc320bfd451c0b6ccecb0054746fa46743ab | |
parent | 7d623f0026af4962e279969e7df5080de74e7e34 (diff) | |
download | chromium_src-4b773fc537e937aab56bc8754a77dc650684bfa7.zip chromium_src-4b773fc537e937aab56bc8754a77dc650684bfa7.tar.gz chromium_src-4b773fc537e937aab56bc8754a77dc650684bfa7.tar.bz2 |
Revert r148496 "Refactor sync-specific parts out of SyncNotifier/SyncNotifierObserver"
It broke sync_integration_tests:
TwoClientExtensionSettingsAndAppSettingsSyncTest.AppsStartWithSameSettings
TwoClientExtensionSettingsAndAppSettingsSyncTest.AppsStartWithDifferentSettings
TBR=dcheng@chromium.org
BUG=
TEST=
Review URL: https://chromiumcodereview.appspot.com/10823037
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@148536 0039d316-1c4b-4281-b951-d872f2087c98
33 files changed, 343 insertions, 632 deletions
diff --git a/chrome/browser/sync/glue/DEPS b/chrome/browser/sync/glue/DEPS index e61591f..71e2b90 100644 --- a/chrome/browser/sync/glue/DEPS +++ b/chrome/browser/sync/glue/DEPS @@ -10,10 +10,8 @@ include_rules = [ # Should these live in their own "includes" (e.g) directory(ies)? # Bug 19878. - "+sync/notifier/invalidation_util.h", "+sync/notifier/mock_sync_notifier_observer.h", "+sync/notifier/sync_notifier.h", - "+sync/notifier/sync_notifier_helper.h", "+sync/notifier/sync_notifier_factory.h", "+sync/notifier/sync_notifier_observer.h", diff --git a/chrome/browser/sync/glue/bridged_sync_notifier.cc b/chrome/browser/sync/glue/bridged_sync_notifier.cc index 5e3f669..a9de057 100644 --- a/chrome/browser/sync/glue/bridged_sync_notifier.cc +++ b/chrome/browser/sync/glue/bridged_sync_notifier.cc @@ -18,12 +18,18 @@ BridgedSyncNotifier::BridgedSyncNotifier( BridgedSyncNotifier::~BridgedSyncNotifier() { } -void BridgedSyncNotifier::UpdateRegisteredIds( - syncer::SyncNotifierObserver* handler, - const syncer::ObjectIdSet& ids) { +void BridgedSyncNotifier::AddObserver( + syncer::SyncNotifierObserver* observer) { if (delegate_.get()) - delegate_->UpdateRegisteredIds(handler, ids); - bridge_->UpdateRegisteredIds(handler, ids); + delegate_->AddObserver(observer); + bridge_->AddObserver(observer); +} + +void BridgedSyncNotifier::RemoveObserver( + syncer::SyncNotifierObserver* observer) { + bridge_->RemoveObserver(observer); + if (delegate_.get()) + delegate_->RemoveObserver(observer); } void BridgedSyncNotifier::SetUniqueId(const std::string& unique_id) { @@ -42,6 +48,12 @@ void BridgedSyncNotifier::UpdateCredentials( delegate_->UpdateCredentials(email, token); } +void BridgedSyncNotifier::UpdateEnabledTypes( + syncer::ModelTypeSet enabled_types) { + if (delegate_.get()) + delegate_->UpdateEnabledTypes(enabled_types); +} + void BridgedSyncNotifier::SendNotification( syncer::ModelTypeSet changed_types) { if (delegate_.get()) diff --git a/chrome/browser/sync/glue/bridged_sync_notifier.h b/chrome/browser/sync/glue/bridged_sync_notifier.h index f48d0f9..b856080ae 100644 --- a/chrome/browser/sync/glue/bridged_sync_notifier.h +++ b/chrome/browser/sync/glue/bridged_sync_notifier.h @@ -28,13 +28,18 @@ class BridgedSyncNotifier : public syncer::SyncNotifier { virtual ~BridgedSyncNotifier(); // SyncNotifier implementation. Passes through all calls to the delegate. - // UpdateRegisteredIds calls will also be forwarded to the bridge. - virtual void UpdateRegisteredIds(syncer::SyncNotifierObserver* handler, - const syncer::ObjectIdSet& ids) OVERRIDE; + // AddObserver/RemoveObserver will also register/deregister |observer| with + // the bridge. + virtual void AddObserver( + syncer::SyncNotifierObserver* observer) OVERRIDE; + virtual void RemoveObserver( + syncer::SyncNotifierObserver* observer) OVERRIDE; virtual void SetUniqueId(const std::string& unique_id) OVERRIDE; virtual void SetStateDeprecated(const std::string& state) OVERRIDE; virtual void UpdateCredentials( const std::string& email, const std::string& token) OVERRIDE; + virtual void UpdateEnabledTypes( + syncer::ModelTypeSet enabled_types) OVERRIDE; virtual void SendNotification( syncer::ModelTypeSet changed_types) OVERRIDE; diff --git a/chrome/browser/sync/glue/bridged_sync_notifier_unittest.cc b/chrome/browser/sync/glue/bridged_sync_notifier_unittest.cc index 7347eac..e12de05 100644 --- a/chrome/browser/sync/glue/bridged_sync_notifier_unittest.cc +++ b/chrome/browser/sync/glue/bridged_sync_notifier_unittest.cc @@ -35,8 +35,8 @@ class MockChromeSyncNotificationBridge : public ChromeSyncNotificationBridge { : ChromeSyncNotificationBridge(profile, sync_task_runner) {} virtual ~MockChromeSyncNotificationBridge() {} - MOCK_METHOD2(UpdateRegisteredIds, void(syncer::SyncNotifierObserver*, - const syncer::ObjectIdSet&)); + MOCK_METHOD1(AddObserver, void(syncer::SyncNotifierObserver*)); + MOCK_METHOD1(RemoveObserver, void(syncer::SyncNotifierObserver*)); }; class MockSyncNotifier : public syncer::SyncNotifier { @@ -44,17 +44,18 @@ class MockSyncNotifier : public syncer::SyncNotifier { MockSyncNotifier() {} virtual ~MockSyncNotifier() {} - MOCK_METHOD2(UpdateRegisteredIds, - void(syncer::SyncNotifierObserver*, const syncer::ObjectIdSet&)); + MOCK_METHOD1(AddObserver, void(syncer::SyncNotifierObserver*)); + MOCK_METHOD1(RemoveObserver, void(syncer::SyncNotifierObserver*)); MOCK_METHOD1(SetUniqueId, void(const std::string&)); MOCK_METHOD1(SetStateDeprecated, void(const std::string&)); MOCK_METHOD2(UpdateCredentials, void(const std::string&, const std::string&)); + MOCK_METHOD1(UpdateEnabledTypes, void(syncer::ModelTypeSet)); MOCK_METHOD1(SendNotification, void(syncer::ModelTypeSet)); }; // All tests just verify that each call is passed through to the delegate, with -// the exception of UpdateRegisteredIds, which also verifies the call is -// forwarded to the bridge. +// the exception of AddObserver/RemoveObserver, which also verify the observer +// is registered with the bridge. class BridgedSyncNotifierTest : public testing::Test { public: BridgedSyncNotifierTest() @@ -73,13 +74,18 @@ class BridgedSyncNotifierTest : public testing::Test { BridgedSyncNotifier bridged_notifier_; }; -TEST_F(BridgedSyncNotifierTest, UpdateRegisteredIds) { +TEST_F(BridgedSyncNotifierTest, AddObserver) { syncer::MockSyncNotifierObserver observer; - EXPECT_CALL(mock_bridge_, UpdateRegisteredIds( - &observer, syncer::ObjectIdSet())); - EXPECT_CALL(*mock_delegate_, UpdateRegisteredIds( - &observer, syncer::ObjectIdSet())); - bridged_notifier_.UpdateRegisteredIds(&observer, syncer::ObjectIdSet()); + EXPECT_CALL(mock_bridge_, AddObserver(&observer)); + EXPECT_CALL(*mock_delegate_, AddObserver(&observer)); + bridged_notifier_.AddObserver(&observer); +} + +TEST_F(BridgedSyncNotifierTest, RemoveObserver) { + syncer::MockSyncNotifierObserver observer; + EXPECT_CALL(mock_bridge_, RemoveObserver(&observer)); + EXPECT_CALL(*mock_delegate_, RemoveObserver(&observer)); + bridged_notifier_.RemoveObserver(&observer); } TEST_F(BridgedSyncNotifierTest, SetUniqueId) { @@ -101,6 +107,13 @@ TEST_F(BridgedSyncNotifierTest, UpdateCredentials) { bridged_notifier_.UpdateCredentials(email, token); } +TEST_F(BridgedSyncNotifierTest, UpdateEnabledTypes) { + syncer::ModelTypeSet enabled_types(syncer::BOOKMARKS, syncer::PREFERENCES); + EXPECT_CALL(*mock_delegate_, + UpdateEnabledTypes(HasModelTypes(enabled_types))); + bridged_notifier_.UpdateEnabledTypes(enabled_types); +} + TEST_F(BridgedSyncNotifierTest, SendNotification) { syncer::ModelTypeSet changed_types(syncer::SESSIONS, syncer::EXTENSIONS); EXPECT_CALL(*mock_delegate_, SendNotification(HasModelTypes(changed_types))); diff --git a/chrome/browser/sync/glue/chrome_sync_notification_bridge.cc b/chrome/browser/sync/glue/chrome_sync_notification_bridge.cc index 31db8e2..76b62bf 100644 --- a/chrome/browser/sync/glue/chrome_sync_notification_bridge.cc +++ b/chrome/browser/sync/glue/chrome_sync_notification_bridge.cc @@ -6,10 +6,10 @@ #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" -#include "sync/notifier/sync_notifier_helper.h" #include "sync/notifier/sync_notifier_observer.h" using content::BrowserThread; @@ -26,8 +26,8 @@ class ChromeSyncNotificationBridge::Core // All member functions below must be called on the sync task runner. void UpdateEnabledTypes(syncer::ModelTypeSet enabled_types); - void UpdateRegisteredIds(syncer::SyncNotifierObserver* handler, - const syncer::ObjectIdSet& ids); + void AddObserver(syncer::SyncNotifierObserver* observer); + void RemoveObserver(syncer::SyncNotifierObserver* observer); void EmitNotification( const syncer::ModelTypePayloadMap& payload_map, @@ -43,7 +43,7 @@ class ChromeSyncNotificationBridge::Core // Used only on |sync_task_runner_|. syncer::ModelTypeSet enabled_types_; - syncer::SyncNotifierHelper helper_; + ObserverList<syncer::SyncNotifierObserver> observers_; }; ChromeSyncNotificationBridge::Core::Core( @@ -64,11 +64,16 @@ void ChromeSyncNotificationBridge::Core::UpdateEnabledTypes( enabled_types_ = types; } -void ChromeSyncNotificationBridge::Core::UpdateRegisteredIds( - syncer::SyncNotifierObserver* handler, - const syncer::ObjectIdSet& ids) { +void ChromeSyncNotificationBridge::Core::AddObserver( + syncer::SyncNotifierObserver* observer) { DCHECK(sync_task_runner_->RunsTasksOnCurrentThread()); - helper_.UpdateRegisteredIds(handler, ids); + observers_.AddObserver(observer); +} + +void ChromeSyncNotificationBridge::Core::RemoveObserver( + syncer::SyncNotifierObserver* observer) { + DCHECK(sync_task_runner_->RunsTasksOnCurrentThread()); + observers_.RemoveObserver(observer); } void ChromeSyncNotificationBridge::Core::EmitNotification( @@ -80,9 +85,9 @@ void ChromeSyncNotificationBridge::Core::EmitNotification( syncer::ModelTypePayloadMapFromEnumSet(enabled_types_, std::string()) : payload_map; - helper_.DispatchInvalidationsToHandlers( - ModelTypePayloadMapToObjectIdPayloadMap(effective_payload_map), - notification_source); + FOR_EACH_OBSERVER( + syncer::SyncNotifierObserver, observers_, + OnIncomingNotification(effective_payload_map, notification_source)); } ChromeSyncNotificationBridge::ChromeSyncNotificationBridge( @@ -106,11 +111,16 @@ void ChromeSyncNotificationBridge::UpdateEnabledTypes( core_->UpdateEnabledTypes(types); } -void ChromeSyncNotificationBridge::UpdateRegisteredIds( - syncer::SyncNotifierObserver* handler, - const syncer::ObjectIdSet& ids) { +void ChromeSyncNotificationBridge::AddObserver( + syncer::SyncNotifierObserver* observer) { + DCHECK(sync_task_runner_->RunsTasksOnCurrentThread()); + core_->AddObserver(observer); +} + +void ChromeSyncNotificationBridge::RemoveObserver( + syncer::SyncNotifierObserver* observer) { DCHECK(sync_task_runner_->RunsTasksOnCurrentThread()); - core_->UpdateRegisteredIds(handler, ids); + core_->RemoveObserver(observer); } void ChromeSyncNotificationBridge::Observe( diff --git a/chrome/browser/sync/glue/chrome_sync_notification_bridge.h b/chrome/browser/sync/glue/chrome_sync_notification_bridge.h index a878ff7..bda23b4 100644 --- a/chrome/browser/sync/glue/chrome_sync_notification_bridge.h +++ b/chrome/browser/sync/glue/chrome_sync_notification_bridge.h @@ -11,7 +11,6 @@ #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" #include "sync/internal_api/public/base/model_type.h" -#include "sync/notifier/invalidation_util.h" class Profile; @@ -39,8 +38,8 @@ class ChromeSyncNotificationBridge : public content::NotificationObserver { // Must be called on the sync task runner. void UpdateEnabledTypes(syncer::ModelTypeSet enabled_types); // Marked virtual for tests. - virtual void UpdateRegisteredIds(syncer::SyncNotifierObserver* handler, - const syncer::ObjectIdSet& ids); + virtual void AddObserver(syncer::SyncNotifierObserver* observer); + virtual void RemoveObserver(syncer::SyncNotifierObserver* observer); // NotificationObserver implementation. Called on UI thread. virtual void Observe(int type, diff --git a/chrome/browser/sync/glue/chrome_sync_notification_bridge_unittest.cc b/chrome/browser/sync/glue/chrome_sync_notification_bridge_unittest.cc index acf0898..1b097eb 100644 --- a/chrome/browser/sync/glue/chrome_sync_notification_bridge_unittest.cc +++ b/chrome/browser/sync/glue/chrome_sync_notification_bridge_unittest.cc @@ -44,7 +44,7 @@ class FakeSyncNotifierObserver : public syncer::SyncNotifierObserver { FakeSyncNotifierObserver( const scoped_refptr<base::SequencedTaskRunner>& sync_task_runner, ChromeSyncNotificationBridge* bridge, - const syncer::ObjectIdPayloadMap& expected_payloads, + const syncer::ModelTypePayloadMap& expected_payloads, syncer::IncomingNotificationSource expected_source) : sync_task_runner_(sync_task_runner), bridge_(bridge), @@ -53,23 +53,17 @@ class FakeSyncNotifierObserver : public syncer::SyncNotifierObserver { expected_payloads_(expected_payloads), expected_source_(expected_source) { DCHECK(sync_task_runner_->RunsTasksOnCurrentThread()); - // TODO(dcheng): We might want a function to go from ObjectIdPayloadMap -> - // ObjectIdSet to avoid this rather long incantation... - const syncer::ObjectIdSet& ids = syncer::ModelTypeSetToObjectIdSet( - syncer::ModelTypePayloadMapToEnumSet( - syncer::ObjectIdPayloadMapToModelTypePayloadMap( - expected_payloads))); - bridge_->UpdateRegisteredIds(this, ids); + bridge_->AddObserver(this); } virtual ~FakeSyncNotifierObserver() { DCHECK(sync_task_runner_->RunsTasksOnCurrentThread()); - bridge_->UpdateRegisteredIds(this, syncer::ObjectIdSet()); + bridge_->RemoveObserver(this); } // SyncNotifierObserver implementation. virtual void OnIncomingNotification( - const syncer::ObjectIdPayloadMap& id_payloads, + const syncer::ModelTypePayloadMap& type_payloads, syncer::IncomingNotificationSource source) OVERRIDE { DCHECK(sync_task_runner_->RunsTasksOnCurrentThread()); notification_count_++; @@ -77,7 +71,7 @@ class FakeSyncNotifierObserver : public syncer::SyncNotifierObserver { LOG(ERROR) << "Received notification with wrong source"; received_improper_notification_ = true; } - if (expected_payloads_ != id_payloads) { + if (expected_payloads_ != type_payloads) { LOG(ERROR) << "Received wrong payload"; received_improper_notification_ = true; } @@ -100,7 +94,7 @@ class FakeSyncNotifierObserver : public syncer::SyncNotifierObserver { ChromeSyncNotificationBridge* const bridge_; bool received_improper_notification_; size_t notification_count_; - const syncer::ObjectIdPayloadMap expected_payloads_; + const syncer::ModelTypePayloadMap expected_payloads_; const syncer::IncomingNotificationSource expected_source_; }; @@ -142,16 +136,14 @@ class ChromeSyncNotificationBridgeTest : public testing::Test { } void CreateObserverWithExpectations( - const syncer::ModelTypePayloadMap& expected_payloads, + syncer::ModelTypePayloadMap expected_payloads, syncer::IncomingNotificationSource expected_source) { - const syncer::ObjectIdPayloadMap& expected_id_payloads = - syncer::ModelTypePayloadMapToObjectIdPayloadMap(expected_payloads); ASSERT_TRUE(sync_thread_.message_loop_proxy()->PostTask( FROM_HERE, base::Bind( &ChromeSyncNotificationBridgeTest::CreateObserverOnSyncThread, base::Unretained(this), - expected_id_payloads, + expected_payloads, expected_source))); BlockForSyncThread(); } @@ -190,7 +182,7 @@ class ChromeSyncNotificationBridgeTest : public testing::Test { } void CreateObserverOnSyncThread( - const syncer::ObjectIdPayloadMap& expected_payloads, + syncer::ModelTypePayloadMap expected_payloads, syncer::IncomingNotificationSource expected_source) { DCHECK(sync_thread_.message_loop_proxy()->RunsTasksOnCurrentThread()); sync_observer_ = new FakeSyncNotifierObserver( diff --git a/sync/internal_api/sync_manager_impl.cc b/sync/internal_api/sync_manager_impl.cc index 98ba4a3..547dae8 100644 --- a/sync/internal_api/sync_manager_impl.cc +++ b/sync/internal_api/sync_manager_impl.cc @@ -39,7 +39,6 @@ #include "sync/js/js_event_details.h" #include "sync/js/js_event_handler.h" #include "sync/js/js_reply_handler.h" -#include "sync/notifier/invalidation_util.h" #include "sync/notifier/notifications_disabled_reason.h" #include "sync/notifier/sync_notifier.h" #include "sync/protocol/encryption.pb.h" @@ -482,6 +481,8 @@ bool SyncManagerImpl::Init( if (!success) return false; + sync_notifier_->AddObserver(this); + return success; } @@ -724,8 +725,7 @@ void SyncManagerImpl::UpdateCredentials( void SyncManagerImpl::UpdateEnabledTypes( const ModelTypeSet& enabled_types) { DCHECK(thread_checker_.CalledOnValidThread()); - sync_notifier_->UpdateRegisteredIds(this, - ModelTypeSetToObjectIdSet(enabled_types)); + sync_notifier_->UpdateEnabledTypes(enabled_types); } void SyncManagerImpl::SetEncryptionPassphrase( @@ -1195,7 +1195,7 @@ void SyncManagerImpl::ShutdownOnSyncThread() { RemoveObserver(&debug_info_event_listener_); if (sync_notifier_.get()) { - sync_notifier_->UpdateRegisteredIds(this, ObjectIdSet()); + sync_notifier_->RemoveObserver(this); } sync_notifier_.reset(); @@ -1781,11 +1781,9 @@ void SyncManagerImpl::OnNotificationsDisabled( } void SyncManagerImpl::OnIncomingNotification( - const ObjectIdPayloadMap& id_payloads, + const ModelTypePayloadMap& type_payloads, IncomingNotificationSource source) { DCHECK(thread_checker_.CalledOnValidThread()); - const ModelTypePayloadMap& type_payloads = - ObjectIdPayloadMapToModelTypePayloadMap(id_payloads); if (source == LOCAL_NOTIFICATION) { scheduler_->ScheduleNudgeWithPayloadsAsync( TimeDelta::FromMilliseconds(kSyncRefreshDelayMsec), diff --git a/sync/internal_api/sync_manager_impl.h b/sync/internal_api/sync_manager_impl.h index bcb2c97..b353c42 100644 --- a/sync/internal_api/sync_manager_impl.h +++ b/sync/internal_api/sync_manager_impl.h @@ -167,7 +167,7 @@ class SyncManagerImpl : public SyncManager, virtual void OnNotificationsDisabled( NotificationsDisabledReason reason) OVERRIDE; virtual void OnIncomingNotification( - const ObjectIdPayloadMap& id_payloads, + const ModelTypePayloadMap& type_payloads, IncomingNotificationSource source) OVERRIDE; // Called only by our NetworkChangeNotifier. diff --git a/sync/internal_api/syncapi_unittest.cc b/sync/internal_api/syncapi_unittest.cc index 40a18f8..6c319fc 100644 --- a/sync/internal_api/syncapi_unittest.cc +++ b/sync/internal_api/syncapi_unittest.cc @@ -695,12 +695,14 @@ class SyncManagerObserverMock : public SyncManager::Observer { class SyncNotifierMock : public SyncNotifier { public: - MOCK_METHOD2(UpdateRegisteredIds, void(SyncNotifierObserver*, - const ObjectIdSet&)); + MOCK_METHOD1(AddObserver, void(SyncNotifierObserver*)); + MOCK_METHOD1(RemoveObserver, void(SyncNotifierObserver*)); MOCK_METHOD1(SetUniqueId, void(const std::string&)); MOCK_METHOD1(SetStateDeprecated, void(const std::string&)); MOCK_METHOD2(UpdateCredentials, void(const std::string&, const std::string&)); + MOCK_METHOD1(UpdateEnabledTypes, + void(ModelTypeSet)); MOCK_METHOD1(SendNotification, void(ModelTypeSet)); }; @@ -722,7 +724,9 @@ class SyncManagerTest : public testing::Test, SyncManagerTest() : sync_notifier_mock_(NULL), - sync_manager_("Test sync manager") {} + sync_manager_("Test sync manager"), + sync_notifier_observer_(NULL), + update_enabled_types_call_count_(0) {} virtual ~SyncManagerTest() { EXPECT_FALSE(sync_notifier_mock_); @@ -737,15 +741,23 @@ class SyncManagerTest : public testing::Test, credentials.sync_token = "sometoken"; sync_notifier_mock_ = new StrictMock<SyncNotifierMock>(); + EXPECT_CALL(*sync_notifier_mock_, AddObserver(_)). + WillOnce(Invoke(this, &SyncManagerTest::SyncNotifierAddObserver)); EXPECT_CALL(*sync_notifier_mock_, SetUniqueId(_)); EXPECT_CALL(*sync_notifier_mock_, SetStateDeprecated("")); EXPECT_CALL(*sync_notifier_mock_, UpdateCredentials(credentials.email, credentials.sync_token)); + EXPECT_CALL(*sync_notifier_mock_, UpdateEnabledTypes(_)). + WillRepeatedly( + Invoke(this, &SyncManagerTest::SyncNotifierUpdateEnabledTypes)); + EXPECT_CALL(*sync_notifier_mock_, RemoveObserver(_)). + WillOnce(Invoke(this, &SyncManagerTest::SyncNotifierRemoveObserver)); sync_manager_.AddObserver(&observer_); EXPECT_CALL(observer_, OnInitializationComplete(_, _)). WillOnce(SaveArg<0>(&js_backend_)); + EXPECT_FALSE(sync_notifier_observer_); EXPECT_FALSE(js_backend_.IsInitialized()); std::vector<ModelSafeWorker*> workers; @@ -769,8 +781,11 @@ class SyncManagerTest : public testing::Test, &handler_, NULL); + EXPECT_TRUE(sync_notifier_observer_); EXPECT_TRUE(js_backend_.IsInitialized()); + EXPECT_EQ(0, update_enabled_types_call_count_); + for (ModelSafeRoutingInfo::iterator i = routing_info.begin(); i != routing_info.end(); ++i) { type_roots_[i->first] = MakeServerNodeForType( @@ -781,10 +796,9 @@ class SyncManagerTest : public testing::Test, void TearDown() { sync_manager_.RemoveObserver(&observer_); - EXPECT_CALL(*sync_notifier_mock_, - UpdateRegisteredIds(_, ObjectIdSet())); sync_manager_.ShutdownOnSyncThread(); sync_notifier_mock_ = NULL; + EXPECT_FALSE(sync_notifier_observer_); PumpLoop(); } @@ -845,6 +859,26 @@ class SyncManagerTest : public testing::Test, return type_roots_[type]; } + void SyncNotifierAddObserver( + SyncNotifierObserver* sync_notifier_observer) { + EXPECT_EQ(NULL, sync_notifier_observer_); + sync_notifier_observer_ = sync_notifier_observer; + } + + void SyncNotifierRemoveObserver( + SyncNotifierObserver* sync_notifier_observer) { + EXPECT_EQ(sync_notifier_observer_, sync_notifier_observer); + sync_notifier_observer_ = NULL; + } + + void SyncNotifierUpdateEnabledTypes(ModelTypeSet types) { + ModelSafeRoutingInfo routes; + GetModelSafeRoutingInfo(&routes); + const ModelTypeSet expected_types = GetRoutingInfoTypes(routes); + EXPECT_TRUE(types.Equals(expected_types)); + ++update_enabled_types_call_count_; + } + void PumpLoop() { message_loop_.RunAllPending(); } @@ -914,9 +948,8 @@ class SyncManagerTest : public testing::Test, DCHECK(sync_manager_.thread_checker_.CalledOnValidThread()); ModelTypePayloadMap model_types_with_payloads = ModelTypePayloadMapFromEnumSet(model_types, std::string()); - sync_manager_.OnIncomingNotification( - ModelTypePayloadMapToObjectIdPayloadMap(model_types_with_payloads), - REMOTE_NOTIFICATION); + sync_manager_.OnIncomingNotification(model_types_with_payloads, + REMOTE_NOTIFICATION); } private: @@ -927,24 +960,27 @@ class SyncManagerTest : public testing::Test, // Sync Id's for the roots of the enabled datatypes. std::map<ModelType, int64> type_roots_; FakeExtensionsActivityMonitor extensions_activity_monitor_; + StrictMock<SyncNotifierMock>* sync_notifier_mock_; protected: FakeEncryptor encryptor_; TestUnrecoverableErrorHandler handler_; - StrictMock<SyncNotifierMock>* sync_notifier_mock_; SyncManagerImpl sync_manager_; WeakHandle<JsBackend> js_backend_; StrictMock<SyncManagerObserverMock> observer_; + SyncNotifierObserver* sync_notifier_observer_; + int update_enabled_types_call_count_; }; TEST_F(SyncManagerTest, UpdateEnabledTypes) { + EXPECT_EQ(0, update_enabled_types_call_count_); + ModelSafeRoutingInfo routes; GetModelSafeRoutingInfo(&routes); const ModelTypeSet enabled_types = GetRoutingInfoTypes(routes); - EXPECT_CALL(*sync_notifier_mock_, - UpdateRegisteredIds(_, ModelTypeSetToObjectIdSet(enabled_types))); sync_manager_.UpdateEnabledTypes(enabled_types); + EXPECT_EQ(1, update_enabled_types_call_count_); } TEST_F(SyncManagerTest, ProcessJsMessage) { diff --git a/sync/notifier/chrome_invalidation_client.h b/sync/notifier/chrome_invalidation_client.h index 2328f99a..ddd5bb0 100644 --- a/sync/notifier/chrome_invalidation_client.h +++ b/sync/notifier/chrome_invalidation_client.h @@ -8,6 +8,7 @@ #ifndef SYNC_NOTIFIER_CHROME_INVALIDATION_CLIENT_H_ #define SYNC_NOTIFIER_CHROME_INVALIDATION_CLIENT_H_ +#include <map> #include <string> #include "base/basictypes.h" @@ -20,8 +21,8 @@ #include "sync/internal_api/public/util/weak_handle.h" #include "sync/notifier/chrome_system_resources.h" #include "sync/notifier/invalidation_state_tracker.h" +#include "sync/notifier/invalidation_util.h" #include "sync/notifier/notifications_disabled_reason.h" -#include "sync/notifier/object_id_payload_map.h" #include "sync/notifier/state_writer.h" namespace buzz { @@ -36,6 +37,10 @@ namespace syncer { class RegistrationManager; +typedef std::map<invalidation::ObjectId, + std::string, + ObjectIdLessThan> ObjectIdPayloadMap; + // ChromeInvalidationClient is not thread-safe and lives on the sync // thread. class ChromeInvalidationClient diff --git a/sync/notifier/invalidation_notifier.cc b/sync/notifier/invalidation_notifier.cc index 3a72f32..0c629c6 100644 --- a/sync/notifier/invalidation_notifier.cc +++ b/sync/notifier/invalidation_notifier.cc @@ -34,10 +34,14 @@ InvalidationNotifier::~InvalidationNotifier() { DCHECK(CalledOnValidThread()); } -void InvalidationNotifier::UpdateRegisteredIds(SyncNotifierObserver* handler, - const ObjectIdSet& ids) { +void InvalidationNotifier::AddObserver(SyncNotifierObserver* observer) { DCHECK(CalledOnValidThread()); - invalidation_client_.RegisterIds(helper_.UpdateRegisteredIds(handler, ids)); + observers_.AddObserver(observer); +} + +void InvalidationNotifier::RemoveObserver(SyncNotifierObserver* observer) { + DCHECK(CalledOnValidThread()); + observers_.RemoveObserver(observer); } void InvalidationNotifier::SetUniqueId(const std::string& unique_id) { @@ -81,6 +85,22 @@ void InvalidationNotifier::UpdateCredentials( invalidation_client_.UpdateCredentials(email, token); } +void InvalidationNotifier::UpdateEnabledTypes(ModelTypeSet enabled_types) { + DCHECK(CalledOnValidThread()); + CHECK(!invalidation_client_id_.empty()); + ObjectIdSet ids; + for (ModelTypeSet::Iterator it = enabled_types.First(); it.Good(); + it.Inc()) { + invalidation::ObjectId id; + if (!RealModelTypeToObjectId(it.Get(), &id)) { + DLOG(WARNING) << "Invalid model type " << it.Get(); + continue; + } + ids.insert(id); + } + invalidation_client_.RegisterIds(ids); +} + void InvalidationNotifier::SendNotification(ModelTypeSet changed_types) { DCHECK(CalledOnValidThread()); // Do nothing. @@ -88,18 +108,33 @@ void InvalidationNotifier::SendNotification(ModelTypeSet changed_types) { void InvalidationNotifier::OnInvalidate(const ObjectIdPayloadMap& id_payloads) { DCHECK(CalledOnValidThread()); - helper_.DispatchInvalidationsToHandlers(id_payloads, REMOTE_NOTIFICATION); + // TODO(dcheng): This should probably be a utility function somewhere... + ModelTypePayloadMap type_payloads; + for (ObjectIdPayloadMap::const_iterator it = id_payloads.begin(); + it != id_payloads.end(); ++it) { + ModelType model_type; + if (!ObjectIdToRealModelType(it->first, &model_type)) { + DLOG(WARNING) << "Invalid object ID: " << ObjectIdToString(it->first); + continue; + } + type_payloads[model_type] = it->second; + } + FOR_EACH_OBSERVER( + SyncNotifierObserver, observers_, + OnIncomingNotification(type_payloads, REMOTE_NOTIFICATION)); } void InvalidationNotifier::OnNotificationsEnabled() { DCHECK(CalledOnValidThread()); - helper_.EmitOnNotificationsEnabled(); + FOR_EACH_OBSERVER(SyncNotifierObserver, observers_, + OnNotificationsEnabled()); } void InvalidationNotifier::OnNotificationsDisabled( NotificationsDisabledReason reason) { DCHECK(CalledOnValidThread()); - helper_.EmitOnNotificationsDisabled(reason); + FOR_EACH_OBSERVER(SyncNotifierObserver, observers_, + OnNotificationsDisabled(reason)); } } // namespace syncer diff --git a/sync/notifier/invalidation_notifier.h b/sync/notifier/invalidation_notifier.h index 8d74552..c287efb 100644 --- a/sync/notifier/invalidation_notifier.h +++ b/sync/notifier/invalidation_notifier.h @@ -17,13 +17,13 @@ #include "base/basictypes.h" #include "base/compiler_specific.h" #include "base/memory/scoped_ptr.h" +#include "base/observer_list.h" #include "base/threading/non_thread_safe.h" #include "sync/internal_api/public/base/model_type.h" #include "sync/internal_api/public/util/weak_handle.h" #include "sync/notifier/chrome_invalidation_client.h" #include "sync/notifier/invalidation_state_tracker.h" #include "sync/notifier/sync_notifier.h" -#include "sync/notifier/sync_notifier_helper.h" namespace notifier { class PushClient; @@ -49,12 +49,13 @@ class InvalidationNotifier virtual ~InvalidationNotifier(); // SyncNotifier implementation. - virtual void UpdateRegisteredIds(SyncNotifierObserver* handler, - const ObjectIdSet& ids) OVERRIDE; + virtual void AddObserver(SyncNotifierObserver* observer) OVERRIDE; + virtual void RemoveObserver(SyncNotifierObserver* observer) OVERRIDE; virtual void SetUniqueId(const std::string& unique_id) OVERRIDE; virtual void SetStateDeprecated(const std::string& state) OVERRIDE; virtual void UpdateCredentials( const std::string& email, const std::string& token) OVERRIDE; + virtual void UpdateEnabledTypes(ModelTypeSet enabled_types) OVERRIDE; virtual void SendNotification(ModelTypeSet changed_types) OVERRIDE; // ChromeInvalidationClient::Listener implementation. @@ -75,8 +76,6 @@ class InvalidationNotifier }; State state_; - SyncNotifierHelper helper_; - // Passed to |invalidation_client_|. const InvalidationVersionMap initial_max_invalidation_versions_; @@ -87,6 +86,9 @@ class InvalidationNotifier // Passed to |invalidation_client_|. const std::string client_info_; + // Our observers (which must live on the same thread). + ObserverList<SyncNotifierObserver> observers_; + // The client ID to pass to |chrome_invalidation_client_|. std::string invalidation_client_id_; diff --git a/sync/notifier/invalidation_notifier_unittest.cc b/sync/notifier/invalidation_notifier_unittest.cc index 4a07678..b0b64c7 100644 --- a/sync/notifier/invalidation_notifier_unittest.cc +++ b/sync/notifier/invalidation_notifier_unittest.cc @@ -50,10 +50,11 @@ class InvalidationNotifierTest : public testing::Test { initial_invalidation_state, MakeWeakHandle(mock_tracker_.AsWeakPtr()), "fake_client_info")); + invalidation_notifier_->AddObserver(&mock_observer_); } void ResetNotifier() { - invalidation_notifier_->UpdateRegisteredIds(&mock_observer_, ObjectIdSet()); + invalidation_notifier_->RemoveObserver(&mock_observer_); // Stopping the invalidation notifier stops its scheduler, which deletes any // pending tasks without running them. Some tasks "run and delete" another // task, so they must be run in order to avoid leaking the inner task. @@ -74,16 +75,15 @@ TEST_F(InvalidationNotifierTest, Basic) { CreateAndObserveNotifier("fake_state"); InSequence dummy; - ModelTypeSet models(PREFERENCES, BOOKMARKS, AUTOFILL); - invalidation_notifier_->UpdateRegisteredIds( - &mock_observer_, ModelTypeSetToObjectIdSet(models)); + ModelTypePayloadMap type_payloads; + type_payloads[PREFERENCES] = "payload"; + type_payloads[BOOKMARKS] = "payload"; + type_payloads[AUTOFILL] = "payload"; - const ModelTypePayloadMap& type_payloads = - ModelTypePayloadMapFromEnumSet(models, "payload"); EXPECT_CALL(mock_observer_, OnNotificationsEnabled()); - EXPECT_CALL(mock_observer_, OnIncomingNotification( - ModelTypePayloadMapToObjectIdPayloadMap(type_payloads), - REMOTE_NOTIFICATION)); + EXPECT_CALL(mock_observer_, + OnIncomingNotification(type_payloads, + REMOTE_NOTIFICATION)); EXPECT_CALL(mock_observer_, OnNotificationsDisabled(TRANSIENT_NOTIFICATION_ERROR)); EXPECT_CALL(mock_observer_, @@ -99,8 +99,14 @@ TEST_F(InvalidationNotifierTest, Basic) { invalidation_notifier_->OnNotificationsEnabled(); - invalidation_notifier_->OnInvalidate( - ModelTypePayloadMapToObjectIdPayloadMap(type_payloads)); + ObjectIdPayloadMap id_payloads; + for (ModelTypePayloadMap::const_iterator it = type_payloads.begin(); + it != type_payloads.end(); ++it) { + invalidation::ObjectId id; + ASSERT_TRUE(RealModelTypeToObjectId(it->first, &id)); + id_payloads[id] = "payload"; + } + invalidation_notifier_->OnInvalidate(id_payloads); invalidation_notifier_->OnNotificationsDisabled( TRANSIENT_NOTIFICATION_ERROR); diff --git a/sync/notifier/invalidation_util.cc b/sync/notifier/invalidation_util.cc index 5b18d66..0065b50 100644 --- a/sync/notifier/invalidation_util.cc +++ b/sync/notifier/invalidation_util.cc @@ -33,32 +33,6 @@ bool ObjectIdToRealModelType(const invalidation::ObjectId& object_id, return NotificationTypeToRealModelType(object_id.name(), model_type); } -ObjectIdSet ModelTypeSetToObjectIdSet(const ModelTypeSet& model_types) { - ObjectIdSet ids; - for (ModelTypeSet::Iterator it = model_types.First(); it.Good(); it.Inc()) { - invalidation::ObjectId model_type_as_id; - if (!RealModelTypeToObjectId(it.Get(), &model_type_as_id)) { - DLOG(WARNING) << "Invalid model type " << it.Get(); - continue; - } - ids.insert(model_type_as_id); - } - return ids; -} - -ModelTypeSet ObjectIdSetToModelTypeSet(const ObjectIdSet& ids) { - ModelTypeSet model_types; - for (ObjectIdSet::const_iterator it = ids.begin(); it != ids.end(); ++it) { - ModelType model_type; - if (!ObjectIdToRealModelType(*it, &model_type)) { - DLOG(WARNING) << "Invalid object ID " << ObjectIdToString(*it); - continue; - } - model_types.Put(model_type); - } - return model_types; -} - std::string ObjectIdToString( const invalidation::ObjectId& object_id) { std::stringstream ss; diff --git a/sync/notifier/invalidation_util.h b/sync/notifier/invalidation_util.h index bc43523..1a706ef 100644 --- a/sync/notifier/invalidation_util.h +++ b/sync/notifier/invalidation_util.h @@ -34,9 +34,6 @@ bool RealModelTypeToObjectId(ModelType model_type, bool ObjectIdToRealModelType(const invalidation::ObjectId& object_id, ModelType* model_type); -ObjectIdSet ModelTypeSetToObjectIdSet(const ModelTypeSet& models); -ModelTypeSet ObjectIdSetToModelTypeSet(const ObjectIdSet& ids); - std::string ObjectIdToString(const invalidation::ObjectId& object_id); std::string InvalidationToString( diff --git a/sync/notifier/mock_sync_notifier_observer.h b/sync/notifier/mock_sync_notifier_observer.h index fc88c52..b3baeb9 100644 --- a/sync/notifier/mock_sync_notifier_observer.h +++ b/sync/notifier/mock_sync_notifier_observer.h @@ -20,7 +20,7 @@ class MockSyncNotifierObserver : public SyncNotifierObserver { MOCK_METHOD0(OnNotificationsEnabled, void()); MOCK_METHOD1(OnNotificationsDisabled, void(NotificationsDisabledReason)); MOCK_METHOD2(OnIncomingNotification, - void(const ObjectIdPayloadMap&, IncomingNotificationSource)); + void(const ModelTypePayloadMap&, IncomingNotificationSource)); }; } // namespace syncer diff --git a/sync/notifier/non_blocking_invalidation_notifier.cc b/sync/notifier/non_blocking_invalidation_notifier.cc index ac0f76a..6ec7849 100644 --- a/sync/notifier/non_blocking_invalidation_notifier.cc +++ b/sync/notifier/non_blocking_invalidation_notifier.cc @@ -33,10 +33,10 @@ class NonBlockingInvalidationNotifier::Core const WeakHandle<InvalidationStateTracker>& invalidation_state_tracker, const std::string& client_info); void Teardown(); - void UpdateRegisteredIds(const ObjectIdSet& ids); void SetUniqueId(const std::string& unique_id); void SetStateDeprecated(const std::string& state); void UpdateCredentials(const std::string& email, const std::string& token); + void UpdateEnabledTypes(ModelTypeSet enabled_types); // SyncNotifierObserver implementation (all called on I/O thread by // InvalidationNotifier). @@ -44,7 +44,7 @@ class NonBlockingInvalidationNotifier::Core virtual void OnNotificationsDisabled( NotificationsDisabledReason reason) OVERRIDE; virtual void OnIncomingNotification( - const ObjectIdPayloadMap& id_payloads, + const ModelTypePayloadMap& type_payloads, IncomingNotificationSource source) OVERRIDE; private: @@ -89,22 +89,17 @@ void NonBlockingInvalidationNotifier::Core::Initialize( initial_invalidation_state, invalidation_state_tracker, client_info)); + invalidation_notifier_->AddObserver(this); } void NonBlockingInvalidationNotifier::Core::Teardown() { DCHECK(network_task_runner_->BelongsToCurrentThread()); - invalidation_notifier_->UpdateRegisteredIds(this, ObjectIdSet()); + invalidation_notifier_->RemoveObserver(this); invalidation_notifier_.reset(); network_task_runner_ = NULL; } -void NonBlockingInvalidationNotifier::Core::UpdateRegisteredIds( - const ObjectIdSet& ids) { - DCHECK(network_task_runner_->BelongsToCurrentThread()); - invalidation_notifier_->UpdateRegisteredIds(this, ids); -} - void NonBlockingInvalidationNotifier::Core::SetUniqueId( const std::string& unique_id) { DCHECK(network_task_runner_->BelongsToCurrentThread()); @@ -123,6 +118,12 @@ void NonBlockingInvalidationNotifier::Core::UpdateCredentials( invalidation_notifier_->UpdateCredentials(email, token); } +void NonBlockingInvalidationNotifier::Core::UpdateEnabledTypes( + ModelTypeSet enabled_types) { + DCHECK(network_task_runner_->BelongsToCurrentThread()); + invalidation_notifier_->UpdateEnabledTypes(enabled_types); +} + void NonBlockingInvalidationNotifier::Core::OnNotificationsEnabled() { DCHECK(network_task_runner_->BelongsToCurrentThread()); delegate_observer_.Call(FROM_HERE, @@ -137,11 +138,12 @@ void NonBlockingInvalidationNotifier::Core::OnNotificationsDisabled( } void NonBlockingInvalidationNotifier::Core::OnIncomingNotification( - const ObjectIdPayloadMap& id_payloads, IncomingNotificationSource source) { + const ModelTypePayloadMap& type_payloads, + IncomingNotificationSource source) { DCHECK(network_task_runner_->BelongsToCurrentThread()); delegate_observer_.Call(FROM_HERE, &SyncNotifierObserver::OnIncomingNotification, - id_payloads, + type_payloads, source); } @@ -183,19 +185,16 @@ NonBlockingInvalidationNotifier::~NonBlockingInvalidationNotifier() { } } -void NonBlockingInvalidationNotifier::UpdateRegisteredIds( - SyncNotifierObserver* handler, const ObjectIdSet& ids) { +void NonBlockingInvalidationNotifier::AddObserver( + SyncNotifierObserver* observer) { DCHECK(parent_task_runner_->BelongsToCurrentThread()); - const ObjectIdSet& all_registered_ids = - helper_.UpdateRegisteredIds(handler, ids); - if (!network_task_runner_->PostTask( - FROM_HERE, - base::Bind( - &NonBlockingInvalidationNotifier::Core::UpdateRegisteredIds, - core_.get(), - all_registered_ids))) { - NOTREACHED(); - } + observers_.AddObserver(observer); +} + +void NonBlockingInvalidationNotifier::RemoveObserver( + SyncNotifierObserver* observer) { + DCHECK(parent_task_runner_->BelongsToCurrentThread()); + observers_.RemoveObserver(observer); } void NonBlockingInvalidationNotifier::SetUniqueId( @@ -232,6 +231,17 @@ void NonBlockingInvalidationNotifier::UpdateCredentials( } } +void NonBlockingInvalidationNotifier::UpdateEnabledTypes( + ModelTypeSet enabled_types) { + DCHECK(parent_task_runner_->BelongsToCurrentThread()); + if (!network_task_runner_->PostTask( + FROM_HERE, + base::Bind(&NonBlockingInvalidationNotifier::Core::UpdateEnabledTypes, + core_.get(), enabled_types))) { + NOTREACHED(); + } +} + void NonBlockingInvalidationNotifier::SendNotification( ModelTypeSet changed_types) { DCHECK(parent_task_runner_->BelongsToCurrentThread()); @@ -241,20 +251,23 @@ void NonBlockingInvalidationNotifier::SendNotification( void NonBlockingInvalidationNotifier::OnNotificationsEnabled() { DCHECK(parent_task_runner_->BelongsToCurrentThread()); - helper_.EmitOnNotificationsEnabled(); + FOR_EACH_OBSERVER(SyncNotifierObserver, observers_, + OnNotificationsEnabled()); } void NonBlockingInvalidationNotifier::OnNotificationsDisabled( NotificationsDisabledReason reason) { DCHECK(parent_task_runner_->BelongsToCurrentThread()); - helper_.EmitOnNotificationsDisabled(reason); + FOR_EACH_OBSERVER(SyncNotifierObserver, observers_, + OnNotificationsDisabled(reason)); } void NonBlockingInvalidationNotifier::OnIncomingNotification( - const ObjectIdPayloadMap& id_payloads, + const ModelTypePayloadMap& type_payloads, IncomingNotificationSource source) { DCHECK(parent_task_runner_->BelongsToCurrentThread()); - helper_.DispatchInvalidationsToHandlers(id_payloads, source); + FOR_EACH_OBSERVER(SyncNotifierObserver, observers_, + OnIncomingNotification(type_payloads, source)); } } // namespace syncer diff --git a/sync/notifier/non_blocking_invalidation_notifier.h b/sync/notifier/non_blocking_invalidation_notifier.h index f76b37b..4756a81 100644 --- a/sync/notifier/non_blocking_invalidation_notifier.h +++ b/sync/notifier/non_blocking_invalidation_notifier.h @@ -14,11 +14,11 @@ #include "base/compiler_specific.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" +#include "base/observer_list.h" #include "jingle/notifier/base/notifier_options.h" #include "sync/internal_api/public/util/weak_handle.h" #include "sync/notifier/invalidation_state_tracker.h" #include "sync/notifier/sync_notifier.h" -#include "sync/notifier/sync_notifier_helper.h" #include "sync/notifier/sync_notifier_observer.h" namespace base { @@ -44,12 +44,13 @@ class NonBlockingInvalidationNotifier virtual ~NonBlockingInvalidationNotifier(); // SyncNotifier implementation. - virtual void UpdateRegisteredIds(SyncNotifierObserver* handler, - const ObjectIdSet& ids) OVERRIDE; + virtual void AddObserver(SyncNotifierObserver* observer) OVERRIDE; + virtual void RemoveObserver(SyncNotifierObserver* observer) OVERRIDE; virtual void SetUniqueId(const std::string& unique_id) OVERRIDE; virtual void SetStateDeprecated(const std::string& state) OVERRIDE; virtual void UpdateCredentials( const std::string& email, const std::string& token) OVERRIDE; + virtual void UpdateEnabledTypes(ModelTypeSet enabled_types) OVERRIDE; virtual void SendNotification(ModelTypeSet changed_types) OVERRIDE; // SyncNotifierObserver implementation. @@ -57,7 +58,7 @@ class NonBlockingInvalidationNotifier virtual void OnNotificationsDisabled( NotificationsDisabledReason reason) OVERRIDE; virtual void OnIncomingNotification( - const ObjectIdPayloadMap& id_payloads, + const ModelTypePayloadMap& type_payloads, IncomingNotificationSource source) OVERRIDE; private: @@ -65,7 +66,8 @@ class NonBlockingInvalidationNotifier base::WeakPtrFactory<NonBlockingInvalidationNotifier> weak_ptr_factory_; - SyncNotifierHelper helper_; + // Our observers (which must live on the parent thread). + ObserverList<SyncNotifierObserver> observers_; // The real guts of NonBlockingInvalidationNotifier, which allows // this class to live completely on the parent thread. diff --git a/sync/notifier/non_blocking_invalidation_notifier_unittest.cc b/sync/notifier/non_blocking_invalidation_notifier_unittest.cc index 36f4532..7a30f58 100644 --- a/sync/notifier/non_blocking_invalidation_notifier_unittest.cc +++ b/sync/notifier/non_blocking_invalidation_notifier_unittest.cc @@ -8,7 +8,6 @@ #include "base/memory/scoped_ptr.h" #include "base/message_loop.h" #include "base/threading/thread.h" -#include "google/cacheinvalidation/v2/types.pb.h" #include "jingle/notifier/base/fake_base_task.h" #include "net/url_request/url_request_test_util.h" #include "sync/internal_api/public/base/model_type.h" @@ -46,10 +45,11 @@ class NonBlockingInvalidationNotifierTest : public testing::Test { std::string(), // initial_invalidation_state MakeWeakHandle(base::WeakPtr<InvalidationStateTracker>()), "fake_client_info")); + invalidation_notifier_->AddObserver(&mock_observer_); } virtual void TearDown() { - invalidation_notifier_->UpdateRegisteredIds(&mock_observer_, ObjectIdSet()); + invalidation_notifier_->RemoveObserver(&mock_observer_); invalidation_notifier_.reset(); request_context_getter_ = NULL; io_thread_.Stop(); @@ -67,16 +67,15 @@ class NonBlockingInvalidationNotifierTest : public testing::Test { TEST_F(NonBlockingInvalidationNotifierTest, Basic) { InSequence dummy; - ModelTypeSet models(PREFERENCES, BOOKMARKS, AUTOFILL); - invalidation_notifier_->UpdateRegisteredIds( - &mock_observer_, ModelTypeSetToObjectIdSet(models)); + ModelTypePayloadMap type_payloads; + type_payloads[PREFERENCES] = "payload"; + type_payloads[BOOKMARKS] = ""; + type_payloads[AUTOFILL] = ""; - const ModelTypePayloadMap& type_payloads = - ModelTypePayloadMapFromEnumSet(models, "payload"); EXPECT_CALL(mock_observer_, OnNotificationsEnabled()); - EXPECT_CALL(mock_observer_, OnIncomingNotification( - ModelTypePayloadMapToObjectIdPayloadMap(type_payloads), - REMOTE_NOTIFICATION)); + EXPECT_CALL(mock_observer_, + OnIncomingNotification(type_payloads, + REMOTE_NOTIFICATION)); EXPECT_CALL(mock_observer_, OnNotificationsDisabled(TRANSIENT_NOTIFICATION_ERROR)); EXPECT_CALL(mock_observer_, @@ -87,9 +86,8 @@ TEST_F(NonBlockingInvalidationNotifierTest, Basic) { invalidation_notifier_->UpdateCredentials("foo@bar.com", "fake_token"); invalidation_notifier_->OnNotificationsEnabled(); - invalidation_notifier_->OnIncomingNotification( - ModelTypePayloadMapToObjectIdPayloadMap(type_payloads), - REMOTE_NOTIFICATION); + invalidation_notifier_->OnIncomingNotification(type_payloads, + REMOTE_NOTIFICATION); invalidation_notifier_->OnNotificationsDisabled( TRANSIENT_NOTIFICATION_ERROR); invalidation_notifier_->OnNotificationsDisabled( diff --git a/sync/notifier/object_id_payload_map.cc b/sync/notifier/object_id_payload_map.cc deleted file mode 100644 index 179f8be..0000000 --- a/sync/notifier/object_id_payload_map.cc +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) 2012 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 "sync/notifier/object_id_payload_map.h" - -namespace syncer { - -ModelTypePayloadMap ObjectIdPayloadMapToModelTypePayloadMap( - const ObjectIdPayloadMap& id_payloads) { - ModelTypePayloadMap types_with_payloads; - for (ObjectIdPayloadMap::const_iterator it = id_payloads.begin(); - it != id_payloads.end(); ++it) { - ModelType model_type; - if (!ObjectIdToRealModelType(it->first, &model_type)) { - DLOG(WARNING) << "Invalid object ID: " - << ObjectIdToString(it->first); - continue; - } - types_with_payloads[model_type] = it->second; - } - return types_with_payloads; -} - -ObjectIdPayloadMap ModelTypePayloadMapToObjectIdPayloadMap( - const ModelTypePayloadMap& type_payloads) { - ObjectIdPayloadMap id_payloads; - for (ModelTypePayloadMap::const_iterator it = type_payloads.begin(); - it != type_payloads.end(); ++it) { - invalidation::ObjectId id; - if (!RealModelTypeToObjectId(it->first, &id)) { - DLOG(WARNING) << "Invalid model type " << it->first; - continue; - } - id_payloads[id] = it->second; - } - return id_payloads; -} - -} // namespace syncer diff --git a/sync/notifier/object_id_payload_map.h b/sync/notifier/object_id_payload_map.h deleted file mode 100644 index 9205326..0000000 --- a/sync/notifier/object_id_payload_map.h +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) 2012 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 SYNC_NOTIFIER_OBJECT_ID_PAYLOAD_MAP_H_ -#define SYNC_NOTIFIER_OBJECT_ID_PAYLOAD_MAP_H_ - -#include <map> -#include <string> - -#include "google/cacheinvalidation/include/types.h" -#include "sync/internal_api/public/base/model_type_payload_map.h" -#include "sync/notifier/invalidation_util.h" - -namespace syncer { - -typedef std::map<invalidation::ObjectId, - std::string, - ObjectIdLessThan> ObjectIdPayloadMap; - -// Converts between ObjectIdPayloadMaps and ModelTypePayloadMaps. -ModelTypePayloadMap ObjectIdPayloadMapToModelTypePayloadMap( - const ObjectIdPayloadMap& id_payloads); -ObjectIdPayloadMap ModelTypePayloadMapToObjectIdPayloadMap( - const ModelTypePayloadMap& type_payloads); - -} // namespace syncer - -#endif // HOME_DCHENG_SRC_CHROMIUM_SRC_SYNC_NOTIFIER_OBJECT_ID_PAYLOAD_MAP_H_ diff --git a/sync/notifier/p2p_notifier.cc b/sync/notifier/p2p_notifier.cc index 5d5aeff..bb16f5e 100644 --- a/sync/notifier/p2p_notifier.cc +++ b/sync/notifier/p2p_notifier.cc @@ -12,7 +12,6 @@ #include "base/values.h" #include "jingle/notifier/listener/push_client.h" #include "sync/internal_api/public/base/model_type_payload_map.h" -#include "sync/notifier/invalidation_util.h" #include "sync/notifier/sync_notifier_observer.h" namespace syncer { @@ -157,16 +156,14 @@ P2PNotifier::~P2PNotifier() { push_client_->RemoveObserver(this); } -void P2PNotifier::UpdateRegisteredIds(SyncNotifierObserver* handler, - const ObjectIdSet& ids) { - const ModelTypeSet enabled_types = ObjectIdSetToModelTypeSet( - helper_.UpdateRegisteredIds(handler, ids)); - const ModelTypeSet new_enabled_types = - Difference(enabled_types, enabled_types_); - const P2PNotificationData notification_data( - unique_id_, NOTIFY_SELF, new_enabled_types); - SendNotificationData(notification_data); - enabled_types_ = enabled_types; +void P2PNotifier::AddObserver(SyncNotifierObserver* observer) { + DCHECK(thread_checker_.CalledOnValidThread()); + observer_list_.AddObserver(observer); +} + +void P2PNotifier::RemoveObserver(SyncNotifierObserver* observer) { + DCHECK(thread_checker_.CalledOnValidThread()); + observer_list_.RemoveObserver(observer); } void P2PNotifier::SetUniqueId(const std::string& unique_id) { @@ -196,6 +193,16 @@ void P2PNotifier::UpdateCredentials( logged_in_ = true; } +void P2PNotifier::UpdateEnabledTypes(ModelTypeSet enabled_types) { + DCHECK(thread_checker_.CalledOnValidThread()); + const ModelTypeSet new_enabled_types = + Difference(enabled_types, enabled_types_); + enabled_types_ = enabled_types; + const P2PNotificationData notification_data( + unique_id_, NOTIFY_SELF, new_enabled_types); + SendNotificationData(notification_data); +} + void P2PNotifier::SendNotification(ModelTypeSet changed_types) { DCHECK(thread_checker_.CalledOnValidThread()); const P2PNotificationData notification_data( @@ -207,7 +214,9 @@ void P2PNotifier::OnNotificationsEnabled() { DCHECK(thread_checker_.CalledOnValidThread()); bool just_turned_on = (notifications_enabled_ == false); notifications_enabled_ = true; - helper_.EmitOnNotificationsEnabled(); + FOR_EACH_OBSERVER( + SyncNotifierObserver, observer_list_, + OnNotificationsEnabled()); if (just_turned_on) { const P2PNotificationData notification_data( unique_id_, NOTIFY_SELF, enabled_types_); @@ -218,7 +227,9 @@ void P2PNotifier::OnNotificationsEnabled() { void P2PNotifier::OnNotificationsDisabled( notifier::NotificationsDisabledReason reason) { DCHECK(thread_checker_.CalledOnValidThread()); - helper_.EmitOnNotificationsDisabled(FromNotifierReason(reason)); + FOR_EACH_OBSERVER( + SyncNotifierObserver, observer_list_, + OnNotificationsDisabled(FromNotifierReason(reason))); } void P2PNotifier::OnIncomingNotification( @@ -255,11 +266,10 @@ void P2PNotifier::OnIncomingNotification( DVLOG(1) << "No enabled and changed types -- not emitting notification"; return; } - const ModelTypePayloadMap& type_payloads = ModelTypePayloadMapFromEnumSet( - notification_data.GetChangedTypes(), std::string()); - helper_.DispatchInvalidationsToHandlers( - ModelTypePayloadMapToObjectIdPayloadMap(type_payloads), - REMOTE_NOTIFICATION); + const ModelTypePayloadMap& type_payloads = + ModelTypePayloadMapFromEnumSet(types_to_notify, std::string()); + FOR_EACH_OBSERVER(SyncNotifierObserver, observer_list_, + OnIncomingNotification(type_payloads, REMOTE_NOTIFICATION)); } void P2PNotifier::SendNotificationDataForTest( diff --git a/sync/notifier/p2p_notifier.h b/sync/notifier/p2p_notifier.h index d2de89d..a360f25 100644 --- a/sync/notifier/p2p_notifier.h +++ b/sync/notifier/p2p_notifier.h @@ -20,7 +20,6 @@ #include "sync/internal_api/public/base/model_type.h" #include "sync/notifier/notifications_disabled_reason.h" #include "sync/notifier/sync_notifier.h" -#include "sync/notifier/sync_notifier_helper.h" namespace notifier { class PushClient; @@ -82,8 +81,9 @@ class P2PNotificationData { ModelTypeSet changed_types_; }; -class P2PNotifier : public SyncNotifier, - public notifier::PushClientObserver { +class P2PNotifier + : public SyncNotifier, + public notifier::PushClientObserver { public: // The |send_notification_target| parameter was added to allow us to send // self-notifications in some cases, but not others. The value should be @@ -96,12 +96,13 @@ class P2PNotifier : public SyncNotifier, virtual ~P2PNotifier(); // SyncNotifier implementation - virtual void UpdateRegisteredIds(SyncNotifierObserver* handler, - const ObjectIdSet& ids) OVERRIDE; + virtual void AddObserver(SyncNotifierObserver* observer) OVERRIDE; + virtual void RemoveObserver(SyncNotifierObserver* observer) OVERRIDE; virtual void SetUniqueId(const std::string& unique_id) OVERRIDE; virtual void SetStateDeprecated(const std::string& state) OVERRIDE; virtual void UpdateCredentials( const std::string& email, const std::string& token) OVERRIDE; + virtual void UpdateEnabledTypes(ModelTypeSet enabled_types) OVERRIDE; virtual void SendNotification(ModelTypeSet changed_types) OVERRIDE; // PushClientObserver implementation. @@ -119,7 +120,7 @@ class P2PNotifier : public SyncNotifier, base::ThreadChecker thread_checker_; - SyncNotifierHelper helper_; + ObserverList<SyncNotifierObserver> observer_list_; // The push client. scoped_ptr<notifier::PushClient> push_client_; diff --git a/sync/notifier/p2p_notifier_unittest.cc b/sync/notifier/p2p_notifier_unittest.cc index 28a73c9..055fd1b 100644 --- a/sync/notifier/p2p_notifier_unittest.cc +++ b/sync/notifier/p2p_notifier_unittest.cc @@ -8,7 +8,6 @@ #include "jingle/notifier/listener/fake_push_client.h" #include "sync/internal_api/public/base/model_type.h" -#include "sync/internal_api/public/base/model_type_payload_map.h" #include "sync/notifier/mock_sync_notifier_observer.h" #include "testing/gtest/include/gtest/gtest.h" @@ -28,14 +27,15 @@ class P2PNotifierTest : public testing::Test { scoped_ptr<notifier::PushClient>(fake_push_client_), NOTIFY_OTHERS), next_sent_notification_to_reflect_(0) { + p2p_notifier_.AddObserver(&mock_observer_); } virtual ~P2PNotifierTest() { - p2p_notifier_.UpdateRegisteredIds(&mock_observer_, ObjectIdSet()); + p2p_notifier_.RemoveObserver(&mock_observer_); } ModelTypePayloadMap MakePayloadMap(ModelTypeSet types) { - return ModelTypePayloadMapFromEnumSet(types, std::string()); + return ModelTypePayloadMapFromEnumSet(types, ""); } // Simulate receiving all the notifications we sent out since last @@ -142,13 +142,10 @@ TEST_F(P2PNotifierTest, P2PNotificationDataNonDefault) { TEST_F(P2PNotifierTest, NotificationsBasic) { ModelTypeSet enabled_types(BOOKMARKS, PREFERENCES); - p2p_notifier_.UpdateRegisteredIds(&mock_observer_, - ModelTypeSetToObjectIdSet(enabled_types)); - EXPECT_CALL(mock_observer_, OnNotificationsEnabled()); - EXPECT_CALL(mock_observer_, OnIncomingNotification( - ModelTypePayloadMapToObjectIdPayloadMap(MakePayloadMap(enabled_types)), - REMOTE_NOTIFICATION)); + EXPECT_CALL(mock_observer_, + OnIncomingNotification(MakePayloadMap(enabled_types), + REMOTE_NOTIFICATION)); p2p_notifier_.SetUniqueId("sender"); @@ -166,6 +163,8 @@ TEST_F(P2PNotifierTest, NotificationsBasic) { EXPECT_EQ(kEmail, fake_push_client_->email()); EXPECT_EQ(kToken, fake_push_client_->token()); + p2p_notifier_.UpdateEnabledTypes(enabled_types); + ReflectSentNotifications(); fake_push_client_->EnableNotifications(); @@ -187,21 +186,17 @@ TEST_F(P2PNotifierTest, SendNotificationData) { ModelTypeSet changed_types(THEMES, APPS); ModelTypeSet expected_types(THEMES); - p2p_notifier_.UpdateRegisteredIds(&mock_observer_, - ModelTypeSetToObjectIdSet(enabled_types)); - const ModelTypePayloadMap& expected_payload_map = MakePayloadMap(expected_types); EXPECT_CALL(mock_observer_, OnNotificationsEnabled()); EXPECT_CALL(mock_observer_, - OnIncomingNotification( - ModelTypePayloadMapToObjectIdPayloadMap( - MakePayloadMap(enabled_types)), - REMOTE_NOTIFICATION)); + OnIncomingNotification(MakePayloadMap(enabled_types), + REMOTE_NOTIFICATION)); p2p_notifier_.SetUniqueId("sender"); p2p_notifier_.UpdateCredentials("foo@bar.com", "fake_token"); + p2p_notifier_.UpdateEnabledTypes(enabled_types); ReflectSentNotifications(); fake_push_client_->EnableNotifications(); @@ -216,9 +211,8 @@ TEST_F(P2PNotifierTest, SendNotificationData) { // Should be propagated. Mock::VerifyAndClearExpectations(&mock_observer_); - EXPECT_CALL(mock_observer_, OnIncomingNotification( - ModelTypePayloadMapToObjectIdPayloadMap(expected_payload_map), - REMOTE_NOTIFICATION)); + EXPECT_CALL(mock_observer_, OnIncomingNotification(expected_payload_map, + REMOTE_NOTIFICATION)); p2p_notifier_.SendNotificationDataForTest( P2PNotificationData("sender", NOTIFY_SELF, changed_types)); @@ -246,9 +240,8 @@ TEST_F(P2PNotifierTest, SendNotificationData) { // Should be propagated. Mock::VerifyAndClearExpectations(&mock_observer_); - EXPECT_CALL(mock_observer_, OnIncomingNotification( - ModelTypePayloadMapToObjectIdPayloadMap(expected_payload_map), - REMOTE_NOTIFICATION)); + EXPECT_CALL(mock_observer_, OnIncomingNotification(expected_payload_map, + REMOTE_NOTIFICATION)); p2p_notifier_.SendNotificationDataForTest( P2PNotificationData("sender2", NOTIFY_OTHERS, changed_types)); @@ -263,9 +256,8 @@ TEST_F(P2PNotifierTest, SendNotificationData) { // Should be propagated. Mock::VerifyAndClearExpectations(&mock_observer_); - EXPECT_CALL(mock_observer_, OnIncomingNotification( - ModelTypePayloadMapToObjectIdPayloadMap(expected_payload_map), - REMOTE_NOTIFICATION)); + EXPECT_CALL(mock_observer_, OnIncomingNotification(expected_payload_map, + REMOTE_NOTIFICATION)); p2p_notifier_.SendNotificationDataForTest( P2PNotificationData("sender", NOTIFY_ALL, changed_types)); @@ -273,9 +265,8 @@ TEST_F(P2PNotifierTest, SendNotificationData) { // Should be propagated. Mock::VerifyAndClearExpectations(&mock_observer_); - EXPECT_CALL(mock_observer_, OnIncomingNotification( - ModelTypePayloadMapToObjectIdPayloadMap(expected_payload_map), - REMOTE_NOTIFICATION)); + EXPECT_CALL(mock_observer_, OnIncomingNotification(expected_payload_map, + REMOTE_NOTIFICATION)); p2p_notifier_.SendNotificationDataForTest( P2PNotificationData("sender2", NOTIFY_ALL, changed_types)); diff --git a/sync/notifier/sync_notifier.h b/sync/notifier/sync_notifier.h index 369ced1..0c775f4 100644 --- a/sync/notifier/sync_notifier.h +++ b/sync/notifier/sync_notifier.h @@ -12,7 +12,6 @@ #include <string> #include "sync/internal_api/public/base/model_type.h" -#include "sync/notifier/invalidation_util.h" namespace syncer { class SyncNotifierObserver; @@ -22,11 +21,8 @@ class SyncNotifier { SyncNotifier() {} virtual ~SyncNotifier() {} - // Updates the set of ObjectIds associated with a given |handler|. Passing an - // empty ObjectIdSet will unregister |handler|. If two different handlers - // attempt to register for the same object ID, the first registration wins. - virtual void UpdateRegisteredIds(SyncNotifierObserver* handler, - const ObjectIdSet& ids) = 0; + virtual void AddObserver(SyncNotifierObserver* observer) = 0; + virtual void RemoveObserver(SyncNotifierObserver* observer) = 0; // SetUniqueId must be called once, before any call to // UpdateCredentials. |unique_id| should be a non-empty globally @@ -44,6 +40,8 @@ class SyncNotifier { virtual void UpdateCredentials( const std::string& email, const std::string& token) = 0; + virtual void UpdateEnabledTypes(ModelTypeSet enabled_types) = 0; + // This is here only to support the old p2p notification implementation, // which is still used by sync integration tests. // TODO(akalin): Remove this once we move the integration tests off p2p diff --git a/sync/notifier/sync_notifier_factory_unittest.cc b/sync/notifier/sync_notifier_factory_unittest.cc index 8036c1a..52fd505 100644 --- a/sync/notifier/sync_notifier_factory_unittest.cc +++ b/sync/notifier/sync_notifier_factory_unittest.cc @@ -60,9 +60,8 @@ TEST_F(SyncNotifierFactoryTest, Basic) { ASSERT_FALSE(notifier.get()); #else ASSERT_TRUE(notifier.get()); - ObjectIdSet ids = ModelTypeSetToObjectIdSet(ModelTypeSet(syncer::BOOKMARKS)); - notifier->UpdateRegisteredIds(&mock_observer_, ids); - notifier->UpdateRegisteredIds(&mock_observer_, ObjectIdSet()); + notifier->AddObserver(&mock_observer_); + notifier->RemoveObserver(&mock_observer_); #endif } @@ -78,9 +77,8 @@ TEST_F(SyncNotifierFactoryTest, Basic_P2P) { ASSERT_FALSE(notifier.get()); #else ASSERT_TRUE(notifier.get()); - ObjectIdSet ids = ModelTypeSetToObjectIdSet(ModelTypeSet(syncer::BOOKMARKS)); - notifier->UpdateRegisteredIds(&mock_observer_, ids); - notifier->UpdateRegisteredIds(&mock_observer_, ObjectIdSet()); + notifier->AddObserver(&mock_observer_); + notifier->RemoveObserver(&mock_observer_); #endif } diff --git a/sync/notifier/sync_notifier_helper.cc b/sync/notifier/sync_notifier_helper.cc deleted file mode 100644 index af3b2ea..0000000 --- a/sync/notifier/sync_notifier_helper.cc +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (c) 2012 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 "sync/notifier/sync_notifier_helper.h" - -#include "base/logging.h" - -namespace syncer { - -SyncNotifierHelper::SyncNotifierHelper() {} -SyncNotifierHelper::~SyncNotifierHelper() {} - -ObjectIdSet SyncNotifierHelper::UpdateRegisteredIds( - SyncNotifierObserver* handler, const ObjectIdSet& ids) { - if (ids.empty()) { - handlers_.RemoveObserver(handler); - } else if (!handlers_.HasObserver(handler)) { - handlers_.AddObserver(handler); - } - - ObjectIdSet registered_ids(ids); - // Remove all existing entries for |handler| and fill |registered_ids| with - // the rest. - for (ObjectIdHandlerMap::iterator it = id_to_handler_map_.begin(); - it != id_to_handler_map_.end(); ) { - if (it->second == handler) { - ObjectIdHandlerMap::iterator erase_it = it; - ++it; - id_to_handler_map_.erase(erase_it); - } else { - registered_ids.insert(it->first); - ++it; - } - } - - // Now add the entries for |handler|. We keep track of the last insertion - // point so we only traverse the map once to insert all the new entries. - ObjectIdHandlerMap::iterator insert_it = id_to_handler_map_.begin(); - for (ObjectIdSet::const_iterator it = ids.begin(); it != ids.end(); ++it) { - insert_it = id_to_handler_map_.insert(insert_it, - std::make_pair(*it, handler)); - CHECK_EQ(handler, insert_it->second) << "Duplicate registration for " - << ObjectIdToString(insert_it->first); - } - if (logging::DEBUG_MODE) { - // The mapping shouldn't contain any handlers that aren't in |handlers_|. - for (ObjectIdHandlerMap::const_iterator it = id_to_handler_map_.begin(); - it != id_to_handler_map_.end(); ++it) { - CHECK(handlers_.HasObserver(it->second)); - } - } - return registered_ids; -} - -void SyncNotifierHelper::DispatchInvalidationsToHandlers( - const ObjectIdPayloadMap& id_payloads, - IncomingNotificationSource source) { - typedef std::map<SyncNotifierObserver*, ObjectIdPayloadMap> DispatchMap; - DispatchMap dispatch_map; - for (ObjectIdPayloadMap::const_iterator it = id_payloads.begin(); - it != id_payloads.end(); ++it) { - ObjectIdHandlerMap::const_iterator find_it = - id_to_handler_map_.find(it->first); - // If we get an invalidation with a source type that we can't map to an - // observer, just drop it--the observer was unregistered while the - // invalidation was in flight. - if (find_it == id_to_handler_map_.end()) - continue; - dispatch_map[find_it->second].insert(*it); - } - - if (handlers_.might_have_observers()) { - ObserverListBase<SyncNotifierObserver>::Iterator it(handlers_); - SyncNotifierObserver* handler = NULL; - while ((handler = it.GetNext()) != NULL) { - DispatchMap::const_iterator dispatch_it = dispatch_map.find(handler); - if (dispatch_it != dispatch_map.end()) { - handler->OnIncomingNotification(dispatch_it->second, source); - } - } - } -} - -void SyncNotifierHelper::EmitOnNotificationsEnabled() { - FOR_EACH_OBSERVER(SyncNotifierObserver, handlers_, OnNotificationsEnabled()); -} - -void SyncNotifierHelper::EmitOnNotificationsDisabled( - NotificationsDisabledReason reason) { - FOR_EACH_OBSERVER(SyncNotifierObserver, handlers_, - OnNotificationsDisabled(reason)); -} - -} // namespace syncer diff --git a/sync/notifier/sync_notifier_helper.h b/sync/notifier/sync_notifier_helper.h deleted file mode 100644 index 28ff187..0000000 --- a/sync/notifier/sync_notifier_helper.h +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) 2012 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 SYNC_NOTIFIER_SYNC_NOTIFIER_HELPER_H_ -#define SYNC_NOTIFIER_SYNC_NOTIFIER_HELPER_H_ - -#include <map> - -#include "base/basictypes.h" -#include "base/observer_list.h" -#include "sync/notifier/invalidation_util.h" -#include "sync/notifier/object_id_payload_map.h" -#include "sync/notifier/sync_notifier_observer.h" - -namespace syncer { - -// A helper class for classes that want to implement the SyncNotifier interface. -// It helps keep track of registered handlers and which object ID registrations -// are associated with which handlers, so implementors can just reuse the logic -// here to dispatch invalidations and other interesting notifications. -class SyncNotifierHelper { - public: - SyncNotifierHelper(); - ~SyncNotifierHelper(); - - // Updates the set of ObjectIds associated with a given |handler|. Passing an - // empty ObjectIdSet will unregister |handler|. The return value is an - // ObjectIdSet containing values for all existing handlers. - ObjectIdSet UpdateRegisteredIds(SyncNotifierObserver* handler, - const ObjectIdSet& ids); - - // Helper that sorts incoming invalidations into a bucket for each handler - // and then dispatches the batched invalidations to the corresponding handler. - void DispatchInvalidationsToHandlers(const ObjectIdPayloadMap& id_payloads, - IncomingNotificationSource source); - - // Calls the given handler method for each handler that has registered IDs. - void EmitOnNotificationsEnabled(); - void EmitOnNotificationsDisabled(NotificationsDisabledReason reason); - - private: - typedef std::map<invalidation::ObjectId, - SyncNotifierObserver*, - ObjectIdLessThan> ObjectIdHandlerMap; - - ObserverList<SyncNotifierObserver> handlers_; - ObjectIdHandlerMap id_to_handler_map_; - - DISALLOW_COPY_AND_ASSIGN(SyncNotifierHelper); -}; - -} // namespace syncer - -#endif // SYNC_NOTIFIER_SYNC_NOTIFIER_HELPER_H_ diff --git a/sync/notifier/sync_notifier_helper_unittest.cc b/sync/notifier/sync_notifier_helper_unittest.cc deleted file mode 100644 index ba2d768..0000000 --- a/sync/notifier/sync_notifier_helper_unittest.cc +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright (c) 2012 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 "google/cacheinvalidation/v2/types.pb.h" -#include "sync/notifier/sync_notifier_helper.h" -#include "sync/notifier/mock_sync_notifier_observer.h" -#include "testing/gtest/include/gtest/gtest.h" - -using testing::StrictMock; - -namespace syncer { - -class SyncNotifierHelperTest : public testing::Test { - protected: - SyncNotifierHelperTest() - : kObjectId1(ipc::invalidation::ObjectSource::TEST, "a"), - kObjectId2(ipc::invalidation::ObjectSource::TEST, "b"), - kObjectId3(ipc::invalidation::ObjectSource::TEST, "c") { - } - - invalidation::ObjectId kObjectId1; - invalidation::ObjectId kObjectId2; - invalidation::ObjectId kObjectId3; -}; - -// Basic check that registrations are correctly updated for one handler. -TEST_F(SyncNotifierHelperTest, Basic) { - SyncNotifierHelper helper; - StrictMock<MockSyncNotifierObserver> observer; - ObjectIdSet ids; - ids.insert(kObjectId1); - ids.insert(kObjectId2); - helper.UpdateRegisteredIds(&observer, ids); - - ObjectIdPayloadMap dispatched_payloads; - dispatched_payloads[kObjectId1] = "1"; - dispatched_payloads[kObjectId2] = "2"; - dispatched_payloads[kObjectId3] = "3"; - - // A object ID with no registration should be ignored. - ObjectIdPayloadMap expected_payload1; - expected_payload1[kObjectId1] = "1"; - expected_payload1[kObjectId2] = "2"; - EXPECT_CALL(observer, OnIncomingNotification(expected_payload1, - REMOTE_NOTIFICATION)); - helper.DispatchInvalidationsToHandlers(dispatched_payloads, - REMOTE_NOTIFICATION); - - // Removed object IDs should not be notified, newly-added ones should. - ids.erase(kObjectId1); - ids.insert(kObjectId3); - helper.UpdateRegisteredIds(&observer, ids); - - ObjectIdPayloadMap expected_payload2; - expected_payload2[kObjectId2] = "2"; - expected_payload2[kObjectId3] = "3"; - EXPECT_CALL(observer, OnIncomingNotification(expected_payload2, - REMOTE_NOTIFICATION)); - helper.DispatchInvalidationsToHandlers(dispatched_payloads, - REMOTE_NOTIFICATION); -} - -// Tests that we correctly bucket and dispatch invalidations on multiple objects -// to the corresponding handlers. -TEST_F(SyncNotifierHelperTest, MultipleHandlers) { - SyncNotifierHelper helper; - StrictMock<MockSyncNotifierObserver> observer; - ObjectIdSet ids; - ids.insert(kObjectId1); - ids.insert(kObjectId2); - helper.UpdateRegisteredIds(&observer, ids); - StrictMock<MockSyncNotifierObserver> observer2; - ObjectIdSet ids2; - ids2.insert(kObjectId3); - helper.UpdateRegisteredIds(&observer2, ids2); - - ObjectIdPayloadMap expected_payload1; - expected_payload1[kObjectId1] = "1"; - expected_payload1[kObjectId2] = "2"; - EXPECT_CALL(observer, OnIncomingNotification(expected_payload1, - REMOTE_NOTIFICATION)); - ObjectIdPayloadMap expected_payload2; - expected_payload2[kObjectId3] = "3"; - EXPECT_CALL(observer2, OnIncomingNotification(expected_payload2, - REMOTE_NOTIFICATION)); - - ObjectIdPayloadMap dispatched_payloads; - dispatched_payloads[kObjectId1] = "1"; - dispatched_payloads[kObjectId2] = "2"; - dispatched_payloads[kObjectId3] = "3"; - helper.DispatchInvalidationsToHandlers(dispatched_payloads, - REMOTE_NOTIFICATION); - - // Also verify that the callbacks for OnNotificationsEnabled/Disabled work. - EXPECT_CALL(observer, OnNotificationsEnabled()); - EXPECT_CALL(observer2, OnNotificationsEnabled()); - EXPECT_CALL(observer, - OnNotificationsDisabled(TRANSIENT_NOTIFICATION_ERROR)); - EXPECT_CALL(observer2, - OnNotificationsDisabled(TRANSIENT_NOTIFICATION_ERROR)); - helper.EmitOnNotificationsEnabled(); - helper.EmitOnNotificationsDisabled(TRANSIENT_NOTIFICATION_ERROR); -} - -// Multiple registrations by different handlers on the same object ID should -// cause a CHECK. -TEST_F(SyncNotifierHelperTest, MultipleRegistration) { - SyncNotifierHelper helper; - StrictMock<MockSyncNotifierObserver> observer; - ObjectIdSet ids; - ids.insert(kObjectId1); - ids.insert(kObjectId2); - helper.UpdateRegisteredIds(&observer, ids); - - StrictMock<MockSyncNotifierObserver> observer2; - EXPECT_DEATH({ helper.UpdateRegisteredIds(&observer2, ids); }, - "Duplicate registration for .*"); -} - -// Make sure that passing an empty set to UpdateRegisteredIds clears the -// corresponding entries for the handler. -TEST_F(SyncNotifierHelperTest, EmptySetUnregisters) { - SyncNotifierHelper helper; - StrictMock<MockSyncNotifierObserver> observer; - ObjectIdSet ids; - ids.insert(kObjectId1); - ids.insert(kObjectId2); - helper.UpdateRegisteredIds(&observer, ids); - // Control observer. - StrictMock<MockSyncNotifierObserver> observer2; - ObjectIdSet ids2; - ids2.insert(kObjectId3); - helper.UpdateRegisteredIds(&observer2, ids2); - // Unregister the first observer. It should not receive any further callbacks. - helper.UpdateRegisteredIds(&observer, ObjectIdSet()); - - ObjectIdPayloadMap expected_payload2; - expected_payload2[kObjectId3] = "3"; - EXPECT_CALL(observer2, OnIncomingNotification(expected_payload2, - REMOTE_NOTIFICATION)); - EXPECT_CALL(observer2, OnNotificationsEnabled()); - EXPECT_CALL(observer2, - OnNotificationsDisabled(TRANSIENT_NOTIFICATION_ERROR)); - - ObjectIdPayloadMap dispatched_payloads; - dispatched_payloads[kObjectId1] = "1"; - dispatched_payloads[kObjectId2] = "2"; - dispatched_payloads[kObjectId3] = "3"; - helper.DispatchInvalidationsToHandlers(dispatched_payloads, - REMOTE_NOTIFICATION); - helper.EmitOnNotificationsEnabled(); - helper.EmitOnNotificationsDisabled(TRANSIENT_NOTIFICATION_ERROR); -} - -} // namespace syncer diff --git a/sync/notifier/sync_notifier_observer.h b/sync/notifier/sync_notifier_observer.h index b79f838..eaea91f 100644 --- a/sync/notifier/sync_notifier_observer.h +++ b/sync/notifier/sync_notifier_observer.h @@ -5,7 +5,7 @@ #ifndef SYNC_NOTIFIER_SYNC_NOTIFIER_OBSERVER_H_ #define SYNC_NOTIFIER_SYNC_NOTIFIER_OBSERVER_H_ -#include "sync/notifier/object_id_payload_map.h" +#include "sync/internal_api/public/base/model_type_payload_map.h" #include "sync/notifier/notifications_disabled_reason.h" namespace syncer { @@ -27,10 +27,10 @@ class SyncNotifierObserver { virtual void OnNotificationsDisabled( NotificationsDisabledReason reason) = 0; - // Called when a notification is received. The per-id payloads + // Called when a notification is received. The per-type payloads // are in |type_payloads| and the source is in |source|. virtual void OnIncomingNotification( - const ObjectIdPayloadMap& id_payloads, + const ModelTypePayloadMap& type_payloads, IncomingNotificationSource source) = 0; protected: diff --git a/sync/sync.gyp b/sync/sync.gyp index ea2f7b3..b517825 100644 --- a/sync/sync.gyp +++ b/sync/sync.gyp @@ -250,15 +250,11 @@ 'sources': [ 'notifier/invalidation_util.cc', 'notifier/invalidation_util.h', - 'notifier/notifications_disabled_reason.cc', 'notifier/notifications_disabled_reason.h', - 'notifier/object_id_payload_map.cc', - 'notifier/object_id_payload_map.h', + 'notifier/notifications_disabled_reason.cc', 'notifier/sync_notifier.h', - 'notifier/sync_notifier_factory.cc', 'notifier/sync_notifier_factory.h', - 'notifier/sync_notifier_helper.cc', - 'notifier/sync_notifier_helper.h', + 'notifier/sync_notifier_factory.cc', 'notifier/sync_notifier_observer.h', ], 'conditions': [ @@ -268,13 +264,13 @@ 'notifier/chrome_invalidation_client.h', 'notifier/chrome_system_resources.cc', 'notifier/chrome_system_resources.h', - 'notifier/invalidation_notifier.cc', 'notifier/invalidation_notifier.h', + 'notifier/invalidation_notifier.cc', 'notifier/invalidation_state_tracker.h', - 'notifier/non_blocking_invalidation_notifier.cc', 'notifier/non_blocking_invalidation_notifier.h', - 'notifier/p2p_notifier.cc', + 'notifier/non_blocking_invalidation_notifier.cc', 'notifier/p2p_notifier.h', + 'notifier/p2p_notifier.cc', 'notifier/push_client_channel.cc', 'notifier/push_client_channel.h', 'notifier/registration_manager.cc', @@ -653,7 +649,6 @@ 'notifier/p2p_notifier_unittest.cc', 'notifier/push_client_channel_unittest.cc', 'notifier/registration_manager_unittest.cc', - 'notifier/sync_notifier_helper_unittest.cc', ], }], ], diff --git a/sync/tools/sync_listen_notifications.cc b/sync/tools/sync_listen_notifications.cc index 22b22d6..25ebcbd 100644 --- a/sync/tools/sync_listen_notifications.cc +++ b/sync/tools/sync_listen_notifications.cc @@ -63,10 +63,8 @@ class NotificationPrinter : public SyncNotifierObserver { } virtual void OnIncomingNotification( - const ObjectIdPayloadMap& id_payloads, + const ModelTypePayloadMap& type_payloads, IncomingNotificationSource source) OVERRIDE { - const ModelTypePayloadMap& type_payloads = - ObjectIdPayloadMapToModelTypePayloadMap(id_payloads); for (ModelTypePayloadMap::const_iterator it = type_payloads.begin(); it != type_payloads.end(); ++it) { LOG(INFO) << (source == REMOTE_NOTIFICATION ? "Remote" : "Local") @@ -235,17 +233,17 @@ int SyncListenNotificationsMain(int argc, char* argv[]) { scoped_ptr<SyncNotifier> sync_notifier( sync_notifier_factory.CreateSyncNotifier()); NotificationPrinter notification_printer; + sync_notifier->AddObserver(¬ification_printer); const char kUniqueId[] = "fake_unique_id"; sync_notifier->SetUniqueId(kUniqueId); sync_notifier->UpdateCredentials(email, token); // Listen for notifications for all known types. - sync_notifier->UpdateRegisteredIds( - ¬ification_printer, ModelTypeSetToObjectIdSet(ModelTypeSet::All())); + sync_notifier->UpdateEnabledTypes(ModelTypeSet::All()); ui_loop.Run(); - sync_notifier->UpdateRegisteredIds(¬ification_printer, ObjectIdSet()); + sync_notifier->RemoveObserver(¬ification_printer); io_thread.Stop(); return 0; } |