OLD | NEW |
(Empty) | |
| 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 |
OLD | NEW |