diff --git a/chrome/browser/sync/glue/sync_backend_host.h b/chrome/browser/sync/glue/sync_backend_host.h index 0ace4140614dff..a2861ef7f57ffe 100644 --- a/chrome/browser/sync/glue/sync_backend_host.h +++ b/chrome/browser/sync/glue/sync_backend_host.h @@ -192,6 +192,9 @@ class SyncBackendHost : public BackendDataTypeConfigurer { // Fetches the DeviceInfo tracker. virtual SyncedDeviceTracker* GetSyncedDeviceTracker() const = 0; + // Sets whether or not the frontend will be notified of network events. + virtual void SetForwardProtocolEvents(bool forward) = 0; + virtual base::MessageLoop* GetSyncLoopForTesting() = 0; DISALLOW_COPY_AND_ASSIGN(SyncBackendHost); diff --git a/chrome/browser/sync/glue/sync_backend_host_core.cc b/chrome/browser/sync/glue/sync_backend_host_core.cc index b6249c9456357d..c433b0b3df9604 100644 --- a/chrome/browser/sync/glue/sync_backend_host_core.cc +++ b/chrome/browser/sync/glue/sync_backend_host_core.cc @@ -12,6 +12,7 @@ #include "chrome/browser/sync/glue/synced_device_tracker.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/chrome_version_info.h" +#include "sync/internal_api/public/events/protocol_event.h" #include "sync/internal_api/public/http_post_provider_factory.h" #include "sync/internal_api/public/internal_components_factory.h" #include "sync/internal_api/public/sessions/sync_session_snapshot.h" @@ -316,6 +317,18 @@ void SyncBackendHostCore::OnMigrationRequested(syncer::ModelTypeSet types) { types); } +void SyncBackendHostCore::OnProtocolEvent( + const syncer::ProtocolEvent& event) { + // TODO(rlarocque): Find a way to pass event_clone as a scoped_ptr. + if (forward_protocol_events_) { + scoped_ptr event_clone(event.Clone()); + host_.Call( + FROM_HERE, + &SyncBackendHostImpl::HandleProtocolEventOnFrontendLoop, + event_clone.release()); + } +} + void SyncBackendHostCore::DoOnInvalidatorStateChange( syncer::InvalidatorState state) { DCHECK_EQ(base::MessageLoop::current(), sync_loop_); @@ -592,6 +605,11 @@ void SyncBackendHostCore::DoRetryConfiguration( retry_callback); } +void SyncBackendHostCore::SetForwardProtocolEvents(bool enabled) { + DCHECK_EQ(base::MessageLoop::current(), sync_loop_); + forward_protocol_events_ = enabled; +} + void SyncBackendHostCore::DeleteSyncDataFolder() { DCHECK_EQ(base::MessageLoop::current(), sync_loop_); if (base::DirectoryExists(sync_data_folder_path_)) { diff --git a/chrome/browser/sync/glue/sync_backend_host_core.h b/chrome/browser/sync/glue/sync_backend_host_core.h index d0b9793980d83f..d246255698d09a 100644 --- a/chrome/browser/sync/glue/sync_backend_host_core.h +++ b/chrome/browser/sync/glue/sync_backend_host_core.h @@ -102,6 +102,7 @@ class SyncBackendHostCore virtual void OnActionableError( const syncer::SyncProtocolError& sync_error) OVERRIDE; virtual void OnMigrationRequested(syncer::ModelTypeSet types) OVERRIDE; + virtual void OnProtocolEvent(const syncer::ProtocolEvent& event) OVERRIDE; // SyncEncryptionHandler::Observer implementation. virtual void OnPassphraseRequired( @@ -208,6 +209,8 @@ class SyncBackendHostCore return synced_device_tracker_.get(); } + void SetForwardProtocolEvents(bool forward); + // Delete the sync data folder to cleanup backend data. Happens the first // time sync is enabled for a user (to prevent accidentally reusing old // sync databases), as well as shutdown when you're no longer syncing. @@ -285,6 +288,9 @@ class SyncBackendHostCore // Should not be used for anything except for UMAs and logging. const bool has_sync_setup_completed_; + // Set when we've been asked to forward sync protocol events to the frontend. + bool forward_protocol_events_; + base::WeakPtrFactory weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(SyncBackendHostCore); diff --git a/chrome/browser/sync/glue/sync_backend_host_impl.cc b/chrome/browser/sync/glue/sync_backend_host_impl.cc index f5b2f6e4677bd9..de87a4939a3725 100644 --- a/chrome/browser/sync/glue/sync_backend_host_impl.cc +++ b/chrome/browser/sync/glue/sync_backend_host_impl.cc @@ -19,6 +19,7 @@ #include "content/public/browser/notification_details.h" #include "content/public/browser/notification_source.h" #include "sync/internal_api/public/base_transaction.h" +#include "sync/internal_api/public/events/protocol_event.h" #include "sync/internal_api/public/http_bridge.h" #include "sync/internal_api/public/internal_components_factory.h" #include "sync/internal_api/public/internal_components_factory_impl.h" @@ -474,6 +475,14 @@ SyncedDeviceTracker* SyncBackendHostImpl::GetSyncedDeviceTracker() const { return core_->synced_device_tracker(); } +void SyncBackendHostImpl::SetForwardProtocolEvents(bool forward) { + DCHECK(initialized()); + registrar_->sync_thread()->message_loop()->PostTask( + FROM_HERE, + base::Bind(&SyncBackendHostCore::SetForwardProtocolEvents, + core_, forward)); +} + void SyncBackendHostImpl::InitCore(scoped_ptr options) { registrar_->sync_thread()->message_loop()->PostTask(FROM_HERE, base::Bind(&SyncBackendHostCore::DoInitialize, @@ -744,6 +753,14 @@ void SyncBackendHostImpl::HandleConnectionStatusChangeOnFrontendLoop( frontend_->OnConnectionStatusChange(status); } +void SyncBackendHostImpl::HandleProtocolEventOnFrontendLoop( + syncer::ProtocolEvent* event) { + scoped_ptr scoped_event(event); + if (!frontend_) + return; + frontend_->OnProtocolEvent(*scoped_event); +} + base::MessageLoop* SyncBackendHostImpl::GetSyncLoopForTesting() { return registrar_->sync_thread()->message_loop(); } diff --git a/chrome/browser/sync/glue/sync_backend_host_impl.h b/chrome/browser/sync/glue/sync_backend_host_impl.h index b2ed9627cd9436..24e621513239c4 100644 --- a/chrome/browser/sync/glue/sync_backend_host_impl.h +++ b/chrome/browser/sync/glue/sync_backend_host_impl.h @@ -124,6 +124,7 @@ class SyncBackendHostImpl virtual void GetModelSafeRoutingInfo( syncer::ModelSafeRoutingInfo* out) const OVERRIDE; virtual SyncedDeviceTracker* GetSyncedDeviceTracker() const OVERRIDE; + virtual void SetForwardProtocolEvents(bool forward) OVERRIDE; virtual base::MessageLoop* GetSyncLoopForTesting() OVERRIDE; protected: @@ -166,6 +167,11 @@ class SyncBackendHostImpl // frontend's sync configure retry method. void HandleControlTypesDownloadRetry(); + // Forwards a ProtocolEvent to the frontend. Will not be called unless a + // call to SetForwardProtocolEvents() explicitly requested that we start + // forwarding these events. + void HandleProtocolEventOnFrontendLoop(syncer::ProtocolEvent* event); + SyncFrontend* frontend() { return frontend_; } private: diff --git a/chrome/browser/sync/glue/sync_backend_host_impl_unittest.cc b/chrome/browser/sync/glue/sync_backend_host_impl_unittest.cc index 62553d15cbb99e..add3e2c5a88dbc 100644 --- a/chrome/browser/sync/glue/sync_backend_host_impl_unittest.cc +++ b/chrome/browser/sync/glue/sync_backend_host_impl_unittest.cc @@ -82,6 +82,7 @@ class MockSyncFrontend : public SyncFrontend { void(syncer::ModelTypeSet, bool)); MOCK_METHOD0(OnEncryptionComplete, void()); MOCK_METHOD1(OnMigrationNeededForTypes, void(syncer::ModelTypeSet)); + MOCK_METHOD1(OnProtocolEvent, void(const syncer::ProtocolEvent&)); MOCK_METHOD1(OnExperimentsChanged, void(const syncer::Experiments&)); MOCK_METHOD1(OnActionableError, diff --git a/chrome/browser/sync/glue/sync_backend_host_mock.cc b/chrome/browser/sync/glue/sync_backend_host_mock.cc index 7f219351a7a753..f7629b22227d2c 100644 --- a/chrome/browser/sync/glue/sync_backend_host_mock.cc +++ b/chrome/browser/sync/glue/sync_backend_host_mock.cc @@ -110,6 +110,8 @@ base::MessageLoop* SyncBackendHostMock::GetSyncLoopForTesting() { return NULL; } +void SyncBackendHostMock::SetForwardProtocolEvents(bool enabled) {} + void SyncBackendHostMock::set_fail_initial_download(bool should_fail) { fail_initial_download_ = should_fail; } diff --git a/chrome/browser/sync/glue/sync_backend_host_mock.h b/chrome/browser/sync/glue/sync_backend_host_mock.h index fb90c2bafb09c1..b75a0879b69849 100644 --- a/chrome/browser/sync/glue/sync_backend_host_mock.h +++ b/chrome/browser/sync/glue/sync_backend_host_mock.h @@ -93,6 +93,8 @@ class SyncBackendHostMock : public SyncBackendHost { virtual SyncedDeviceTracker* GetSyncedDeviceTracker() const OVERRIDE; + virtual void SetForwardProtocolEvents(bool enabled) OVERRIDE; + virtual base::MessageLoop* GetSyncLoopForTesting() OVERRIDE; void set_fail_initial_download(bool should_fail); diff --git a/chrome/browser/sync/profile_sync_service.cc b/chrome/browser/sync/profile_sync_service.cc index 616c2bb45bcddd..57f6c2cf96fe70 100644 --- a/chrome/browser/sync/profile_sync_service.cc +++ b/chrome/browser/sync/profile_sync_service.cc @@ -562,6 +562,13 @@ void ProfileSyncService::OnSyncConfigureRetry() { NotifyObservers(); } +void ProfileSyncService::OnProtocolEvent( + const syncer::ProtocolEvent& event) { + FOR_EACH_OBSERVER(browser_sync::ProtocolEventObserver, + protocol_event_observers_, + OnProtocolEvent(event)); +} + void ProfileSyncService::OnDataTypeRequestsSyncStartup( syncer::ModelType type) { DCHECK(syncer::UserTypes().Has(type)); @@ -936,6 +943,10 @@ void ProfileSyncService::OnBackendInitialized( sync_js_controller_.AttachJsBackend(js_backend); debug_info_listener_ = debug_info_listener; + if (protocol_event_observers_.might_have_observers()) { + backend_->SetForwardProtocolEvents(true); + } + // If we have a cached passphrase use it to decrypt/encrypt data now that the // backend is initialized. We want to call this before notifying observers in // case this operation affects the "passphrase required" status. @@ -2070,6 +2081,24 @@ void ProfileSyncService::RemoveObserver( observers_.RemoveObserver(observer); } +void ProfileSyncService::AddProtocolEventObserver( + browser_sync::ProtocolEventObserver* observer) { + protocol_event_observers_.AddObserver(observer); + if (backend_) { + backend_->SetForwardProtocolEvents( + protocol_event_observers_.might_have_observers()); + } +} + +void ProfileSyncService::RemoveProtocolEventObserver( + browser_sync::ProtocolEventObserver* observer) { + protocol_event_observers_.RemoveObserver(observer); + if (backend_) { + backend_->SetForwardProtocolEvents( + protocol_event_observers_.might_have_observers()); + } +} + bool ProfileSyncService::HasObserver( ProfileSyncServiceBase::Observer* observer) const { return observers_.HasObserver(observer); diff --git a/chrome/browser/sync/profile_sync_service.h b/chrome/browser/sync/profile_sync_service.h index 0b3c439a5e8124..cdffa0b38f4a15 100644 --- a/chrome/browser/sync/profile_sync_service.h +++ b/chrome/browser/sync/profile_sync_service.h @@ -25,6 +25,7 @@ #include "chrome/browser/sync/glue/synced_device_tracker.h" #include "chrome/browser/sync/profile_sync_service_base.h" #include "chrome/browser/sync/profile_sync_service_observer.h" +#include "chrome/browser/sync/protocol_event_observer.h" #include "chrome/browser/sync/sessions2/sessions_sync_manager.h" #include "chrome/browser/sync/startup_controller.h" #include "components/keyed_service/core/keyed_service.h" @@ -273,6 +274,11 @@ class ProfileSyncService : public ProfileSyncServiceBase, virtual bool HasObserver( ProfileSyncServiceBase::Observer* observer) const OVERRIDE; + + void AddProtocolEventObserver(browser_sync::ProtocolEventObserver* observer); + void RemoveProtocolEventObserver( + browser_sync::ProtocolEventObserver* observer); + void RegisterAuthNotifications(); void UnregisterAuthNotifications(); @@ -365,6 +371,7 @@ class ProfileSyncService : public ProfileSyncServiceBase, debug_info_listener, bool success) OVERRIDE; virtual void OnSyncCycleCompleted() OVERRIDE; + virtual void OnProtocolEvent(const syncer::ProtocolEvent& event) OVERRIDE; virtual void OnSyncConfigureRetry() OVERRIDE; virtual void OnConnectionStatusChange( syncer::ConnectionStatus status) OVERRIDE; @@ -911,6 +918,7 @@ class ProfileSyncService : public ProfileSyncServiceBase, scoped_ptr data_type_manager_; ObserverList observers_; + ObserverList protocol_event_observers_; syncer::SyncJsController sync_js_controller_; diff --git a/chrome/browser/sync/protocol_event_observer.cc b/chrome/browser/sync/protocol_event_observer.cc new file mode 100644 index 00000000000000..b9079078a42748 --- /dev/null +++ b/chrome/browser/sync/protocol_event_observer.cc @@ -0,0 +1,13 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/sync/protocol_event_observer.h" + +namespace browser_sync { + +ProtocolEventObserver::ProtocolEventObserver() {} + +ProtocolEventObserver::~ProtocolEventObserver() {} + +} // namespace browser_sync diff --git a/chrome/browser/sync/protocol_event_observer.h b/chrome/browser/sync/protocol_event_observer.h new file mode 100644 index 00000000000000..3ed4095fb72990 --- /dev/null +++ b/chrome/browser/sync/protocol_event_observer.h @@ -0,0 +1,24 @@ +// Copyright 2014 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 CHROME_BROWSER_SYNC_PROTOCOL_EVENT_OBSERVER_H_ +#define CHROME_BROWSER_SYNC_PROTOCOL_EVENT_OBSERVER_H_ + +namespace syncer { +class ProtocolEvent; +} + +namespace browser_sync { + +class ProtocolEventObserver { + public: + ProtocolEventObserver(); + virtual ~ProtocolEventObserver(); + + virtual void OnProtocolEvent(const syncer::ProtocolEvent& event) = 0; +}; + +} // namespace browser_sync + +#endif // CHROME_BROWSER_SYNC_PROTOCOL_EVENT_OBSERVER_H_ diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 295efb63d64dd7..ef9bedfed104d2 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -2360,6 +2360,8 @@ 'browser/sync/profile_sync_service_model_type_selection_android.h', 'browser/sync/profile_sync_service_observer.cc', 'browser/sync/profile_sync_service_observer.h', + 'browser/sync/protocol_event_observer.cc', + 'browser/sync/protocol_event_observer.h', 'browser/sync/sessions2/notification_service_sessions_router.cc', 'browser/sync/sessions2/notification_service_sessions_router.h', 'browser/sync/sessions2/session_data_type_controller2.cc', diff --git a/components/sync_driver/sync_frontend.h b/components/sync_driver/sync_frontend.h index f7ed853d50bd3a..47d76bead8a124 100644 --- a/components/sync_driver/sync_frontend.h +++ b/components/sync_driver/sync_frontend.h @@ -15,6 +15,7 @@ namespace syncer { class DataTypeDebugInfoListener; class JsBackend; +class ProtocolEvent; } // namespace syncer namespace sync_pb { @@ -53,6 +54,14 @@ class SyncFrontend { // retried. virtual void OnSyncConfigureRetry() = 0; + // Informs the frontned of some network event. These notifications are + // disabled by default and must be enabled through an explicit request to the + // SyncBackendHost. + // + // It's disabld by default to avoid copying data across threads when no one + // is listening for it. + virtual void OnProtocolEvent(const syncer::ProtocolEvent& event) = 0; + // The status of the connection to the sync server has changed. virtual void OnConnectionStatusChange( syncer::ConnectionStatus status) = 0; diff --git a/sync/engine/DEPS b/sync/engine/DEPS index b43d31c6cd0310..097869789fd1e8 100644 --- a/sync/engine/DEPS +++ b/sync/engine/DEPS @@ -2,6 +2,7 @@ include_rules = [ "+sync/base", "+sync/internal_api/public/base", "+sync/internal_api/public/engine", + "+sync/internal_api/public/events", "+sync/internal_api/public/sessions", "+sync/internal_api/public/test", "+sync/internal_api/public/util", diff --git a/sync/engine/all_status.cc b/sync/engine/all_status.cc index 6fa98d35c538af..d73f206eae9afa 100644 --- a/sync/engine/all_status.cc +++ b/sync/engine/all_status.cc @@ -124,6 +124,8 @@ void AllStatus::OnThrottledTypesChanged(ModelTypeSet throttled_types) { void AllStatus::OnMigrationRequested(ModelTypeSet) {} +void AllStatus::OnProtocolEvent(const ProtocolEvent&) {} + SyncStatus AllStatus::status() const { base::AutoLock lock(mutex_); return status_; diff --git a/sync/engine/all_status.h b/sync/engine/all_status.h index add42e5b30053f..999f2f36449f53 100644 --- a/sync/engine/all_status.h +++ b/sync/engine/all_status.h @@ -46,6 +46,7 @@ class AllStatus : public SyncEngineEventListener { virtual void OnRetryTimeChanged(base::Time retry_time) OVERRIDE; virtual void OnThrottledTypesChanged(ModelTypeSet throttled_types) OVERRIDE; virtual void OnMigrationRequested(ModelTypeSet types) OVERRIDE; + virtual void OnProtocolEvent(const ProtocolEvent& event) OVERRIDE; SyncStatus status() const; diff --git a/sync/engine/commit.cc b/sync/engine/commit.cc index 90b97427025fff..92cf4d2aa776fd 100644 --- a/sync/engine/commit.cc +++ b/sync/engine/commit.cc @@ -10,6 +10,8 @@ #include "sync/engine/commit_util.h" #include "sync/engine/syncer.h" #include "sync/engine/syncer_proto_util.h" +#include "sync/internal_api/public/events/commit_request_event.h" +#include "sync/internal_api/public/events/commit_response_event.h" #include "sync/sessions/sync_session.h" namespace syncer { @@ -97,11 +99,26 @@ SyncerError Commit::PostAndProcessResponse( } DVLOG(1) << "Sending commit message."; + + CommitRequestEvent request_event( + base::Time::Now(), + message_.commit().entries_size(), + request_types, + message_); + session->SendProtocolEvent(request_event); + TRACE_EVENT_BEGIN0("sync", "PostCommit"); const SyncerError post_result = SyncerProtoUtil::PostClientToServerMessage( &message_, &response_, session); TRACE_EVENT_END0("sync", "PostCommit"); + // TODO(rlarocque): Use result that includes errors captured later? + CommitResponseEvent response_event( + base::Time::Now(), + post_result, + response_); + session->SendProtocolEvent(response_event); + if (post_result != SYNCER_OK) { LOG(WARNING) << "Post commit failed"; return post_result; diff --git a/sync/engine/get_updates_delegate.cc b/sync/engine/get_updates_delegate.cc index 4697485b52f9de..fe538412ea8297 100644 --- a/sync/engine/get_updates_delegate.cc +++ b/sync/engine/get_updates_delegate.cc @@ -6,6 +6,9 @@ #include "sync/engine/directory_update_handler.h" #include "sync/engine/get_updates_processor.h" +#include "sync/internal_api/public/events/configure_get_updates_request_event.h" +#include "sync/internal_api/public/events/normal_get_updates_request_event.h" +#include "sync/internal_api/public/events/poll_get_updates_request_event.h" namespace syncer { @@ -80,6 +83,13 @@ void NormalGetUpdatesDelegate::ApplyUpdates( NonPassiveApplyUpdates(status_controller, update_handler_map); } +scoped_ptr NormalGetUpdatesDelegate::GetNetworkRequestEvent( + base::Time timestamp, + const sync_pb::ClientToServerMessage& request) const { + return scoped_ptr( + new NormalGetUpdatesRequestEvent(timestamp, nudge_tracker_, request)); +} + ConfigureGetUpdatesDelegate::ConfigureGetUpdatesDelegate( sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source) : source_(source) {} @@ -97,6 +107,16 @@ void ConfigureGetUpdatesDelegate::ApplyUpdates( PassiveApplyUpdates(status_controller, update_handler_map); } +scoped_ptr ConfigureGetUpdatesDelegate::GetNetworkRequestEvent( + base::Time timestamp, + const sync_pb::ClientToServerMessage& request) const { + return scoped_ptr( + new ConfigureGetUpdatesRequestEvent( + timestamp, + ConvertConfigureSourceToOrigin(source_), + request)); +} + sync_pb::SyncEnums::GetUpdatesOrigin ConfigureGetUpdatesDelegate::ConvertConfigureSourceToOrigin( sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source) { @@ -136,4 +156,11 @@ void PollGetUpdatesDelegate::ApplyUpdates( NonPassiveApplyUpdates(status_controller, update_handler_map); } +scoped_ptr PollGetUpdatesDelegate::GetNetworkRequestEvent( + base::Time timestamp, + const sync_pb::ClientToServerMessage& request) const { + return scoped_ptr( + new PollGetUpdatesRequestEvent(timestamp, request)); +} + } // namespace syncer diff --git a/sync/engine/get_updates_delegate.h b/sync/engine/get_updates_delegate.h index 9ebc6d8fc7b46f..d897edfbcd05ab 100644 --- a/sync/engine/get_updates_delegate.h +++ b/sync/engine/get_updates_delegate.h @@ -5,6 +5,7 @@ #ifndef SYNC_ENGINE_GET_UPDATES_DELEGATE_H_ #define SYNC_ENGINE_GET_UPDATES_DELEGATE_H_ +#include "sync/internal_api/public/events/protocol_event.h" #include "sync/protocol/sync.pb.h" #include "sync/sessions/model_type_registry.h" #include "sync/sessions/nudge_tracker.h" @@ -31,6 +32,10 @@ class SYNC_EXPORT_PRIVATE GetUpdatesDelegate { virtual void ApplyUpdates( sessions::StatusController* session, UpdateHandlerMap* update_handler_map) const = 0; + + virtual scoped_ptr GetNetworkRequestEvent( + base::Time timestamp, + const sync_pb::ClientToServerMessage& request) const = 0; }; // Functionality specific to the normal GetUpdate request. @@ -48,6 +53,9 @@ class SYNC_EXPORT_PRIVATE NormalGetUpdatesDelegate : public GetUpdatesDelegate { sessions::StatusController* status, UpdateHandlerMap* update_handler_map) const OVERRIDE; + virtual scoped_ptr GetNetworkRequestEvent( + base::Time timestamp, + const sync_pb::ClientToServerMessage& request) const OVERRIDE; private: DISALLOW_COPY_AND_ASSIGN(NormalGetUpdatesDelegate); @@ -74,6 +82,9 @@ class SYNC_EXPORT_PRIVATE ConfigureGetUpdatesDelegate sessions::StatusController* status, UpdateHandlerMap* update_handler_map) const OVERRIDE; + virtual scoped_ptr GetNetworkRequestEvent( + base::Time timestamp, + const sync_pb::ClientToServerMessage& request) const OVERRIDE; private: DISALLOW_COPY_AND_ASSIGN(ConfigureGetUpdatesDelegate); @@ -98,6 +109,9 @@ class SYNC_EXPORT_PRIVATE PollGetUpdatesDelegate : public GetUpdatesDelegate { sessions::StatusController* status, UpdateHandlerMap* update_handler_map) const OVERRIDE; + virtual scoped_ptr GetNetworkRequestEvent( + base::Time timestamp, + const sync_pb::ClientToServerMessage& request) const OVERRIDE; private: DISALLOW_COPY_AND_ASSIGN(PollGetUpdatesDelegate); }; diff --git a/sync/engine/get_updates_processor.cc b/sync/engine/get_updates_processor.cc index 399c78c714e62b..a5ab59b60fd36c 100644 --- a/sync/engine/get_updates_processor.cc +++ b/sync/engine/get_updates_processor.cc @@ -10,6 +10,7 @@ #include "sync/engine/get_updates_delegate.h" #include "sync/engine/syncer_proto_util.h" #include "sync/engine/update_handler.h" +#include "sync/internal_api/public/events/get_updates_response_event.h" #include "sync/protocol/sync.pb.h" #include "sync/sessions/status_controller.h" #include "sync/sessions/sync_session.h" @@ -193,6 +194,9 @@ SyncerError GetUpdatesProcessor::ExecuteDownloadUpdates( CopyClientDebugInfo(session->context()->debug_info_getter(), debug_info); } + session->SendProtocolEvent( + *(delegate_.GetNetworkRequestEvent(base::Time::Now(), *msg))); + SyncerError result = SyncerProtoUtil::PostClientToServerMessage( msg, &update_response, @@ -202,6 +206,10 @@ SyncerError GetUpdatesProcessor::ExecuteDownloadUpdates( update_response); if (result != SYNCER_OK) { + GetUpdatesResponseEvent response_event( + base::Time::Now(), update_response, result); + session->SendProtocolEvent(response_event); + LOG(ERROR) << "PostClientToServerMessage() failed during GetUpdates"; return result; } @@ -225,9 +233,15 @@ SyncerError GetUpdatesProcessor::ExecuteDownloadUpdates( HandleGetEncryptionKeyResponse(update_response, dir)); } - return ProcessResponse(update_response.get_updates(), - request_types, - status); + SyncerError process_result = ProcessResponse(update_response.get_updates(), + request_types, + status); + + GetUpdatesResponseEvent response_event( + base::Time::Now(), update_response, process_result); + session->SendProtocolEvent(response_event); + + return process_result; } SyncerError GetUpdatesProcessor::ProcessResponse( diff --git a/sync/engine/sync_engine_event_listener.h b/sync/engine/sync_engine_event_listener.h index 35fc05e8ce956d..d5678a92a5edf3 100644 --- a/sync/engine/sync_engine_event_listener.h +++ b/sync/engine/sync_engine_event_listener.h @@ -13,6 +13,7 @@ namespace syncer { struct SyncProtocolError; struct SyncCycleEvent; +class ProtocolEvent; class SYNC_EXPORT_PRIVATE SyncEngineEventListener { public: @@ -36,6 +37,9 @@ class SYNC_EXPORT_PRIVATE SyncEngineEventListener { // This event is sent when the server requests a migration. virtual void OnMigrationRequested(ModelTypeSet migration_types) = 0; + // Emits events when sync communicates with the server. + virtual void OnProtocolEvent(const ProtocolEvent& event) = 0; + protected: virtual ~SyncEngineEventListener(); }; diff --git a/sync/engine/sync_scheduler_impl.cc b/sync/engine/sync_scheduler_impl.cc index a9c635979445b6..2240cd6a0987b7 100644 --- a/sync/engine/sync_scheduler_impl.cc +++ b/sync/engine/sync_scheduler_impl.cc @@ -744,6 +744,7 @@ void SyncSchedulerImpl::Unthrottle() { // We're no longer throttled, so clear the wait interval. wait_interval_.reset(); NotifyRetryTime(base::Time()); + NotifyThrottledTypesChanged(nudge_tracker_.GetThrottledTypes()); // We treat this as a 'canary' in the sense that it was originally scheduled // to run some time ago, failed, and we now want to retry, versus a job that @@ -815,6 +816,7 @@ void SyncSchedulerImpl::OnThrottled(const base::TimeDelta& throttle_duration) { wait_interval_.reset(new WaitInterval(WaitInterval::THROTTLED, throttle_duration)); NotifyRetryTime(base::Time::Now() + wait_interval_->length); + NotifyThrottledTypesChanged(ModelTypeSet::All()); } void SyncSchedulerImpl::OnTypesThrottled( diff --git a/sync/engine/syncer_proto_util_unittest.cc b/sync/engine/syncer_proto_util_unittest.cc index d43b350b346e61..93f9088f6a8888 100644 --- a/sync/engine/syncer_proto_util_unittest.cc +++ b/sync/engine/syncer_proto_util_unittest.cc @@ -39,13 +39,11 @@ class MockDelegate : public sessions::SyncSession::Delegate { MockDelegate() {} ~MockDelegate() {} - MOCK_METHOD0(IsSyncingCurrentlySilenced, bool()); MOCK_METHOD1(OnReceivedShortPollIntervalUpdate, void(const base::TimeDelta&)); MOCK_METHOD1(OnReceivedLongPollIntervalUpdate ,void(const base::TimeDelta&)); MOCK_METHOD1(OnReceivedSessionsCommitDelay, void(const base::TimeDelta&)); MOCK_METHOD1(OnReceivedClientInvalidationHintBufferSize, void(int)); MOCK_METHOD1(OnSyncProtocolError, void(const SyncProtocolError&)); - MOCK_METHOD1(OnSilencedUntil, void(const base::TimeTicks&)); }; // Builds a ClientToServerResponse with some data type ids, including diff --git a/sync/engine/syncer_unittest.cc b/sync/engine/syncer_unittest.cc index d0a2ab4f4262a5..7a3afe317e2207 100644 --- a/sync/engine/syncer_unittest.cc +++ b/sync/engine/syncer_unittest.cc @@ -152,6 +152,7 @@ class SyncerTest : public testing::Test, } virtual void OnReceivedGuRetryDelay(const base::TimeDelta& delay) OVERRIDE {} virtual void OnReceivedMigrationRequest(ModelTypeSet types) OVERRIDE {} + virtual void OnProtocolEvent(const ProtocolEvent& event) OVERRIDE {} virtual void OnSyncProtocolError(const SyncProtocolError& error) OVERRIDE {} void GetModelSafeRoutingInfo(ModelSafeRoutingInfo* out) { diff --git a/sync/internal_api/debug_info_event_listener.cc b/sync/internal_api/debug_info_event_listener.cc index 6319a03cacf43d..b3d55056eb77f3 100644 --- a/sync/internal_api/debug_info_event_listener.cc +++ b/sync/internal_api/debug_info_event_listener.cc @@ -118,6 +118,8 @@ void DebugInfoEventListener::OnActionableError( void DebugInfoEventListener::OnMigrationRequested(ModelTypeSet types) {} +void DebugInfoEventListener::OnProtocolEvent(const ProtocolEvent& event) {} + void DebugInfoEventListener::OnNudgeFromDatatype(ModelType datatype) { DCHECK(thread_checker_.CalledOnValidThread()); sync_pb::DebugEventInfo event_info; diff --git a/sync/internal_api/debug_info_event_listener.h b/sync/internal_api/debug_info_event_listener.h index d9a77c75a94e61..1f716825f09c35 100644 --- a/sync/internal_api/debug_info_event_listener.h +++ b/sync/internal_api/debug_info_event_listener.h @@ -51,6 +51,7 @@ class SYNC_EXPORT_PRIVATE DebugInfoEventListener virtual void OnActionableError( const SyncProtocolError& sync_error) OVERRIDE; virtual void OnMigrationRequested(ModelTypeSet types) OVERRIDE; + virtual void OnProtocolEvent(const ProtocolEvent& event) OVERRIDE; // SyncEncryptionHandler::Observer implementation. virtual void OnPassphraseRequired( diff --git a/sync/internal_api/events/commit_request_event.cc b/sync/internal_api/events/commit_request_event.cc index bed23d3c6bc386..0a1de1f56d415b 100644 --- a/sync/internal_api/events/commit_request_event.cc +++ b/sync/internal_api/events/commit_request_event.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "sync/internal_api/events/commit_request_event.h" +#include "sync/internal_api/public/events/commit_request_event.h" #include "base/format_macros.h" #include "base/strings/stringprintf.h" diff --git a/sync/internal_api/events/commit_response_event.cc b/sync/internal_api/events/commit_response_event.cc index ec51f5e9107b3c..c263e944adb3fb 100644 --- a/sync/internal_api/events/commit_response_event.cc +++ b/sync/internal_api/events/commit_response_event.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "sync/internal_api/events/commit_response_event.h" +#include "sync/internal_api/public/events/commit_response_event.h" #include "base/strings/stringprintf.h" #include "sync/protocol/proto_value_conversions.h" diff --git a/sync/internal_api/events/configure_get_updates_request_event.cc b/sync/internal_api/events/configure_get_updates_request_event.cc index 252ae0a9a3aecd..8b487b60c862e5 100644 --- a/sync/internal_api/events/configure_get_updates_request_event.cc +++ b/sync/internal_api/events/configure_get_updates_request_event.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "sync/internal_api/events/configure_get_updates_request_event.h" +#include "sync/internal_api/public/events/configure_get_updates_request_event.h" #include "base/strings/stringprintf.h" #include "sync/protocol/proto_enum_conversions.h" diff --git a/sync/internal_api/events/get_updates_response_event.cc b/sync/internal_api/events/get_updates_response_event.cc index 17c0e8e50a410a..50bc551900fb95 100644 --- a/sync/internal_api/events/get_updates_response_event.cc +++ b/sync/internal_api/events/get_updates_response_event.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "sync/internal_api/events/get_updates_response_event.h" +#include "sync/internal_api/public/events/get_updates_response_event.h" #include "base/strings/stringprintf.h" #include "sync/protocol/proto_value_conversions.h" diff --git a/sync/internal_api/events/normal_get_updates_request_event.cc b/sync/internal_api/events/normal_get_updates_request_event.cc index d6a2f884431aae..f5d6cd4112e24c 100644 --- a/sync/internal_api/events/normal_get_updates_request_event.cc +++ b/sync/internal_api/events/normal_get_updates_request_event.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "sync/internal_api/events/normal_get_updates_request_event.h" +#include "sync/internal_api/public/events/normal_get_updates_request_event.h" #include "base/strings/stringprintf.h" #include "sync/protocol/proto_value_conversions.h" diff --git a/sync/internal_api/events/poll_get_updates_request_event.cc b/sync/internal_api/events/poll_get_updates_request_event.cc index 802d4cbed1179a..c6eecb9807459f 100644 --- a/sync/internal_api/events/poll_get_updates_request_event.cc +++ b/sync/internal_api/events/poll_get_updates_request_event.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "sync/internal_api/events/poll_get_updates_request_event.h" +#include "sync/internal_api/public/events/poll_get_updates_request_event.h" #include "sync/protocol/proto_value_conversions.h" diff --git a/sync/internal_api/js_sync_manager_observer.cc b/sync/internal_api/js_sync_manager_observer.cc index 57df9d3e340b59..b5f84524ad98e7 100644 --- a/sync/internal_api/js_sync_manager_observer.cc +++ b/sync/internal_api/js_sync_manager_observer.cc @@ -60,6 +60,9 @@ void JsSyncManagerObserver::OnActionableError( JsEventDetails(&details)); } +void JsSyncManagerObserver::OnProtocolEvent( + const ProtocolEvent& event) { } + void JsSyncManagerObserver::OnMigrationRequested(ModelTypeSet types) { } void JsSyncManagerObserver::OnInitializationComplete( diff --git a/sync/internal_api/js_sync_manager_observer.h b/sync/internal_api/js_sync_manager_observer.h index a30a40bbd8a5c9..6f220054b7671b 100644 --- a/sync/internal_api/js_sync_manager_observer.h +++ b/sync/internal_api/js_sync_manager_observer.h @@ -42,6 +42,7 @@ class SYNC_EXPORT_PRIVATE JsSyncManagerObserver : public SyncManager::Observer { syncer::ModelTypeSet restored_types) OVERRIDE; virtual void OnActionableError( const SyncProtocolError& sync_protocol_error) OVERRIDE; + virtual void OnProtocolEvent(const ProtocolEvent& event) OVERRIDE; virtual void OnMigrationRequested( syncer::ModelTypeSet types) OVERRIDE; diff --git a/sync/internal_api/events/commit_request_event.h b/sync/internal_api/public/events/commit_request_event.h similarity index 100% rename from sync/internal_api/events/commit_request_event.h rename to sync/internal_api/public/events/commit_request_event.h diff --git a/sync/internal_api/events/commit_response_event.h b/sync/internal_api/public/events/commit_response_event.h similarity index 100% rename from sync/internal_api/events/commit_response_event.h rename to sync/internal_api/public/events/commit_response_event.h diff --git a/sync/internal_api/events/configure_get_updates_request_event.h b/sync/internal_api/public/events/configure_get_updates_request_event.h similarity index 100% rename from sync/internal_api/events/configure_get_updates_request_event.h rename to sync/internal_api/public/events/configure_get_updates_request_event.h diff --git a/sync/internal_api/events/get_updates_response_event.h b/sync/internal_api/public/events/get_updates_response_event.h similarity index 100% rename from sync/internal_api/events/get_updates_response_event.h rename to sync/internal_api/public/events/get_updates_response_event.h diff --git a/sync/internal_api/events/normal_get_updates_request_event.h b/sync/internal_api/public/events/normal_get_updates_request_event.h similarity index 100% rename from sync/internal_api/events/normal_get_updates_request_event.h rename to sync/internal_api/public/events/normal_get_updates_request_event.h diff --git a/sync/internal_api/events/poll_get_updates_request_event.h b/sync/internal_api/public/events/poll_get_updates_request_event.h similarity index 100% rename from sync/internal_api/events/poll_get_updates_request_event.h rename to sync/internal_api/public/events/poll_get_updates_request_event.h diff --git a/sync/internal_api/public/sync_manager.h b/sync/internal_api/public/sync_manager.h index fa2e58511f2dac..6f6d9fc0a1b517 100644 --- a/sync/internal_api/public/sync_manager.h +++ b/sync/internal_api/public/sync_manager.h @@ -20,6 +20,7 @@ #include "sync/internal_api/public/configure_reason.h" #include "sync/internal_api/public/engine/model_safe_worker.h" #include "sync/internal_api/public/engine/sync_status.h" +#include "sync/internal_api/public/events/protocol_event.h" #include "sync/internal_api/public/sync_encryption_handler.h" #include "sync/internal_api/public/util/report_unrecoverable_error_function.h" #include "sync/internal_api/public/util/unrecoverable_error_handler.h" @@ -43,6 +44,7 @@ class InternalComponentsFactory; class JsBackend; class JsEventHandler; class SyncEncryptionHandler; +class ProtocolEvent; class SyncScheduler; struct UserShare; class CancelationSignal; @@ -196,6 +198,8 @@ class SYNC_EXPORT SyncManager : public syncer::InvalidationHandler { virtual void OnMigrationRequested(ModelTypeSet types) = 0; + virtual void OnProtocolEvent(const ProtocolEvent& event) = 0; + protected: virtual ~Observer(); }; diff --git a/sync/internal_api/sync_manager_impl.cc b/sync/internal_api/sync_manager_impl.cc index 501f8873df13eb..8ecb29fd822685 100644 --- a/sync/internal_api/sync_manager_impl.cc +++ b/sync/internal_api/sync_manager_impl.cc @@ -899,7 +899,6 @@ void SyncManagerImpl::RequestNudgeForDataTypes( base::TimeDelta nudge_delay = NudgeStrategy::GetNudgeDelayTimeDelta( types.First().Get(), this); - allstatus_.IncrementNudgeCounter(NUDGE_SOURCE_LOCAL); scheduler_->ScheduleLocalNudge(nudge_delay, types, nudge_location); @@ -943,6 +942,11 @@ void SyncManagerImpl::OnMigrationRequested(ModelTypeSet types) { OnMigrationRequested(types)); } +void SyncManagerImpl::OnProtocolEvent(const ProtocolEvent& event) { + FOR_EACH_OBSERVER(SyncManager::Observer, observers_, + OnProtocolEvent(event)); +} + void SyncManagerImpl::SetJsEventHandler( const WeakHandle& event_handler) { js_sync_manager_observer_.SetJsEventHandler(event_handler); @@ -1029,11 +1033,9 @@ void SyncManagerImpl::OnIncomingInvalidation( if (invalidation_map.Empty()) { LOG(WARNING) << "Sync received invalidation without any type information."; } else { - allstatus_.IncrementNudgeCounter(NUDGE_SOURCE_NOTIFICATION); scheduler_->ScheduleInvalidationNudge( TimeDelta::FromMilliseconds(kSyncSchedulerDelayMsec), invalidation_map, FROM_HERE); - allstatus_.IncrementNotificationsReceived(); debug_info_event_listener_.OnIncomingNotification(invalidation_map); } } @@ -1045,7 +1047,6 @@ void SyncManagerImpl::RefreshTypes(ModelTypeSet types) { if (types.Empty()) { LOG(WARNING) << "Sync received refresh request with no types specified."; } else { - allstatus_.IncrementNudgeCounter(NUDGE_SOURCE_LOCAL_REFRESH); scheduler_->ScheduleLocalRefreshRequest( TimeDelta::FromMilliseconds(kSyncRefreshDelayMsec), types, FROM_HERE); diff --git a/sync/internal_api/sync_manager_impl.h b/sync/internal_api/sync_manager_impl.h index e2b3fb4f1a2f46..71890268150dad 100644 --- a/sync/internal_api/sync_manager_impl.h +++ b/sync/internal_api/sync_manager_impl.h @@ -142,6 +142,7 @@ class SYNC_EXPORT_PRIVATE SyncManagerImpl : virtual void OnRetryTimeChanged(base::Time retry_time) OVERRIDE; virtual void OnThrottledTypesChanged(ModelTypeSet throttled_types) OVERRIDE; virtual void OnMigrationRequested(ModelTypeSet types) OVERRIDE; + virtual void OnProtocolEvent(const ProtocolEvent& event) OVERRIDE; // ServerConnectionEventListener implementation. virtual void OnServerConnectionEvent( diff --git a/sync/internal_api/sync_manager_impl_unittest.cc b/sync/internal_api/sync_manager_impl_unittest.cc index 064db9e2be2491..7da7070223e922 100644 --- a/sync/internal_api/sync_manager_impl_unittest.cc +++ b/sync/internal_api/sync_manager_impl_unittest.cc @@ -29,6 +29,7 @@ #include "sync/internal_api/public/change_record.h" #include "sync/internal_api/public/engine/model_safe_worker.h" #include "sync/internal_api/public/engine/polling_constants.h" +#include "sync/internal_api/public/events/protocol_event.h" #include "sync/internal_api/public/http_post_provider_factory.h" #include "sync/internal_api/public/http_post_provider_interface.h" #include "sync/internal_api/public/read_node.h" @@ -646,10 +647,9 @@ class SyncManagerObserverMock : public SyncManager::Observer { syncer::ModelTypeSet)); // NOLINT MOCK_METHOD1(OnConnectionStatusChange, void(ConnectionStatus)); // NOLINT MOCK_METHOD1(OnUpdatedToken, void(const std::string&)); // NOLINT - MOCK_METHOD1(OnActionableError, - void(const SyncProtocolError&)); // NOLINT - MOCK_METHOD1(OnMigrationRequested, - void(syncer::ModelTypeSet)); // NOLINT + MOCK_METHOD1(OnActionableError, void(const SyncProtocolError&)); // NOLINT + MOCK_METHOD1(OnMigrationRequested, void(syncer::ModelTypeSet)); // NOLINT + MOCK_METHOD1(OnProtocolEvent, void(const ProtocolEvent&)); // NOLINT }; class SyncEncryptionHandlerObserverMock diff --git a/sync/sessions/sync_session.cc b/sync/sessions/sync_session.cc index 957cfbfd741a15..e352e70b48eef1 100644 --- a/sync/sessions/sync_session.cc +++ b/sync/sessions/sync_session.cc @@ -89,5 +89,11 @@ void SyncSession::SendEventNotification(SyncCycleEvent::EventCause cause) { OnSyncCycleEvent(event)); } +void SyncSession::SendProtocolEvent(const ProtocolEvent& event) { + FOR_EACH_OBSERVER(SyncEngineEventListener, + *(context_->listeners()), + OnProtocolEvent(event)); +} + } // namespace sessions } // namespace syncer diff --git a/sync/sessions/sync_session.h b/sync/sessions/sync_session.h index 2a96fbc475e691..d61a7920f08265 100644 --- a/sync/sessions/sync_session.h +++ b/sync/sessions/sync_session.h @@ -30,6 +30,7 @@ namespace syncer { class ModelSafeWorker; +class ProtocolEvent; namespace sessions { @@ -110,6 +111,8 @@ class SYNC_EXPORT_PRIVATE SyncSession { sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source); void SendEventNotification(SyncCycleEvent::EventCause cause); + void SendProtocolEvent(const ProtocolEvent& event); + // TODO(akalin): Split this into context() and mutable_context(). SyncSessionContext* context() const { return context_; } Delegate* delegate() const { return delegate_; } diff --git a/sync/sync_internal_api.gypi b/sync/sync_internal_api.gypi index 77416eb7ebe043..8f4644285924a8 100644 --- a/sync/sync_internal_api.gypi +++ b/sync/sync_internal_api.gypi @@ -25,17 +25,11 @@ 'internal_api/debug_info_event_listener.h', 'internal_api/delete_journal.cc', 'internal_api/events/commit_request_event.cc', - 'internal_api/events/commit_request_event.h', 'internal_api/events/commit_response_event.cc', - 'internal_api/events/commit_response_event.h', 'internal_api/events/configure_get_updates_request_event.cc', - 'internal_api/events/configure_get_updates_request_event.h', 'internal_api/events/get_updates_response_event.cc', - 'internal_api/events/get_updates_response_event.h', 'internal_api/events/normal_get_updates_request_event.cc', - 'internal_api/events/normal_get_updates_request_event.h', 'internal_api/events/poll_get_updates_request_event.cc', - 'internal_api/events/poll_get_updates_request_event.h', 'internal_api/events/protocol_event.cc', 'internal_api/http_bridge.cc', 'internal_api/http_bridge_network_resources.cc', @@ -81,6 +75,12 @@ 'internal_api/public/engine/polling_constants.h', 'internal_api/public/engine/sync_status.cc', 'internal_api/public/engine/sync_status.h', + 'internal_api/public/events/commit_request_event.h', + 'internal_api/public/events/commit_response_event.h', + 'internal_api/public/events/configure_get_updates_request_event.h', + 'internal_api/public/events/get_updates_response_event.h', + 'internal_api/public/events/normal_get_updates_request_event.h', + 'internal_api/public/events/poll_get_updates_request_event.h', 'internal_api/public/events/protocol_event.h', 'internal_api/public/http_bridge.h', 'internal_api/public/http_bridge_network_resources.h',