// Copyright (c) 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. #include "sync/notifier/sync_system_resources.h" #include #include #include #include "base/bind.h" #include "base/logging.h" #include "base/message_loop.h" #include "base/stl_util.h" #include "base/string_util.h" #include "base/stringprintf.h" #include "google/cacheinvalidation/deps/callback.h" #include "google/cacheinvalidation/include/types.h" #include "jingle/notifier/listener/push_client.h" #include "sync/notifier/invalidation_util.h" namespace syncer { SyncLogger::SyncLogger() {} SyncLogger::~SyncLogger() {} void SyncLogger::Log(LogLevel level, const char* file, int line, const char* format, ...) { logging::LogSeverity log_severity = -2; // VLOG(2) bool emit_log = false; switch (level) { case FINE_LEVEL: log_severity = -2; // VLOG(2) emit_log = VLOG_IS_ON(2); break; case INFO_LEVEL: log_severity = -1; // VLOG(1) emit_log = VLOG_IS_ON(1); break; case WARNING_LEVEL: log_severity = logging::LOG_WARNING; emit_log = LOG_IS_ON(WARNING); break; case SEVERE_LEVEL: log_severity = logging::LOG_ERROR; emit_log = LOG_IS_ON(ERROR); break; } if (emit_log) { va_list ap; va_start(ap, format); std::string result; base::StringAppendV(&result, format, ap); logging::LogMessage(file, line, log_severity).stream() << result; va_end(ap); } } void SyncLogger::SetSystemResources(invalidation::SystemResources* resources) { // Do nothing. } SyncInvalidationScheduler::SyncInvalidationScheduler() : ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), created_on_loop_(MessageLoop::current()), is_started_(false), is_stopped_(false) { CHECK(created_on_loop_); } SyncInvalidationScheduler::~SyncInvalidationScheduler() { CHECK_EQ(created_on_loop_, MessageLoop::current()); CHECK(is_stopped_); } void SyncInvalidationScheduler::Start() { CHECK_EQ(created_on_loop_, MessageLoop::current()); CHECK(!is_started_); is_started_ = true; is_stopped_ = false; weak_factory_.InvalidateWeakPtrs(); } void SyncInvalidationScheduler::Stop() { CHECK_EQ(created_on_loop_, MessageLoop::current()); is_stopped_ = true; is_started_ = false; weak_factory_.InvalidateWeakPtrs(); STLDeleteElements(&posted_tasks_); posted_tasks_.clear(); } void SyncInvalidationScheduler::Schedule(invalidation::TimeDelta delay, invalidation::Closure* task) { DCHECK(invalidation::IsCallbackRepeatable(task)); CHECK_EQ(created_on_loop_, MessageLoop::current()); if (!is_started_) { delete task; return; } posted_tasks_.insert(task); MessageLoop::current()->PostDelayedTask( FROM_HERE, base::Bind(&SyncInvalidationScheduler::RunPostedTask, weak_factory_.GetWeakPtr(), task), delay); } bool SyncInvalidationScheduler::IsRunningOnThread() const { return created_on_loop_ == MessageLoop::current(); } invalidation::Time SyncInvalidationScheduler::GetCurrentTime() const { CHECK_EQ(created_on_loop_, MessageLoop::current()); return base::Time::Now(); } void SyncInvalidationScheduler::SetSystemResources( invalidation::SystemResources* resources) { // Do nothing. } void SyncInvalidationScheduler::RunPostedTask(invalidation::Closure* task) { CHECK_EQ(created_on_loop_, MessageLoop::current()); task->Run(); posted_tasks_.erase(task); delete task; } SyncStorage::SyncStorage(StateWriter* state_writer, invalidation::Scheduler* scheduler) : state_writer_(state_writer), scheduler_(scheduler) { DCHECK(state_writer_); DCHECK(scheduler_); } SyncStorage::~SyncStorage() {} void SyncStorage::WriteKey(const std::string& key, const std::string& value, invalidation::WriteKeyCallback* done) { CHECK(state_writer_); // TODO(ghc): actually write key,value associations, and don't invoke the // callback until the operation completes. state_writer_->WriteState(value); cached_state_ = value; // According to the cache invalidation API folks, we can do this as // long as we make sure to clear the persistent state that we start // up the cache invalidation client with. However, we musn't do it // right away, as we may be called under a lock that the callback // uses. scheduler_->Schedule( invalidation::Scheduler::NoDelay(), invalidation::NewPermanentCallback( this, &SyncStorage::RunAndDeleteWriteKeyCallback, done)); } void SyncStorage::ReadKey(const std::string& key, invalidation::ReadKeyCallback* done) { DCHECK(scheduler_->IsRunningOnThread()) << "not running on scheduler thread"; RunAndDeleteReadKeyCallback(done, cached_state_); } void SyncStorage::DeleteKey(const std::string& key, invalidation::DeleteKeyCallback* done) { // TODO(ghc): Implement. LOG(WARNING) << "ignoring call to DeleteKey(" << key << ", callback)"; } void SyncStorage::ReadAllKeys(invalidation::ReadAllKeysCallback* done) { // TODO(ghc): Implement. LOG(WARNING) << "ignoring call to ReadAllKeys(callback)"; } void SyncStorage::SetSystemResources( invalidation::SystemResources* resources) { // Do nothing. } void SyncStorage::RunAndDeleteWriteKeyCallback( invalidation::WriteKeyCallback* callback) { callback->Run(invalidation::Status(invalidation::Status::SUCCESS, "")); delete callback; } void SyncStorage::RunAndDeleteReadKeyCallback( invalidation::ReadKeyCallback* callback, const std::string& value) { callback->Run(std::make_pair( invalidation::Status(invalidation::Status::SUCCESS, ""), value)); delete callback; } SyncSystemResources::SyncSystemResources( scoped_ptr push_client, StateWriter* state_writer) : is_started_(false), logger_(new SyncLogger()), internal_scheduler_(new SyncInvalidationScheduler()), listener_scheduler_(new SyncInvalidationScheduler()), storage_(new SyncStorage(state_writer, internal_scheduler_.get())), push_client_channel_(push_client.Pass()) { } SyncSystemResources::~SyncSystemResources() { Stop(); } void SyncSystemResources::Start() { internal_scheduler_->Start(); listener_scheduler_->Start(); is_started_ = true; } void SyncSystemResources::Stop() { internal_scheduler_->Stop(); listener_scheduler_->Stop(); } bool SyncSystemResources::IsStarted() const { return is_started_; } void SyncSystemResources::set_platform(const std::string& platform) { platform_ = platform; } std::string SyncSystemResources::platform() const { return platform_; } SyncLogger* SyncSystemResources::logger() { return logger_.get(); } SyncStorage* SyncSystemResources::storage() { return storage_.get(); } PushClientChannel* SyncSystemResources::network() { return &push_client_channel_; } SyncInvalidationScheduler* SyncSystemResources::internal_scheduler() { return internal_scheduler_.get(); } SyncInvalidationScheduler* SyncSystemResources::listener_scheduler() { return listener_scheduler_.get(); } } // namespace syncer