// 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. // // Simple system resources class that uses the current message loop // for scheduling. Assumes the current message loop is already // running. #ifndef COMPONENTS_INVALIDATION_SYNC_SYSTEM_RESOURCES_H_ #define COMPONENTS_INVALIDATION_SYNC_SYSTEM_RESOURCES_H_ #include #include #include #include "base/compiler_specific.h" #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "base/message_loop/message_loop.h" #include "base/threading/non_thread_safe.h" #include "base/values.h" #include "components/invalidation/invalidation_export.h" #include "components/invalidation/invalidator_state.h" #include "components/invalidation/state_writer.h" #include "google/cacheinvalidation/include/system-resources.h" #include "jingle/notifier/base/notifier_options.h" namespace syncer { class GCMNetworkChannelDelegate; class SyncLogger : public invalidation::Logger { public: SyncLogger(); ~SyncLogger() override; // invalidation::Logger implementation. void Log(LogLevel level, const char* file, int line, const char* format, ...) override; void SetSystemResources(invalidation::SystemResources* resources) override; }; class SyncInvalidationScheduler : public invalidation::Scheduler { public: SyncInvalidationScheduler(); ~SyncInvalidationScheduler() override; // Start and stop the scheduler. void Start(); void Stop(); // invalidation::Scheduler implementation. void Schedule(invalidation::TimeDelta delay, invalidation::Closure* task) override; bool IsRunningOnThread() const override; invalidation::Time GetCurrentTime() const override; void SetSystemResources(invalidation::SystemResources* resources) override; private: // Runs the task, deletes it, and removes it from |posted_tasks_|. void RunPostedTask(invalidation::Closure* task); // Holds all posted tasks that have not yet been run. std::set posted_tasks_; const base::MessageLoop* created_on_loop_; bool is_started_; bool is_stopped_; base::WeakPtrFactory weak_factory_; }; // SyncNetworkChannel implements common tasks needed to interact with // invalidation library: // - registering message and network status callbacks // - notifying observers about network channel state change // Implementation of particular network protocol should implement // SendMessage and call NotifyStateChange and DeliverIncomingMessage. class INVALIDATION_EXPORT_PRIVATE SyncNetworkChannel : public NON_EXPORTED_BASE(invalidation::NetworkChannel) { public: class Observer { public: // Called when network channel state changes. Possible states are: // - INVALIDATIONS_ENABLED : connection is established and working // - TRANSIENT_INVALIDATION_ERROR : no network, connection lost, etc. // - INVALIDATION_CREDENTIALS_REJECTED : Issues with auth token virtual void OnNetworkChannelStateChanged( InvalidatorState invalidator_state) = 0; }; SyncNetworkChannel(); ~SyncNetworkChannel() override; // invalidation::NetworkChannel implementation. // SyncNetworkChannel doesn't implement SendMessage. It is responsibility of // subclass to implement it. void SetMessageReceiver( invalidation::MessageCallback* incoming_receiver) override; void AddNetworkStatusReceiver( invalidation::NetworkStatusCallback* network_status_receiver) override; void SetSystemResources(invalidation::SystemResources* resources) override; // Subclass should implement UpdateCredentials to pass new token to channel // library. virtual void UpdateCredentials(const std::string& email, const std::string& token) = 0; // Return value from GetInvalidationClientType will be passed to // invalidation::CreateInvalidationClient. Subclass should return one of the // values from ipc::invalidation::ClientType enum from types.proto. virtual int GetInvalidationClientType() = 0; // Subclass should implement RequestDetailedStatus to provide debugging // information. virtual void RequestDetailedStatus( base::Callback callback) = 0; // Classes interested in network channel state changes should implement // SyncNetworkChannel::Observer and register here. void AddObserver(Observer* observer); void RemoveObserver(Observer* observer); // Helper functions that know how to construct network channels from channel // specific parameters. static scoped_ptr CreatePushClientChannel( const notifier::NotifierOptions& notifier_options); static scoped_ptr CreateGCMNetworkChannel( scoped_refptr request_context_getter, scoped_ptr delegate); // Get the count of how many valid received messages were received. int GetReceivedMessagesCount() const; protected: // Subclass should call NotifyNetworkStatusChange to notify about network // changes. This triggers cacheinvalidation to try resending failed message // ahead of schedule when client comes online or IP address changes. void NotifyNetworkStatusChange(bool online); // Subclass should notify about connection state through // NotifyChannelStateChange. If communication doesn't work and it is possible // that invalidations from server will not reach this client then channel // should call this function with TRANSIENT_INVALIDATION_ERROR. void NotifyChannelStateChange(InvalidatorState invalidator_state); // Subclass should call DeliverIncomingMessage for message to reach // invalidations library. bool DeliverIncomingMessage(const std::string& message); private: typedef std::vector NetworkStatusReceiverList; // Callbacks into invalidation library scoped_ptr incoming_receiver_; NetworkStatusReceiverList network_status_receivers_; // Last network status for new network status receivers. bool last_network_status_; int received_messages_count_; ObserverList observers_; }; class SyncStorage : public invalidation::Storage { public: SyncStorage(StateWriter* state_writer, invalidation::Scheduler* scheduler); ~SyncStorage() override; void SetInitialState(const std::string& value) { cached_state_ = value; } // invalidation::Storage implementation. void WriteKey(const std::string& key, const std::string& value, invalidation::WriteKeyCallback* done) override; void ReadKey(const std::string& key, invalidation::ReadKeyCallback* done) override; void DeleteKey(const std::string& key, invalidation::DeleteKeyCallback* done) override; void ReadAllKeys(invalidation::ReadAllKeysCallback* key_callback) override; void SetSystemResources(invalidation::SystemResources* resources) override; private: // Runs the given storage callback with SUCCESS status and deletes it. void RunAndDeleteWriteKeyCallback( invalidation::WriteKeyCallback* callback); // Runs the given callback with the given value and deletes it. void RunAndDeleteReadKeyCallback( invalidation::ReadKeyCallback* callback, const std::string& value); StateWriter* state_writer_; invalidation::Scheduler* scheduler_; std::string cached_state_; }; class INVALIDATION_EXPORT_PRIVATE SyncSystemResources : public NON_EXPORTED_BASE(invalidation::SystemResources) { public: SyncSystemResources(SyncNetworkChannel* sync_network_channel, StateWriter* state_writer); ~SyncSystemResources() override; // invalidation::SystemResources implementation. void Start() override; void Stop() override; bool IsStarted() const override; virtual void set_platform(const std::string& platform); std::string platform() const override; SyncLogger* logger() override; SyncStorage* storage() override; SyncNetworkChannel* network() override; SyncInvalidationScheduler* internal_scheduler() override; SyncInvalidationScheduler* listener_scheduler() override; private: bool is_started_; std::string platform_; scoped_ptr logger_; scoped_ptr internal_scheduler_; scoped_ptr listener_scheduler_; scoped_ptr storage_; // sync_network_channel_ is owned by SyncInvalidationListener. SyncNetworkChannel* sync_network_channel_; }; } // namespace syncer #endif // COMPONENTS_INVALIDATION_SYNC_SYSTEM_RESOURCES_H_