diff options
author | akalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-18 20:50:28 +0000 |
---|---|---|
committer | akalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-18 20:50:28 +0000 |
commit | 2d3d1d19828e0ad8ef5218a2cd7967079e13a1c8 (patch) | |
tree | 1469346ebe8cd33fe3c98aba590b53e6e90fb0ee /sync | |
parent | e341fb8781ffac9f1a6e166a2b304137508f58ff (diff) | |
download | chromium_src-2d3d1d19828e0ad8ef5218a2cd7967079e13a1c8.zip chromium_src-2d3d1d19828e0ad8ef5218a2cd7967079e13a1c8.tar.gz chromium_src-2d3d1d19828e0ad8ef5218a2cd7967079e13a1c8.tar.bz2 |
[Sync] Propagate XMPP auth errors to SyncNotifierObservers
Detect XMPP auth errors and add new notifications to SingleLoginAttempt
and Login.
Replace PushClientObserver::OnNotificationStateChange with
OnNotifications{Enabled,Disabled} notifications.
Change SyncNotifierObserver similarly.
Handle InvalidationClient errors and propagate auth errors from that,
too.
Propagate XMPP auth errors all the way up to SyncManager. It will be
handled in a future CL.
BUG=38091
TEST=
Review URL: https://chromiumcodereview.appspot.com/10545170
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@142806 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'sync')
25 files changed, 466 insertions, 132 deletions
diff --git a/sync/internal_api/public/engine/sync_status.h b/sync/internal_api/public/engine/sync_status.h index 1c9ba1a..f05a5bc 100644 --- a/sync/internal_api/public/engine/sync_status.h +++ b/sync/internal_api/public/engine/sync_status.h @@ -22,6 +22,8 @@ struct SyncStatus { SyncStatus(); ~SyncStatus(); + // TODO(akalin): Replace this with a NotificationsDisabledReason + // variable. bool notifications_enabled; // True only if subscribed for notifications. // Notifications counters updated by the actions in synapi. diff --git a/sync/internal_api/public/sync_manager.h b/sync/internal_api/public/sync_manager.h index f4a42e3..a03e2d7 100644 --- a/sync/internal_api/public/sync_manager.h +++ b/sync/internal_api/public/sync_manager.h @@ -532,8 +532,9 @@ class SyncManager { // Functions used for testing. - void TriggerOnNotificationStateChangeForTest( - bool notifications_enabled); + void SimulateEnableNotificationsForTest(); + + void SimulateDisableNotificationsForTest(int reason); void TriggerOnIncomingNotificationForTest( syncable::ModelTypeSet model_types); diff --git a/sync/internal_api/sync_manager.cc b/sync/internal_api/sync_manager.cc index 8c95292..52a9c76 100644 --- a/sync/internal_api/sync_manager.cc +++ b/sync/internal_api/sync_manager.cc @@ -46,6 +46,7 @@ #include "sync/js/js_event_details.h" #include "sync/js/js_event_handler.h" #include "sync/js/js_reply_handler.h" +#include "sync/notifier/notifications_disabled_reason.h" #include "sync/notifier/sync_notifier.h" #include "sync/notifier/sync_notifier_observer.h" #include "sync/protocol/encryption.pb.h" @@ -321,9 +322,9 @@ class SyncManager::SyncInternal bool encrypt_everything) OVERRIDE; // SyncNotifierObserver implementation. - virtual void OnNotificationStateChange( - bool notifications_enabled) OVERRIDE; - + virtual void OnNotificationsEnabled() OVERRIDE; + virtual void OnNotificationsDisabled( + sync_notifier::NotificationsDisabledReason reason) OVERRIDE; virtual void OnIncomingNotification( const syncable::ModelTypePayloadMap& type_payloads, sync_notifier::IncomingNotificationSource source) OVERRIDE; @@ -2274,17 +2275,27 @@ void SyncManager::SyncInternal::OnEncryptedTypesChanged( OnEncryptedTypesChanged(encrypted_types, encrypt_everything)); } -void SyncManager::SyncInternal::OnNotificationStateChange( - bool notifications_enabled) { - DVLOG(1) << "P2P: Notifications enabled = " - << (notifications_enabled ? "true" : "false"); - allstatus_.SetNotificationsEnabled(notifications_enabled); +void SyncManager::SyncInternal::UpdateNotificationInfo( + const syncable::ModelTypePayloadMap& type_payloads) { + for (syncable::ModelTypePayloadMap::const_iterator it = type_payloads.begin(); + it != type_payloads.end(); ++it) { + NotificationInfo* info = ¬ification_info_map_[it->first]; + info->total_count++; + info->payload = it->second; + } +} + +void SyncManager::SyncInternal::OnNotificationsEnabled() { + DVLOG(1) << "Notifications enabled"; + allstatus_.SetNotificationsEnabled(true); if (scheduler()) { - scheduler()->set_notifications_enabled(notifications_enabled); + scheduler()->set_notifications_enabled(true); } + // TODO(akalin): Separate onNotificationStateChange into + // enabled/disabled events. if (js_event_handler_.IsInitialized()) { DictionaryValue details; - details.Set("enabled", Value::CreateBooleanValue(notifications_enabled)); + details.Set("enabled", Value::CreateBooleanValue(true)); js_event_handler_.Call(FROM_HERE, &JsEventHandler::HandleJsEvent, "onNotificationStateChange", @@ -2292,14 +2303,24 @@ void SyncManager::SyncInternal::OnNotificationStateChange( } } -void SyncManager::SyncInternal::UpdateNotificationInfo( - const syncable::ModelTypePayloadMap& type_payloads) { - for (syncable::ModelTypePayloadMap::const_iterator it = type_payloads.begin(); - it != type_payloads.end(); ++it) { - NotificationInfo* info = ¬ification_info_map_[it->first]; - info->total_count++; - info->payload = it->second; +void SyncManager::SyncInternal::OnNotificationsDisabled( + sync_notifier::NotificationsDisabledReason reason) { + DVLOG(1) << "Notifications disabled with reason " + << sync_notifier::NotificationsDisabledReasonToString(reason); + allstatus_.SetNotificationsEnabled(false); + if (scheduler()) { + scheduler()->set_notifications_enabled(false); + } + if (js_event_handler_.IsInitialized()) { + DictionaryValue details; + details.Set("enabled", Value::CreateBooleanValue(false)); + js_event_handler_.Call(FROM_HERE, + &JsEventHandler::HandleJsEvent, + "onNotificationStateChange", + JsEventDetails(&details)); } + // TODO(akalin): Treat a CREDENTIALS_REJECTED state as an auth + // error. } void SyncManager::SyncInternal::OnIncomingNotification( @@ -2422,10 +2443,15 @@ bool SyncManager::HasUnsyncedItems() const { return (trans.GetWrappedTrans()->directory()->unsynced_entity_count() != 0); } -void SyncManager::TriggerOnNotificationStateChangeForTest( - bool notifications_enabled) { +void SyncManager::SimulateEnableNotificationsForTest() { + DCHECK(thread_checker_.CalledOnValidThread()); + data_->OnNotificationsEnabled(); +} + +void SyncManager::SimulateDisableNotificationsForTest(int reason) { DCHECK(thread_checker_.CalledOnValidThread()); - data_->OnNotificationStateChange(notifications_enabled); + data_->OnNotificationsDisabled( + static_cast<sync_notifier::NotificationsDisabledReason>(reason)); } void SyncManager::TriggerOnIncomingNotificationForTest( diff --git a/sync/internal_api/syncapi_unittest.cc b/sync/internal_api/syncapi_unittest.cc index 1f1079c..460ee92 100644 --- a/sync/internal_api/syncapi_unittest.cc +++ b/sync/internal_api/syncapi_unittest.cc @@ -1275,16 +1275,19 @@ TEST_F(SyncManagerTest, OnNotificationStateChange) { HandleJsEvent("onNotificationStateChange", HasDetailsAsDictionary(false_details))); - sync_manager_.TriggerOnNotificationStateChangeForTest(true); - sync_manager_.TriggerOnNotificationStateChangeForTest(false); + sync_manager_.SimulateEnableNotificationsForTest(); + sync_manager_.SimulateDisableNotificationsForTest( + sync_notifier::TRANSIENT_NOTIFICATION_ERROR); SetJsEventHandler(event_handler.AsWeakHandle()); - sync_manager_.TriggerOnNotificationStateChangeForTest(true); - sync_manager_.TriggerOnNotificationStateChangeForTest(false); + sync_manager_.SimulateEnableNotificationsForTest(); + sync_manager_.SimulateDisableNotificationsForTest( + sync_notifier::TRANSIENT_NOTIFICATION_ERROR); SetJsEventHandler(WeakHandle<JsEventHandler>()); - sync_manager_.TriggerOnNotificationStateChangeForTest(true); - sync_manager_.TriggerOnNotificationStateChangeForTest(false); + sync_manager_.SimulateEnableNotificationsForTest(); + sync_manager_.SimulateDisableNotificationsForTest( + sync_notifier::TRANSIENT_NOTIFICATION_ERROR); // Should trigger the replies. PumpLoop(); diff --git a/sync/notifier/chrome_invalidation_client.cc b/sync/notifier/chrome_invalidation_client.cc index 278076f..030d7e5 100644 --- a/sync/notifier/chrome_invalidation_client.cc +++ b/sync/notifier/chrome_invalidation_client.cc @@ -31,15 +31,19 @@ ChromeInvalidationClient::Listener::~Listener() {} ChromeInvalidationClient::ChromeInvalidationClient( scoped_ptr<notifier::PushClient> push_client) - : chrome_system_resources_(push_client.Pass(), + : push_client_(push_client.get()), + chrome_system_resources_(push_client.Pass(), ALLOW_THIS_IN_INITIALIZER_LIST(this)), listener_(NULL), - ticl_ready_(false) { + ticl_state_(DEFAULT_NOTIFICATION_ERROR), + push_client_state_(DEFAULT_NOTIFICATION_ERROR) { DCHECK(CalledOnValidThread()); + push_client_->AddObserver(this); } ChromeInvalidationClient::~ChromeInvalidationClient() { DCHECK(CalledOnValidThread()); + push_client_->RemoveObserver(this); Stop(); DCHECK(!listener_); } @@ -98,27 +102,10 @@ void ChromeInvalidationClient::UpdateCredentials( chrome_system_resources_.network()->UpdateCredentials(email, token); } -void ChromeInvalidationClient::Stop() { - DCHECK(CalledOnValidThread()); - if (!invalidation_client_.get()) { - return; - } - - registration_manager_.reset(); - chrome_system_resources_.Stop(); - invalidation_client_->Stop(); - - invalidation_client_.reset(); - listener_ = NULL; - - invalidation_state_tracker_.Reset(); - max_invalidation_versions_.clear(); -} - void ChromeInvalidationClient::RegisterTypes(syncable::ModelTypeSet types) { DCHECK(CalledOnValidThread()); registered_types_ = types; - if (ticl_ready_ && registration_manager_.get()) { + if (GetState() == NO_NOTIFICATION_ERROR && registration_manager_.get()) { registration_manager_->SetRegisteredTypes(registered_types_); } // TODO(akalin): Clear invalidation versions for unregistered types. @@ -126,8 +113,8 @@ void ChromeInvalidationClient::RegisterTypes(syncable::ModelTypeSet types) { void ChromeInvalidationClient::Ready( invalidation::InvalidationClient* client) { - ticl_ready_ = true; - listener_->OnSessionStatusChanged(true); + ticl_state_ = NO_NOTIFICATION_ERROR; + EmitStateChange(); registration_manager_->SetRegisteredTypes(registered_types_); } @@ -286,9 +273,15 @@ void ChromeInvalidationClient::ReissueRegistrations( void ChromeInvalidationClient::InformError( invalidation::InvalidationClient* client, const invalidation::ErrorInfo& error_info) { - listener_->OnSessionStatusChanged(false); - LOG(ERROR) << "Invalidation client encountered an error"; - // TODO(ghc): handle the error. + LOG(ERROR) << "Ticl error " << error_info.error_reason() << ": " + << error_info.error_message() + << " (transient = " << error_info.is_transient() << ")"; + if (error_info.error_reason() == invalidation::ErrorReason::AUTH_FAILURE) { + ticl_state_ = NOTIFICATION_CREDENTIALS_REJECTED; + } else { + ticl_state_ = TRANSIENT_NOTIFICATION_ERROR; + } + EmitStateChange(); } void ChromeInvalidationClient::WriteState(const std::string& state) { @@ -298,4 +291,69 @@ void ChromeInvalidationClient::WriteState(const std::string& state) { FROM_HERE, &InvalidationStateTracker::SetInvalidationState, state); } +void ChromeInvalidationClient::Stop() { + DCHECK(CalledOnValidThread()); + if (!invalidation_client_.get()) { + return; + } + + registration_manager_.reset(); + chrome_system_resources_.Stop(); + invalidation_client_->Stop(); + + invalidation_client_.reset(); + listener_ = NULL; + + invalidation_state_tracker_.Reset(); + max_invalidation_versions_.clear(); + ticl_state_ = DEFAULT_NOTIFICATION_ERROR; + push_client_state_ = DEFAULT_NOTIFICATION_ERROR; +} + +NotificationsDisabledReason ChromeInvalidationClient::GetState() const { + DCHECK(CalledOnValidThread()); + if (ticl_state_ == NOTIFICATION_CREDENTIALS_REJECTED || + push_client_state_ == NOTIFICATION_CREDENTIALS_REJECTED) { + // If either the ticl or the push client rejected our credentials, + // return NOTIFICATION_CREDENTIALS_REJECTED. + return NOTIFICATION_CREDENTIALS_REJECTED; + } + if (ticl_state_ == NO_NOTIFICATION_ERROR && + push_client_state_ == NO_NOTIFICATION_ERROR) { + // If the ticl is ready and the push client notifications are + // enabled, return NO_NOTIFICATION_ERROR. + return NO_NOTIFICATION_ERROR; + } + // Otherwise, we have a transient error. + return TRANSIENT_NOTIFICATION_ERROR; +} + +void ChromeInvalidationClient::EmitStateChange() { + DCHECK(CalledOnValidThread()); + if (GetState() == NO_NOTIFICATION_ERROR) { + listener_->OnNotificationsEnabled(); + } else { + listener_->OnNotificationsDisabled(GetState()); + } +} + +void ChromeInvalidationClient::OnNotificationsEnabled() { + DCHECK(CalledOnValidThread()); + push_client_state_ = NO_NOTIFICATION_ERROR; + EmitStateChange(); +} + +void ChromeInvalidationClient::OnNotificationsDisabled( + notifier::NotificationsDisabledReason reason) { + DCHECK(CalledOnValidThread()); + push_client_state_ = FromNotifierReason(reason); + EmitStateChange(); +} + +void ChromeInvalidationClient::OnIncomingNotification( + const notifier::Notification& notification) { + DCHECK(CalledOnValidThread()); + // Do nothing, since this is already handled by |invalidation_client_|. +} + } // namespace sync_notifier diff --git a/sync/notifier/chrome_invalidation_client.h b/sync/notifier/chrome_invalidation_client.h index fe25dc3..c423c8d 100644 --- a/sync/notifier/chrome_invalidation_client.h +++ b/sync/notifier/chrome_invalidation_client.h @@ -17,11 +17,13 @@ #include "base/memory/weak_ptr.h" #include "base/threading/non_thread_safe.h" #include "google/cacheinvalidation/include/invalidation-listener.h" +#include "jingle/notifier/listener/push_client_observer.h" #include "sync/internal_api/public/syncable/model_type.h" #include "sync/internal_api/public/syncable/model_type_payload_map.h" #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/notifications_disabled_reason.h" #include "sync/notifier/state_writer.h" namespace buzz { @@ -43,6 +45,7 @@ class RegistrationManager; class ChromeInvalidationClient : public InvalidationListener, public StateWriter, + public notifier::PushClientObserver, public base::NonThreadSafe { public: class Listener { @@ -52,7 +55,10 @@ class ChromeInvalidationClient virtual void OnInvalidate( const syncable::ModelTypePayloadMap& type_payloads) = 0; - virtual void OnSessionStatusChanged(bool has_session) = 0; + virtual void OnNotificationsEnabled() = 0; + + virtual void OnNotificationsDisabled( + NotificationsDisabledReason reason) = 0; }; explicit ChromeInvalidationClient( @@ -77,8 +83,6 @@ class ChromeInvalidationClient // notifications for. May be called at any time. void RegisterTypes(syncable::ModelTypeSet types); - virtual void WriteState(const std::string& state) OVERRIDE; - // invalidation::InvalidationListener implementation. virtual void Ready( invalidation::InvalidationClient* client) OVERRIDE; @@ -110,14 +114,30 @@ class ChromeInvalidationClient invalidation::InvalidationClient* client, const invalidation::ErrorInfo& error_info) OVERRIDE; + // StateWriter implementation. + virtual void WriteState(const std::string& state) OVERRIDE; + + // notifier::PushClientObserver implementation. + virtual void OnNotificationsEnabled() OVERRIDE; + virtual void OnNotificationsDisabled( + notifier::NotificationsDisabledReason reason) OVERRIDE; + virtual void OnIncomingNotification( + const notifier::Notification& notification) OVERRIDE; + private: friend class ChromeInvalidationClientTest; void Stop(); + NotificationsDisabledReason GetState() const; + + void EmitStateChange(); + void EmitInvalidation( syncable::ModelTypeSet types, const std::string& payload); + // Owned by |chrome_system_resources_|. + notifier::PushClient* const push_client_; ChromeSystemResources chrome_system_resources_; InvalidationVersionMap max_invalidation_versions_; browser_sync::WeakHandle<InvalidationStateTracker> @@ -127,7 +147,11 @@ class ChromeInvalidationClient scoped_ptr<RegistrationManager> registration_manager_; // Stored to pass to |registration_manager_| on start. syncable::ModelTypeSet registered_types_; - bool ticl_ready_; + + // The states of the ticl and the push client (with + // NO_NOTIFICATION_ERROR meaning notifications are enabled). + NotificationsDisabledReason ticl_state_; + NotificationsDisabledReason push_client_state_; DISALLOW_COPY_AND_ASSIGN(ChromeInvalidationClient); }; diff --git a/sync/notifier/chrome_invalidation_client_unittest.cc b/sync/notifier/chrome_invalidation_client_unittest.cc index f1470ac..7fa94ff 100644 --- a/sync/notifier/chrome_invalidation_client_unittest.cc +++ b/sync/notifier/chrome_invalidation_client_unittest.cc @@ -20,6 +20,7 @@ namespace sync_notifier { using ::testing::_; +using ::testing::InSequence; using ::testing::Return; using ::testing::StrictMock; @@ -44,7 +45,8 @@ class MockInvalidationClient : public invalidation::InvalidationClient { class MockListener : public ChromeInvalidationClient::Listener { public: MOCK_METHOD1(OnInvalidate, void(const syncable::ModelTypePayloadMap&)); - MOCK_METHOD1(OnSessionStatusChanged, void(bool)); + MOCK_METHOD0(OnNotificationsEnabled, void()); + MOCK_METHOD1(OnNotificationsDisabled, void(NotificationsDisabledReason)); }; } // namespace @@ -52,9 +54,8 @@ class MockListener : public ChromeInvalidationClient::Listener { class ChromeInvalidationClientTest : public testing::Test { protected: ChromeInvalidationClientTest() - : client_( - scoped_ptr<notifier::PushClient>( - new notifier::FakePushClient())) {} + : fake_push_client_(new notifier::FakePushClient()), + client_(scoped_ptr<notifier::PushClient>(fake_push_client_)) {} virtual void SetUp() { client_.Start(kClientId, kClientInfo, kState, @@ -116,6 +117,7 @@ class ChromeInvalidationClientTest : public testing::Test { StrictMock<MockInvalidationStateTracker> mock_invalidation_state_tracker_; StrictMock<MockInvalidationClient> mock_invalidation_client_; + notifier::FakePushClient* const fake_push_client_; ChromeInvalidationClient client_; }; @@ -159,12 +161,6 @@ TEST_F(ChromeInvalidationClientTest, InvalidateWithPayload) { FireInvalidate("PREFERENCE", 1, "payload"); } -TEST_F(ChromeInvalidationClientTest, WriteState) { - EXPECT_CALL(mock_invalidation_state_tracker_, - SetInvalidationState(kNewState)); - client_.WriteState(kNewState); -} - TEST_F(ChromeInvalidationClientTest, InvalidateVersion) { using ::testing::Mock; @@ -266,6 +262,74 @@ TEST_F(ChromeInvalidationClientTest, RegisterTypes) { FireInvalidateAll(); } -// TODO(akalin): Flesh out unit tests. +TEST_F(ChromeInvalidationClientTest, WriteState) { + EXPECT_CALL(mock_invalidation_state_tracker_, + SetInvalidationState(kNewState)); + client_.WriteState(kNewState); +} + +TEST_F(ChromeInvalidationClientTest, StateChangesNotReady) { + InSequence dummy; + EXPECT_CALL(mock_listener_, + OnNotificationsDisabled(TRANSIENT_NOTIFICATION_ERROR)); + EXPECT_CALL(mock_listener_, + OnNotificationsDisabled(NOTIFICATION_CREDENTIALS_REJECTED)); + EXPECT_CALL(mock_listener_, + OnNotificationsDisabled(TRANSIENT_NOTIFICATION_ERROR)); + + fake_push_client_->DisableNotifications( + notifier::TRANSIENT_NOTIFICATION_ERROR); + fake_push_client_->DisableNotifications( + notifier::NOTIFICATION_CREDENTIALS_REJECTED); + fake_push_client_->EnableNotifications(); +} + +TEST_F(ChromeInvalidationClientTest, StateChangesReady) { + InSequence dummy; + EXPECT_CALL(mock_listener_, + OnNotificationsDisabled(TRANSIENT_NOTIFICATION_ERROR)); + EXPECT_CALL(mock_listener_, OnNotificationsEnabled()); + EXPECT_CALL(mock_listener_, + OnNotificationsDisabled(TRANSIENT_NOTIFICATION_ERROR)); + EXPECT_CALL(mock_listener_, + OnNotificationsDisabled(NOTIFICATION_CREDENTIALS_REJECTED)); + EXPECT_CALL(mock_listener_, OnNotificationsEnabled()); + + fake_push_client_->EnableNotifications(); + client_.Ready(NULL); + fake_push_client_->DisableNotifications( + notifier::TRANSIENT_NOTIFICATION_ERROR); + fake_push_client_->DisableNotifications( + notifier::NOTIFICATION_CREDENTIALS_REJECTED); + fake_push_client_->EnableNotifications(); +} + +TEST_F(ChromeInvalidationClientTest, StateChangesAuthError) { + InSequence dummy; + EXPECT_CALL(mock_listener_, + OnNotificationsDisabled(TRANSIENT_NOTIFICATION_ERROR)); + EXPECT_CALL(mock_listener_, OnNotificationsEnabled()); + EXPECT_CALL(mock_listener_, + OnNotificationsDisabled(NOTIFICATION_CREDENTIALS_REJECTED)) + .Times(4); + EXPECT_CALL(mock_listener_, OnNotificationsEnabled()); + + fake_push_client_->EnableNotifications(); + client_.Ready(NULL); + + client_.InformError( + NULL, + invalidation::ErrorInfo( + invalidation::ErrorReason::AUTH_FAILURE, + false /* is_transient */, + "auth error", + invalidation::ErrorContext())); + fake_push_client_->DisableNotifications( + notifier::TRANSIENT_NOTIFICATION_ERROR); + fake_push_client_->DisableNotifications( + notifier::NOTIFICATION_CREDENTIALS_REJECTED); + fake_push_client_->EnableNotifications(); + client_.Ready(NULL); +} } // namespace sync_notifier diff --git a/sync/notifier/invalidation_notifier.cc b/sync/notifier/invalidation_notifier.cc index 485e969..9925041 100644 --- a/sync/notifier/invalidation_notifier.cc +++ b/sync/notifier/invalidation_notifier.cc @@ -102,14 +102,23 @@ void InvalidationNotifier::SendNotification( void InvalidationNotifier::OnInvalidate( const syncable::ModelTypePayloadMap& type_payloads) { DCHECK(CalledOnValidThread()); + FOR_EACH_OBSERVER( + SyncNotifierObserver, observers_, + OnIncomingNotification(type_payloads, + sync_notifier::REMOTE_NOTIFICATION)); +} + +void InvalidationNotifier::OnNotificationsEnabled() { + DCHECK(CalledOnValidThread()); FOR_EACH_OBSERVER(SyncNotifierObserver, observers_, - OnIncomingNotification(type_payloads, - sync_notifier::REMOTE_NOTIFICATION)); + OnNotificationsEnabled()); } -void InvalidationNotifier::OnSessionStatusChanged(bool has_session) { +void InvalidationNotifier::OnNotificationsDisabled( + NotificationsDisabledReason reason) { + DCHECK(CalledOnValidThread()); FOR_EACH_OBSERVER(SyncNotifierObserver, observers_, - OnNotificationStateChange(has_session)); + OnNotificationsDisabled(reason)); } } // namespace sync_notifier diff --git a/sync/notifier/invalidation_notifier.h b/sync/notifier/invalidation_notifier.h index 4ac715e..5441094 100644 --- a/sync/notifier/invalidation_notifier.h +++ b/sync/notifier/invalidation_notifier.h @@ -64,7 +64,9 @@ class InvalidationNotifier // ChromeInvalidationClient::Listener implementation. virtual void OnInvalidate( const syncable::ModelTypePayloadMap& type_payloads) OVERRIDE; - virtual void OnSessionStatusChanged(bool has_session) OVERRIDE; + virtual void OnNotificationsEnabled() OVERRIDE; + virtual void OnNotificationsDisabled( + NotificationsDisabledReason reason) OVERRIDE; private: // We start off in the STOPPED state. When we get our initial diff --git a/sync/notifier/invalidation_notifier_unittest.cc b/sync/notifier/invalidation_notifier_unittest.cc index 16b70c1..9bd1840 100644 --- a/sync/notifier/invalidation_notifier_unittest.cc +++ b/sync/notifier/invalidation_notifier_unittest.cc @@ -80,11 +80,14 @@ TEST_F(InvalidationNotifierTest, Basic) { type_payloads[syncable::BOOKMARKS] = ""; type_payloads[syncable::AUTOFILL] = ""; - EXPECT_CALL(mock_observer_, OnNotificationStateChange(true)); + EXPECT_CALL(mock_observer_, OnNotificationsEnabled()); EXPECT_CALL(mock_observer_, OnIncomingNotification(type_payloads, REMOTE_NOTIFICATION)); - EXPECT_CALL(mock_observer_, OnNotificationStateChange(false)); + EXPECT_CALL(mock_observer_, + OnNotificationsDisabled(TRANSIENT_NOTIFICATION_ERROR)); + EXPECT_CALL(mock_observer_, + OnNotificationsDisabled(NOTIFICATION_CREDENTIALS_REJECTED)); // Note no expectation on mock_tracker_, as we initialized with // non-empty initial_invalidation_state above. @@ -94,11 +97,14 @@ TEST_F(InvalidationNotifierTest, Basic) { invalidation_notifier_->SetUniqueId("fake_id"); invalidation_notifier_->UpdateCredentials("foo@bar.com", "fake_token"); - invalidation_notifier_->OnSessionStatusChanged(true); + invalidation_notifier_->OnNotificationsEnabled(); invalidation_notifier_->OnInvalidate(type_payloads); - invalidation_notifier_->OnSessionStatusChanged(false); + invalidation_notifier_->OnNotificationsDisabled( + TRANSIENT_NOTIFICATION_ERROR); + invalidation_notifier_->OnNotificationsDisabled( + NOTIFICATION_CREDENTIALS_REJECTED); } TEST_F(InvalidationNotifierTest, MigrateState) { diff --git a/sync/notifier/mock_sync_notifier_observer.h b/sync/notifier/mock_sync_notifier_observer.h index 426f065..95a5f06 100644 --- a/sync/notifier/mock_sync_notifier_observer.h +++ b/sync/notifier/mock_sync_notifier_observer.h @@ -18,10 +18,11 @@ class MockSyncNotifierObserver : public SyncNotifierObserver { MockSyncNotifierObserver(); virtual ~MockSyncNotifierObserver(); + MOCK_METHOD0(OnNotificationsEnabled, void()); + MOCK_METHOD1(OnNotificationsDisabled, void(NotificationsDisabledReason)); MOCK_METHOD2(OnIncomingNotification, void(const syncable::ModelTypePayloadMap&, IncomingNotificationSource)); - MOCK_METHOD1(OnNotificationStateChange, void(bool)); }; } // namespace sync_notifier diff --git a/sync/notifier/non_blocking_invalidation_notifier.cc b/sync/notifier/non_blocking_invalidation_notifier.cc index f9a7bd1..a92bd66 100644 --- a/sync/notifier/non_blocking_invalidation_notifier.cc +++ b/sync/notifier/non_blocking_invalidation_notifier.cc @@ -42,10 +42,12 @@ class NonBlockingInvalidationNotifier::Core // SyncNotifierObserver implementation (all called on I/O thread by // InvalidationNotifier). + virtual void OnNotificationsEnabled() OVERRIDE; + virtual void OnNotificationsDisabled( + NotificationsDisabledReason reason) OVERRIDE; virtual void OnIncomingNotification( const syncable::ModelTypePayloadMap& type_payloads, - IncomingNotificationSource source); - virtual void OnNotificationStateChange(bool notifications_enabled); + IncomingNotificationSource source) OVERRIDE; private: friend class @@ -126,22 +128,27 @@ void NonBlockingInvalidationNotifier::Core::UpdateEnabledTypes( invalidation_notifier_->UpdateEnabledTypes(enabled_types); } -void NonBlockingInvalidationNotifier::Core::OnIncomingNotification( - const syncable::ModelTypePayloadMap& type_payloads, - IncomingNotificationSource source) { +void NonBlockingInvalidationNotifier::Core::OnNotificationsEnabled() { DCHECK(network_task_runner_->BelongsToCurrentThread()); delegate_observer_.Call(FROM_HERE, - &SyncNotifierObserver::OnIncomingNotification, - type_payloads, - source); + &SyncNotifierObserver::OnNotificationsEnabled); } -void NonBlockingInvalidationNotifier::Core::OnNotificationStateChange( - bool notifications_enabled) { +void NonBlockingInvalidationNotifier::Core::OnNotificationsDisabled( + NotificationsDisabledReason reason) { + DCHECK(network_task_runner_->BelongsToCurrentThread()); + delegate_observer_.Call( + FROM_HERE, &SyncNotifierObserver::OnNotificationsDisabled, reason); +} + +void NonBlockingInvalidationNotifier::Core::OnIncomingNotification( + const syncable::ModelTypePayloadMap& type_payloads, + IncomingNotificationSource source) { DCHECK(network_task_runner_->BelongsToCurrentThread()); delegate_observer_.Call(FROM_HERE, - &SyncNotifierObserver::OnNotificationStateChange, - notifications_enabled); + &SyncNotifierObserver::OnIncomingNotification, + type_payloads, + source); } NonBlockingInvalidationNotifier::NonBlockingInvalidationNotifier( @@ -247,19 +254,25 @@ void NonBlockingInvalidationNotifier::SendNotification( // need to forward on the call. } -void NonBlockingInvalidationNotifier::OnIncomingNotification( - const syncable::ModelTypePayloadMap& type_payloads, - IncomingNotificationSource source) { +void NonBlockingInvalidationNotifier::OnNotificationsEnabled() { DCHECK(parent_task_runner_->BelongsToCurrentThread()); FOR_EACH_OBSERVER(SyncNotifierObserver, observers_, - OnIncomingNotification(type_payloads, source)); + OnNotificationsEnabled()); +} + +void NonBlockingInvalidationNotifier::OnNotificationsDisabled( + NotificationsDisabledReason reason) { + DCHECK(parent_task_runner_->BelongsToCurrentThread()); + FOR_EACH_OBSERVER(SyncNotifierObserver, observers_, + OnNotificationsDisabled(reason)); } -void NonBlockingInvalidationNotifier::OnNotificationStateChange( - bool notifications_enabled) { +void NonBlockingInvalidationNotifier::OnIncomingNotification( + const syncable::ModelTypePayloadMap& type_payloads, + IncomingNotificationSource source) { DCHECK(parent_task_runner_->BelongsToCurrentThread()); FOR_EACH_OBSERVER(SyncNotifierObserver, observers_, - OnNotificationStateChange(notifications_enabled)); + OnIncomingNotification(type_payloads, source)); } } // namespace sync_notifier diff --git a/sync/notifier/non_blocking_invalidation_notifier.h b/sync/notifier/non_blocking_invalidation_notifier.h index dfcf63f..ff59c43 100644 --- a/sync/notifier/non_blocking_invalidation_notifier.h +++ b/sync/notifier/non_blocking_invalidation_notifier.h @@ -57,10 +57,12 @@ class NonBlockingInvalidationNotifier syncable::ModelTypeSet changed_types) OVERRIDE; // SyncNotifierObserver implementation. + virtual void OnNotificationsEnabled() OVERRIDE; + virtual void OnNotificationsDisabled( + NotificationsDisabledReason reason) OVERRIDE; virtual void OnIncomingNotification( const syncable::ModelTypePayloadMap& type_payloads, IncomingNotificationSource source) OVERRIDE; - virtual void OnNotificationStateChange(bool notifications_enabled) OVERRIDE; private: class Core; diff --git a/sync/notifier/non_blocking_invalidation_notifier_unittest.cc b/sync/notifier/non_blocking_invalidation_notifier_unittest.cc index 42cc5d1..831b443 100644 --- a/sync/notifier/non_blocking_invalidation_notifier_unittest.cc +++ b/sync/notifier/non_blocking_invalidation_notifier_unittest.cc @@ -73,20 +73,26 @@ TEST_F(NonBlockingInvalidationNotifierTest, Basic) { type_payloads[syncable::BOOKMARKS] = ""; type_payloads[syncable::AUTOFILL] = ""; - EXPECT_CALL(mock_observer_, OnNotificationStateChange(true)); + EXPECT_CALL(mock_observer_, OnNotificationsEnabled()); EXPECT_CALL(mock_observer_, OnIncomingNotification(type_payloads, REMOTE_NOTIFICATION)); - EXPECT_CALL(mock_observer_, OnNotificationStateChange(false)); + EXPECT_CALL(mock_observer_, + OnNotificationsDisabled(TRANSIENT_NOTIFICATION_ERROR)); + EXPECT_CALL(mock_observer_, + OnNotificationsDisabled(NOTIFICATION_CREDENTIALS_REJECTED)); invalidation_notifier_->SetStateDeprecated("fake_state"); invalidation_notifier_->SetUniqueId("fake_id"); invalidation_notifier_->UpdateCredentials("foo@bar.com", "fake_token"); - invalidation_notifier_->OnNotificationStateChange(true); + invalidation_notifier_->OnNotificationsEnabled(); invalidation_notifier_->OnIncomingNotification(type_payloads, REMOTE_NOTIFICATION); - invalidation_notifier_->OnNotificationStateChange(false); + invalidation_notifier_->OnNotificationsDisabled( + TRANSIENT_NOTIFICATION_ERROR); + invalidation_notifier_->OnNotificationsDisabled( + NOTIFICATION_CREDENTIALS_REJECTED); ui_loop_.RunAllPending(); } diff --git a/sync/notifier/notifications_disabled_reason.cc b/sync/notifier/notifications_disabled_reason.cc new file mode 100644 index 0000000..9503140 --- /dev/null +++ b/sync/notifier/notifications_disabled_reason.cc @@ -0,0 +1,41 @@ +// 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/notifications_disabled_reason.h" + +#include "base/logging.h" + +namespace sync_notifier { + +const char* NotificationsDisabledReasonToString( + NotificationsDisabledReason reason) { + switch (reason) { + case NO_NOTIFICATION_ERROR: + return "NO_NOTIFICATION_ERROR"; + case TRANSIENT_NOTIFICATION_ERROR: + return "TRANSIENT_NOTIFICATION_ERROR"; + case NOTIFICATION_CREDENTIALS_REJECTED: + return "NOTIFICATION_CREDENTIALS_REJECTED"; + default: + NOTREACHED(); + return "UNKNOWN"; + } +} + +NotificationsDisabledReason FromNotifierReason( + notifier::NotificationsDisabledReason reason) { + switch (reason) { + case notifier::NO_NOTIFICATION_ERROR: + return NO_NOTIFICATION_ERROR; + case notifier::TRANSIENT_NOTIFICATION_ERROR: + return TRANSIENT_NOTIFICATION_ERROR; + case notifier::NOTIFICATION_CREDENTIALS_REJECTED: + return NOTIFICATION_CREDENTIALS_REJECTED; + default: + NOTREACHED(); + return TRANSIENT_NOTIFICATION_ERROR; + } +} + +} // sync_notifier diff --git a/sync/notifier/notifications_disabled_reason.h b/sync/notifier/notifications_disabled_reason.h new file mode 100644 index 0000000..75239cd --- /dev/null +++ b/sync/notifier/notifications_disabled_reason.h @@ -0,0 +1,33 @@ +// 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_NOTIFICATIONS_DISABLED_REASON_H_ +#define SYNC_NOTIFIER_NOTIFICATIONS_DISABLED_REASON_H_ +#pragma once + +#include "jingle/notifier/listener/push_client_observer.h" + +namespace sync_notifier { + +enum NotificationsDisabledReason { + // There is an underlying transient problem (e.g., network- or + // XMPP-related). + TRANSIENT_NOTIFICATION_ERROR, + DEFAULT_NOTIFICATION_ERROR = TRANSIENT_NOTIFICATION_ERROR, + // Our credentials have been rejected. + NOTIFICATION_CREDENTIALS_REJECTED, + // No error (useful as a default value or to avoid keeping a + // separate bool for notifications enabled/disabled). + NO_NOTIFICATION_ERROR +}; + +const char* NotificationsDisabledReasonToString( + NotificationsDisabledReason reason); + +NotificationsDisabledReason FromNotifierReason( + notifier::NotificationsDisabledReason reason); + +} // namespace sync_notifier + +#endif // SYNC_NOTIFIER_NOTIFICATIONS_DISABLED_REASON_H_ diff --git a/sync/notifier/p2p_notifier.cc b/sync/notifier/p2p_notifier.cc index 2eae246..211cb2a 100644 --- a/sync/notifier/p2p_notifier.cc +++ b/sync/notifier/p2p_notifier.cc @@ -212,19 +212,28 @@ void P2PNotifier::SendNotification( SendNotificationData(notification_data); } -void P2PNotifier::OnNotificationStateChange(bool notifications_enabled) { +void P2PNotifier::OnNotificationsEnabled() { DCHECK(non_thread_safe_.CalledOnValidThread()); - bool disabled_to_enabled = notifications_enabled && !notifications_enabled_; - notifications_enabled_ = notifications_enabled; - FOR_EACH_OBSERVER(SyncNotifierObserver, observer_list_, - OnNotificationStateChange(notifications_enabled_)); - if (disabled_to_enabled) { + bool just_turned_on = (notifications_enabled_ == false); + notifications_enabled_ = true; + FOR_EACH_OBSERVER( + SyncNotifierObserver, observer_list_, + OnNotificationsEnabled()); + if (just_turned_on) { const P2PNotificationData notification_data( unique_id_, NOTIFY_SELF, enabled_types_); SendNotificationData(notification_data); } } +void P2PNotifier::OnNotificationsDisabled( + notifier::NotificationsDisabledReason reason) { + DCHECK(non_thread_safe_.CalledOnValidThread()); + FOR_EACH_OBSERVER( + SyncNotifierObserver, observer_list_, + OnNotificationsDisabled(FromNotifierReason(reason))); +} + void P2PNotifier::OnIncomingNotification( const notifier::Notification& notification) { DCHECK(non_thread_safe_.CalledOnValidThread()); @@ -234,7 +243,7 @@ void P2PNotifier::OnIncomingNotification( return; } if (!notifications_enabled_) { - DVLOG(1) << "Notifications not enabled -- not emitting notification"; + DVLOG(1) << "Notifications not on -- not emitting notification"; return; } if (notification.channel != kSyncP2PNotificationChannel) { diff --git a/sync/notifier/p2p_notifier.h b/sync/notifier/p2p_notifier.h index 341bc8b..2243ff4 100644 --- a/sync/notifier/p2p_notifier.h +++ b/sync/notifier/p2p_notifier.h @@ -18,6 +18,7 @@ #include "base/threading/non_thread_safe.h" #include "jingle/notifier/listener/push_client_observer.h" #include "sync/internal_api/public/syncable/model_type.h" +#include "sync/notifier/notifications_disabled_reason.h" #include "sync/notifier/sync_notifier.h" namespace notifier { @@ -107,7 +108,9 @@ class P2PNotifier syncable::ModelTypeSet changed_types) OVERRIDE; // PushClientObserver implementation. - virtual void OnNotificationStateChange(bool notifications_enabled) OVERRIDE; + virtual void OnNotificationsEnabled() OVERRIDE; + virtual void OnNotificationsDisabled( + notifier::NotificationsDisabledReason reason) OVERRIDE; virtual void OnIncomingNotification( const notifier::Notification& notification) OVERRIDE; @@ -127,8 +130,6 @@ class P2PNotifier std::string unique_id_; // Whether we have called UpdateCredentials() yet. bool logged_in_; - // Whether |push_client_| has notified us that notifications are - // enabled. bool notifications_enabled_; // Which set of clients should be sent notifications. P2PNotificationTarget send_notification_target_; diff --git a/sync/notifier/p2p_notifier_unittest.cc b/sync/notifier/p2p_notifier_unittest.cc index 28ec600..d1ed20d 100644 --- a/sync/notifier/p2p_notifier_unittest.cc +++ b/sync/notifier/p2p_notifier_unittest.cc @@ -145,7 +145,7 @@ TEST_F(P2PNotifierTest, NotificationsBasic) { syncable::ModelTypeSet enabled_types( syncable::BOOKMARKS, syncable::PREFERENCES); - EXPECT_CALL(mock_observer_, OnNotificationStateChange(true)); + EXPECT_CALL(mock_observer_, OnNotificationsEnabled()); EXPECT_CALL(mock_observer_, OnIncomingNotification(MakePayloadMap(enabled_types), REMOTE_NOTIFICATION)); @@ -169,7 +169,7 @@ TEST_F(P2PNotifierTest, NotificationsBasic) { p2p_notifier_.UpdateEnabledTypes(enabled_types); ReflectSentNotifications(); - fake_push_client_->SimulateNotificationStateChange(true); + fake_push_client_->EnableNotifications(); // Sent with target NOTIFY_OTHERS so should not be propagated to // |mock_observer_|. @@ -195,7 +195,7 @@ TEST_F(P2PNotifierTest, SendNotificationData) { const syncable::ModelTypePayloadMap& changed_payload_map = MakePayloadMap(changed_types); - EXPECT_CALL(mock_observer_, OnNotificationStateChange(true)); + EXPECT_CALL(mock_observer_, OnNotificationsEnabled()); EXPECT_CALL(mock_observer_, OnIncomingNotification(MakePayloadMap(enabled_types), REMOTE_NOTIFICATION)); @@ -205,7 +205,7 @@ TEST_F(P2PNotifierTest, SendNotificationData) { p2p_notifier_.UpdateEnabledTypes(enabled_types); ReflectSentNotifications(); - fake_push_client_->SimulateNotificationStateChange(true); + fake_push_client_->EnableNotifications(); ReflectSentNotifications(); diff --git a/sync/notifier/push_client_channel.cc b/sync/notifier/push_client_channel.cc index cfd3129..4ef60bc 100644 --- a/sync/notifier/push_client_channel.cc +++ b/sync/notifier/push_client_channel.cc @@ -62,12 +62,20 @@ void PushClientChannel::SetSystemResources( // Do nothing. } -void PushClientChannel::OnNotificationStateChange( - bool notifications_enabled) { +void PushClientChannel::OnNotificationsEnabled() { for (NetworkStatusReceiverList::const_iterator it = network_status_receivers_.begin(); it != network_status_receivers_.end(); ++it) { - (*it)->Run(notifications_enabled); + (*it)->Run(true); + } +} + +void PushClientChannel::OnNotificationsDisabled( + notifier::NotificationsDisabledReason reason) { + for (NetworkStatusReceiverList::const_iterator it = + network_status_receivers_.begin(); + it != network_status_receivers_.end(); ++it) { + (*it)->Run(false); } } diff --git a/sync/notifier/push_client_channel.h b/sync/notifier/push_client_channel.h index 1721def..8ad1853 100644 --- a/sync/notifier/push_client_channel.h +++ b/sync/notifier/push_client_channel.h @@ -27,6 +27,8 @@ class PushClientChannel : public invalidation::NetworkChannel, public notifier::PushClientObserver { public: + // |push_client| is guaranteed to be destroyed only when this object + // is destroyed. explicit PushClientChannel(scoped_ptr<notifier::PushClient> push_client); virtual ~PushClientChannel(); @@ -46,7 +48,9 @@ class PushClientChannel invalidation::SystemResources* resources) OVERRIDE; // notifier::PushClient::Observer implementation. - virtual void OnNotificationStateChange(bool notifications_enabled) OVERRIDE; + virtual void OnNotificationsEnabled() OVERRIDE; + virtual void OnNotificationsDisabled( + notifier::NotificationsDisabledReason reason) OVERRIDE; virtual void OnIncomingNotification( const notifier::Notification& notification) OVERRIDE; diff --git a/sync/notifier/push_client_channel_unittest.cc b/sync/notifier/push_client_channel_unittest.cc index e179109..f63cb86 100644 --- a/sync/notifier/push_client_channel_unittest.cc +++ b/sync/notifier/push_client_channel_unittest.cc @@ -151,13 +151,19 @@ TEST_F(PushClientChannelTest, SendMessage) { expected_notification)); } -// Simulate notification state changes on the push client. It should +// Simulate push client state changes on the push client. It should // propagate to the channel. -TEST_F(PushClientChannelTest, OnNotificationStateChange) { +TEST_F(PushClientChannelTest, OnPushClientStateChange) { EXPECT_FALSE(connected_); - fake_push_client_->SimulateNotificationStateChange(true); + fake_push_client_->EnableNotifications(); EXPECT_TRUE(connected_); - fake_push_client_->SimulateNotificationStateChange(false); + fake_push_client_->DisableNotifications( + notifier::TRANSIENT_NOTIFICATION_ERROR); + EXPECT_FALSE(connected_); + fake_push_client_->EnableNotifications(); + EXPECT_TRUE(connected_); + fake_push_client_->DisableNotifications( + notifier::NOTIFICATION_CREDENTIALS_REJECTED); EXPECT_FALSE(connected_); } diff --git a/sync/notifier/sync_notifier_observer.h b/sync/notifier/sync_notifier_observer.h index 0685528..4ca43dc 100644 --- a/sync/notifier/sync_notifier_observer.h +++ b/sync/notifier/sync_notifier_observer.h @@ -6,9 +6,8 @@ #define SYNC_NOTIFIER_SYNC_NOTIFIER_OBSERVER_H_ #pragma once -#include <string> - #include "sync/internal_api/public/syncable/model_type_payload_map.h" +#include "sync/notifier/notifications_disabled_reason.h" namespace sync_notifier { @@ -21,10 +20,19 @@ enum IncomingNotificationSource { class SyncNotifierObserver { public: + // Called when notifications are enabled. + virtual void OnNotificationsEnabled() = 0; + + // Called when notifications are disabled, with the reason in + // |reason|. + virtual void OnNotificationsDisabled( + NotificationsDisabledReason reason) = 0; + + // Called when a notification is received. The per-type payloads + // are in |type_payloads| and the source is in |source|. virtual void OnIncomingNotification( const syncable::ModelTypePayloadMap& type_payloads, IncomingNotificationSource source) = 0; - virtual void OnNotificationStateChange(bool notifications_enabled) = 0; protected: virtual ~SyncNotifierObserver() {} diff --git a/sync/sync.gyp b/sync/sync.gyp index 934d318..5413055 100644 --- a/sync/sync.gyp +++ b/sync/sync.gyp @@ -219,6 +219,8 @@ '../third_party/cacheinvalidation/cacheinvalidation.gyp:cacheinvalidation', ], 'sources': [ + 'notifier/notifications_disabled_reason.h', + 'notifier/notifications_disabled_reason.cc', 'notifier/sync_notifier.h', 'notifier/sync_notifier_factory.h', 'notifier/sync_notifier_factory.cc', diff --git a/sync/tools/sync_listen_notifications.cc b/sync/tools/sync_listen_notifications.cc index 52e2efa..d160285 100644 --- a/sync/tools/sync_listen_notifications.cc +++ b/sync/tools/sync_listen_notifications.cc @@ -38,6 +38,16 @@ class NotificationPrinter : public sync_notifier::SyncNotifierObserver { NotificationPrinter() {} virtual ~NotificationPrinter() {} + virtual void OnNotificationsEnabled() OVERRIDE { + LOG(INFO) << "Notifications enabled"; + } + + virtual void OnNotificationsDisabled( + sync_notifier::NotificationsDisabledReason reason) OVERRIDE { + LOG(INFO) << "Notifications disabled with reason " + << sync_notifier::NotificationsDisabledReasonToString(reason); + } + virtual void OnIncomingNotification( const syncable::ModelTypePayloadMap& type_payloads, sync_notifier::IncomingNotificationSource source) OVERRIDE { @@ -51,11 +61,6 @@ class NotificationPrinter : public sync_notifier::SyncNotifierObserver { } } - virtual void OnNotificationStateChange( - bool notifications_enabled) OVERRIDE { - LOG(INFO) << "Notifications enabled: " << notifications_enabled; - } - private: DISALLOW_COPY_AND_ASSIGN(NotificationPrinter); }; |