Home | History | Annotate | Download | only in setup
      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::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 
     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 
     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 
     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 
     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 
    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 
    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 
    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 
    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 
    143 void DaemonController::DoInstallHost(const CompletionCallback& done) {
    144   DCHECK(delegate_task_runner_->BelongsToCurrentThread());
    145 
    146   delegate_->InstallHost(done);
    147 }
    148 
    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 
    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 
    166 void DaemonController::DoStop(const CompletionCallback& done) {
    167   DCHECK(delegate_task_runner_->BelongsToCurrentThread());
    168 
    169   delegate_->Stop(done);
    170 }
    171 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    238 void DaemonController::ScheduleNext() {
    239   DCHECK(caller_task_runner_->BelongsToCurrentThread());
    240 
    241   pending_requests_.pop();
    242   ServiceNextRequest();
    243 }
    244 
    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 
    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