sync_system_resources.cc revision 868fa2fe829687343ffae624259930155e16dbd8
1// Copyright (c) 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#include "sync/notifier/sync_system_resources.h"
6
7#include <cstdlib>
8#include <cstring>
9#include <string>
10
11#include "base/bind.h"
12#include "base/logging.h"
13#include "base/message_loop.h"
14#include "base/stl_util.h"
15#include "base/strings/string_util.h"
16#include "base/strings/stringprintf.h"
17#include "google/cacheinvalidation/deps/callback.h"
18#include "google/cacheinvalidation/include/types.h"
19#include "jingle/notifier/listener/push_client.h"
20#include "sync/notifier/invalidation_util.h"
21
22namespace syncer {
23
24SyncLogger::SyncLogger() {}
25SyncLogger::~SyncLogger() {}
26
27void SyncLogger::Log(LogLevel level, const char* file, int line,
28                     const char* format, ...) {
29  logging::LogSeverity log_severity = -2;  // VLOG(2)
30  bool emit_log = false;
31  switch (level) {
32    case FINE_LEVEL:
33      log_severity = -2;  // VLOG(2)
34      emit_log = VLOG_IS_ON(2);
35      break;
36    case INFO_LEVEL:
37      log_severity = -1;  // VLOG(1)
38      emit_log = VLOG_IS_ON(1);
39      break;
40    case WARNING_LEVEL:
41      log_severity = logging::LOG_WARNING;
42      emit_log = LOG_IS_ON(WARNING);
43      break;
44    case SEVERE_LEVEL:
45      log_severity = logging::LOG_ERROR;
46      emit_log = LOG_IS_ON(ERROR);
47      break;
48  }
49  if (emit_log) {
50    va_list ap;
51    va_start(ap, format);
52    std::string result;
53    base::StringAppendV(&result, format, ap);
54    logging::LogMessage(file, line, log_severity).stream() << result;
55    va_end(ap);
56  }
57}
58
59void SyncLogger::SetSystemResources(invalidation::SystemResources* resources) {
60  // Do nothing.
61}
62
63SyncInvalidationScheduler::SyncInvalidationScheduler()
64    : weak_factory_(this),
65      created_on_loop_(base::MessageLoop::current()),
66      is_started_(false),
67      is_stopped_(false) {
68  CHECK(created_on_loop_);
69}
70
71SyncInvalidationScheduler::~SyncInvalidationScheduler() {
72  CHECK_EQ(created_on_loop_, base::MessageLoop::current());
73  CHECK(is_stopped_);
74}
75
76void SyncInvalidationScheduler::Start() {
77  CHECK_EQ(created_on_loop_, base::MessageLoop::current());
78  CHECK(!is_started_);
79  is_started_ = true;
80  is_stopped_ = false;
81  weak_factory_.InvalidateWeakPtrs();
82}
83
84void SyncInvalidationScheduler::Stop() {
85  CHECK_EQ(created_on_loop_, base::MessageLoop::current());
86  is_stopped_ = true;
87  is_started_ = false;
88  weak_factory_.InvalidateWeakPtrs();
89  STLDeleteElements(&posted_tasks_);
90  posted_tasks_.clear();
91}
92
93void SyncInvalidationScheduler::Schedule(invalidation::TimeDelta delay,
94                                         invalidation::Closure* task) {
95  DCHECK(invalidation::IsCallbackRepeatable(task));
96  CHECK_EQ(created_on_loop_, base::MessageLoop::current());
97
98  if (!is_started_) {
99    delete task;
100    return;
101  }
102
103  posted_tasks_.insert(task);
104  base::MessageLoop::current()->PostDelayedTask(
105      FROM_HERE, base::Bind(&SyncInvalidationScheduler::RunPostedTask,
106                            weak_factory_.GetWeakPtr(), task),
107      delay);
108}
109
110bool SyncInvalidationScheduler::IsRunningOnThread() const {
111  return created_on_loop_ == base::MessageLoop::current();
112}
113
114invalidation::Time SyncInvalidationScheduler::GetCurrentTime() const {
115  CHECK_EQ(created_on_loop_, base::MessageLoop::current());
116  return base::Time::Now();
117}
118
119void SyncInvalidationScheduler::SetSystemResources(
120    invalidation::SystemResources* resources) {
121  // Do nothing.
122}
123
124void SyncInvalidationScheduler::RunPostedTask(invalidation::Closure* task) {
125  CHECK_EQ(created_on_loop_, base::MessageLoop::current());
126  task->Run();
127  posted_tasks_.erase(task);
128  delete task;
129}
130
131SyncStorage::SyncStorage(StateWriter* state_writer,
132                         invalidation::Scheduler* scheduler)
133    : state_writer_(state_writer),
134      scheduler_(scheduler) {
135  DCHECK(state_writer_);
136  DCHECK(scheduler_);
137}
138
139SyncStorage::~SyncStorage() {}
140
141void SyncStorage::WriteKey(const std::string& key, const std::string& value,
142                           invalidation::WriteKeyCallback* done) {
143  CHECK(state_writer_);
144  // TODO(ghc): actually write key,value associations, and don't invoke the
145  // callback until the operation completes.
146  state_writer_->WriteState(value);
147  cached_state_ = value;
148  // According to the cache invalidation API folks, we can do this as
149  // long as we make sure to clear the persistent state that we start
150  // up the cache invalidation client with.  However, we musn't do it
151  // right away, as we may be called under a lock that the callback
152  // uses.
153  scheduler_->Schedule(
154      invalidation::Scheduler::NoDelay(),
155      invalidation::NewPermanentCallback(
156          this, &SyncStorage::RunAndDeleteWriteKeyCallback,
157          done));
158}
159
160void SyncStorage::ReadKey(const std::string& key,
161                          invalidation::ReadKeyCallback* done) {
162  DCHECK(scheduler_->IsRunningOnThread()) << "not running on scheduler thread";
163  RunAndDeleteReadKeyCallback(done, cached_state_);
164}
165
166void SyncStorage::DeleteKey(const std::string& key,
167                            invalidation::DeleteKeyCallback* done) {
168  // TODO(ghc): Implement.
169  LOG(WARNING) << "ignoring call to DeleteKey(" << key << ", callback)";
170}
171
172void SyncStorage::ReadAllKeys(invalidation::ReadAllKeysCallback* done) {
173  // TODO(ghc): Implement.
174  LOG(WARNING) << "ignoring call to ReadAllKeys(callback)";
175}
176
177void SyncStorage::SetSystemResources(
178    invalidation::SystemResources* resources) {
179  // Do nothing.
180}
181
182void SyncStorage::RunAndDeleteWriteKeyCallback(
183    invalidation::WriteKeyCallback* callback) {
184  callback->Run(
185      invalidation::Status(invalidation::Status::SUCCESS, std::string()));
186  delete callback;
187}
188
189void SyncStorage::RunAndDeleteReadKeyCallback(
190    invalidation::ReadKeyCallback* callback, const std::string& value) {
191  callback->Run(std::make_pair(
192      invalidation::Status(invalidation::Status::SUCCESS, std::string()),
193      value));
194  delete callback;
195}
196
197SyncSystemResources::SyncSystemResources(
198    scoped_ptr<notifier::PushClient> push_client,
199    StateWriter* state_writer)
200    : is_started_(false),
201      logger_(new SyncLogger()),
202      internal_scheduler_(new SyncInvalidationScheduler()),
203      listener_scheduler_(new SyncInvalidationScheduler()),
204      storage_(new SyncStorage(state_writer, internal_scheduler_.get())),
205      push_client_channel_(push_client.Pass()) {
206}
207
208SyncSystemResources::~SyncSystemResources() {
209  Stop();
210}
211
212void SyncSystemResources::Start() {
213  internal_scheduler_->Start();
214  listener_scheduler_->Start();
215  is_started_ = true;
216}
217
218void SyncSystemResources::Stop() {
219  internal_scheduler_->Stop();
220  listener_scheduler_->Stop();
221}
222
223bool SyncSystemResources::IsStarted() const {
224  return is_started_;
225}
226
227void SyncSystemResources::set_platform(const std::string& platform) {
228  platform_ = platform;
229}
230
231std::string SyncSystemResources::platform() const {
232  return platform_;
233}
234
235SyncLogger* SyncSystemResources::logger() {
236  return logger_.get();
237}
238
239SyncStorage* SyncSystemResources::storage() {
240  return storage_.get();
241}
242
243PushClientChannel* SyncSystemResources::network() {
244  return &push_client_channel_;
245}
246
247SyncInvalidationScheduler* SyncSystemResources::internal_scheduler() {
248  return internal_scheduler_.get();
249}
250
251SyncInvalidationScheduler* SyncSystemResources::listener_scheduler() {
252  return listener_scheduler_.get();
253}
254
255}  // namespace syncer
256