1// Copyright 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4//
5// Simple system resources class that uses the current message loop
6// for scheduling.  Assumes the current message loop is already
7// running.
8
9#ifndef SYNC_NOTIFIER_SYNC_SYSTEM_RESOURCES_H_
10#define SYNC_NOTIFIER_SYNC_SYSTEM_RESOURCES_H_
11
12#include <set>
13#include <string>
14#include <vector>
15
16#include "base/compiler_specific.h"
17#include "base/memory/scoped_ptr.h"
18#include "base/memory/weak_ptr.h"
19#include "base/message_loop/message_loop.h"
20#include "base/threading/non_thread_safe.h"
21#include "google/cacheinvalidation/include/system-resources.h"
22#include "sync/base/sync_export.h"
23#include "sync/notifier/invalidator_state.h"
24#include "sync/notifier/state_writer.h"
25
26namespace syncer {
27
28class SyncLogger : public invalidation::Logger {
29 public:
30  SyncLogger();
31
32  virtual ~SyncLogger();
33
34  // invalidation::Logger implementation.
35  virtual void Log(LogLevel level, const char* file, int line,
36                   const char* format, ...) OVERRIDE;
37
38  virtual void SetSystemResources(
39      invalidation::SystemResources* resources) OVERRIDE;
40};
41
42class SyncInvalidationScheduler : public invalidation::Scheduler {
43 public:
44  SyncInvalidationScheduler();
45
46  virtual ~SyncInvalidationScheduler();
47
48  // Start and stop the scheduler.
49  void Start();
50  void Stop();
51
52  // invalidation::Scheduler implementation.
53  virtual void Schedule(invalidation::TimeDelta delay,
54                        invalidation::Closure* task) OVERRIDE;
55
56  virtual bool IsRunningOnThread() const OVERRIDE;
57
58  virtual invalidation::Time GetCurrentTime() const OVERRIDE;
59
60  virtual void SetSystemResources(
61      invalidation::SystemResources* resources) OVERRIDE;
62
63 private:
64  // Runs the task, deletes it, and removes it from |posted_tasks_|.
65  void RunPostedTask(invalidation::Closure* task);
66
67  // Holds all posted tasks that have not yet been run.
68  std::set<invalidation::Closure*> posted_tasks_;
69
70  const base::MessageLoop* created_on_loop_;
71  bool is_started_;
72  bool is_stopped_;
73
74  base::WeakPtrFactory<SyncInvalidationScheduler> weak_factory_;
75};
76
77// SyncNetworkChannel implements common tasks needed to interact with
78// invalidation library:
79//  - registering message and network status callbacks
80//  - Encoding/Decoding message to ClientGatewayMessage
81//  - notifying observers about network channel state change
82// Implementation of particular network protocol should implement
83// SendEncodedMessage and call NotifyStateChange and DeliverIncomingMessage.
84class SYNC_EXPORT_PRIVATE SyncNetworkChannel
85    : public NON_EXPORTED_BASE(invalidation::NetworkChannel) {
86 public:
87  class Observer {
88   public:
89    // Called when network channel state changes. Possible states are:
90    //  - INVALIDATIONS_ENABLED : connection is established and working
91    //  - TRANSIENT_INVALIDATION_ERROR : no network, connection lost, etc.
92    //  - INVALIDATION_CREDENTIALS_REJECTED : Issues with auth token
93    virtual void OnNetworkChannelStateChanged(
94        InvalidatorState invalidator_state) = 0;
95  };
96
97  SyncNetworkChannel();
98
99  virtual ~SyncNetworkChannel();
100
101  // invalidation::NetworkChannel implementation.
102  virtual void SendMessage(const std::string& outgoing_message) OVERRIDE;
103  virtual void SetMessageReceiver(
104      invalidation::MessageCallback* incoming_receiver) OVERRIDE;
105  virtual void AddNetworkStatusReceiver(
106      invalidation::NetworkStatusCallback* network_status_receiver) OVERRIDE;
107  virtual void SetSystemResources(
108      invalidation::SystemResources* resources) OVERRIDE;
109
110  // Subclass should implement SendEncodedMessage to send encoded message to
111  // Tango over network.
112  virtual void SendEncodedMessage(const std::string& encoded_message) = 0;
113
114  // Classes interested in network channel state changes should implement
115  // SyncNetworkChannel::Observer and register here.
116  void AddObserver(Observer* observer);
117  void RemoveObserver(Observer* observer);
118
119  const std::string& GetServiceContextForTest() const;
120
121  int64 GetSchedulingHashForTest() const;
122
123  static std::string EncodeMessageForTest(
124      const std::string& message,
125      const std::string& service_context,
126      int64 scheduling_hash);
127
128  static bool DecodeMessageForTest(
129      const std::string& notification,
130      std::string* message,
131      std::string* service_context,
132      int64* scheduling_hash);
133
134 protected:
135  // Subclass should notify about connection state through NotifyStateChange.
136  void NotifyStateChange(InvalidatorState invalidator_state);
137  // Subclass should call DeliverIncomingMessage for message to reach
138  // invalidations library.
139  void DeliverIncomingMessage(const std::string& message);
140
141 private:
142  typedef std::vector<invalidation::NetworkStatusCallback*>
143      NetworkStatusReceiverList;
144
145  static void EncodeMessage(
146      std::string* encoded_message,
147      const std::string& message,
148      const std::string& service_context,
149      int64 scheduling_hash);
150
151  static bool DecodeMessage(
152      const std::string& data,
153      std::string* message,
154      std::string* service_context,
155      int64* scheduling_hash);
156
157  // Callbacks into invalidation library
158  scoped_ptr<invalidation::MessageCallback> incoming_receiver_;
159  NetworkStatusReceiverList network_status_receivers_;
160
161  // Last channel state for new network status receivers.
162  InvalidatorState invalidator_state_;
163
164  ObserverList<Observer> observers_;
165
166  std::string service_context_;
167  int64 scheduling_hash_;
168};
169
170class SyncStorage : public invalidation::Storage {
171 public:
172  SyncStorage(StateWriter* state_writer, invalidation::Scheduler* scheduler);
173
174  virtual ~SyncStorage();
175
176  void SetInitialState(const std::string& value) {
177    cached_state_ = value;
178  }
179
180  // invalidation::Storage implementation.
181  virtual void WriteKey(const std::string& key, const std::string& value,
182                        invalidation::WriteKeyCallback* done) OVERRIDE;
183
184  virtual void ReadKey(const std::string& key,
185                       invalidation::ReadKeyCallback* done) OVERRIDE;
186
187  virtual void DeleteKey(const std::string& key,
188                         invalidation::DeleteKeyCallback* done) OVERRIDE;
189
190  virtual void ReadAllKeys(
191      invalidation::ReadAllKeysCallback* key_callback) OVERRIDE;
192
193  virtual void SetSystemResources(
194      invalidation::SystemResources* resources) OVERRIDE;
195
196 private:
197  // Runs the given storage callback with SUCCESS status and deletes it.
198  void RunAndDeleteWriteKeyCallback(
199      invalidation::WriteKeyCallback* callback);
200
201  // Runs the given callback with the given value and deletes it.
202  void RunAndDeleteReadKeyCallback(
203      invalidation::ReadKeyCallback* callback, const std::string& value);
204
205  StateWriter* state_writer_;
206  invalidation::Scheduler* scheduler_;
207  std::string cached_state_;
208};
209
210class SYNC_EXPORT_PRIVATE SyncSystemResources
211    : public NON_EXPORTED_BASE(invalidation::SystemResources) {
212 public:
213  SyncSystemResources(SyncNetworkChannel* sync_network_channel,
214                      StateWriter* state_writer);
215
216  virtual ~SyncSystemResources();
217
218  // invalidation::SystemResources implementation.
219  virtual void Start() OVERRIDE;
220  virtual void Stop() OVERRIDE;
221  virtual bool IsStarted() const OVERRIDE;
222  virtual void set_platform(const std::string& platform);
223  virtual std::string platform() const OVERRIDE;
224  virtual SyncLogger* logger() OVERRIDE;
225  virtual SyncStorage* storage() OVERRIDE;
226  virtual SyncNetworkChannel* network() OVERRIDE;
227  virtual SyncInvalidationScheduler* internal_scheduler() OVERRIDE;
228  virtual SyncInvalidationScheduler* listener_scheduler() OVERRIDE;
229
230 private:
231  bool is_started_;
232  std::string platform_;
233  scoped_ptr<SyncLogger> logger_;
234  scoped_ptr<SyncInvalidationScheduler> internal_scheduler_;
235  scoped_ptr<SyncInvalidationScheduler> listener_scheduler_;
236  scoped_ptr<SyncStorage> storage_;
237  // sync_network_channel_ is owned by SyncInvalidationListener.
238  SyncNetworkChannel* sync_network_channel_;
239};
240
241}  // namespace syncer
242
243#endif  // SYNC_NOTIFIER_SYNC_SYSTEM_RESOURCES_H_
244