1// Copyright 2014 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 COMPONENTS_INVALIDATION_SYNC_SYSTEM_RESOURCES_H_
10#define COMPONENTS_INVALIDATION_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 "base/values.h"
22#include "components/invalidation/invalidation_export.h"
23#include "components/invalidation/invalidator_state.h"
24#include "components/invalidation/state_writer.h"
25#include "google/cacheinvalidation/include/system-resources.h"
26#include "jingle/notifier/base/notifier_options.h"
27
28namespace syncer {
29
30class GCMNetworkChannelDelegate;
31
32class SyncLogger : public invalidation::Logger {
33 public:
34  SyncLogger();
35
36  virtual ~SyncLogger();
37
38  // invalidation::Logger implementation.
39  virtual void Log(LogLevel level, const char* file, int line,
40                   const char* format, ...) OVERRIDE;
41
42  virtual void SetSystemResources(
43      invalidation::SystemResources* resources) OVERRIDE;
44};
45
46class SyncInvalidationScheduler : public invalidation::Scheduler {
47 public:
48  SyncInvalidationScheduler();
49
50  virtual ~SyncInvalidationScheduler();
51
52  // Start and stop the scheduler.
53  void Start();
54  void Stop();
55
56  // invalidation::Scheduler implementation.
57  virtual void Schedule(invalidation::TimeDelta delay,
58                        invalidation::Closure* task) OVERRIDE;
59
60  virtual bool IsRunningOnThread() const OVERRIDE;
61
62  virtual invalidation::Time GetCurrentTime() const OVERRIDE;
63
64  virtual void SetSystemResources(
65      invalidation::SystemResources* resources) OVERRIDE;
66
67 private:
68  // Runs the task, deletes it, and removes it from |posted_tasks_|.
69  void RunPostedTask(invalidation::Closure* task);
70
71  // Holds all posted tasks that have not yet been run.
72  std::set<invalidation::Closure*> posted_tasks_;
73
74  const base::MessageLoop* created_on_loop_;
75  bool is_started_;
76  bool is_stopped_;
77
78  base::WeakPtrFactory<SyncInvalidationScheduler> weak_factory_;
79};
80
81// SyncNetworkChannel implements common tasks needed to interact with
82// invalidation library:
83//  - registering message and network status callbacks
84//  - notifying observers about network channel state change
85// Implementation of particular network protocol should implement
86// SendMessage and call NotifyStateChange and DeliverIncomingMessage.
87class INVALIDATION_EXPORT_PRIVATE SyncNetworkChannel
88    : public NON_EXPORTED_BASE(invalidation::NetworkChannel) {
89 public:
90  class Observer {
91   public:
92    // Called when network channel state changes. Possible states are:
93    //  - INVALIDATIONS_ENABLED : connection is established and working
94    //  - TRANSIENT_INVALIDATION_ERROR : no network, connection lost, etc.
95    //  - INVALIDATION_CREDENTIALS_REJECTED : Issues with auth token
96    virtual void OnNetworkChannelStateChanged(
97        InvalidatorState invalidator_state) = 0;
98  };
99
100  SyncNetworkChannel();
101
102  virtual ~SyncNetworkChannel();
103
104  // invalidation::NetworkChannel implementation.
105  // SyncNetworkChannel doesn't implement SendMessage. It is responsibility of
106  // subclass to implement it.
107  virtual void SetMessageReceiver(
108      invalidation::MessageCallback* incoming_receiver) OVERRIDE;
109  virtual void AddNetworkStatusReceiver(
110      invalidation::NetworkStatusCallback* network_status_receiver) OVERRIDE;
111  virtual void SetSystemResources(
112      invalidation::SystemResources* resources) OVERRIDE;
113
114  // Subclass should implement UpdateCredentials to pass new token to channel
115  // library.
116  virtual void UpdateCredentials(const std::string& email,
117      const std::string& token) = 0;
118
119  // Return value from GetInvalidationClientType will be passed to
120  // invalidation::CreateInvalidationClient. Subclass should return one of the
121  // values from ipc::invalidation::ClientType enum from types.proto.
122  virtual int GetInvalidationClientType() = 0;
123
124  // Subclass should implement RequestDetailedStatus to provide debugging
125  // information.
126  virtual void RequestDetailedStatus(
127      base::Callback<void(const base::DictionaryValue&)> callback) = 0;
128
129  // Classes interested in network channel state changes should implement
130  // SyncNetworkChannel::Observer and register here.
131  void AddObserver(Observer* observer);
132  void RemoveObserver(Observer* observer);
133
134  // Helper functions that know how to construct network channels from channel
135  // specific parameters.
136  static scoped_ptr<SyncNetworkChannel> CreatePushClientChannel(
137      const notifier::NotifierOptions& notifier_options);
138  static scoped_ptr<SyncNetworkChannel> CreateGCMNetworkChannel(
139      scoped_refptr<net::URLRequestContextGetter> request_context_getter,
140      scoped_ptr<GCMNetworkChannelDelegate> delegate);
141
142  // Get the count of how many valid received messages were received.
143  int GetReceivedMessagesCount() const;
144
145 protected:
146  // Subclass should call NotifyNetworkStatusChange to notify about network
147  // changes. This triggers cacheinvalidation to try resending failed message
148  // ahead of schedule when client comes online or IP address changes.
149  void NotifyNetworkStatusChange(bool online);
150
151  // Subclass should notify about connection state through
152  // NotifyChannelStateChange. If communication doesn't work and it is possible
153  // that invalidations from server will not reach this client then channel
154  // should call this function with TRANSIENT_INVALIDATION_ERROR.
155  void NotifyChannelStateChange(InvalidatorState invalidator_state);
156
157  // Subclass should call DeliverIncomingMessage for message to reach
158  // invalidations library.
159  bool DeliverIncomingMessage(const std::string& message);
160
161 private:
162  typedef std::vector<invalidation::NetworkStatusCallback*>
163      NetworkStatusReceiverList;
164
165  // Callbacks into invalidation library
166  scoped_ptr<invalidation::MessageCallback> incoming_receiver_;
167  NetworkStatusReceiverList network_status_receivers_;
168
169  // Last network status for new network status receivers.
170  bool last_network_status_;
171
172  int received_messages_count_;
173
174  ObserverList<Observer> observers_;
175};
176
177class SyncStorage : public invalidation::Storage {
178 public:
179  SyncStorage(StateWriter* state_writer, invalidation::Scheduler* scheduler);
180
181  virtual ~SyncStorage();
182
183  void SetInitialState(const std::string& value) {
184    cached_state_ = value;
185  }
186
187  // invalidation::Storage implementation.
188  virtual void WriteKey(const std::string& key, const std::string& value,
189                        invalidation::WriteKeyCallback* done) OVERRIDE;
190
191  virtual void ReadKey(const std::string& key,
192                       invalidation::ReadKeyCallback* done) OVERRIDE;
193
194  virtual void DeleteKey(const std::string& key,
195                         invalidation::DeleteKeyCallback* done) OVERRIDE;
196
197  virtual void ReadAllKeys(
198      invalidation::ReadAllKeysCallback* key_callback) OVERRIDE;
199
200  virtual void SetSystemResources(
201      invalidation::SystemResources* resources) OVERRIDE;
202
203 private:
204  // Runs the given storage callback with SUCCESS status and deletes it.
205  void RunAndDeleteWriteKeyCallback(
206      invalidation::WriteKeyCallback* callback);
207
208  // Runs the given callback with the given value and deletes it.
209  void RunAndDeleteReadKeyCallback(
210      invalidation::ReadKeyCallback* callback, const std::string& value);
211
212  StateWriter* state_writer_;
213  invalidation::Scheduler* scheduler_;
214  std::string cached_state_;
215};
216
217class INVALIDATION_EXPORT_PRIVATE SyncSystemResources
218    : public NON_EXPORTED_BASE(invalidation::SystemResources) {
219 public:
220  SyncSystemResources(SyncNetworkChannel* sync_network_channel,
221                      StateWriter* state_writer);
222
223  virtual ~SyncSystemResources();
224
225  // invalidation::SystemResources implementation.
226  virtual void Start() OVERRIDE;
227  virtual void Stop() OVERRIDE;
228  virtual bool IsStarted() const OVERRIDE;
229  virtual void set_platform(const std::string& platform);
230  virtual std::string platform() const OVERRIDE;
231  virtual SyncLogger* logger() OVERRIDE;
232  virtual SyncStorage* storage() OVERRIDE;
233  virtual SyncNetworkChannel* network() OVERRIDE;
234  virtual SyncInvalidationScheduler* internal_scheduler() OVERRIDE;
235  virtual SyncInvalidationScheduler* listener_scheduler() OVERRIDE;
236
237 private:
238  bool is_started_;
239  std::string platform_;
240  scoped_ptr<SyncLogger> logger_;
241  scoped_ptr<SyncInvalidationScheduler> internal_scheduler_;
242  scoped_ptr<SyncInvalidationScheduler> listener_scheduler_;
243  scoped_ptr<SyncStorage> storage_;
244  // sync_network_channel_ is owned by SyncInvalidationListener.
245  SyncNetworkChannel* sync_network_channel_;
246};
247
248}  // namespace syncer
249
250#endif  // COMPONENTS_INVALIDATION_SYNC_SYSTEM_RESOURCES_H_
251