• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
DaemonController(scoped_ptr<Delegate> delegate)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 
GetState()35 DaemonController::State DaemonController::GetState() {
36   DCHECK(caller_task_runner_->BelongsToCurrentThread());
37   return delegate_->GetState();
38 }
39 
GetConfig(const GetConfigCallback & done)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 
InstallHost(const CompletionCallback & done)50 void DaemonController::InstallHost(const CompletionCallback& done) {
51   DCHECK(caller_task_runner_->BelongsToCurrentThread());
52 
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);
58 }
59 
SetConfigAndStart(scoped_ptr<base::DictionaryValue> config,bool consent,const CompletionCallback & done)60 void DaemonController::SetConfigAndStart(
61     scoped_ptr<base::DictionaryValue> config,
62     bool consent,
63     const CompletionCallback& done) {
64   DCHECK(caller_task_runner_->BelongsToCurrentThread());
65 
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);
72 }
73 
UpdateConfig(scoped_ptr<base::DictionaryValue> config,const CompletionCallback & done)74 void DaemonController::UpdateConfig(scoped_ptr<base::DictionaryValue> config,
75                                     const CompletionCallback& done) {
76   DCHECK(caller_task_runner_->BelongsToCurrentThread());
77 
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),
82       wrapped_done);
83   ServiceOrQueueRequest(request);
84 }
85 
Stop(const CompletionCallback & done)86 void DaemonController::Stop(const CompletionCallback& done) {
87   DCHECK(caller_task_runner_->BelongsToCurrentThread());
88 
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);
94 }
95 
SetWindow(void * window_handle)96 void DaemonController::SetWindow(void* window_handle) {
97   DCHECK(caller_task_runner_->BelongsToCurrentThread());
98 
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);
103 }
104 
GetVersion(const GetVersionCallback & done)105 void DaemonController::GetVersion(const GetVersionCallback& done) {
106   DCHECK(caller_task_runner_->BelongsToCurrentThread());
107 
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);
113 }
114 
GetUsageStatsConsent(const GetUsageStatsConsentCallback & done)115 void DaemonController::GetUsageStatsConsent(
116     const GetUsageStatsConsentCallback& done) {
117   DCHECK(caller_task_runner_->BelongsToCurrentThread());
118 
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);
124 }
125 
~DaemonController()126 DaemonController::~DaemonController() {
127   // Make sure |delegate_| is deleted on the background thread.
128   delegate_task_runner_->DeleteSoon(FROM_HERE, delegate_.release());
129 
130   // Stop the thread.
131   delegate_task_runner_ = NULL;
132   caller_task_runner_->DeleteSoon(FROM_HERE, delegate_thread_.release());
133 }
134 
DoGetConfig(const GetConfigCallback & done)135 void DaemonController::DoGetConfig(const GetConfigCallback& done) {
136   DCHECK(delegate_task_runner_->BelongsToCurrentThread());
137 
138   scoped_ptr<base::DictionaryValue> config = delegate_->GetConfig();
139   caller_task_runner_->PostTask(FROM_HERE,
140                                 base::Bind(done, base::Passed(&config)));
141 }
142 
DoInstallHost(const CompletionCallback & done)143 void DaemonController::DoInstallHost(const CompletionCallback& done) {
144   DCHECK(delegate_task_runner_->BelongsToCurrentThread());
145 
146   delegate_->InstallHost(done);
147 }
148 
DoSetConfigAndStart(scoped_ptr<base::DictionaryValue> config,bool consent,const CompletionCallback & done)149 void DaemonController::DoSetConfigAndStart(
150     scoped_ptr<base::DictionaryValue> config,
151     bool consent,
152     const CompletionCallback& done) {
153   DCHECK(delegate_task_runner_->BelongsToCurrentThread());
154 
155   delegate_->SetConfigAndStart(config.Pass(), consent, done);
156 }
157 
DoUpdateConfig(scoped_ptr<base::DictionaryValue> config,const CompletionCallback & done)158 void DaemonController::DoUpdateConfig(
159     scoped_ptr<base::DictionaryValue> config,
160     const CompletionCallback& done) {
161   DCHECK(delegate_task_runner_->BelongsToCurrentThread());
162 
163   delegate_->UpdateConfig(config.Pass(), done);
164 }
165 
DoStop(const CompletionCallback & done)166 void DaemonController::DoStop(const CompletionCallback& done) {
167   DCHECK(delegate_task_runner_->BelongsToCurrentThread());
168 
169   delegate_->Stop(done);
170 }
171 
DoSetWindow(void * window_handle,const base::Closure & done)172 void DaemonController::DoSetWindow(void* window_handle,
173                                    const base::Closure& done) {
174   DCHECK(delegate_task_runner_->BelongsToCurrentThread());
175 
176   delegate_->SetWindow(window_handle);
177   caller_task_runner_->PostTask(FROM_HERE, done);
178 }
179 
DoGetVersion(const GetVersionCallback & done)180 void DaemonController::DoGetVersion(const GetVersionCallback& done) {
181   DCHECK(delegate_task_runner_->BelongsToCurrentThread());
182 
183   std::string version = delegate_->GetVersion();
184   caller_task_runner_->PostTask(FROM_HERE, base::Bind(done, version));
185 }
186 
DoGetUsageStatsConsent(const GetUsageStatsConsentCallback & done)187 void DaemonController::DoGetUsageStatsConsent(
188     const GetUsageStatsConsentCallback& done) {
189   DCHECK(delegate_task_runner_->BelongsToCurrentThread());
190 
191   DaemonController::UsageStatsConsent consent =
192       delegate_->GetUsageStatsConsent();
193   caller_task_runner_->PostTask(FROM_HERE, base::Bind(done, consent));
194 }
195 
InvokeCompletionCallbackAndScheduleNext(const CompletionCallback & done,AsyncResult result)196 void DaemonController::InvokeCompletionCallbackAndScheduleNext(
197     const CompletionCallback& done,
198     AsyncResult result) {
199   if (!caller_task_runner_->BelongsToCurrentThread()) {
200     caller_task_runner_->PostTask(
201         FROM_HERE,
202         base::Bind(&DaemonController::InvokeCompletionCallbackAndScheduleNext,
203                    this, done, result));
204     return;
205   }
206 
207   done.Run(result);
208   ScheduleNext();
209 }
210 
InvokeConfigCallbackAndScheduleNext(const GetConfigCallback & done,scoped_ptr<base::DictionaryValue> config)211 void DaemonController::InvokeConfigCallbackAndScheduleNext(
212     const GetConfigCallback& done,
213     scoped_ptr<base::DictionaryValue> config) {
214   DCHECK(caller_task_runner_->BelongsToCurrentThread());
215 
216   done.Run(config.Pass());
217   ScheduleNext();
218 }
219 
InvokeConsentCallbackAndScheduleNext(const GetUsageStatsConsentCallback & done,const UsageStatsConsent & consent)220 void DaemonController::InvokeConsentCallbackAndScheduleNext(
221     const GetUsageStatsConsentCallback& done,
222     const UsageStatsConsent& consent) {
223   DCHECK(caller_task_runner_->BelongsToCurrentThread());
224 
225   done.Run(consent);
226   ScheduleNext();
227 }
228 
InvokeVersionCallbackAndScheduleNext(const GetVersionCallback & done,const std::string & version)229 void DaemonController::InvokeVersionCallbackAndScheduleNext(
230     const GetVersionCallback& done,
231     const std::string& version) {
232   DCHECK(caller_task_runner_->BelongsToCurrentThread());
233 
234   done.Run(version);
235   ScheduleNext();
236 }
237 
ScheduleNext()238 void DaemonController::ScheduleNext() {
239   DCHECK(caller_task_runner_->BelongsToCurrentThread());
240 
241   pending_requests_.pop();
242   ServiceNextRequest();
243 }
244 
ServiceOrQueueRequest(const base::Closure & request)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();
250 }
251 
ServiceNextRequest()252 void DaemonController::ServiceNextRequest() {
253   if (!pending_requests_.empty())
254     delegate_task_runner_->PostTask(FROM_HERE, pending_requests_.front());
255 }
256 
257 }  // namespace remoting
258