root/remoting/host/setup/daemon_controller.cc

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. delegate_
  2. GetState
  3. GetConfig
  4. SetConfigAndStart
  5. UpdateConfig
  6. Stop
  7. SetWindow
  8. GetVersion
  9. GetUsageStatsConsent
  10. DoGetConfig
  11. DoSetConfigAndStart
  12. DoUpdateConfig
  13. DoStop
  14. DoSetWindow
  15. DoGetVersion
  16. DoGetUsageStatsConsent
  17. InvokeCompletionCallbackAndScheduleNext
  18. InvokeConfigCallbackAndScheduleNext
  19. InvokeConsentCallbackAndScheduleNext
  20. InvokeVersionCallbackAndScheduleNext
  21. ScheduleNext
  22. ServiceOrQueueRequest
  23. ServiceNextRequest

// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "remoting/host/setup/daemon_controller.h"

#include "base/bind.h"
#include "base/location.h"
#include "base/single_thread_task_runner.h"
#include "base/thread_task_runner_handle.h"
#include "base/values.h"
#include "remoting/base/auto_thread.h"
#include "remoting/base/auto_thread_task_runner.h"

namespace remoting {

// Name of the Daemon Controller's worker thread.
const char kDaemonControllerThreadName[] = "Daemon Controller thread";

DaemonController::DaemonController(scoped_ptr<Delegate> delegate)
    : caller_task_runner_(base::ThreadTaskRunnerHandle::Get()),
      delegate_(delegate.Pass()) {
  // Launch the delegate thread.
  delegate_thread_.reset(new AutoThread(kDaemonControllerThreadName));
#if defined(OS_WIN)
  delegate_thread_->SetComInitType(AutoThread::COM_INIT_STA);
  delegate_task_runner_ =
      delegate_thread_->StartWithType(base::MessageLoop::TYPE_UI);
#else
  delegate_task_runner_ =
      delegate_thread_->StartWithType(base::MessageLoop::TYPE_DEFAULT);
#endif
}

DaemonController::State DaemonController::GetState() {
  DCHECK(caller_task_runner_->BelongsToCurrentThread());
  return delegate_->GetState();
}

void DaemonController::GetConfig(const GetConfigCallback& done) {
  DCHECK(caller_task_runner_->BelongsToCurrentThread());

  DaemonController::GetConfigCallback wrapped_done = base::Bind(
      &DaemonController::InvokeConfigCallbackAndScheduleNext, this, done);
  base::Closure request = base::Bind(
      &DaemonController::DoGetConfig, this, wrapped_done);
  ServiceOrQueueRequest(request);
}

void DaemonController::SetConfigAndStart(
    scoped_ptr<base::DictionaryValue> config,
    bool consent,
    const CompletionCallback& done) {
  DCHECK(caller_task_runner_->BelongsToCurrentThread());

  DaemonController::CompletionCallback wrapped_done = base::Bind(
      &DaemonController::InvokeCompletionCallbackAndScheduleNext, this, done);
  base::Closure request = base::Bind(
      &DaemonController::DoSetConfigAndStart, this, base::Passed(&config),
      consent, wrapped_done);
  ServiceOrQueueRequest(request);
}

void DaemonController::UpdateConfig(scoped_ptr<base::DictionaryValue> config,
                                    const CompletionCallback& done) {
  DCHECK(caller_task_runner_->BelongsToCurrentThread());

  DaemonController::CompletionCallback wrapped_done = base::Bind(
      &DaemonController::InvokeCompletionCallbackAndScheduleNext, this, done);
  base::Closure request = base::Bind(
      &DaemonController::DoUpdateConfig, this, base::Passed(&config),
      wrapped_done);
  ServiceOrQueueRequest(request);
}

void DaemonController::Stop(const CompletionCallback& done) {
  DCHECK(caller_task_runner_->BelongsToCurrentThread());

  DaemonController::CompletionCallback wrapped_done = base::Bind(
      &DaemonController::InvokeCompletionCallbackAndScheduleNext, this, done);
  base::Closure request = base::Bind(
      &DaemonController::DoStop, this, wrapped_done);
  ServiceOrQueueRequest(request);
}

void DaemonController::SetWindow(void* window_handle) {
  DCHECK(caller_task_runner_->BelongsToCurrentThread());

  base::Closure done = base::Bind(&DaemonController::ScheduleNext, this);
  base::Closure request = base::Bind(
      &DaemonController::DoSetWindow, this, window_handle, done);
  ServiceOrQueueRequest(request);
}

void DaemonController::GetVersion(const GetVersionCallback& done) {
  DCHECK(caller_task_runner_->BelongsToCurrentThread());

  DaemonController::GetVersionCallback wrapped_done = base::Bind(
      &DaemonController::InvokeVersionCallbackAndScheduleNext, this, done);
  base::Closure request = base::Bind(
      &DaemonController::DoGetVersion, this, wrapped_done);
  ServiceOrQueueRequest(request);
}

void DaemonController::GetUsageStatsConsent(
    const GetUsageStatsConsentCallback& done) {
  DCHECK(caller_task_runner_->BelongsToCurrentThread());

  DaemonController::GetUsageStatsConsentCallback wrapped_done = base::Bind(
      &DaemonController::InvokeConsentCallbackAndScheduleNext, this, done);
  base::Closure request = base::Bind(
      &DaemonController::DoGetUsageStatsConsent, this, wrapped_done);
  ServiceOrQueueRequest(request);
}

DaemonController::~DaemonController() {
  // Make sure |delegate_| is deleted on the background thread.
  delegate_task_runner_->DeleteSoon(FROM_HERE, delegate_.release());

  // Stop the thread.
  delegate_task_runner_ = NULL;
  caller_task_runner_->DeleteSoon(FROM_HERE, delegate_thread_.release());
}

void DaemonController::DoGetConfig(const GetConfigCallback& done) {
  DCHECK(delegate_task_runner_->BelongsToCurrentThread());

  scoped_ptr<base::DictionaryValue> config = delegate_->GetConfig();
  caller_task_runner_->PostTask(FROM_HERE,
                                base::Bind(done, base::Passed(&config)));
}

void DaemonController::DoSetConfigAndStart(
    scoped_ptr<base::DictionaryValue> config,
    bool consent,
    const CompletionCallback& done) {
  DCHECK(delegate_task_runner_->BelongsToCurrentThread());

  delegate_->SetConfigAndStart(config.Pass(), consent, done);
}

void DaemonController::DoUpdateConfig(
    scoped_ptr<base::DictionaryValue> config,
    const CompletionCallback& done) {
  DCHECK(delegate_task_runner_->BelongsToCurrentThread());

  delegate_->UpdateConfig(config.Pass(), done);
}

void DaemonController::DoStop(const CompletionCallback& done) {
  DCHECK(delegate_task_runner_->BelongsToCurrentThread());

  delegate_->Stop(done);
}

void DaemonController::DoSetWindow(void* window_handle,
                                   const base::Closure& done) {
  DCHECK(delegate_task_runner_->BelongsToCurrentThread());

  delegate_->SetWindow(window_handle);
  caller_task_runner_->PostTask(FROM_HERE, done);
}

void DaemonController::DoGetVersion(const GetVersionCallback& done) {
  DCHECK(delegate_task_runner_->BelongsToCurrentThread());

  std::string version = delegate_->GetVersion();
  caller_task_runner_->PostTask(FROM_HERE, base::Bind(done, version));
}

void DaemonController::DoGetUsageStatsConsent(
    const GetUsageStatsConsentCallback& done) {
  DCHECK(delegate_task_runner_->BelongsToCurrentThread());

  DaemonController::UsageStatsConsent consent =
      delegate_->GetUsageStatsConsent();
  caller_task_runner_->PostTask(FROM_HERE, base::Bind(done, consent));
}

void DaemonController::InvokeCompletionCallbackAndScheduleNext(
    const CompletionCallback& done,
    AsyncResult result) {
  if (!caller_task_runner_->BelongsToCurrentThread()) {
    caller_task_runner_->PostTask(
        FROM_HERE,
        base::Bind(&DaemonController::InvokeCompletionCallbackAndScheduleNext,
                   this, done, result));
    return;
  }

  done.Run(result);
  ScheduleNext();
}

void DaemonController::InvokeConfigCallbackAndScheduleNext(
    const GetConfigCallback& done,
    scoped_ptr<base::DictionaryValue> config) {
  DCHECK(caller_task_runner_->BelongsToCurrentThread());

  done.Run(config.Pass());
  ScheduleNext();
}

void DaemonController::InvokeConsentCallbackAndScheduleNext(
    const GetUsageStatsConsentCallback& done,
    const UsageStatsConsent& consent) {
  DCHECK(caller_task_runner_->BelongsToCurrentThread());

  done.Run(consent);
  ScheduleNext();
}

void DaemonController::InvokeVersionCallbackAndScheduleNext(
    const GetVersionCallback& done,
    const std::string& version) {
  DCHECK(caller_task_runner_->BelongsToCurrentThread());

  done.Run(version);
  ScheduleNext();
}

void DaemonController::ScheduleNext() {
  DCHECK(caller_task_runner_->BelongsToCurrentThread());

  pending_requests_.pop();
  ServiceNextRequest();
}

void DaemonController::ServiceOrQueueRequest(const base::Closure& request) {
  bool servicing_request = !pending_requests_.empty();
  pending_requests_.push(request);
  if (!servicing_request)
    ServiceNextRequest();
}

void DaemonController::ServiceNextRequest() {
  if (!pending_requests_.empty())
    delegate_task_runner_->PostTask(FROM_HERE, pending_requests_.front());
}

}  // namespace remoting

/* [<][>][^][v][top][bottom][index][help] */