// Copyright 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. // // Simple system resources class that uses the current message loop // for scheduling. Assumes the current message loop is already // running. #ifndef SYNC_NOTIFIER_SYNC_SYSTEM_RESOURCES_H_ #define SYNC_NOTIFIER_SYNC_SYSTEM_RESOURCES_H_ #include <set> #include <string> #include <vector> #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 "google/cacheinvalidation/include/system-resources.h" #include "sync/base/sync_export.h" #include "sync/notifier/invalidator_state.h" #include "sync/notifier/state_writer.h" namespace syncer { class SyncLogger : public invalidation::Logger { public: SyncLogger(); virtual ~SyncLogger(); // invalidation::Logger implementation. virtual void Log(LogLevel level, const char* file, int line, const char* format, ...) OVERRIDE; virtual void SetSystemResources( invalidation::SystemResources* resources) OVERRIDE; }; class SyncInvalidationScheduler : public invalidation::Scheduler { public: SyncInvalidationScheduler(); virtual ~SyncInvalidationScheduler(); // Start and stop the scheduler. void Start(); void Stop(); // invalidation::Scheduler implementation. virtual void Schedule(invalidation::TimeDelta delay, invalidation::Closure* task) OVERRIDE; virtual bool IsRunningOnThread() const OVERRIDE; virtual invalidation::Time GetCurrentTime() const OVERRIDE; virtual 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<invalidation::Closure*> posted_tasks_; const base::MessageLoop* created_on_loop_; bool is_started_; bool is_stopped_; base::WeakPtrFactory<SyncInvalidationScheduler> weak_factory_; }; // SyncNetworkChannel implements common tasks needed to interact with // invalidation library: // - registering message and network status callbacks // - Encoding/Decoding message to ClientGatewayMessage // - notifying observers about network channel state change // Implementation of particular network protocol should implement // SendEncodedMessage and call NotifyStateChange and DeliverIncomingMessage. class SYNC_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(); virtual ~SyncNetworkChannel(); // invalidation::NetworkChannel implementation. virtual void SendMessage(const std::string& outgoing_message) OVERRIDE; virtual void SetMessageReceiver( invalidation::MessageCallback* incoming_receiver) OVERRIDE; virtual void AddNetworkStatusReceiver( invalidation::NetworkStatusCallback* network_status_receiver) OVERRIDE; virtual void SetSystemResources( invalidation::SystemResources* resources) OVERRIDE; // Subclass should implement SendEncodedMessage to send encoded message to // Tango over network. virtual void SendEncodedMessage(const std::string& encoded_message) = 0; // Classes interested in network channel state changes should implement // SyncNetworkChannel::Observer and register here. void AddObserver(Observer* observer); void RemoveObserver(Observer* observer); const std::string& GetServiceContextForTest() const; int64 GetSchedulingHashForTest() const; static std::string EncodeMessageForTest( const std::string& message, const std::string& service_context, int64 scheduling_hash); static bool DecodeMessageForTest( const std::string& notification, std::string* message, std::string* service_context, int64* scheduling_hash); protected: // Subclass should notify about connection state through NotifyStateChange. void NotifyStateChange(InvalidatorState invalidator_state); // Subclass should call DeliverIncomingMessage for message to reach // invalidations library. void DeliverIncomingMessage(const std::string& message); private: typedef std::vector<invalidation::NetworkStatusCallback*> NetworkStatusReceiverList; static void EncodeMessage( std::string* encoded_message, const std::string& message, const std::string& service_context, int64 scheduling_hash); static bool DecodeMessage( const std::string& data, std::string* message, std::string* service_context, int64* scheduling_hash); // Callbacks into invalidation library scoped_ptr<invalidation::MessageCallback> incoming_receiver_; NetworkStatusReceiverList network_status_receivers_; // Last channel state for new network status receivers. InvalidatorState invalidator_state_; ObserverList<Observer> observers_; std::string service_context_; int64 scheduling_hash_; }; class SyncStorage : public invalidation::Storage { public: SyncStorage(StateWriter* state_writer, invalidation::Scheduler* scheduler); virtual ~SyncStorage(); void SetInitialState(const std::string& value) { cached_state_ = value; } // invalidation::Storage implementation. virtual void WriteKey(const std::string& key, const std::string& value, invalidation::WriteKeyCallback* done) OVERRIDE; virtual void ReadKey(const std::string& key, invalidation::ReadKeyCallback* done) OVERRIDE; virtual void DeleteKey(const std::string& key, invalidation::DeleteKeyCallback* done) OVERRIDE; virtual void ReadAllKeys( invalidation::ReadAllKeysCallback* key_callback) OVERRIDE; virtual 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 SYNC_EXPORT_PRIVATE SyncSystemResources : public NON_EXPORTED_BASE(invalidation::SystemResources) { public: SyncSystemResources(SyncNetworkChannel* sync_network_channel, StateWriter* state_writer); virtual ~SyncSystemResources(); // invalidation::SystemResources implementation. virtual void Start() OVERRIDE; virtual void Stop() OVERRIDE; virtual bool IsStarted() const OVERRIDE; virtual void set_platform(const std::string& platform); virtual std::string platform() const OVERRIDE; virtual SyncLogger* logger() OVERRIDE; virtual SyncStorage* storage() OVERRIDE; virtual SyncNetworkChannel* network() OVERRIDE; virtual SyncInvalidationScheduler* internal_scheduler() OVERRIDE; virtual SyncInvalidationScheduler* listener_scheduler() OVERRIDE; private: bool is_started_; std::string platform_; scoped_ptr<SyncLogger> logger_; scoped_ptr<SyncInvalidationScheduler> internal_scheduler_; scoped_ptr<SyncInvalidationScheduler> listener_scheduler_; scoped_ptr<SyncStorage> storage_; // sync_network_channel_ is owned by SyncInvalidationListener. SyncNetworkChannel* sync_network_channel_; }; } // namespace syncer #endif // SYNC_NOTIFIER_SYNC_SYSTEM_RESOURCES_H_