Home | History | Annotate | Download | only in notifier
      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/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 
     22 namespace syncer {
     23 
     24 SyncLogger::SyncLogger() {}
     25 SyncLogger::~SyncLogger() {}
     26 
     27 void 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 
     59 void SyncLogger::SetSystemResources(invalidation::SystemResources* resources) {
     60   // Do nothing.
     61 }
     62 
     63 SyncInvalidationScheduler::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 
     71 SyncInvalidationScheduler::~SyncInvalidationScheduler() {
     72   CHECK_EQ(created_on_loop_, base::MessageLoop::current());
     73   CHECK(is_stopped_);
     74 }
     75 
     76 void 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 
     84 void 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 
     93 void 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 
    110 bool SyncInvalidationScheduler::IsRunningOnThread() const {
    111   return created_on_loop_ == base::MessageLoop::current();
    112 }
    113 
    114 invalidation::Time SyncInvalidationScheduler::GetCurrentTime() const {
    115   CHECK_EQ(created_on_loop_, base::MessageLoop::current());
    116   return base::Time::Now();
    117 }
    118 
    119 void SyncInvalidationScheduler::SetSystemResources(
    120     invalidation::SystemResources* resources) {
    121   // Do nothing.
    122 }
    123 
    124 void 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 
    131 SyncStorage::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 
    139 SyncStorage::~SyncStorage() {}
    140 
    141 void 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 
    160 void 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 
    166 void 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 
    172 void SyncStorage::ReadAllKeys(invalidation::ReadAllKeysCallback* done) {
    173   // TODO(ghc): Implement.
    174   LOG(WARNING) << "ignoring call to ReadAllKeys(callback)";
    175 }
    176 
    177 void SyncStorage::SetSystemResources(
    178     invalidation::SystemResources* resources) {
    179   // Do nothing.
    180 }
    181 
    182 void SyncStorage::RunAndDeleteWriteKeyCallback(
    183     invalidation::WriteKeyCallback* callback) {
    184   callback->Run(
    185       invalidation::Status(invalidation::Status::SUCCESS, std::string()));
    186   delete callback;
    187 }
    188 
    189 void 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 
    197 SyncSystemResources::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 
    208 SyncSystemResources::~SyncSystemResources() {
    209   Stop();
    210 }
    211 
    212 void SyncSystemResources::Start() {
    213   internal_scheduler_->Start();
    214   listener_scheduler_->Start();
    215   is_started_ = true;
    216 }
    217 
    218 void SyncSystemResources::Stop() {
    219   internal_scheduler_->Stop();
    220   listener_scheduler_->Stop();
    221 }
    222 
    223 bool SyncSystemResources::IsStarted() const {
    224   return is_started_;
    225 }
    226 
    227 void SyncSystemResources::set_platform(const std::string& platform) {
    228   platform_ = platform;
    229 }
    230 
    231 std::string SyncSystemResources::platform() const {
    232   return platform_;
    233 }
    234 
    235 SyncLogger* SyncSystemResources::logger() {
    236   return logger_.get();
    237 }
    238 
    239 SyncStorage* SyncSystemResources::storage() {
    240   return storage_.get();
    241 }
    242 
    243 PushClientChannel* SyncSystemResources::network() {
    244   return &push_client_channel_;
    245 }
    246 
    247 SyncInvalidationScheduler* SyncSystemResources::internal_scheduler() {
    248   return internal_scheduler_.get();
    249 }
    250 
    251 SyncInvalidationScheduler* SyncSystemResources::listener_scheduler() {
    252   return listener_scheduler_.get();
    253 }
    254 
    255 }  // namespace syncer
    256