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::SetConfigAndStart(
51 scoped_ptr
<base::DictionaryValue
> config
,
53 const CompletionCallback
& done
) {
54 DCHECK(caller_task_runner_
->BelongsToCurrentThread());
56 DaemonController::CompletionCallback wrapped_done
= base::Bind(
57 &DaemonController::InvokeCompletionCallbackAndScheduleNext
, this, done
);
58 base::Closure request
= base::Bind(
59 &DaemonController::DoSetConfigAndStart
, this, base::Passed(&config
),
60 consent
, wrapped_done
);
61 ServiceOrQueueRequest(request
);
64 void DaemonController::UpdateConfig(scoped_ptr
<base::DictionaryValue
> config
,
65 const CompletionCallback
& done
) {
66 DCHECK(caller_task_runner_
->BelongsToCurrentThread());
68 DaemonController::CompletionCallback wrapped_done
= base::Bind(
69 &DaemonController::InvokeCompletionCallbackAndScheduleNext
, this, done
);
70 base::Closure request
= base::Bind(
71 &DaemonController::DoUpdateConfig
, this, base::Passed(&config
),
73 ServiceOrQueueRequest(request
);
76 void DaemonController::Stop(const CompletionCallback
& done
) {
77 DCHECK(caller_task_runner_
->BelongsToCurrentThread());
79 DaemonController::CompletionCallback wrapped_done
= base::Bind(
80 &DaemonController::InvokeCompletionCallbackAndScheduleNext
, this, done
);
81 base::Closure request
= base::Bind(
82 &DaemonController::DoStop
, this, wrapped_done
);
83 ServiceOrQueueRequest(request
);
86 void DaemonController::GetUsageStatsConsent(
87 const GetUsageStatsConsentCallback
& done
) {
88 DCHECK(caller_task_runner_
->BelongsToCurrentThread());
90 DaemonController::GetUsageStatsConsentCallback wrapped_done
= base::Bind(
91 &DaemonController::InvokeConsentCallbackAndScheduleNext
, this, done
);
92 base::Closure request
= base::Bind(
93 &DaemonController::DoGetUsageStatsConsent
, this, wrapped_done
);
94 ServiceOrQueueRequest(request
);
97 DaemonController::~DaemonController() {
98 // Make sure |delegate_| is deleted on the background thread.
99 delegate_task_runner_
->DeleteSoon(FROM_HERE
, delegate_
.release());
102 delegate_task_runner_
= nullptr;
103 caller_task_runner_
->DeleteSoon(FROM_HERE
, delegate_thread_
.release());
106 void DaemonController::DoGetConfig(const GetConfigCallback
& done
) {
107 DCHECK(delegate_task_runner_
->BelongsToCurrentThread());
109 scoped_ptr
<base::DictionaryValue
> config
= delegate_
->GetConfig();
110 caller_task_runner_
->PostTask(FROM_HERE
,
111 base::Bind(done
, base::Passed(&config
)));
114 void DaemonController::DoSetConfigAndStart(
115 scoped_ptr
<base::DictionaryValue
> config
,
117 const CompletionCallback
& done
) {
118 DCHECK(delegate_task_runner_
->BelongsToCurrentThread());
120 delegate_
->SetConfigAndStart(config
.Pass(), consent
, done
);
123 void DaemonController::DoUpdateConfig(
124 scoped_ptr
<base::DictionaryValue
> config
,
125 const CompletionCallback
& done
) {
126 DCHECK(delegate_task_runner_
->BelongsToCurrentThread());
128 delegate_
->UpdateConfig(config
.Pass(), done
);
131 void DaemonController::DoStop(const CompletionCallback
& done
) {
132 DCHECK(delegate_task_runner_
->BelongsToCurrentThread());
134 delegate_
->Stop(done
);
137 void DaemonController::DoGetUsageStatsConsent(
138 const GetUsageStatsConsentCallback
& done
) {
139 DCHECK(delegate_task_runner_
->BelongsToCurrentThread());
141 DaemonController::UsageStatsConsent consent
=
142 delegate_
->GetUsageStatsConsent();
143 caller_task_runner_
->PostTask(FROM_HERE
, base::Bind(done
, consent
));
146 void DaemonController::InvokeCompletionCallbackAndScheduleNext(
147 const CompletionCallback
& done
,
148 AsyncResult result
) {
149 if (!caller_task_runner_
->BelongsToCurrentThread()) {
150 caller_task_runner_
->PostTask(
152 base::Bind(&DaemonController::InvokeCompletionCallbackAndScheduleNext
,
153 this, done
, result
));
161 void DaemonController::InvokeConfigCallbackAndScheduleNext(
162 const GetConfigCallback
& done
,
163 scoped_ptr
<base::DictionaryValue
> config
) {
164 DCHECK(caller_task_runner_
->BelongsToCurrentThread());
166 done
.Run(config
.Pass());
170 void DaemonController::InvokeConsentCallbackAndScheduleNext(
171 const GetUsageStatsConsentCallback
& done
,
172 const UsageStatsConsent
& consent
) {
173 DCHECK(caller_task_runner_
->BelongsToCurrentThread());
179 void DaemonController::ScheduleNext() {
180 DCHECK(caller_task_runner_
->BelongsToCurrentThread());
182 pending_requests_
.pop();
183 ServiceNextRequest();
186 void DaemonController::ServiceOrQueueRequest(const base::Closure
& request
) {
187 bool servicing_request
= !pending_requests_
.empty();
188 pending_requests_
.push(request
);
189 if (!servicing_request
)
190 ServiceNextRequest();
193 void DaemonController::ServiceNextRequest() {
194 if (!pending_requests_
.empty())
195 delegate_task_runner_
->PostTask(FROM_HERE
, pending_requests_
.front());
198 } // namespace remoting