OLD | NEW |
(Empty) | |
| 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/gcm_network_channel.h" |
| 21 #include "sync/notifier/gcm_network_channel_delegate.h" |
| 22 #include "sync/notifier/invalidation_util.h" |
| 23 #include "sync/notifier/push_client_channel.h" |
| 24 |
| 25 namespace syncer { |
| 26 |
| 27 SyncLogger::SyncLogger() {} |
| 28 SyncLogger::~SyncLogger() {} |
| 29 |
| 30 void SyncLogger::Log(LogLevel level, const char* file, int line, |
| 31 const char* format, ...) { |
| 32 logging::LogSeverity log_severity = -2; // VLOG(2) |
| 33 bool emit_log = false; |
| 34 switch (level) { |
| 35 case FINE_LEVEL: |
| 36 log_severity = -2; // VLOG(2) |
| 37 emit_log = VLOG_IS_ON(2); |
| 38 break; |
| 39 case INFO_LEVEL: |
| 40 log_severity = -1; // VLOG(1) |
| 41 emit_log = VLOG_IS_ON(1); |
| 42 break; |
| 43 case WARNING_LEVEL: |
| 44 log_severity = logging::LOG_WARNING; |
| 45 emit_log = LOG_IS_ON(WARNING); |
| 46 break; |
| 47 case SEVERE_LEVEL: |
| 48 log_severity = logging::LOG_ERROR; |
| 49 emit_log = LOG_IS_ON(ERROR); |
| 50 break; |
| 51 } |
| 52 if (emit_log) { |
| 53 va_list ap; |
| 54 va_start(ap, format); |
| 55 std::string result; |
| 56 base::StringAppendV(&result, format, ap); |
| 57 logging::LogMessage(file, line, log_severity).stream() << result; |
| 58 va_end(ap); |
| 59 } |
| 60 } |
| 61 |
| 62 void SyncLogger::SetSystemResources(invalidation::SystemResources* resources) { |
| 63 // Do nothing. |
| 64 } |
| 65 |
| 66 SyncInvalidationScheduler::SyncInvalidationScheduler() |
| 67 : created_on_loop_(base::MessageLoop::current()), |
| 68 is_started_(false), |
| 69 is_stopped_(false), |
| 70 weak_factory_(this) { |
| 71 CHECK(created_on_loop_); |
| 72 } |
| 73 |
| 74 SyncInvalidationScheduler::~SyncInvalidationScheduler() { |
| 75 CHECK_EQ(created_on_loop_, base::MessageLoop::current()); |
| 76 CHECK(is_stopped_); |
| 77 } |
| 78 |
| 79 void SyncInvalidationScheduler::Start() { |
| 80 CHECK_EQ(created_on_loop_, base::MessageLoop::current()); |
| 81 CHECK(!is_started_); |
| 82 is_started_ = true; |
| 83 is_stopped_ = false; |
| 84 weak_factory_.InvalidateWeakPtrs(); |
| 85 } |
| 86 |
| 87 void SyncInvalidationScheduler::Stop() { |
| 88 CHECK_EQ(created_on_loop_, base::MessageLoop::current()); |
| 89 is_stopped_ = true; |
| 90 is_started_ = false; |
| 91 weak_factory_.InvalidateWeakPtrs(); |
| 92 STLDeleteElements(&posted_tasks_); |
| 93 posted_tasks_.clear(); |
| 94 } |
| 95 |
| 96 void SyncInvalidationScheduler::Schedule(invalidation::TimeDelta delay, |
| 97 invalidation::Closure* task) { |
| 98 DCHECK(invalidation::IsCallbackRepeatable(task)); |
| 99 CHECK_EQ(created_on_loop_, base::MessageLoop::current()); |
| 100 |
| 101 if (!is_started_) { |
| 102 delete task; |
| 103 return; |
| 104 } |
| 105 |
| 106 posted_tasks_.insert(task); |
| 107 base::MessageLoop::current()->PostDelayedTask( |
| 108 FROM_HERE, base::Bind(&SyncInvalidationScheduler::RunPostedTask, |
| 109 weak_factory_.GetWeakPtr(), task), |
| 110 delay); |
| 111 } |
| 112 |
| 113 bool SyncInvalidationScheduler::IsRunningOnThread() const { |
| 114 return created_on_loop_ == base::MessageLoop::current(); |
| 115 } |
| 116 |
| 117 invalidation::Time SyncInvalidationScheduler::GetCurrentTime() const { |
| 118 CHECK_EQ(created_on_loop_, base::MessageLoop::current()); |
| 119 return base::Time::Now(); |
| 120 } |
| 121 |
| 122 void SyncInvalidationScheduler::SetSystemResources( |
| 123 invalidation::SystemResources* resources) { |
| 124 // Do nothing. |
| 125 } |
| 126 |
| 127 void SyncInvalidationScheduler::RunPostedTask(invalidation::Closure* task) { |
| 128 CHECK_EQ(created_on_loop_, base::MessageLoop::current()); |
| 129 task->Run(); |
| 130 posted_tasks_.erase(task); |
| 131 delete task; |
| 132 } |
| 133 |
| 134 SyncNetworkChannel::SyncNetworkChannel() |
| 135 : invalidator_state_(DEFAULT_INVALIDATION_ERROR), |
| 136 received_messages_count_(0) {} |
| 137 |
| 138 SyncNetworkChannel::~SyncNetworkChannel() { |
| 139 STLDeleteElements(&network_status_receivers_); |
| 140 } |
| 141 |
| 142 void SyncNetworkChannel::SetMessageReceiver( |
| 143 invalidation::MessageCallback* incoming_receiver) { |
| 144 incoming_receiver_.reset(incoming_receiver); |
| 145 } |
| 146 |
| 147 void SyncNetworkChannel::AddNetworkStatusReceiver( |
| 148 invalidation::NetworkStatusCallback* network_status_receiver) { |
| 149 network_status_receiver->Run(invalidator_state_ == INVALIDATIONS_ENABLED); |
| 150 network_status_receivers_.push_back(network_status_receiver); |
| 151 } |
| 152 |
| 153 void SyncNetworkChannel::SetSystemResources( |
| 154 invalidation::SystemResources* resources) { |
| 155 // Do nothing. |
| 156 } |
| 157 |
| 158 void SyncNetworkChannel::AddObserver(Observer* observer) { |
| 159 observers_.AddObserver(observer); |
| 160 } |
| 161 |
| 162 void SyncNetworkChannel::RemoveObserver(Observer* observer) { |
| 163 observers_.RemoveObserver(observer); |
| 164 } |
| 165 |
| 166 scoped_ptr<SyncNetworkChannel> SyncNetworkChannel::CreatePushClientChannel( |
| 167 const notifier::NotifierOptions& notifier_options) { |
| 168 scoped_ptr<notifier::PushClient> push_client( |
| 169 notifier::PushClient::CreateDefaultOnIOThread(notifier_options)); |
| 170 return scoped_ptr<SyncNetworkChannel>( |
| 171 new PushClientChannel(push_client.Pass())); |
| 172 } |
| 173 |
| 174 scoped_ptr<SyncNetworkChannel> SyncNetworkChannel::CreateGCMNetworkChannel( |
| 175 scoped_refptr<net::URLRequestContextGetter> request_context_getter, |
| 176 scoped_ptr<GCMNetworkChannelDelegate> delegate) { |
| 177 return scoped_ptr<SyncNetworkChannel>(new GCMNetworkChannel( |
| 178 request_context_getter, delegate.Pass())); |
| 179 } |
| 180 |
| 181 void SyncNetworkChannel::NotifyStateChange(InvalidatorState invalidator_state) { |
| 182 // Remember state for future NetworkStatusReceivers. |
| 183 invalidator_state_ = invalidator_state; |
| 184 // Notify NetworkStatusReceivers in cacheinvalidation. |
| 185 for (NetworkStatusReceiverList::const_iterator it = |
| 186 network_status_receivers_.begin(); |
| 187 it != network_status_receivers_.end(); ++it) { |
| 188 (*it)->Run(invalidator_state_ == INVALIDATIONS_ENABLED); |
| 189 } |
| 190 // Notify observers. |
| 191 FOR_EACH_OBSERVER(Observer, observers_, |
| 192 OnNetworkChannelStateChanged(invalidator_state_)); |
| 193 } |
| 194 |
| 195 bool SyncNetworkChannel::DeliverIncomingMessage(const std::string& message) { |
| 196 if (!incoming_receiver_) { |
| 197 DLOG(ERROR) << "No receiver for incoming notification"; |
| 198 return false; |
| 199 } |
| 200 received_messages_count_++; |
| 201 incoming_receiver_->Run(message); |
| 202 return true; |
| 203 } |
| 204 |
| 205 int SyncNetworkChannel::GetReceivedMessagesCount() const { |
| 206 return received_messages_count_; |
| 207 } |
| 208 |
| 209 SyncStorage::SyncStorage(StateWriter* state_writer, |
| 210 invalidation::Scheduler* scheduler) |
| 211 : state_writer_(state_writer), |
| 212 scheduler_(scheduler) { |
| 213 DCHECK(state_writer_); |
| 214 DCHECK(scheduler_); |
| 215 } |
| 216 |
| 217 SyncStorage::~SyncStorage() {} |
| 218 |
| 219 void SyncStorage::WriteKey(const std::string& key, const std::string& value, |
| 220 invalidation::WriteKeyCallback* done) { |
| 221 CHECK(state_writer_); |
| 222 // TODO(ghc): actually write key,value associations, and don't invoke the |
| 223 // callback until the operation completes. |
| 224 state_writer_->WriteState(value); |
| 225 cached_state_ = value; |
| 226 // According to the cache invalidation API folks, we can do this as |
| 227 // long as we make sure to clear the persistent state that we start |
| 228 // up the cache invalidation client with. However, we musn't do it |
| 229 // right away, as we may be called under a lock that the callback |
| 230 // uses. |
| 231 scheduler_->Schedule( |
| 232 invalidation::Scheduler::NoDelay(), |
| 233 invalidation::NewPermanentCallback( |
| 234 this, &SyncStorage::RunAndDeleteWriteKeyCallback, |
| 235 done)); |
| 236 } |
| 237 |
| 238 void SyncStorage::ReadKey(const std::string& key, |
| 239 invalidation::ReadKeyCallback* done) { |
| 240 DCHECK(scheduler_->IsRunningOnThread()) << "not running on scheduler thread"; |
| 241 RunAndDeleteReadKeyCallback(done, cached_state_); |
| 242 } |
| 243 |
| 244 void SyncStorage::DeleteKey(const std::string& key, |
| 245 invalidation::DeleteKeyCallback* done) { |
| 246 // TODO(ghc): Implement. |
| 247 LOG(WARNING) << "ignoring call to DeleteKey(" << key << ", callback)"; |
| 248 } |
| 249 |
| 250 void SyncStorage::ReadAllKeys(invalidation::ReadAllKeysCallback* done) { |
| 251 // TODO(ghc): Implement. |
| 252 LOG(WARNING) << "ignoring call to ReadAllKeys(callback)"; |
| 253 } |
| 254 |
| 255 void SyncStorage::SetSystemResources( |
| 256 invalidation::SystemResources* resources) { |
| 257 // Do nothing. |
| 258 } |
| 259 |
| 260 void SyncStorage::RunAndDeleteWriteKeyCallback( |
| 261 invalidation::WriteKeyCallback* callback) { |
| 262 callback->Run( |
| 263 invalidation::Status(invalidation::Status::SUCCESS, std::string())); |
| 264 delete callback; |
| 265 } |
| 266 |
| 267 void SyncStorage::RunAndDeleteReadKeyCallback( |
| 268 invalidation::ReadKeyCallback* callback, const std::string& value) { |
| 269 callback->Run(std::make_pair( |
| 270 invalidation::Status(invalidation::Status::SUCCESS, std::string()), |
| 271 value)); |
| 272 delete callback; |
| 273 } |
| 274 |
| 275 SyncSystemResources::SyncSystemResources( |
| 276 SyncNetworkChannel* sync_network_channel, |
| 277 StateWriter* state_writer) |
| 278 : is_started_(false), |
| 279 logger_(new SyncLogger()), |
| 280 internal_scheduler_(new SyncInvalidationScheduler()), |
| 281 listener_scheduler_(new SyncInvalidationScheduler()), |
| 282 storage_(new SyncStorage(state_writer, internal_scheduler_.get())), |
| 283 sync_network_channel_(sync_network_channel) { |
| 284 } |
| 285 |
| 286 SyncSystemResources::~SyncSystemResources() { |
| 287 Stop(); |
| 288 } |
| 289 |
| 290 void SyncSystemResources::Start() { |
| 291 internal_scheduler_->Start(); |
| 292 listener_scheduler_->Start(); |
| 293 is_started_ = true; |
| 294 } |
| 295 |
| 296 void SyncSystemResources::Stop() { |
| 297 internal_scheduler_->Stop(); |
| 298 listener_scheduler_->Stop(); |
| 299 } |
| 300 |
| 301 bool SyncSystemResources::IsStarted() const { |
| 302 return is_started_; |
| 303 } |
| 304 |
| 305 void SyncSystemResources::set_platform(const std::string& platform) { |
| 306 platform_ = platform; |
| 307 } |
| 308 |
| 309 std::string SyncSystemResources::platform() const { |
| 310 return platform_; |
| 311 } |
| 312 |
| 313 SyncLogger* SyncSystemResources::logger() { |
| 314 return logger_.get(); |
| 315 } |
| 316 |
| 317 SyncStorage* SyncSystemResources::storage() { |
| 318 return storage_.get(); |
| 319 } |
| 320 |
| 321 SyncNetworkChannel* SyncSystemResources::network() { |
| 322 return sync_network_channel_; |
| 323 } |
| 324 |
| 325 SyncInvalidationScheduler* SyncSystemResources::internal_scheduler() { |
| 326 return internal_scheduler_.get(); |
| 327 } |
| 328 |
| 329 SyncInvalidationScheduler* SyncSystemResources::listener_scheduler() { |
| 330 return listener_scheduler_.get(); |
| 331 } |
| 332 |
| 333 } // namespace syncer |
OLD | NEW |