Commit 8c5d6c02 authored by alexeypa@chromium.org's avatar alexeypa@chromium.org

Refactor the daemon controller so that the callbacks are called on the caller thread.

This CL switches DaemonController to the same model that is used by PairingRegistry. DaemonController becomes a ref-counted object responsible for dispatching calls between threads. Platform-specific logic is implemented in non thread-safe delegate class. Most of the delegate's methods are synchronous and are running on a backgorund thread.

BUG=173509

Review URL: https://chromiumcodereview.appspot.com/23606019

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@222162 0039d316-1c4b-4281-b951-d872f2087c98
parent d5049719
...@@ -645,7 +645,6 @@ HostNPScriptObject::HostNPScriptObject( ...@@ -645,7 +645,6 @@ HostNPScriptObject::HostNPScriptObject(
plugin_task_runner_(plugin_task_runner), plugin_task_runner_(plugin_task_runner),
am_currently_logging_(false), am_currently_logging_(false),
state_(kDisconnected), state_(kDisconnected),
daemon_controller_(DaemonController::Create()),
weak_factory_(this), weak_factory_(this),
weak_ptr_(weak_factory_.GetWeakPtr()) { weak_ptr_(weak_factory_.GetWeakPtr()) {
DCHECK(plugin_task_runner_->BelongsToCurrentThread()); DCHECK(plugin_task_runner_->BelongsToCurrentThread());
...@@ -667,6 +666,8 @@ HostNPScriptObject::HostNPScriptObject( ...@@ -667,6 +666,8 @@ HostNPScriptObject::HostNPScriptObject(
new base::ThreadTaskRunnerHandle(plugin_task_runner_)); new base::ThreadTaskRunnerHandle(plugin_task_runner_));
} }
daemon_controller_ = DaemonController::Create();
ServiceUrls* service_urls = ServiceUrls::GetInstance(); ServiceUrls* service_urls = ServiceUrls::GetInstance();
bool xmpp_server_valid = net::ParseHostAndPort( bool xmpp_server_valid = net::ParseHostAndPort(
service_urls->xmpp_server_address(), service_urls->xmpp_server_address(),
...@@ -1255,8 +1256,6 @@ bool HostNPScriptObject::UpdateDaemonConfig(const NPVariant* args, ...@@ -1255,8 +1256,6 @@ bool HostNPScriptObject::UpdateDaemonConfig(const NPVariant* args,
return false; return false;
} }
// TODO(wez): Pass a static method here, that will post the result
// back to us on the right thread (crbug.com/156257).
daemon_controller_->UpdateConfig( daemon_controller_->UpdateConfig(
config_dict.Pass(), config_dict.Pass(),
base::Bind(&HostNPScriptObject::InvokeAsyncResultCallback, base::Bind(&HostNPScriptObject::InvokeAsyncResultCallback,
...@@ -1278,8 +1277,6 @@ bool HostNPScriptObject::GetDaemonConfig(const NPVariant* args, ...@@ -1278,8 +1277,6 @@ bool HostNPScriptObject::GetDaemonConfig(const NPVariant* args,
return false; return false;
} }
// TODO(wez): Pass a static method here, that will post the result
// back to us on the right thread (crbug.com/156257).
daemon_controller_->GetConfig( daemon_controller_->GetConfig(
base::Bind(&HostNPScriptObject::InvokeGetDaemonConfigCallback, base::Bind(&HostNPScriptObject::InvokeGetDaemonConfigCallback,
base::Unretained(this), callback_obj)); base::Unretained(this), callback_obj));
...@@ -1301,8 +1298,6 @@ bool HostNPScriptObject::GetDaemonVersion(const NPVariant* args, ...@@ -1301,8 +1298,6 @@ bool HostNPScriptObject::GetDaemonVersion(const NPVariant* args,
return false; return false;
} }
// TODO(wez): Pass a static method here, that will post the result
// back to us on the right thread (crbug.com/156257).
daemon_controller_->GetVersion( daemon_controller_->GetVersion(
base::Bind(&HostNPScriptObject::InvokeGetDaemonVersionCallback, base::Bind(&HostNPScriptObject::InvokeGetDaemonVersionCallback,
base::Unretained(this), callback_obj)); base::Unretained(this), callback_obj));
...@@ -1349,8 +1344,6 @@ bool HostNPScriptObject::GetUsageStatsConsent(const NPVariant* args, ...@@ -1349,8 +1344,6 @@ bool HostNPScriptObject::GetUsageStatsConsent(const NPVariant* args,
return false; return false;
} }
// TODO(wez): Pass a static method here, that will post the result
// back to us on the right thread (crbug.com/156257).
daemon_controller_->GetUsageStatsConsent( daemon_controller_->GetUsageStatsConsent(
base::Bind(&HostNPScriptObject::InvokeGetUsageStatsConsentCallback, base::Bind(&HostNPScriptObject::InvokeGetUsageStatsConsentCallback,
base::Unretained(this), callback_obj)); base::Unretained(this), callback_obj));
...@@ -1389,8 +1382,6 @@ bool HostNPScriptObject::StartDaemon(const NPVariant* args, ...@@ -1389,8 +1382,6 @@ bool HostNPScriptObject::StartDaemon(const NPVariant* args,
return false; return false;
} }
// TODO(wez): Pass a static method here, that will post the result
// back to us on the right thread (crbug.com/156257).
daemon_controller_->SetConfigAndStart( daemon_controller_->SetConfigAndStart(
config_dict.Pass(), config_dict.Pass(),
NPVARIANT_TO_BOOLEAN(args[1]), NPVARIANT_TO_BOOLEAN(args[1]),
...@@ -1415,8 +1406,6 @@ bool HostNPScriptObject::StopDaemon(const NPVariant* args, ...@@ -1415,8 +1406,6 @@ bool HostNPScriptObject::StopDaemon(const NPVariant* args,
return false; return false;
} }
// TODO(wez): Pass a static method here, that will post the result
// back to us on the right thread (crbug.com/156257).
daemon_controller_->Stop( daemon_controller_->Stop(
base::Bind(&HostNPScriptObject::InvokeAsyncResultCallback, base::Bind(&HostNPScriptObject::InvokeAsyncResultCallback,
base::Unretained(this), callback_obj)); base::Unretained(this), callback_obj));
...@@ -1558,13 +1547,7 @@ void HostNPScriptObject::InvokeGenerateKeyPairCallback( ...@@ -1558,13 +1547,7 @@ void HostNPScriptObject::InvokeGenerateKeyPairCallback(
void HostNPScriptObject::InvokeAsyncResultCallback( void HostNPScriptObject::InvokeAsyncResultCallback(
const ScopedRefNPObject& callback, const ScopedRefNPObject& callback,
DaemonController::AsyncResult result) { DaemonController::AsyncResult result) {
if (!plugin_task_runner_->BelongsToCurrentThread()) { DCHECK(plugin_task_runner_->BelongsToCurrentThread());
plugin_task_runner_->PostTask(
FROM_HERE, base::Bind(
&HostNPScriptObject::InvokeAsyncResultCallback,
weak_ptr_, callback, result));
return;
}
NPVariant result_var; NPVariant result_var;
INT32_TO_NPVARIANT(static_cast<int32>(result), result_var); INT32_TO_NPVARIANT(static_cast<int32>(result), result_var);
...@@ -1591,13 +1574,7 @@ void HostNPScriptObject::InvokeBooleanCallback( ...@@ -1591,13 +1574,7 @@ void HostNPScriptObject::InvokeBooleanCallback(
void HostNPScriptObject::InvokeGetDaemonConfigCallback( void HostNPScriptObject::InvokeGetDaemonConfigCallback(
const ScopedRefNPObject& callback, const ScopedRefNPObject& callback,
scoped_ptr<base::DictionaryValue> config) { scoped_ptr<base::DictionaryValue> config) {
if (!plugin_task_runner_->BelongsToCurrentThread()) { DCHECK(plugin_task_runner_->BelongsToCurrentThread());
plugin_task_runner_->PostTask(
FROM_HERE, base::Bind(
&HostNPScriptObject::InvokeGetDaemonConfigCallback,
weak_ptr_, callback, base::Passed(&config)));
return;
}
// There is no easy way to create a dictionary from an NPAPI plugin // There is no easy way to create a dictionary from an NPAPI plugin
// so we have to serialize the dictionary to pass it to JavaScript. // so we have to serialize the dictionary to pass it to JavaScript.
...@@ -1612,13 +1589,7 @@ void HostNPScriptObject::InvokeGetDaemonConfigCallback( ...@@ -1612,13 +1589,7 @@ void HostNPScriptObject::InvokeGetDaemonConfigCallback(
void HostNPScriptObject::InvokeGetDaemonVersionCallback( void HostNPScriptObject::InvokeGetDaemonVersionCallback(
const ScopedRefNPObject& callback, const std::string& version) { const ScopedRefNPObject& callback, const std::string& version) {
if (!plugin_task_runner_->BelongsToCurrentThread()) { DCHECK(plugin_task_runner_->BelongsToCurrentThread());
plugin_task_runner_->PostTask(
FROM_HERE, base::Bind(
&HostNPScriptObject::InvokeGetDaemonVersionCallback,
weak_ptr_, callback, version));
return;
}
NPVariant version_val = NPVariantFromString(version); NPVariant version_val = NPVariantFromString(version);
InvokeAndIgnoreResult(callback.get(), &version_val, 1); InvokeAndIgnoreResult(callback.get(), &version_val, 1);
...@@ -1646,22 +1617,13 @@ void HostNPScriptObject::InvokeGetPairedClientsCallback( ...@@ -1646,22 +1617,13 @@ void HostNPScriptObject::InvokeGetPairedClientsCallback(
void HostNPScriptObject::InvokeGetUsageStatsConsentCallback( void HostNPScriptObject::InvokeGetUsageStatsConsentCallback(
const ScopedRefNPObject& callback, const ScopedRefNPObject& callback,
bool supported, const DaemonController::UsageStatsConsent& consent) {
bool allowed, DCHECK(plugin_task_runner_->BelongsToCurrentThread());
bool set_by_policy) {
if (!plugin_task_runner_->BelongsToCurrentThread()) {
plugin_task_runner_->PostTask(
FROM_HERE, base::Bind(
&HostNPScriptObject::InvokeGetUsageStatsConsentCallback,
weak_ptr_, callback, supported, allowed,
set_by_policy));
return;
}
NPVariant params[3]; NPVariant params[3];
BOOLEAN_TO_NPVARIANT(supported, params[0]); BOOLEAN_TO_NPVARIANT(consent.supported, params[0]);
BOOLEAN_TO_NPVARIANT(allowed, params[1]); BOOLEAN_TO_NPVARIANT(consent.allowed, params[1]);
BOOLEAN_TO_NPVARIANT(set_by_policy, params[2]); BOOLEAN_TO_NPVARIANT(consent.set_by_policy, params[2]);
InvokeAndIgnoreResult(callback.get(), params, arraysize(params)); InvokeAndIgnoreResult(callback.get(), params, arraysize(params));
g_npnetscape_funcs->releasevariantvalue(&(params[0])); g_npnetscape_funcs->releasevariantvalue(&(params[0]));
g_npnetscape_funcs->releasevariantvalue(&(params[1])); g_npnetscape_funcs->releasevariantvalue(&(params[1]));
......
...@@ -255,10 +255,9 @@ class HostNPScriptObject { ...@@ -255,10 +255,9 @@ class HostNPScriptObject {
scoped_ptr<base::ListValue> paired_clients); scoped_ptr<base::ListValue> paired_clients);
// Callback handler for DaemonController::GetUsageStatsConsent(). // Callback handler for DaemonController::GetUsageStatsConsent().
void InvokeGetUsageStatsConsentCallback(const ScopedRefNPObject& callback, void InvokeGetUsageStatsConsentCallback(
bool supported, const ScopedRefNPObject& callback,
bool allowed, const DaemonController::UsageStatsConsent& consent);
bool set_by_policy);
////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////
// Basic helper methods used for both It2Me and Me2me. // Basic helper methods used for both It2Me and Me2me.
...@@ -315,7 +314,7 @@ class HostNPScriptObject { ...@@ -315,7 +314,7 @@ class HostNPScriptObject {
// Me2Me host state. // Me2Me host state.
// Platform-specific installation & configuration implementation. // Platform-specific installation & configuration implementation.
scoped_ptr<DaemonController> daemon_controller_; scoped_refptr<DaemonController> daemon_controller_;
// TODO(sergeyu): Replace this thread with // TODO(sergeyu): Replace this thread with
// SequencedWorkerPool. Problem is that SequencedWorkerPool relies // SequencedWorkerPool. Problem is that SequencedWorkerPool relies
......
// 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
...@@ -5,18 +5,24 @@ ...@@ -5,18 +5,24 @@
#ifndef REMOTING_HOST_SETUP_DAEMON_CONTROLLER_H_ #ifndef REMOTING_HOST_SETUP_DAEMON_CONTROLLER_H_
#define REMOTING_HOST_SETUP_DAEMON_CONTROLLER_H_ #define REMOTING_HOST_SETUP_DAEMON_CONTROLLER_H_
#include <queue>
#include <string> #include <string>
#include "base/callback_forward.h" #include "base/callback.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
namespace base { namespace base {
class DictionaryValue; class DictionaryValue;
class SingleThreadTaskRunner;
} // namespace base } // namespace base
namespace remoting { namespace remoting {
class DaemonController { class AutoThread;
class AutoThreadTaskRunner;
class DaemonController : public base::RefCountedThreadSafe<DaemonController> {
public: public:
// Note that these enumeration values are duplicated in host_controller.js and // Note that these enumeration values are duplicated in host_controller.js and
// must be kept in sync. // must be kept in sync.
...@@ -79,16 +85,72 @@ class DaemonController { ...@@ -79,16 +85,72 @@ class DaemonController {
// Callback type for GetVersion(). // Callback type for GetVersion().
typedef base::Callback<void (const std::string&)> GetVersionCallback; typedef base::Callback<void (const std::string&)> GetVersionCallback;
struct UsageStatsConsent {
bool supported;
bool allowed;
bool set_by_policy;
};
// Callback type for GetUsageStatsConsent(). |supported| indicates whether // Callback type for GetUsageStatsConsent(). |supported| indicates whether
// crash dump reporting is supported by the host. |allowed| indicates if // crash dump reporting is supported by the host. |allowed| indicates if
// crash dump reporting is allowed by the user. |set_by_policy| carries // crash dump reporting is allowed by the user. |set_by_policy| carries
// information whether the crash dump reporting is controlled by policy. // information whether the crash dump reporting is controlled by policy.
typedef base::Callback<void ( typedef base::Callback<void (const UsageStatsConsent&)>
bool supported, GetUsageStatsConsentCallback;
bool allowed,
bool set_by_policy)> GetUsageStatsConsentCallback; // Interface representing the platform-spacific back-end. Most of its methods
// are blocking and should called on a background thread. There are two
// exceptions:
// - GetState() is synchronous and called on the UI thread. It should avoid
// accessing any data members of the implementation.
// - SetConfigAndStart() is non blocking. |done| callback is posted to
// |task_runner| when the operation completes.
class Delegate {
public:
virtual ~Delegate() {}
// Return the "installed/running" state of the daemon process. This method
// should avoid accessing any data members of the implementation.
virtual State GetState() = 0;
// Queries current host configuration. Any values that might be security
// sensitive have been filtered out.
virtual scoped_ptr<base::DictionaryValue> GetConfig() = 0;
virtual ~DaemonController() {} // Starts the daemon process. This may require that the daemon be
// downloaded and installed. |done| is invoked when the operation is
// finished or fails.
virtual void SetConfigAndStart(
scoped_ptr<base::DictionaryValue> config,
bool consent,
const CompletionCallback& done) = 0;
// Updates current host configuration with the values specified in
// |config|. Any value in the existing configuration that isn't specified in
// |config| is preserved. |config| must not contain host_id or xmpp_login
// values, because implementations of this method cannot change them.
virtual void UpdateConfig(
scoped_ptr<base::DictionaryValue> config,
const CompletionCallback& done) = 0;
// Stops the daemon process.
virtual void Stop(const CompletionCallback& done) = 0;
// Caches the native handle of the plugin window so it can be used to focus
// elevation prompts properly.
virtual void SetWindow(void* window_handle) = 0;
// Get the version of the daemon as a dotted decimal string of the form
// major.minor.build.patch, if it is installed, or "" otherwise.
virtual std::string GetVersion() = 0;
// Get the user's consent to crash reporting.
virtual UsageStatsConsent GetUsageStatsConsent() = 0;
};
static scoped_refptr<DaemonController> Create();
explicit DaemonController(scoped_ptr<Delegate> delegate);
// Return the "installed/running" state of the daemon process. // Return the "installed/running" state of the daemon process.
// //
...@@ -96,32 +158,32 @@ class DaemonController { ...@@ -96,32 +158,32 @@ class DaemonController {
// webapp. In most cases it requires IO operations, so it may block // webapp. In most cases it requires IO operations, so it may block
// the user interface. Replace it with asynchronous notifications, // the user interface. Replace it with asynchronous notifications,
// e.g. with StartStateNotifications()/StopStateNotifications() methods. // e.g. with StartStateNotifications()/StopStateNotifications() methods.
virtual State GetState() = 0; State GetState();
// Queries current host configuration. The |callback| is called // Queries current host configuration. The |done| is called
// after the configuration is read, and any values that might be security // after the configuration is read, and any values that might be security
// sensitive have been filtered out. // sensitive have been filtered out.
virtual void GetConfig(const GetConfigCallback& callback) = 0; void GetConfig(const GetConfigCallback& done);
// Start the daemon process. This may require that the daemon be // Start the daemon process. This may require that the daemon be
// downloaded and installed. |done_callback| is called when the // downloaded and installed. |done| is called when the
// operation is finished or fails. // operation is finished or fails.
// //
// TODO(sergeyu): This method writes config and starts the host - // TODO(sergeyu): This method writes config and starts the host -
// these two steps are merged for simplicity. Consider splitting it // these two steps are merged for simplicity. Consider splitting it
// into SetConfig() and Start() once we have basic host setup flow // into SetConfig() and Start() once we have basic host setup flow
// working. // working.
virtual void SetConfigAndStart(scoped_ptr<base::DictionaryValue> config, void SetConfigAndStart(scoped_ptr<base::DictionaryValue> config,
bool consent, bool consent,
const CompletionCallback& done) = 0; const CompletionCallback& done);
// Updates current host configuration with the values specified in // Updates current host configuration with the values specified in
// |config|. Changes must take effect before the call completes. // |config|. Changes must take effect before the call completes.
// Any value in the existing configuration that isn't specified in |config| // Any value in the existing configuration that isn't specified in |config|
// is preserved. |config| must not contain host_id or xmpp_login values, // is preserved. |config| must not contain host_id or xmpp_login values,
// because implementations of this method cannot change them. // because implementations of this method cannot change them.
virtual void UpdateConfig(scoped_ptr<base::DictionaryValue> config, void UpdateConfig(scoped_ptr<base::DictionaryValue> config,
const CompletionCallback& done_callback) = 0; const CompletionCallback& done);
// Stop the daemon process. It is permitted to call Stop while the daemon // Stop the daemon process. It is permitted to call Stop while the daemon
// process is being installed, in which case the installation should be // process is being installed, in which case the installation should be
...@@ -129,21 +191,70 @@ class DaemonController { ...@@ -129,21 +191,70 @@ class DaemonController {
// daemon process is not started automatically upon successful installation. // daemon process is not started automatically upon successful installation.
// As with Start, Stop may return before the operation is complete--poll // As with Start, Stop may return before the operation is complete--poll
// GetState until the state is STATE_STOPPED. // GetState until the state is STATE_STOPPED.
virtual void Stop(const CompletionCallback& done_callback) = 0; void Stop(const CompletionCallback& done);
// Caches the native handle of the plugin window so it can be used to focus // Caches the native handle of the plugin window so it can be used to focus
// elevation prompts properly. // elevation prompts properly.
virtual void SetWindow(void* window_handle) = 0; void SetWindow(void* window_handle);
// Get the version of the daemon as a dotted decimal string of the form // Get the version of the daemon as a dotted decimal string of the form
// major.minor.build.patch, if it is installed, or "" otherwise. // major.minor.build.patch, if it is installed, or "" otherwise.
virtual void GetVersion(const GetVersionCallback& done_callback) = 0; void GetVersion(const GetVersionCallback& done);
// Get the user's consent to crash reporting. // Get the user's consent to crash reporting.
virtual void GetUsageStatsConsent( void GetUsageStatsConsent(const GetUsageStatsConsentCallback& done);
const GetUsageStatsConsentCallback& done) = 0;
private:
friend class base::RefCountedThreadSafe<DaemonController>;
virtual ~DaemonController();
// Blocking helper methods used to call the delegate.
void DoGetConfig(const GetConfigCallback& done);
void DoSetConfigAndStart(scoped_ptr<base::DictionaryValue> config,
bool consent,
const CompletionCallback& done);
void DoUpdateConfig(scoped_ptr<base::DictionaryValue> config,
const CompletionCallback& done);
void DoStop(const CompletionCallback& done);
void DoSetWindow(void* window_handle, const base::Closure& done);
void DoGetVersion(const GetVersionCallback& done);
void DoGetUsageStatsConsent(const GetUsageStatsConsentCallback& done);
// "Trampoline" callbacks that schedule the next pending request and then
// invoke the original caller-supplied callback.
void InvokeCompletionCallbackAndScheduleNext(
const CompletionCallback& done,
AsyncResult result);
void InvokeConfigCallbackAndScheduleNext(
const GetConfigCallback& done,
scoped_ptr<base::DictionaryValue> config);
void InvokeConsentCallbackAndScheduleNext(
const GetUsageStatsConsentCallback& done,
const UsageStatsConsent& consent);
void InvokeVersionCallbackAndScheduleNext(
const GetVersionCallback& done,
const std::string& version);
// Queue management methods.
void ScheduleNext();
void ServiceOrQueueRequest(const base::Closure& request);
void ServiceNextRequest();
// Task runner on which all public methods of this class should be called.
scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_;
// Task runner used to run blocking calls to the delegate. A single thread
// task runner is used to guarantee that one one method of the delegate is
// called at a time.
scoped_refptr<AutoThreadTaskRunner> delegate_task_runner_;
scoped_ptr<AutoThread> delegate_thread_;
scoped_ptr<Delegate> delegate_;
std::queue<base::Closure> pending_requests_;
static scoped_ptr<DaemonController> Create(); DISALLOW_COPY_AND_ASSIGN(DaemonController);
}; };
} // namespace remoting } // namespace remoting
......
// 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.
#ifndef REMOTING_HOST_SETUP_DAEMON_CONTROLLER_DELEGATE_LINUX_H_
#define REMOTING_HOST_SETUP_DAEMON_CONTROLLER_DELEGATE_LINUX_H_
#include "base/memory/scoped_ptr.h"
#include "remoting/host/setup/daemon_controller.h"
namespace remoting {
class DaemonControllerDelegateLinux : public DaemonController::Delegate {
public:
DaemonControllerDelegateLinux();
virtual ~DaemonControllerDelegateLinux();
// DaemonController::Delegate interface.
virtual DaemonController::State GetState() OVERRIDE;
virtual scoped_ptr<base::DictionaryValue> GetConfig() OVERRIDE;
virtual void SetConfigAndStart(
scoped_ptr<base::DictionaryValue> config,
bool consent,
const DaemonController::CompletionCallback& done) OVERRIDE;
virtual void UpdateConfig(
scoped_ptr<base::DictionaryValue> config,
const DaemonController::CompletionCallback& done) OVERRIDE;
virtual void Stop(const DaemonController::CompletionCallback& done) OVERRIDE;
virtual void SetWindow(void* window_handle) OVERRIDE;
virtual std::string GetVersion() OVERRIDE;
virtual DaemonController::UsageStatsConsent GetUsageStatsConsent() OVERRIDE;
private:
DISALLOW_COPY_AND_ASSIGN(DaemonControllerDelegateLinux);
};
} // namespace remoting
#endif // REMOTING_HOST_SETUP_DAEMON_CONTROLLER_DELEGATE_LINUX_H_
// 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.
#ifndef REMOTING_HOST_SETUP_DAEMON_CONTROLLER_DELEGATE_MAC_H_
#define REMOTING_HOST_SETUP_DAEMON_CONTROLLER_DELEGATE_MAC_H_
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "remoting/host/setup/daemon_controller.h"
namespace remoting {
class DaemonControllerDelegateMac : public DaemonController::Delegate {
public:
DaemonControllerDelegateMac();
virtual ~DaemonControllerDelegateMac();
// DaemonController::Delegate interface.
virtual DaemonController::State GetState() OVERRIDE;
virtual scoped_ptr<base::DictionaryValue> GetConfig() OVERRIDE;
virtual void SetConfigAndStart(
scoped_ptr<base::DictionaryValue> config,
bool consent,
const DaemonController::CompletionCallback& done) OVERRIDE;
virtual void UpdateConfig(
scoped_ptr<base::DictionaryValue> config,
const DaemonController::CompletionCallback& done) OVERRIDE;
virtual void Stop(const DaemonController::CompletionCallback& done) OVERRIDE;
virtual void SetWindow(void* window_handle) OVERRIDE;
virtual std::string GetVersion() OVERRIDE;
virtual DaemonController::UsageStatsConsent GetUsageStatsConsent() OVERRIDE;
private:
void ShowPreferencePane(const std::string& config_data,
const DaemonController::CompletionCallback& done);
void RegisterForPreferencePaneNotifications(
const DaemonController::CompletionCallback &done);
void DeregisterForPreferencePaneNotifications();
void PreferencePaneCallbackDelegate(CFStringRef name);
static bool DoShowPreferencePane(const std::string& config_data);
static void PreferencePaneCallback(CFNotificationCenterRef center,
void* observer,
CFStringRef name,
const void* object,
CFDictionaryRef user_info);
DaemonController::CompletionCallback current_callback_;
DISALLOW_COPY_AND_ASSIGN(DaemonControllerDelegateMac);
};
} // namespace remoting
#endif // REMOTING_HOST_SETUP_DAEMON_CONTROLLER_DELEGATE_MAC_H_
// 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.
#ifndef REMOTING_HOST_SETUP_DAEMON_CONTROLLER_DELEGATE_WIN_H_
#define REMOTING_HOST_SETUP_DAEMON_CONTROLLER_DELEGATE_WIN_H_
#include "base/memory/scoped_ptr.h"
#include "base/timer/timer.h"
#include "base/win/scoped_comptr.h"
// chromoting_lib.h contains MIDL-generated declarations.
#include "remoting/host/chromoting_lib.h"
#include "remoting/host/setup/daemon_controller.h"
namespace remoting {
class DaemonInstallerWin;
class DaemonControllerDelegateWin : public DaemonController::Delegate {
public:
DaemonControllerDelegateWin();
virtual ~DaemonControllerDelegateWin();
// DaemonController::Delegate interface.
virtual DaemonController::State GetState() OVERRIDE;
virtual scoped_ptr<base::DictionaryValue> GetConfig() OVERRIDE;
virtual void SetConfigAndStart(
scoped_ptr<base::DictionaryValue> config,
bool consent,
const DaemonController::CompletionCallback& done) OVERRIDE;
virtual void UpdateConfig(
scoped_ptr<base::DictionaryValue> config,
const DaemonController::CompletionCallback& done) OVERRIDE;
virtual void Stop(const DaemonController::CompletionCallback& done) OVERRIDE;
virtual void SetWindow(void* window_handle) OVERRIDE;
virtual std::string GetVersion() OVERRIDE;
virtual DaemonController::UsageStatsConsent GetUsageStatsConsent() OVERRIDE;
private:
// Activates an unprivileged instance of the daemon controller and caches it.
HRESULT ActivateController();
// Activates an instance of the daemon controller and caches it. If COM
// Elevation is supported (Vista+) the activated instance is elevated,
// otherwise it is activated under credentials of the caller.
HRESULT ActivateElevatedController();
// Releases the cached instance of the controller.
void ReleaseController();
// Procedes with the daemon configuration if the installation succeeded,
// otherwise reports the error.
void OnInstallationComplete(
scoped_ptr<base::DictionaryValue> config,
bool consent,
const DaemonController::CompletionCallback& done,
HRESULT hr);
// |control_| and |control2_| hold references to an instance of the daemon
// controller to prevent a UAC prompt on every operation.
base::win::ScopedComPtr<IDaemonControl> control_;
base::win::ScopedComPtr<IDaemonControl2> control2_;
// True if |control_| holds a reference to an elevated instance of the daemon
// controller.
bool control_is_elevated_;
// This timer is used to release |control_| after a timeout.
scoped_ptr<base::OneShotTimer<DaemonControllerDelegateWin> > release_timer_;
// Handle of the plugin window.
HWND window_handle_;
scoped_ptr<DaemonInstallerWin> installer_;
DISALLOW_COPY_AND_ASSIGN(DaemonControllerDelegateWin);
};
} // namespace remoting
#endif // REMOTING_HOST_SETUP_DAEMON_CONTROLLER_DELEGATE_WIN_H_
...@@ -20,10 +20,10 @@ namespace remoting { ...@@ -20,10 +20,10 @@ namespace remoting {
HostStarter::HostStarter( HostStarter::HostStarter(
scoped_ptr<gaia::GaiaOAuthClient> oauth_client, scoped_ptr<gaia::GaiaOAuthClient> oauth_client,
scoped_ptr<remoting::ServiceClient> service_client, scoped_ptr<remoting::ServiceClient> service_client,
scoped_ptr<remoting::DaemonController> daemon_controller) scoped_refptr<remoting::DaemonController> daemon_controller)
: oauth_client_(oauth_client.Pass()), : oauth_client_(oauth_client.Pass()),
service_client_(service_client.Pass()), service_client_(service_client.Pass()),
daemon_controller_(daemon_controller.Pass()), daemon_controller_(daemon_controller),
consent_to_data_collection_(false), consent_to_data_collection_(false),
unregistering_host_(false), unregistering_host_(false),
weak_ptr_factory_(this), weak_ptr_factory_(this),
...@@ -42,11 +42,11 @@ scoped_ptr<HostStarter> HostStarter::Create( ...@@ -42,11 +42,11 @@ scoped_ptr<HostStarter> HostStarter::Create(
scoped_ptr<remoting::ServiceClient> service_client( scoped_ptr<remoting::ServiceClient> service_client(
new remoting::ServiceClient( new remoting::ServiceClient(
chromoting_hosts_url, url_request_context_getter)); chromoting_hosts_url, url_request_context_getter));
scoped_ptr<remoting::DaemonController> daemon_controller( scoped_refptr<remoting::DaemonController> daemon_controller(
remoting::DaemonController::Create()); remoting::DaemonController::Create());
return scoped_ptr<HostStarter>( return scoped_ptr<HostStarter>(
new HostStarter(oauth_client.Pass(), service_client.Pass(), new HostStarter(oauth_client.Pass(), service_client.Pass(),
daemon_controller.Pass())); daemon_controller));
} }
void HostStarter::StartHost( void HostStarter::StartHost(
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <string> #include <string>
#include "base/callback.h" #include "base/callback.h"
#include "base/memory/ref_counted.h"
#include "google_apis/gaia/gaia_oauth_client.h" #include "google_apis/gaia/gaia_oauth_client.h"
#include "remoting/base/rsa_key_pair.h" #include "remoting/base/rsa_key_pair.h"
#include "remoting/base/url_request_context.h" #include "remoting/base/url_request_context.h"
...@@ -68,7 +69,7 @@ class HostStarter : public gaia::GaiaOAuthClient::Delegate, ...@@ -68,7 +69,7 @@ class HostStarter : public gaia::GaiaOAuthClient::Delegate,
private: private:
HostStarter(scoped_ptr<gaia::GaiaOAuthClient> oauth_client, HostStarter(scoped_ptr<gaia::GaiaOAuthClient> oauth_client,
scoped_ptr<remoting::ServiceClient> service_client, scoped_ptr<remoting::ServiceClient> service_client,
scoped_ptr<remoting::DaemonController> daemon_controller); scoped_refptr<remoting::DaemonController> daemon_controller);
void StartHostProcess(); void StartHostProcess();
...@@ -76,7 +77,7 @@ class HostStarter : public gaia::GaiaOAuthClient::Delegate, ...@@ -76,7 +77,7 @@ class HostStarter : public gaia::GaiaOAuthClient::Delegate,
scoped_ptr<gaia::GaiaOAuthClient> oauth_client_; scoped_ptr<gaia::GaiaOAuthClient> oauth_client_;
scoped_ptr<remoting::ServiceClient> service_client_; scoped_ptr<remoting::ServiceClient> service_client_;
scoped_ptr<remoting::DaemonController> daemon_controller_; scoped_refptr<remoting::DaemonController> daemon_controller_;
gaia::OAuthClientInfo oauth_client_info_; gaia::OAuthClientInfo oauth_client_info_;
std::string host_name_; std::string host_name_;
std::string host_pin_; std::string host_pin_;
......
...@@ -62,7 +62,7 @@ scoped_ptr<base::DictionaryValue> ConfigDictionaryFromMessage( ...@@ -62,7 +62,7 @@ scoped_ptr<base::DictionaryValue> ConfigDictionaryFromMessage(
namespace remoting { namespace remoting {
NativeMessagingHost::NativeMessagingHost( NativeMessagingHost::NativeMessagingHost(
scoped_ptr<DaemonController> daemon_controller, scoped_refptr<DaemonController> daemon_controller,
scoped_refptr<protocol::PairingRegistry> pairing_registry, scoped_refptr<protocol::PairingRegistry> pairing_registry,
scoped_ptr<OAuthClient> oauth_client, scoped_ptr<OAuthClient> oauth_client,
base::PlatformFile input, base::PlatformFile input,
...@@ -73,7 +73,7 @@ NativeMessagingHost::NativeMessagingHost( ...@@ -73,7 +73,7 @@ NativeMessagingHost::NativeMessagingHost(
quit_closure_(quit_closure), quit_closure_(quit_closure),
native_messaging_reader_(input), native_messaging_reader_(input),
native_messaging_writer_(output), native_messaging_writer_(output),
daemon_controller_(daemon_controller.Pass()), daemon_controller_(daemon_controller),
pairing_registry_(pairing_registry), pairing_registry_(pairing_registry),
oauth_client_(oauth_client.Pass()), oauth_client_(oauth_client.Pass()),
pending_requests_(0), pending_requests_(0),
...@@ -270,11 +270,9 @@ bool NativeMessagingHost::ProcessUpdateDaemonConfig( ...@@ -270,11 +270,9 @@ bool NativeMessagingHost::ProcessUpdateDaemonConfig(
if (!config_dict) if (!config_dict)
return false; return false;
// base::Unretained() is safe because this object owns |daemon_controller_|
// which owns the thread that will run the callback.
daemon_controller_->UpdateConfig( daemon_controller_->UpdateConfig(
config_dict.Pass(), config_dict.Pass(),
base::Bind(&NativeMessagingHost::SendAsyncResult, base::Unretained(this), base::Bind(&NativeMessagingHost::SendAsyncResult, weak_ptr_,
base::Passed(&response))); base::Passed(&response)));
return true; return true;
} }
...@@ -283,8 +281,8 @@ bool NativeMessagingHost::ProcessGetDaemonConfig( ...@@ -283,8 +281,8 @@ bool NativeMessagingHost::ProcessGetDaemonConfig(
const base::DictionaryValue& message, const base::DictionaryValue& message,
scoped_ptr<base::DictionaryValue> response) { scoped_ptr<base::DictionaryValue> response) {
daemon_controller_->GetConfig( daemon_controller_->GetConfig(
base::Bind(&NativeMessagingHost::SendConfigResponse, base::Bind(&NativeMessagingHost::SendConfigResponse, weak_ptr_,
base::Unretained(this), base::Passed(&response))); base::Passed(&response)));
return true; return true;
} }
...@@ -307,7 +305,7 @@ bool NativeMessagingHost::ProcessGetUsageStatsConsent( ...@@ -307,7 +305,7 @@ bool NativeMessagingHost::ProcessGetUsageStatsConsent(
scoped_ptr<base::DictionaryValue> response) { scoped_ptr<base::DictionaryValue> response) {
daemon_controller_->GetUsageStatsConsent( daemon_controller_->GetUsageStatsConsent(
base::Bind(&NativeMessagingHost::SendUsageStatsConsentResponse, base::Bind(&NativeMessagingHost::SendUsageStatsConsentResponse,
base::Unretained(this), base::Passed(&response))); weak_ptr_, base::Passed(&response)));
return true; return true;
} }
...@@ -327,7 +325,7 @@ bool NativeMessagingHost::ProcessStartDaemon( ...@@ -327,7 +325,7 @@ bool NativeMessagingHost::ProcessStartDaemon(
daemon_controller_->SetConfigAndStart( daemon_controller_->SetConfigAndStart(
config_dict.Pass(), consent, config_dict.Pass(), consent,
base::Bind(&NativeMessagingHost::SendAsyncResult, base::Unretained(this), base::Bind(&NativeMessagingHost::SendAsyncResult, weak_ptr_,
base::Passed(&response))); base::Passed(&response)));
return true; return true;
} }
...@@ -336,7 +334,7 @@ bool NativeMessagingHost::ProcessStopDaemon( ...@@ -336,7 +334,7 @@ bool NativeMessagingHost::ProcessStopDaemon(
const base::DictionaryValue& message, const base::DictionaryValue& message,
scoped_ptr<base::DictionaryValue> response) { scoped_ptr<base::DictionaryValue> response) {
daemon_controller_->Stop( daemon_controller_->Stop(
base::Bind(&NativeMessagingHost::SendAsyncResult, base::Unretained(this), base::Bind(&NativeMessagingHost::SendAsyncResult, weak_ptr_,
base::Passed(&response))); base::Passed(&response)));
return true; return true;
} }
...@@ -446,12 +444,10 @@ void NativeMessagingHost::SendPairedClientsResponse( ...@@ -446,12 +444,10 @@ void NativeMessagingHost::SendPairedClientsResponse(
void NativeMessagingHost::SendUsageStatsConsentResponse( void NativeMessagingHost::SendUsageStatsConsentResponse(
scoped_ptr<base::DictionaryValue> response, scoped_ptr<base::DictionaryValue> response,
bool supported, const DaemonController::UsageStatsConsent& consent) {
bool allowed, response->SetBoolean("supported", consent.supported);
bool set_by_policy) { response->SetBoolean("allowed", consent.allowed);
response->SetBoolean("supported", supported); response->SetBoolean("setByPolicy", consent.set_by_policy);
response->SetBoolean("allowed", allowed);
response->SetBoolean("setByPolicy", set_by_policy);
SendResponse(response.Pass()); SendResponse(response.Pass());
} }
......
...@@ -36,7 +36,7 @@ class PairingRegistry; ...@@ -36,7 +36,7 @@ class PairingRegistry;
class NativeMessagingHost { class NativeMessagingHost {
public: public:
NativeMessagingHost( NativeMessagingHost(
scoped_ptr<DaemonController> daemon_controller, scoped_refptr<DaemonController> daemon_controller,
scoped_refptr<protocol::PairingRegistry> pairing_registry, scoped_refptr<protocol::PairingRegistry> pairing_registry,
scoped_ptr<OAuthClient> oauth_client, scoped_ptr<OAuthClient> oauth_client,
base::PlatformFile input, base::PlatformFile input,
...@@ -104,10 +104,9 @@ class NativeMessagingHost { ...@@ -104,10 +104,9 @@ class NativeMessagingHost {
scoped_ptr<base::DictionaryValue> config); scoped_ptr<base::DictionaryValue> config);
void SendPairedClientsResponse(scoped_ptr<base::DictionaryValue> response, void SendPairedClientsResponse(scoped_ptr<base::DictionaryValue> response,
scoped_ptr<base::ListValue> pairings); scoped_ptr<base::ListValue> pairings);
void SendUsageStatsConsentResponse(scoped_ptr<base::DictionaryValue> response, void SendUsageStatsConsentResponse(
bool supported, scoped_ptr<base::DictionaryValue> response,
bool allowed, const DaemonController::UsageStatsConsent& consent);
bool set_by_policy);
void SendAsyncResult(scoped_ptr<base::DictionaryValue> response, void SendAsyncResult(scoped_ptr<base::DictionaryValue> response,
DaemonController::AsyncResult result); DaemonController::AsyncResult result);
void SendBooleanResult(scoped_ptr<base::DictionaryValue> response, void SendBooleanResult(scoped_ptr<base::DictionaryValue> response,
...@@ -130,7 +129,7 @@ class NativeMessagingHost { ...@@ -130,7 +129,7 @@ class NativeMessagingHost {
// The DaemonController may post tasks to this object during destruction (but // The DaemonController may post tasks to this object during destruction (but
// not afterwards), so it needs to be destroyed before other members of this // not afterwards), so it needs to be destroyed before other members of this
// class (except for |weak_factory_|). // class (except for |weak_factory_|).
scoped_ptr<remoting::DaemonController> daemon_controller_; scoped_refptr<remoting::DaemonController> daemon_controller_;
// Used to load and update the paired clients for this host. // Used to load and update the paired clients for this host.
scoped_refptr<protocol::PairingRegistry> pairing_registry_; scoped_refptr<protocol::PairingRegistry> pairing_registry_;
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "google_apis/gaia/gaia_oauth_client.h" #include "google_apis/gaia/gaia_oauth_client.h"
#include "net/base/file_stream.h" #include "net/base/file_stream.h"
#include "net/base/net_util.h" #include "net/base/net_util.h"
#include "remoting/base/auto_thread_task_runner.h"
#include "remoting/host/pin_hash.h" #include "remoting/host/pin_hash.h"
#include "remoting/host/setup/test_util.h" #include "remoting/host/setup/test_util.h"
#include "remoting/protocol/pairing_registry.h" #include "remoting/protocol/pairing_registry.h"
...@@ -130,77 +131,86 @@ void VerifyStartDaemonResponse(scoped_ptr<base::DictionaryValue> response) { ...@@ -130,77 +131,86 @@ void VerifyStartDaemonResponse(scoped_ptr<base::DictionaryValue> response) {
namespace remoting { namespace remoting {
class MockDaemonController : public DaemonController { class MockDaemonControllerDelegate : public DaemonController::Delegate {
public: public:
MockDaemonController(); MockDaemonControllerDelegate();
virtual ~MockDaemonController(); virtual ~MockDaemonControllerDelegate();
virtual State GetState() OVERRIDE; // DaemonController::Delegate interface.
virtual void GetConfig(const GetConfigCallback& callback) OVERRIDE; virtual DaemonController::State GetState() OVERRIDE;
virtual void SetConfigAndStart(scoped_ptr<base::DictionaryValue> config, virtual scoped_ptr<base::DictionaryValue> GetConfig() OVERRIDE;
bool consent, virtual void SetConfigAndStart(
const CompletionCallback& callback) OVERRIDE; scoped_ptr<base::DictionaryValue> config,
virtual void UpdateConfig(scoped_ptr<base::DictionaryValue> config, bool consent,
const CompletionCallback& callback) OVERRIDE; const DaemonController::CompletionCallback& done) OVERRIDE;
virtual void Stop(const CompletionCallback& callback) OVERRIDE; virtual void UpdateConfig(
scoped_ptr<base::DictionaryValue> config,
const DaemonController::CompletionCallback& done) OVERRIDE;
virtual void Stop(const DaemonController::CompletionCallback& done) OVERRIDE;
virtual void SetWindow(void* window_handle) OVERRIDE; virtual void SetWindow(void* window_handle) OVERRIDE;
virtual void GetVersion(const GetVersionCallback& callback) OVERRIDE; virtual std::string GetVersion() OVERRIDE;
virtual void GetUsageStatsConsent( virtual DaemonController::UsageStatsConsent GetUsageStatsConsent() OVERRIDE;
const GetUsageStatsConsentCallback& callback) OVERRIDE;
private: private:
DISALLOW_COPY_AND_ASSIGN(MockDaemonController); DISALLOW_COPY_AND_ASSIGN(MockDaemonControllerDelegate);
}; };
MockDaemonController::MockDaemonController() {} MockDaemonControllerDelegate::MockDaemonControllerDelegate() {}
MockDaemonController::~MockDaemonController() {} MockDaemonControllerDelegate::~MockDaemonControllerDelegate() {}
DaemonController::State MockDaemonController::GetState() { DaemonController::State MockDaemonControllerDelegate::GetState() {
return DaemonController::STATE_STARTED; return DaemonController::STATE_STARTED;
} }
void MockDaemonController::GetConfig(const GetConfigCallback& callback) { scoped_ptr<base::DictionaryValue> MockDaemonControllerDelegate::GetConfig() {
scoped_ptr<base::DictionaryValue> config(new base::DictionaryValue()); return scoped_ptr<base::DictionaryValue>(new base::DictionaryValue());
callback.Run(config.Pass());
} }
void MockDaemonController::SetConfigAndStart( void MockDaemonControllerDelegate::SetConfigAndStart(
scoped_ptr<base::DictionaryValue> config, bool consent, scoped_ptr<base::DictionaryValue> config,
const CompletionCallback& callback) { bool consent,
const DaemonController::CompletionCallback& done) {
// Verify parameters passed in. // Verify parameters passed in.
if (consent && config && config->HasKey("start")) { if (consent && config && config->HasKey("start")) {
callback.Run(DaemonController::RESULT_OK); done.Run(DaemonController::RESULT_OK);
} else { } else {
callback.Run(DaemonController::RESULT_FAILED); done.Run(DaemonController::RESULT_FAILED);
} }
} }
void MockDaemonController::UpdateConfig( void MockDaemonControllerDelegate::UpdateConfig(
scoped_ptr<base::DictionaryValue> config, scoped_ptr<base::DictionaryValue> config,
const CompletionCallback& callback) { const DaemonController::CompletionCallback& done) {
if (config && config->HasKey("update")) { if (config && config->HasKey("update")) {
callback.Run(DaemonController::RESULT_OK); done.Run(DaemonController::RESULT_OK);
} else { } else {
callback.Run(DaemonController::RESULT_FAILED); done.Run(DaemonController::RESULT_FAILED);
} }
} }
void MockDaemonController::Stop(const CompletionCallback& callback) { void MockDaemonControllerDelegate::Stop(
callback.Run(DaemonController::RESULT_OK); const DaemonController::CompletionCallback& done) {
done.Run(DaemonController::RESULT_OK);
} }
void MockDaemonController::SetWindow(void* window_handle) {} void MockDaemonControllerDelegate::SetWindow(void* window_handle) {}
void MockDaemonController::GetVersion(const GetVersionCallback& callback) { std::string MockDaemonControllerDelegate::GetVersion() {
// Unused - NativeMessagingHost returns the compiled-in version string // Unused - NativeMessagingHost returns the compiled-in version string
// instead of calling this method. // instead of calling this method.
NOTREACHED();
return std::string();
} }
void MockDaemonController::GetUsageStatsConsent( DaemonController::UsageStatsConsent
const GetUsageStatsConsentCallback& callback) { MockDaemonControllerDelegate::GetUsageStatsConsent() {
callback.Run(true, true, true); DaemonController::UsageStatsConsent consent;
consent.supported = true;
consent.allowed = true;
consent.set_by_policy = true;
return consent;
} }
class NativeMessagingHostTest : public testing::Test { class NativeMessagingHostTest : public testing::Test {
...@@ -213,6 +223,9 @@ class NativeMessagingHostTest : public testing::Test { ...@@ -213,6 +223,9 @@ class NativeMessagingHostTest : public testing::Test {
void Run(); void Run();
// Deletes |host_|.
void DeleteHost();
scoped_ptr<base::DictionaryValue> ReadMessageFromOutputPipe(); scoped_ptr<base::DictionaryValue> ReadMessageFromOutputPipe();
void WriteMessageToInputPipe(const base::Value& message); void WriteMessageToInputPipe(const base::Value& message);
...@@ -224,8 +237,8 @@ class NativeMessagingHostTest : public testing::Test { ...@@ -224,8 +237,8 @@ class NativeMessagingHostTest : public testing::Test {
void TestBadRequest(const base::Value& message); void TestBadRequest(const base::Value& message);
protected: protected:
// Reference to the MockDaemonController, which is owned by |host_|. // Reference to the MockDaemonControllerDelegate, which is owned by |host_|.
MockDaemonController* daemon_controller_; MockDaemonControllerDelegate* daemon_controller_delegate_;
private: private:
// Each test creates two unidirectional pipes: "input" and "output". // Each test creates two unidirectional pipes: "input" and "output".
...@@ -255,19 +268,27 @@ void NativeMessagingHostTest::SetUp() { ...@@ -255,19 +268,27 @@ void NativeMessagingHostTest::SetUp() {
ASSERT_TRUE(MakePipe(&input_read_handle_, &input_write_handle_)); ASSERT_TRUE(MakePipe(&input_read_handle_, &input_write_handle_));
ASSERT_TRUE(MakePipe(&output_read_handle_, &output_write_handle_)); ASSERT_TRUE(MakePipe(&output_read_handle_, &output_write_handle_));
daemon_controller_ = new MockDaemonController(); // Arrange to run |message_loop_| until no components depend on it.
scoped_ptr<DaemonController> daemon_controller(daemon_controller_); scoped_refptr<AutoThreadTaskRunner> task_runner = new AutoThreadTaskRunner(
message_loop_.message_loop_proxy(), run_loop_.QuitClosure());
daemon_controller_delegate_ = new MockDaemonControllerDelegate();
scoped_refptr<DaemonController> daemon_controller(
new DaemonController(
scoped_ptr<DaemonController::Delegate>(daemon_controller_delegate_)));
scoped_refptr<PairingRegistry> pairing_registry = scoped_refptr<PairingRegistry> pairing_registry =
new SynchronousPairingRegistry(scoped_ptr<PairingRegistry::Delegate>( new SynchronousPairingRegistry(scoped_ptr<PairingRegistry::Delegate>(
new MockPairingRegistryDelegate())); new MockPairingRegistryDelegate()));
host_.reset(new NativeMessagingHost(daemon_controller.Pass(), host_.reset(new NativeMessagingHost(
pairing_registry, daemon_controller,
scoped_ptr<remoting::OAuthClient>(), pairing_registry,
input_read_handle_, output_write_handle_, scoped_ptr<remoting::OAuthClient>(),
message_loop_.message_loop_proxy(), input_read_handle_, output_write_handle_,
run_loop_.QuitClosure())); task_runner,
base::Bind(&NativeMessagingHostTest::DeleteHost,
base::Unretained(this))));
} }
void NativeMessagingHostTest::TearDown() { void NativeMessagingHostTest::TearDown() {
...@@ -283,7 +304,9 @@ void NativeMessagingHostTest::Run() { ...@@ -283,7 +304,9 @@ void NativeMessagingHostTest::Run() {
base::ClosePlatformFile(input_write_handle_); base::ClosePlatformFile(input_write_handle_);
host_->Start(); host_->Start();
run_loop_.Run(); run_loop_.Run();
}
void NativeMessagingHostTest::DeleteHost() {
// Destroy |host_| so that it closes its end of the output pipe, so that // Destroy |host_| so that it closes its end of the output pipe, so that
// TestBadRequest() will see EOF and won't block waiting for more data. // TestBadRequest() will see EOF and won't block waiting for more data.
host_.reset(); host_.reset();
......
...@@ -577,10 +577,14 @@ ...@@ -577,10 +577,14 @@
'VERSION=<(version_full)', 'VERSION=<(version_full)',
], ],
'sources': [ 'sources': [
'host/setup/daemon_controller.cc',
'host/setup/daemon_controller.h', 'host/setup/daemon_controller.h',
'host/setup/daemon_controller_linux.cc', 'host/setup/daemon_controller_delegate_linux.cc',
'host/setup/daemon_controller_mac.mm', 'host/setup/daemon_controller_delegate_linux.h',
'host/setup/daemon_controller_win.cc', 'host/setup/daemon_controller_delegate_mac.h',
'host/setup/daemon_controller_delegate_mac.mm',
'host/setup/daemon_controller_delegate_win.cc',
'host/setup/daemon_controller_delegate_win.h',
'host/setup/daemon_installer_win.cc', 'host/setup/daemon_installer_win.cc',
'host/setup/daemon_installer_win.h', 'host/setup/daemon_installer_win.h',
'host/setup/host_starter.cc', 'host/setup/host_starter.cc',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment