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..2befd413310c1237abbce8453018eb20a78406c0 |
--- /dev/null |
+++ b/remoting/host/setup/daemon_controller.cc |
@@ -0,0 +1,241 @@ |
+// 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) { |
+ DCHECK(delegate_task_runner_->BelongsToCurrentThread()); |
+ |
+ 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) { |
+ DCHECK(delegate_task_runner_->BelongsToCurrentThread()); |
+ |
+ delegate_->SetConfigAndStart(config.Pass(), consent, done); |
+} |
+ |
+void DaemonController::DoUpdateConfig( |
+ scoped_ptr<base::DictionaryValue> config, |
+ const CompletionCallback& done) { |
+ DCHECK(delegate_task_runner_->BelongsToCurrentThread()); |
+ |
+ delegate_->UpdateConfig(config.Pass(), done); |
+} |
+ |
+void DaemonController::DoStop(const CompletionCallback& done) { |
+ DCHECK(delegate_task_runner_->BelongsToCurrentThread()); |
+ |
+ delegate_->Stop(done); |
+} |
+ |
+void DaemonController::DoSetWindow(void* window_handle, |
+ const base::Closure& done) { |
+ DCHECK(delegate_task_runner_->BelongsToCurrentThread()); |
+ |
+ delegate_->SetWindow(window_handle); |
+ caller_task_runner_->PostTask(FROM_HERE, done); |
+} |
+ |
+void DaemonController::DoGetVersion(const GetVersionCallback& done) { |
+ DCHECK(delegate_task_runner_->BelongsToCurrentThread()); |
+ |
+ std::string version = delegate_->GetVersion(); |
+ caller_task_runner_->PostTask(FROM_HERE, base::Bind(done, version)); |
+} |
+ |
+void DaemonController::DoGetUsageStatsConsent( |
+ const GetUsageStatsConsentCallback& done) { |
+ DCHECK(delegate_task_runner_->BelongsToCurrentThread()); |
+ |
+ 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()) |
+ delegate_task_runner_->PostTask(FROM_HERE, pending_requests_.front()); |
+} |
+ |
+} // namespace remoting |