- add sources.
[platform/framework/web/crosswalk.git] / src / remoting / host / setup / daemon_controller.cc
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.
4
5 #include "remoting/host/setup/daemon_controller.h"
6
7 #include "base/bind.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"
14
15 namespace remoting {
16
17 // Name of the Daemon Controller's worker thread.
18 const char kDaemonControllerThreadName[] = "Daemon Controller thread";
19
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));
25 #if defined(OS_WIN)
26   delegate_thread_->SetComInitType(AutoThread::COM_INIT_STA);
27   delegate_task_runner_ =
28       delegate_thread_->StartWithType(base::MessageLoop::TYPE_UI);
29 #else
30   delegate_task_runner_ =
31       delegate_thread_->StartWithType(base::MessageLoop::TYPE_DEFAULT);
32 #endif
33 }
34
35 DaemonController::State DaemonController::GetState() {
36   DCHECK(caller_task_runner_->BelongsToCurrentThread());
37   return delegate_->GetState();
38 }
39
40 void DaemonController::GetConfig(const GetConfigCallback& done) {
41   DCHECK(caller_task_runner_->BelongsToCurrentThread());
42
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);
48 }
49
50 void DaemonController::SetConfigAndStart(
51     scoped_ptr<base::DictionaryValue> config,
52     bool consent,
53     const CompletionCallback& done) {
54   DCHECK(caller_task_runner_->BelongsToCurrentThread());
55
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);
62 }
63
64 void DaemonController::UpdateConfig(scoped_ptr<base::DictionaryValue> config,
65                                     const CompletionCallback& done) {
66   DCHECK(caller_task_runner_->BelongsToCurrentThread());
67
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),
72       wrapped_done);
73   ServiceOrQueueRequest(request);
74 }
75
76 void DaemonController::Stop(const CompletionCallback& done) {
77   DCHECK(caller_task_runner_->BelongsToCurrentThread());
78
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);
84 }
85
86 void DaemonController::SetWindow(void* window_handle) {
87   DCHECK(caller_task_runner_->BelongsToCurrentThread());
88
89   base::Closure done = base::Bind(&DaemonController::ScheduleNext, this);
90   base::Closure request = base::Bind(
91       &DaemonController::DoSetWindow, this, window_handle, done);
92   ServiceOrQueueRequest(request);
93 }
94
95 void DaemonController::GetVersion(const GetVersionCallback& done) {
96   DCHECK(caller_task_runner_->BelongsToCurrentThread());
97
98   DaemonController::GetVersionCallback wrapped_done = base::Bind(
99       &DaemonController::InvokeVersionCallbackAndScheduleNext, this, done);
100   base::Closure request = base::Bind(
101       &DaemonController::DoGetVersion, this, wrapped_done);
102   ServiceOrQueueRequest(request);
103 }
104
105 void DaemonController::GetUsageStatsConsent(
106     const GetUsageStatsConsentCallback& done) {
107   DCHECK(caller_task_runner_->BelongsToCurrentThread());
108
109   DaemonController::GetUsageStatsConsentCallback wrapped_done = base::Bind(
110       &DaemonController::InvokeConsentCallbackAndScheduleNext, this, done);
111   base::Closure request = base::Bind(
112       &DaemonController::DoGetUsageStatsConsent, this, wrapped_done);
113   ServiceOrQueueRequest(request);
114 }
115
116 DaemonController::~DaemonController() {
117   // Make sure |delegate_| is deleted on the background thread.
118   delegate_task_runner_->DeleteSoon(FROM_HERE, delegate_.release());
119
120   // Stop the thread.
121   delegate_task_runner_ = NULL;
122   caller_task_runner_->DeleteSoon(FROM_HERE, delegate_thread_.release());
123 }
124
125 void DaemonController::DoGetConfig(const GetConfigCallback& done) {
126   DCHECK(delegate_task_runner_->BelongsToCurrentThread());
127
128   scoped_ptr<base::DictionaryValue> config = delegate_->GetConfig();
129   caller_task_runner_->PostTask(FROM_HERE,
130                                 base::Bind(done, base::Passed(&config)));
131 }
132
133 void DaemonController::DoSetConfigAndStart(
134     scoped_ptr<base::DictionaryValue> config,
135     bool consent,
136     const CompletionCallback& done) {
137   DCHECK(delegate_task_runner_->BelongsToCurrentThread());
138
139   delegate_->SetConfigAndStart(config.Pass(), consent, done);
140 }
141
142 void DaemonController::DoUpdateConfig(
143     scoped_ptr<base::DictionaryValue> config,
144     const CompletionCallback& done) {
145   DCHECK(delegate_task_runner_->BelongsToCurrentThread());
146
147   delegate_->UpdateConfig(config.Pass(), done);
148 }
149
150 void DaemonController::DoStop(const CompletionCallback& done) {
151   DCHECK(delegate_task_runner_->BelongsToCurrentThread());
152
153   delegate_->Stop(done);
154 }
155
156 void DaemonController::DoSetWindow(void* window_handle,
157                                    const base::Closure& done) {
158   DCHECK(delegate_task_runner_->BelongsToCurrentThread());
159
160   delegate_->SetWindow(window_handle);
161   caller_task_runner_->PostTask(FROM_HERE, done);
162 }
163
164 void DaemonController::DoGetVersion(const GetVersionCallback& done) {
165   DCHECK(delegate_task_runner_->BelongsToCurrentThread());
166
167   std::string version = delegate_->GetVersion();
168   caller_task_runner_->PostTask(FROM_HERE, base::Bind(done, version));
169 }
170
171 void DaemonController::DoGetUsageStatsConsent(
172     const GetUsageStatsConsentCallback& done) {
173   DCHECK(delegate_task_runner_->BelongsToCurrentThread());
174
175   DaemonController::UsageStatsConsent consent =
176       delegate_->GetUsageStatsConsent();
177   caller_task_runner_->PostTask(FROM_HERE, base::Bind(done, consent));
178 }
179
180 void DaemonController::InvokeCompletionCallbackAndScheduleNext(
181     const CompletionCallback& done,
182     AsyncResult result) {
183   if (!caller_task_runner_->BelongsToCurrentThread()) {
184     caller_task_runner_->PostTask(
185         FROM_HERE,
186         base::Bind(&DaemonController::InvokeCompletionCallbackAndScheduleNext,
187                    this, done, result));
188     return;
189   }
190
191   done.Run(result);
192   ScheduleNext();
193 }
194
195 void DaemonController::InvokeConfigCallbackAndScheduleNext(
196     const GetConfigCallback& done,
197     scoped_ptr<base::DictionaryValue> config) {
198   DCHECK(caller_task_runner_->BelongsToCurrentThread());
199
200   done.Run(config.Pass());
201   ScheduleNext();
202 }
203
204 void DaemonController::InvokeConsentCallbackAndScheduleNext(
205     const GetUsageStatsConsentCallback& done,
206     const UsageStatsConsent& consent) {
207   DCHECK(caller_task_runner_->BelongsToCurrentThread());
208
209   done.Run(consent);
210   ScheduleNext();
211 }
212
213 void DaemonController::InvokeVersionCallbackAndScheduleNext(
214     const GetVersionCallback& done,
215     const std::string& version) {
216   DCHECK(caller_task_runner_->BelongsToCurrentThread());
217
218   done.Run(version);
219   ScheduleNext();
220 }
221
222 void DaemonController::ScheduleNext() {
223   DCHECK(caller_task_runner_->BelongsToCurrentThread());
224
225   pending_requests_.pop();
226   ServiceNextRequest();
227 }
228
229 void DaemonController::ServiceOrQueueRequest(const base::Closure& request) {
230   bool servicing_request = !pending_requests_.empty();
231   pending_requests_.push(request);
232   if (!servicing_request)
233     ServiceNextRequest();
234 }
235
236 void DaemonController::ServiceNextRequest() {
237   if (!pending_requests_.empty())
238     delegate_task_runner_->PostTask(FROM_HERE, pending_requests_.front());
239 }
240
241 }  // namespace remoting