Chromium Code Reviews| Index: remoting/host/setup/daemon_controller.cc |
| diff --git a/remoting/host/setup/daemon_controller.cc b/remoting/host/setup/daemon_controller.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..6d60636ade8059a01ee06f4e95726f884777acc2 |
| --- /dev/null |
| +++ b/remoting/host/setup/daemon_controller.cc |
| @@ -0,0 +1,273 @@ |
| +// Copyright 2013 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 "remoting/host/setup/daemon_controller.h" |
| + |
| +#include "base/bind.h" |
| +#include "base/location.h" |
| +#include "base/single_thread_task_runner.h" |
| +#include "base/thread_task_runner_handle.h" |
| +#include "base/values.h" |
| +#include "remoting/base/auto_thread.h" |
| +#include "remoting/base/auto_thread_task_runner.h" |
| + |
| +namespace remoting { |
| + |
| +// Name of the Daemon Controller's worker thread. |
| +const char kDaemonControllerThreadName[] = "Daemon Controller thread"; |
| + |
| +DaemonController::DaemonController(scoped_ptr<Delegate> delegate) |
| + : caller_task_runner_(base::ThreadTaskRunnerHandle::Get()), |
| + delegate_(delegate.Pass()) { |
| + // Launch the delegate thread. |
| + delegate_thread_.reset(new AutoThread(kDaemonControllerThreadName)); |
| +#if defined(OS_WIN) |
| + delegate_thread_->SetComInitType(AutoThread::COM_INIT_STA); |
| + delegate_task_runner_ = |
| + delegate_thread_->StartWithType(base::MessageLoop::TYPE_UI); |
| +#else |
| + delegate_task_runner_ = |
| + delegate_thread_->StartWithType(base::MessageLoop::TYPE_DEFAULT); |
| +#endif |
| +} |
| + |
| +DaemonController::State DaemonController::GetState() { |
| + DCHECK(caller_task_runner_->BelongsToCurrentThread()); |
| + return delegate_->GetState(); |
| +} |
| + |
| +void DaemonController::GetConfig(const GetConfigCallback& done) { |
| + DCHECK(caller_task_runner_->BelongsToCurrentThread()); |
| + |
| + DaemonController::GetConfigCallback wrapped_done = base::Bind( |
| + &DaemonController::InvokeConfigCallbackAndScheduleNext, this, done); |
| + base::Closure request = base::Bind( |
| + &DaemonController::DoGetConfig, this, wrapped_done); |
| + ServiceOrQueueRequest(request); |
| +} |
| + |
| +void DaemonController::SetConfigAndStart( |
| + scoped_ptr<base::DictionaryValue> config, |
| + bool consent, |
| + const CompletionCallback& done) { |
| + DCHECK(caller_task_runner_->BelongsToCurrentThread()); |
| + |
| + DaemonController::CompletionCallback wrapped_done = base::Bind( |
| + &DaemonController::InvokeCompletionCallbackAndScheduleNext, this, done); |
| + base::Closure request = base::Bind( |
| + &DaemonController::DoSetConfigAndStart, this, base::Passed(&config), |
| + consent, wrapped_done); |
| + ServiceOrQueueRequest(request); |
| +} |
| + |
| +void DaemonController::UpdateConfig(scoped_ptr<base::DictionaryValue> config, |
| + const CompletionCallback& done) { |
| + DCHECK(caller_task_runner_->BelongsToCurrentThread()); |
| + |
| + DaemonController::CompletionCallback wrapped_done = base::Bind( |
| + &DaemonController::InvokeCompletionCallbackAndScheduleNext, this, done); |
| + base::Closure request = base::Bind( |
| + &DaemonController::DoUpdateConfig, this, base::Passed(&config), |
| + wrapped_done); |
| + ServiceOrQueueRequest(request); |
| +} |
| + |
| +void DaemonController::Stop(const CompletionCallback& done) { |
| + DCHECK(caller_task_runner_->BelongsToCurrentThread()); |
| + |
| + DaemonController::CompletionCallback wrapped_done = base::Bind( |
| + &DaemonController::InvokeCompletionCallbackAndScheduleNext, this, done); |
| + base::Closure request = base::Bind( |
| + &DaemonController::DoStop, this, wrapped_done); |
| + ServiceOrQueueRequest(request); |
| +} |
| + |
| +void DaemonController::SetWindow(void* window_handle) { |
| + DCHECK(caller_task_runner_->BelongsToCurrentThread()); |
| + |
| + base::Closure done = base::Bind(&DaemonController::ScheduleNext, this); |
| + base::Closure request = base::Bind( |
| + &DaemonController::DoSetWindow, this, window_handle, done); |
| + ServiceOrQueueRequest(request); |
| +} |
| + |
| +void DaemonController::GetVersion(const GetVersionCallback& done) { |
| + DCHECK(caller_task_runner_->BelongsToCurrentThread()); |
| + |
| + DaemonController::GetVersionCallback wrapped_done = base::Bind( |
| + &DaemonController::InvokeVersionCallbackAndScheduleNext, this, done); |
| + base::Closure request = base::Bind( |
| + &DaemonController::DoGetVersion, this, wrapped_done); |
| + ServiceOrQueueRequest(request); |
| +} |
| + |
| +void DaemonController::GetUsageStatsConsent( |
| + const GetUsageStatsConsentCallback& done) { |
| + DCHECK(caller_task_runner_->BelongsToCurrentThread()); |
| + |
| + DaemonController::GetUsageStatsConsentCallback wrapped_done = base::Bind( |
| + &DaemonController::InvokeConsentCallbackAndScheduleNext, this, done); |
| + base::Closure request = base::Bind( |
| + &DaemonController::DoGetUsageStatsConsent, this, wrapped_done); |
| + ServiceOrQueueRequest(request); |
| +} |
| + |
| +DaemonController::~DaemonController() { |
| + // Make sure |delegate_| is deleted on the background thread. |
| + delegate_task_runner_->DeleteSoon(FROM_HERE, delegate_.release()); |
| + |
| + // Stop the thread. |
| + delegate_task_runner_ = NULL; |
| + caller_task_runner_->DeleteSoon(FROM_HERE, delegate_thread_.release()); |
| +} |
| + |
| +void DaemonController::DoGetConfig(const GetConfigCallback& done) { |
| + if (!delegate_task_runner_->BelongsToCurrentThread()) { |
|
Sergey Ulanov
2013/09/09 18:12:31
Here and in other Do*() methods you can replace it
alexeypa (please no reviews)
2013/09/09 19:30:57
Only if DaemonController::ServiceNextRequest() pos
|
| + delegate_task_runner_->PostTask( |
| + FROM_HERE, base::Bind(&DaemonController::DoGetConfig, this, done)); |
| + return; |
| + } |
| + |
| + scoped_ptr<base::DictionaryValue> config = delegate_->GetConfig(); |
| + caller_task_runner_->PostTask(FROM_HERE, |
| + base::Bind(done, base::Passed(&config))); |
| +} |
| + |
| +void DaemonController::DoSetConfigAndStart( |
| + scoped_ptr<base::DictionaryValue> config, |
| + bool consent, |
| + const CompletionCallback& done) { |
| + if (!delegate_task_runner_->BelongsToCurrentThread()) { |
| + delegate_task_runner_->PostTask( |
| + FROM_HERE, base::Bind(&DaemonController::DoSetConfigAndStart, this, |
| + base::Passed(&config), consent, done)); |
| + return; |
| + } |
| + |
| + delegate_->SetConfigAndStart(config.Pass(), consent, done); |
| +} |
| + |
| +void DaemonController::DoUpdateConfig( |
| + scoped_ptr<base::DictionaryValue> config, |
| + const CompletionCallback& done) { |
| + if (!delegate_task_runner_->BelongsToCurrentThread()) { |
| + delegate_task_runner_->PostTask( |
| + FROM_HERE, base::Bind(&DaemonController::DoUpdateConfig, this, |
| + base::Passed(&config), done)); |
| + return; |
| + } |
| + |
| + delegate_->UpdateConfig(config.Pass(), done); |
| +} |
| + |
| +void DaemonController::DoStop(const CompletionCallback& done) { |
| + if (!delegate_task_runner_->BelongsToCurrentThread()) { |
| + delegate_task_runner_->PostTask( |
| + FROM_HERE, base::Bind(&DaemonController::DoStop, this, done)); |
| + return; |
| + } |
| + |
| + delegate_->Stop(done); |
| +} |
| + |
| +void DaemonController::DoSetWindow(void* window_handle, |
| + const base::Closure& done) { |
| + if (!delegate_task_runner_->BelongsToCurrentThread()) { |
| + delegate_task_runner_->PostTask( |
| + FROM_HERE, base::Bind(&DaemonController::DoSetWindow, this, |
| + window_handle, done)); |
| + return; |
| + } |
| + |
| + delegate_->SetWindow(window_handle); |
| + caller_task_runner_->PostTask(FROM_HERE, done); |
| +} |
| + |
| +void DaemonController::DoGetVersion(const GetVersionCallback& done) { |
| + if (!delegate_task_runner_->BelongsToCurrentThread()) { |
| + delegate_task_runner_->PostTask( |
| + FROM_HERE, base::Bind(&DaemonController::DoGetVersion, this, done)); |
| + return; |
| + } |
| + |
| + std::string version = delegate_->GetVersion(); |
| + caller_task_runner_->PostTask(FROM_HERE, base::Bind(done, version)); |
| +} |
| + |
| +void DaemonController::DoGetUsageStatsConsent( |
| + const GetUsageStatsConsentCallback& done) { |
| + if (!delegate_task_runner_->BelongsToCurrentThread()) { |
| + delegate_task_runner_->PostTask( |
| + FROM_HERE, base::Bind(&DaemonController::DoGetUsageStatsConsent, this, |
| + done)); |
| + return; |
| + } |
| + |
| + DaemonController::UsageStatsConsent consent = |
| + delegate_->GetUsageStatsConsent(); |
| + caller_task_runner_->PostTask(FROM_HERE, base::Bind(done, consent)); |
| +} |
| + |
| +void DaemonController::InvokeCompletionCallbackAndScheduleNext( |
| + const CompletionCallback& done, |
| + AsyncResult result) { |
| + if (!caller_task_runner_->BelongsToCurrentThread()) { |
| + caller_task_runner_->PostTask( |
| + FROM_HERE, |
| + base::Bind(&DaemonController::InvokeCompletionCallbackAndScheduleNext, |
| + this, done, result)); |
| + return; |
| + } |
| + |
| + done.Run(result); |
| + ScheduleNext(); |
| +} |
| + |
| +void DaemonController::InvokeConfigCallbackAndScheduleNext( |
| + const GetConfigCallback& done, |
| + scoped_ptr<base::DictionaryValue> config) { |
| + DCHECK(caller_task_runner_->BelongsToCurrentThread()); |
| + |
| + done.Run(config.Pass()); |
| + ScheduleNext(); |
| +} |
| + |
| +void DaemonController::InvokeConsentCallbackAndScheduleNext( |
| + const GetUsageStatsConsentCallback& done, |
| + const UsageStatsConsent& consent) { |
| + DCHECK(caller_task_runner_->BelongsToCurrentThread()); |
| + |
| + done.Run(consent); |
| + ScheduleNext(); |
| +} |
| + |
| +void DaemonController::InvokeVersionCallbackAndScheduleNext( |
| + const GetVersionCallback& done, |
| + const std::string& version) { |
| + DCHECK(caller_task_runner_->BelongsToCurrentThread()); |
| + |
| + done.Run(version); |
| + ScheduleNext(); |
| +} |
| + |
| +void DaemonController::ScheduleNext() { |
| + DCHECK(caller_task_runner_->BelongsToCurrentThread()); |
| + |
| + pending_requests_.pop(); |
| + ServiceNextRequest(); |
| +} |
| + |
| +void DaemonController::ServiceOrQueueRequest(const base::Closure& request) { |
| + bool servicing_request = !pending_requests_.empty(); |
| + pending_requests_.push(request); |
| + if (!servicing_request) |
| + ServiceNextRequest(); |
| +} |
| + |
| +void DaemonController::ServiceNextRequest() { |
| + if (!pending_requests_.empty()) |
| + pending_requests_.front().Run(); |
| +} |
| + |
| +} // namespace remoting |