1 // Copyright 2013 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.
5 #include "remoting/host/setup/daemon_controller.h"
8 #include "base/location.h"
9 #include "base/single_thread_task_runner.h"
10 #include "base/thread_task_runner_handle.h"
11 #include "base/values.h"
12 #include "remoting/base/auto_thread.h"
13 #include "remoting/base/auto_thread_task_runner.h"
17 // Name of the Daemon Controller's worker thread.
18 const char kDaemonControllerThreadName
[] = "Daemon Controller thread";
20 DaemonController::DaemonController(scoped_ptr
<Delegate
> delegate
)
21 : caller_task_runner_(base::ThreadTaskRunnerHandle::Get()),
22 delegate_(delegate
.Pass()) {
23 // Launch the delegate thread.
24 delegate_thread_
.reset(new AutoThread(kDaemonControllerThreadName
));
26 delegate_thread_
->SetComInitType(AutoThread::COM_INIT_STA
);
27 delegate_task_runner_
=
28 delegate_thread_
->StartWithType(base::MessageLoop::TYPE_UI
);
30 delegate_task_runner_
=
31 delegate_thread_
->StartWithType(base::MessageLoop::TYPE_DEFAULT
);
35 DaemonController::State
DaemonController::GetState() {
36 DCHECK(caller_task_runner_
->BelongsToCurrentThread());
37 return delegate_
->GetState();
40 void DaemonController::GetConfig(const GetConfigCallback
& done
) {
41 DCHECK(caller_task_runner_
->BelongsToCurrentThread());
43 DaemonController::GetConfigCallback wrapped_done
= base::Bind(
44 &DaemonController::InvokeConfigCallbackAndScheduleNext
, this, done
);
45 base::Closure request
= base::Bind(
46 &DaemonController::DoGetConfig
, this, wrapped_done
);
47 ServiceOrQueueRequest(request
);
50 void DaemonController::InstallHost(const CompletionCallback
& done
) {
51 DCHECK(caller_task_runner_
->BelongsToCurrentThread());
53 DaemonController::CompletionCallback wrapped_done
= base::Bind(
54 &DaemonController::InvokeCompletionCallbackAndScheduleNext
, this, done
);
55 base::Closure request
= base::Bind(
56 &DaemonController::DoInstallHost
, this, wrapped_done
);
57 ServiceOrQueueRequest(request
);
60 void DaemonController::SetConfigAndStart(
61 scoped_ptr
<base::DictionaryValue
> config
,
63 const CompletionCallback
& done
) {
64 DCHECK(caller_task_runner_
->BelongsToCurrentThread());
66 DaemonController::CompletionCallback wrapped_done
= base::Bind(
67 &DaemonController::InvokeCompletionCallbackAndScheduleNext
, this, done
);
68 base::Closure request
= base::Bind(
69 &DaemonController::DoSetConfigAndStart
, this, base::Passed(&config
),
70 consent
, wrapped_done
);
71 ServiceOrQueueRequest(request
);
74 void DaemonController::UpdateConfig(scoped_ptr
<base::DictionaryValue
> config
,
75 const CompletionCallback
& done
) {
76 DCHECK(caller_task_runner_
->BelongsToCurrentThread());
78 DaemonController::CompletionCallback wrapped_done
= base::Bind(
79 &DaemonController::InvokeCompletionCallbackAndScheduleNext
, this, done
);
80 base::Closure request
= base::Bind(
81 &DaemonController::DoUpdateConfig
, this, base::Passed(&config
),
83 ServiceOrQueueRequest(request
);
86 void DaemonController::Stop(const CompletionCallback
& done
) {
87 DCHECK(caller_task_runner_
->BelongsToCurrentThread());
89 DaemonController::CompletionCallback wrapped_done
= base::Bind(
90 &DaemonController::InvokeCompletionCallbackAndScheduleNext
, this, done
);
91 base::Closure request
= base::Bind(
92 &DaemonController::DoStop
, this, wrapped_done
);
93 ServiceOrQueueRequest(request
);
96 void DaemonController::SetWindow(void* window_handle
) {
97 DCHECK(caller_task_runner_
->BelongsToCurrentThread());
99 base::Closure done
= base::Bind(&DaemonController::ScheduleNext
, this);
100 base::Closure request
= base::Bind(
101 &DaemonController::DoSetWindow
, this, window_handle
, done
);
102 ServiceOrQueueRequest(request
);
105 void DaemonController::GetVersion(const GetVersionCallback
& done
) {
106 DCHECK(caller_task_runner_
->BelongsToCurrentThread());
108 DaemonController::GetVersionCallback wrapped_done
= base::Bind(
109 &DaemonController::InvokeVersionCallbackAndScheduleNext
, this, done
);
110 base::Closure request
= base::Bind(
111 &DaemonController::DoGetVersion
, this, wrapped_done
);
112 ServiceOrQueueRequest(request
);
115 void DaemonController::GetUsageStatsConsent(
116 const GetUsageStatsConsentCallback
& done
) {
117 DCHECK(caller_task_runner_
->BelongsToCurrentThread());
119 DaemonController::GetUsageStatsConsentCallback wrapped_done
= base::Bind(
120 &DaemonController::InvokeConsentCallbackAndScheduleNext
, this, done
);
121 base::Closure request
= base::Bind(
122 &DaemonController::DoGetUsageStatsConsent
, this, wrapped_done
);
123 ServiceOrQueueRequest(request
);
126 DaemonController::~DaemonController() {
127 // Make sure |delegate_| is deleted on the background thread.
128 delegate_task_runner_
->DeleteSoon(FROM_HERE
, delegate_
.release());
131 delegate_task_runner_
= NULL
;
132 caller_task_runner_
->DeleteSoon(FROM_HERE
, delegate_thread_
.release());
135 void DaemonController::DoGetConfig(const GetConfigCallback
& done
) {
136 DCHECK(delegate_task_runner_
->BelongsToCurrentThread());
138 scoped_ptr
<base::DictionaryValue
> config
= delegate_
->GetConfig();
139 caller_task_runner_
->PostTask(FROM_HERE
,
140 base::Bind(done
, base::Passed(&config
)));
143 void DaemonController::DoInstallHost(const CompletionCallback
& done
) {
144 DCHECK(delegate_task_runner_
->BelongsToCurrentThread());
146 delegate_
->InstallHost(done
);
149 void DaemonController::DoSetConfigAndStart(
150 scoped_ptr
<base::DictionaryValue
> config
,
152 const CompletionCallback
& done
) {
153 DCHECK(delegate_task_runner_
->BelongsToCurrentThread());
155 delegate_
->SetConfigAndStart(config
.Pass(), consent
, done
);
158 void DaemonController::DoUpdateConfig(
159 scoped_ptr
<base::DictionaryValue
> config
,
160 const CompletionCallback
& done
) {
161 DCHECK(delegate_task_runner_
->BelongsToCurrentThread());
163 delegate_
->UpdateConfig(config
.Pass(), done
);
166 void DaemonController::DoStop(const CompletionCallback
& done
) {
167 DCHECK(delegate_task_runner_
->BelongsToCurrentThread());
169 delegate_
->Stop(done
);
172 void DaemonController::DoSetWindow(void* window_handle
,
173 const base::Closure
& done
) {
174 DCHECK(delegate_task_runner_
->BelongsToCurrentThread());
176 delegate_
->SetWindow(window_handle
);
177 caller_task_runner_
->PostTask(FROM_HERE
, done
);
180 void DaemonController::DoGetVersion(const GetVersionCallback
& done
) {
181 DCHECK(delegate_task_runner_
->BelongsToCurrentThread());
183 std::string version
= delegate_
->GetVersion();
184 caller_task_runner_
->PostTask(FROM_HERE
, base::Bind(done
, version
));
187 void DaemonController::DoGetUsageStatsConsent(
188 const GetUsageStatsConsentCallback
& done
) {
189 DCHECK(delegate_task_runner_
->BelongsToCurrentThread());
191 DaemonController::UsageStatsConsent consent
=
192 delegate_
->GetUsageStatsConsent();
193 caller_task_runner_
->PostTask(FROM_HERE
, base::Bind(done
, consent
));
196 void DaemonController::InvokeCompletionCallbackAndScheduleNext(
197 const CompletionCallback
& done
,
198 AsyncResult result
) {
199 if (!caller_task_runner_
->BelongsToCurrentThread()) {
200 caller_task_runner_
->PostTask(
202 base::Bind(&DaemonController::InvokeCompletionCallbackAndScheduleNext
,
203 this, done
, result
));
211 void DaemonController::InvokeConfigCallbackAndScheduleNext(
212 const GetConfigCallback
& done
,
213 scoped_ptr
<base::DictionaryValue
> config
) {
214 DCHECK(caller_task_runner_
->BelongsToCurrentThread());
216 done
.Run(config
.Pass());
220 void DaemonController::InvokeConsentCallbackAndScheduleNext(
221 const GetUsageStatsConsentCallback
& done
,
222 const UsageStatsConsent
& consent
) {
223 DCHECK(caller_task_runner_
->BelongsToCurrentThread());
229 void DaemonController::InvokeVersionCallbackAndScheduleNext(
230 const GetVersionCallback
& done
,
231 const std::string
& version
) {
232 DCHECK(caller_task_runner_
->BelongsToCurrentThread());
238 void DaemonController::ScheduleNext() {
239 DCHECK(caller_task_runner_
->BelongsToCurrentThread());
241 pending_requests_
.pop();
242 ServiceNextRequest();
245 void DaemonController::ServiceOrQueueRequest(const base::Closure
& request
) {
246 bool servicing_request
= !pending_requests_
.empty();
247 pending_requests_
.push(request
);
248 if (!servicing_request
)
249 ServiceNextRequest();
252 void DaemonController::ServiceNextRequest() {
253 if (!pending_requests_
.empty())
254 delegate_task_runner_
->PostTask(FROM_HERE
, pending_requests_
.front());
257 } // namespace remoting