summaryrefslogtreecommitdiffstats
path: root/remoting/host/plugin
diff options
context:
space:
mode:
authorsergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-09-29 14:10:00 +0000
committersergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-09-29 14:10:00 +0000
commit31f71b329a4ffe735a7af3ceb27dcd559d943a05 (patch)
tree2a641db384fcb98c08d2e17990766d8047455131 /remoting/host/plugin
parent19a0ee47090984c3f3bb3f04d5e58656a2075b7b (diff)
downloadchromium_src-31f71b329a4ffe735a7af3ceb27dcd559d943a05.zip
chromium_src-31f71b329a4ffe735a7af3ceb27dcd559d943a05.tar.gz
chromium_src-31f71b329a4ffe735a7af3ceb27dcd559d943a05.tar.bz2
Move DaemonController to remoting/host/setup
DaemonController will be used outside of the plugin, so it doesn't make sense to keep it in the plugin directory. Review URL: https://chromiumcodereview.appspot.com/10985086 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@159402 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting/host/plugin')
-rw-r--r--remoting/host/plugin/daemon_controller.h151
-rw-r--r--remoting/host/plugin/daemon_controller_linux.cc343
-rw-r--r--remoting/host/plugin/daemon_controller_mac.cc368
-rw-r--r--remoting/host/plugin/daemon_controller_win.cc698
-rw-r--r--remoting/host/plugin/daemon_installer_win.h1
-rw-r--r--remoting/host/plugin/host_script_object.cc1
-rw-r--r--remoting/host/plugin/host_script_object.h2
7 files changed, 1 insertions, 1563 deletions
diff --git a/remoting/host/plugin/daemon_controller.h b/remoting/host/plugin/daemon_controller.h
deleted file mode 100644
index bf67345..0000000
--- a/remoting/host/plugin/daemon_controller.h
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright (c) 2012 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_DAEMON_CONTROLLER_H_
-#define REMOTING_HOST_DAEMON_CONTROLLER_H_
-
-#include <string>
-
-#include "base/callback_forward.h"
-#include "base/memory/scoped_ptr.h"
-
-namespace base {
-class DictionaryValue;
-} // namespace base
-
-namespace remoting {
-
-class DaemonController {
- public:
- // Note that these enumeration values are duplicated in daemon_plugin.js and
- // must be kept in sync.
- enum State {
- // Placeholder state for platforms on which the daemon process is not
- // implemented. The web-app will not show the corresponding UI. This value
- // will eventually be deprecated or removed.
- STATE_NOT_IMPLEMENTED = -1,
- // The daemon is not installed. This is functionally equivalent to
- // STATE_STOPPED, but the start method is expected to be significantly
- // slower, and might involve user interaction. It might be appropriate to
- // indicate this in the UI.
- STATE_NOT_INSTALLED = 0,
- // The daemon is being installed.
- STATE_INSTALLING = 1,
- // The daemon is installed but not running. Call Start to start it.
- STATE_STOPPED = 2,
- // The daemon process is starting.
- STATE_STARTING = 3,
- // The daemon process is running. Call Start again to change the PIN or
- // Stop to stop it.
- STATE_STARTED = 4,
- // The daemon process is stopping.
- STATE_STOPPING = 5,
- // The state cannot be determined. This could indicate that the plugin
- // has not been provided with sufficient information, for example, the
- // user for which to query state on a multi-user system.
- STATE_UNKNOWN = 6
- };
-
- // Enum used for completion callback.
- enum AsyncResult {
- RESULT_OK = 0,
-
- // The operation has FAILED.
- RESULT_FAILED = 1,
-
- // User has cancelled the action (e.g. rejected UAC prompt).
- // TODO(sergeyu): Current implementations don't return this value.
- RESULT_CANCELLED = 2,
-
- // Failed to access host directory.
- RESULT_FAILED_DIRECTORY = 3
-
- // TODO(sergeyu): Add more error codes when we know how to handle
- // them in the webapp.
- };
-
- // Callback type for GetConfig(). If the host is configured then a dictionary
- // is returned containing host_id and xmpp_login, with security-sensitive
- // fields filtered out. An empty dictionary is returned if the host is not
- // configured, and NULL if the configuration is corrupt or cannot be read.
- typedef base::Callback<void (scoped_ptr<base::DictionaryValue> config)>
- GetConfigCallback;
-
- // Callback used for asynchronous operations, e.g. when
- // starting/stopping the service.
- typedef base::Callback<void (AsyncResult result)> CompletionCallback;
-
- // Callback type for GetVersion().
- typedef base::Callback<void (const std::string&)> GetVersionCallback;
-
- // Callback type for GetUsageStatsConsent(). |supported| indicates whether
- // crash dump reporting is supported by the host. |allowed| indicates if
- // crash dump reporting is allowed by the user. |set_by_policy| carries
- // information whether the crash dump reporting is controlled by policy.
- typedef base::Callback<void (
- bool supported,
- bool allowed,
- bool set_by_policy)> GetUsageStatsConsentCallback;
-
- virtual ~DaemonController() {}
-
- // Return the "installed/running" state of the daemon process.
- //
- // TODO(sergeyu): This method is called synchronously from the
- // webapp. In most cases it requires IO operations, so it may block
- // the user interface. Replace it with asynchronous notifications,
- // e.g. with StartStateNotifications()/StopStateNotifications() methods.
- virtual State GetState() = 0;
-
- // Queries current host configuration. The |callback| is called
- // after the configuration is read, and any values that might be security
- // sensitive have been filtered out.
- virtual void GetConfig(const GetConfigCallback& callback) = 0;
-
- // Start the daemon process. This may require that the daemon be
- // downloaded and installed. |done_callback| is called when the
- // operation is finished or fails.
- //
- // TODO(sergeyu): This method writes config and starts the host -
- // these two steps are merged for simplicity. Consider splitting it
- // into SetConfig() and Start() once we have basic host setup flow
- // working.
- virtual void SetConfigAndStart(scoped_ptr<base::DictionaryValue> config,
- bool consent,
- const CompletionCallback& done) = 0;
-
- // Updates current host configuration with the values specified in
- // |config|. Changes must take effect before the call completes.
- // 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_callback) = 0;
-
- // Stop the daemon process. It is permitted to call Stop while the daemon
- // process is being installed, in which case the installation should be
- // aborted if possible; if not then it is sufficient to ensure that the
- // daemon process is not started automatically upon successful installation.
- // As with Start, Stop may return before the operation is complete--poll
- // GetState until the state is STATE_STOPPED.
- virtual void Stop(const CompletionCallback& done_callback) = 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 void GetVersion(const GetVersionCallback& done_callback) = 0;
-
- // Get the user's consent to crash reporting.
- virtual void GetUsageStatsConsent(
- const GetUsageStatsConsentCallback& done) = 0;
-
- static scoped_ptr<DaemonController> Create();
-};
-
-} // namespace remoting
-
-#endif // REMOTING_HOST_DAEMON_CONTROLLER_H_
diff --git a/remoting/host/plugin/daemon_controller_linux.cc b/remoting/host/plugin/daemon_controller_linux.cc
deleted file mode 100644
index ab2e087..0000000
--- a/remoting/host/plugin/daemon_controller_linux.cc
+++ /dev/null
@@ -1,343 +0,0 @@
-// Copyright (c) 2012 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/plugin/daemon_controller.h"
-
-#include <unistd.h>
-
-#include "base/basictypes.h"
-#include "base/bind.h"
-#include "base/command_line.h"
-#include "base/compiler_specific.h"
-#include "base/environment.h"
-#include "base/file_path.h"
-#include "base/file_util.h"
-#include "base/json/json_writer.h"
-#include "base/logging.h"
-#include "base/md5.h"
-#include "base/process_util.h"
-#include "base/string_number_conversions.h"
-#include "base/string_split.h"
-#include "base/string_util.h"
-#include "base/threading/thread.h"
-#include "base/values.h"
-#include "net/base/net_util.h"
-#include "remoting/host/host_config.h"
-#include "remoting/host/json_host_config.h"
-#include "remoting/host/usage_stats_consent.h"
-
-namespace remoting {
-
-namespace {
-
-const char kDaemonScript[] =
- "/opt/google/chrome-remote-desktop/chrome-remote-desktop";
-
-// Timeout for running daemon script.
-const int64 kDaemonTimeoutMs = 5000;
-
-// Timeout for commands that require password prompt- 1 minute;
-const int64 kSudoTimeoutMs = 60000;
-
-std::string GetMd5(const std::string& value) {
- base::MD5Context ctx;
- base::MD5Init(&ctx);
- base::MD5Update(&ctx, value);
- base::MD5Digest digest;
- base::MD5Final(&digest, &ctx);
- return StringToLowerASCII(base::HexEncode(digest.a, sizeof(digest.a)));
-}
-
-class DaemonControllerLinux : public remoting::DaemonController {
- public:
- DaemonControllerLinux();
-
- virtual State GetState() OVERRIDE;
- virtual void GetConfig(const GetConfigCallback& callback) OVERRIDE;
- virtual void SetConfigAndStart(
- scoped_ptr<base::DictionaryValue> config,
- bool consent,
- const CompletionCallback& done) OVERRIDE;
- virtual void UpdateConfig(scoped_ptr<base::DictionaryValue> config,
- const CompletionCallback& done_callback) OVERRIDE;
- virtual void Stop(const CompletionCallback& done_callback) OVERRIDE;
- virtual void SetWindow(void* window_handle) OVERRIDE;
- virtual void GetVersion(const GetVersionCallback& done_callback) OVERRIDE;
- virtual void GetUsageStatsConsent(
- const GetUsageStatsConsentCallback& done) OVERRIDE;
-
- private:
- FilePath GetConfigPath();
-
- void DoGetConfig(const GetConfigCallback& callback);
- void DoSetConfigAndStart(scoped_ptr<base::DictionaryValue> config,
- const CompletionCallback& done);
- void DoUpdateConfig(scoped_ptr<base::DictionaryValue> config,
- const CompletionCallback& done_callback);
- void DoStop(const CompletionCallback& done_callback);
- void DoGetVersion(const GetVersionCallback& done_callback);
-
- base::Thread file_io_thread_;
-
- DISALLOW_COPY_AND_ASSIGN(DaemonControllerLinux);
-};
-
-DaemonControllerLinux::DaemonControllerLinux()
- : file_io_thread_("DaemonControllerFileIO") {
- file_io_thread_.Start();
-}
-
-static bool GetScriptPath(FilePath* result) {
- FilePath candidate_exe(kDaemonScript);
- if (access(candidate_exe.value().c_str(), X_OK) == 0) {
- *result = candidate_exe;
- return true;
- }
- return false;
-}
-
-static bool RunHostScriptWithTimeout(
- const std::vector<std::string>& args,
- base::TimeDelta timeout,
- int* exit_code) {
- // As long as we're relying on running an external binary from the
- // PATH, don't do it as root.
- if (getuid() == 0) {
- return false;
- }
- FilePath script_path;
- if (!GetScriptPath(&script_path)) {
- return false;
- }
- CommandLine command_line(script_path);
- for (unsigned int i = 0; i < args.size(); ++i) {
- command_line.AppendArg(args[i]);
- }
- base::ProcessHandle process_handle;
- bool result = base::LaunchProcess(command_line,
- base::LaunchOptions(),
- &process_handle);
- if (result) {
- if (exit_code) {
- result = base::WaitForExitCodeWithTimeout(
- process_handle, exit_code, timeout);
- }
- base::CloseProcessHandle(process_handle);
- }
- return result;
-}
-
-static bool RunHostScript(const std::vector<std::string>& args,
- int* exit_code) {
- return RunHostScriptWithTimeout(
- args, base::TimeDelta::FromMilliseconds(kDaemonTimeoutMs), exit_code);
-}
-
-remoting::DaemonController::State DaemonControllerLinux::GetState() {
- std::vector<std::string> args;
- args.push_back("--check-running");
- int exit_code = 0;
- if (!RunHostScript(args, &exit_code)) {
- // TODO(jamiewalch): When we have a good story for installing, return
- // NOT_INSTALLED rather than NOT_IMPLEMENTED (the former suppresses
- // the relevant UI in the web-app).
- return remoting::DaemonController::STATE_NOT_IMPLEMENTED;
- }
-
- if (exit_code == 0) {
- return remoting::DaemonController::STATE_STARTED;
- } else {
- return remoting::DaemonController::STATE_STOPPED;
- }
-}
-
-void DaemonControllerLinux::GetConfig(const GetConfigCallback& callback) {
- // base::Unretained() is safe because we control lifetime of the thread.
- file_io_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
- &DaemonControllerLinux::DoGetConfig, base::Unretained(this), callback));
-}
-
-void DaemonControllerLinux::GetUsageStatsConsent(
- const GetUsageStatsConsentCallback& done) {
- // Crash dump collection is not implemented on Linux yet.
- // http://crbug.com/130678.
- done.Run(false, false, false);
-}
-
-void DaemonControllerLinux::SetConfigAndStart(
- scoped_ptr<base::DictionaryValue> config,
- bool /* consent */,
- const CompletionCallback& done) {
- // base::Unretained() is safe because we control lifetime of the thread.
- file_io_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
- &DaemonControllerLinux::DoSetConfigAndStart, base::Unretained(this),
- base::Passed(&config), done));
-}
-
-void DaemonControllerLinux::UpdateConfig(
- scoped_ptr<base::DictionaryValue> config,
- const CompletionCallback& done_callback) {
- file_io_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
- &DaemonControllerLinux::DoUpdateConfig, base::Unretained(this),
- base::Passed(&config), done_callback));
-}
-
-void DaemonControllerLinux::Stop(const CompletionCallback& done_callback) {
- file_io_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
- &DaemonControllerLinux::DoStop, base::Unretained(this),
- done_callback));
-}
-
-void DaemonControllerLinux::SetWindow(void* window_handle) {
- // noop
-}
-
-void DaemonControllerLinux::GetVersion(
- const GetVersionCallback& done_callback) {
- file_io_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
- &DaemonControllerLinux::DoGetVersion, base::Unretained(this),
- done_callback));
-}
-
-FilePath DaemonControllerLinux::GetConfigPath() {
- std::string filename = "host#" + GetMd5(net::GetHostName()) + ".json";
- return file_util::GetHomeDir().
- Append(".config/chrome-remote-desktop").Append(filename);
-}
-
-void DaemonControllerLinux::DoGetConfig(const GetConfigCallback& callback) {
- scoped_ptr<base::DictionaryValue> result(new base::DictionaryValue());
-
- if (GetState() != remoting::DaemonController::STATE_NOT_IMPLEMENTED) {
- JsonHostConfig config(GetConfigPath());
- if (config.Read()) {
- std::string value;
- if (config.GetString(kHostIdConfigPath, &value)) {
- result->SetString(kHostIdConfigPath, value);
- }
- if (config.GetString(kXmppLoginConfigPath, &value)) {
- result->SetString(kXmppLoginConfigPath, value);
- }
- } else {
- result.reset(); // Return NULL in case of error.
- }
- }
-
- callback.Run(result.Pass());
-}
-
-void DaemonControllerLinux::DoSetConfigAndStart(
- scoped_ptr<base::DictionaryValue> config,
- const CompletionCallback& done_callback) {
-
- // Add the user to chrome-remote-desktop group first.
- std::vector<std::string> args;
- args.push_back("--add-user");
- int exit_code;
- if (!RunHostScriptWithTimeout(
- args, base::TimeDelta::FromMilliseconds(kSudoTimeoutMs),
- &exit_code) ||
- exit_code != 0) {
- LOG(ERROR) << "Failed to add user to chrome-remote-desktop group.";
- done_callback.Run(RESULT_FAILED);
- return;
- }
-
- // Write config.
- JsonHostConfig config_file(GetConfigPath());
- if (!config_file.CopyFrom(config.get()) ||
- !config_file.Save()) {
- LOG(ERROR) << "Failed to update config file.";
- done_callback.Run(RESULT_FAILED);
- return;
- }
-
- // Finally start the host.
- args.clear();
- args.push_back("--start");
- AsyncResult result;
- if (RunHostScript(args, &exit_code)) {
- result = (exit_code == 0) ? RESULT_OK : RESULT_FAILED;
- } else {
- result = RESULT_FAILED;
- }
- done_callback.Run(result);
-}
-
-void DaemonControllerLinux::DoUpdateConfig(
- scoped_ptr<base::DictionaryValue> config,
- const CompletionCallback& done_callback) {
- JsonHostConfig config_file(GetConfigPath());
- if (!config_file.Read() ||
- !config_file.CopyFrom(config.get()) ||
- !config_file.Save()) {
- LOG(ERROR) << "Failed to update config file.";
- done_callback.Run(RESULT_FAILED);
- return;
- }
-
- std::vector<std::string> args;
- args.push_back("--reload");
- AsyncResult result;
- int exit_code;
- if (RunHostScript(args, &exit_code)) {
- result = (exit_code == 0) ? RESULT_OK : RESULT_FAILED;
- } else {
- result = RESULT_FAILED;
- }
-
- done_callback.Run(result);
-}
-
-void DaemonControllerLinux::DoStop(const CompletionCallback& done_callback) {
- std::vector<std::string> args;
- args.push_back("--stop");
- int exit_code = 0;
- AsyncResult result;
- if (RunHostScript(args, &exit_code)) {
- result = (exit_code == 0) ? RESULT_OK : RESULT_FAILED;
- } else {
- result = RESULT_FAILED;
- }
- done_callback.Run(result);
-}
-
-void DaemonControllerLinux::DoGetVersion(
- const GetVersionCallback& done_callback) {
- FilePath script_path;
- if (!GetScriptPath(&script_path)) {
- done_callback.Run("");
- return;
- }
- CommandLine command_line(script_path);
- command_line.AppendArg("--host-version");
-
- std::string version;
- int exit_code = 0;
- int result =
- base::GetAppOutputWithExitCode(command_line, &version, &exit_code);
- if (!result || exit_code != 0) {
- LOG(ERROR) << "Failed to run \"" << command_line.GetCommandLineString()
- << "\". Exit code: " << exit_code;
- done_callback.Run("");
- return;
- }
-
- TrimWhitespaceASCII(version, TRIM_ALL, &version);
- if (!ContainsOnlyChars(version, "0123456789.")) {
- LOG(ERROR) << "Received invalid host version number: " << version;
- done_callback.Run("");
- return;
- }
-
- done_callback.Run(version);
-}
-
-} // namespace
-
-scoped_ptr<DaemonController> remoting::DaemonController::Create() {
- return scoped_ptr<DaemonController>(new DaemonControllerLinux());
-}
-
-} // namespace remoting
diff --git a/remoting/host/plugin/daemon_controller_mac.cc b/remoting/host/plugin/daemon_controller_mac.cc
deleted file mode 100644
index 54c59b3..0000000
--- a/remoting/host/plugin/daemon_controller_mac.cc
+++ /dev/null
@@ -1,368 +0,0 @@
-// Copyright (c) 2012 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/plugin/daemon_controller.h"
-
-#include <launch.h>
-#include <stdio.h>
-#include <sys/types.h>
-
-#include "base/basictypes.h"
-#include "base/bind.h"
-#include "base/compiler_specific.h"
-#include "base/file_path.h"
-#include "base/file_util.h"
-#include "base/json/json_writer.h"
-#include "base/logging.h"
-#include "base/mac/foundation_util.h"
-#include "base/mac/launchd.h"
-#include "base/mac/mac_logging.h"
-#include "base/mac/mac_util.h"
-#include "base/mac/scoped_launch_data.h"
-#include "base/threading/thread.h"
-#include "base/time.h"
-#include "base/values.h"
-#include "remoting/host/constants_mac.h"
-#include "remoting/host/json_host_config.h"
-#include "remoting/host/usage_stats_consent.h"
-
-namespace remoting {
-
-namespace {
-
-// The NSSystemDirectories.h header has a conflicting definition of
-// NSSearchPathDirectory with the one in base/mac/foundation_util.h.
-// Foundation.h would work, but it can only be included from Objective-C files.
-// Therefore, we define the needed constants here.
-const int NSLibraryDirectory = 5;
-
-class DaemonControllerMac : public remoting::DaemonController {
- public:
- DaemonControllerMac();
- virtual ~DaemonControllerMac();
-
- virtual State GetState() OVERRIDE;
- virtual void GetConfig(const GetConfigCallback& callback) OVERRIDE;
- virtual void SetConfigAndStart(
- scoped_ptr<base::DictionaryValue> config,
- bool consent,
- const CompletionCallback& done) OVERRIDE;
- virtual void UpdateConfig(scoped_ptr<base::DictionaryValue> config,
- const CompletionCallback& done_callback) OVERRIDE;
- virtual void Stop(const CompletionCallback& done_callback) OVERRIDE;
- virtual void SetWindow(void* window_handle) OVERRIDE;
- virtual void GetVersion(const GetVersionCallback& done_callback) OVERRIDE;
- virtual void GetUsageStatsConsent(
- const GetUsageStatsConsentCallback& callback) OVERRIDE;
-
- private:
- void DoGetConfig(const GetConfigCallback& callback);
- void DoGetVersion(const GetVersionCallback& callback);
- void DoSetConfigAndStart(scoped_ptr<base::DictionaryValue> config,
- const CompletionCallback& done);
- void DoUpdateConfig(scoped_ptr<base::DictionaryValue> config,
- const CompletionCallback& done_callback);
- void DoStop(const CompletionCallback& done_callback);
-
- void ShowPreferencePane(const std::string& config_data,
- const CompletionCallback& done_callback);
- void RegisterForPreferencePaneNotifications(
- const CompletionCallback &done_callback);
- 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);
-
- base::Thread auth_thread_;
- CompletionCallback current_callback_;
-
- DISALLOW_COPY_AND_ASSIGN(DaemonControllerMac);
-};
-
-DaemonControllerMac::DaemonControllerMac()
- : auth_thread_("Auth thread") {
- auth_thread_.Start();
-}
-
-DaemonControllerMac::~DaemonControllerMac() {
- auth_thread_.Stop();
- DeregisterForPreferencePaneNotifications();
-}
-
-void DaemonControllerMac::DeregisterForPreferencePaneNotifications() {
- CFNotificationCenterRemoveObserver(
- CFNotificationCenterGetDistributedCenter(),
- this,
- CFSTR(UPDATE_SUCCEEDED_NOTIFICATION_NAME),
- NULL);
- CFNotificationCenterRemoveObserver(
- CFNotificationCenterGetDistributedCenter(),
- this,
- CFSTR(UPDATE_FAILED_NOTIFICATION_NAME),
- NULL);
-}
-
-DaemonController::State DaemonControllerMac::GetState() {
- pid_t job_pid = base::mac::PIDForJob(kServiceName);
- if (job_pid < 0) {
- return DaemonController::STATE_NOT_INSTALLED;
- } else if (job_pid == 0) {
- // Service is stopped, or a start attempt failed.
- return DaemonController::STATE_STOPPED;
- } else {
- return DaemonController::STATE_STARTED;
- }
-}
-
-void DaemonControllerMac::GetConfig(const GetConfigCallback& callback) {
- // base::Unretained() is safe, since this object owns the thread and therefore
- // outlives it.
- auth_thread_.message_loop_proxy()->PostTask(
- FROM_HERE,
- base::Bind(&DaemonControllerMac::DoGetConfig, base::Unretained(this),
- callback));
-}
-
-void DaemonControllerMac::SetConfigAndStart(
- scoped_ptr<base::DictionaryValue> config,
- bool /* consent */,
- const CompletionCallback& done) {
- auth_thread_.message_loop_proxy()->PostTask(
- FROM_HERE, base::Bind(
- &DaemonControllerMac::DoSetConfigAndStart, base::Unretained(this),
- base::Passed(&config), done));
-}
-
-void DaemonControllerMac::UpdateConfig(
- scoped_ptr<base::DictionaryValue> config,
- const CompletionCallback& done_callback) {
- auth_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
- &DaemonControllerMac::DoUpdateConfig, base::Unretained(this),
- base::Passed(&config), done_callback));
-}
-
-void DaemonControllerMac::Stop(const CompletionCallback& done_callback) {
- auth_thread_.message_loop_proxy()->PostTask(
- FROM_HERE, base::Bind(
- &DaemonControllerMac::DoStop, base::Unretained(this), done_callback));
-}
-
-void DaemonControllerMac::SetWindow(void* window_handle) {
- // noop
-}
-
-void DaemonControllerMac::GetVersion(const GetVersionCallback& callback) {
- auth_thread_.message_loop_proxy()->PostTask(
- FROM_HERE,
- base::Bind(&DaemonControllerMac::DoGetVersion, base::Unretained(this),
- callback));
-}
-
-void DaemonControllerMac::GetUsageStatsConsent(
- const GetUsageStatsConsentCallback& callback) {
- // Crash dump collection is not implemented on Mac yet.
- // http://crbug.com/130678.
- callback.Run(false, false, false);
-}
-
-void DaemonControllerMac::DoGetConfig(const GetConfigCallback& callback) {
- FilePath config_path(kHostConfigFilePath);
- JsonHostConfig host_config(config_path);
- scoped_ptr<base::DictionaryValue> config;
-
- if (host_config.Read()) {
- config.reset(new base::DictionaryValue());
- std::string value;
- if (host_config.GetString(kHostIdConfigPath, &value))
- config.get()->SetString(kHostIdConfigPath, value);
- if (host_config.GetString(kXmppLoginConfigPath, &value))
- config.get()->SetString(kXmppLoginConfigPath, value);
- }
-
- callback.Run(config.Pass());
-}
-
-void DaemonControllerMac::DoGetVersion(const GetVersionCallback& callback) {
- std::string version = "";
- std::string command_line = remoting::kHostHelperScriptPath;
- command_line += " --host-version";
- FILE* script_output = popen(command_line.c_str(), "r");
- if (script_output) {
- char buffer[100];
- char* result = fgets(buffer, sizeof(buffer), script_output);
- pclose(script_output);
- if (result) {
- // The string is guaranteed to be null-terminated, but probably contains
- // a newline character, which we don't want.
- for (int i = 0; result[i]; ++i) {
- if (result[i] < ' ') {
- result[i] = 0;
- break;
- }
- }
- version = result;
- }
- }
- callback.Run(version);
-}
-
-void DaemonControllerMac::DoSetConfigAndStart(
- scoped_ptr<base::DictionaryValue> config,
- const CompletionCallback& done) {
- std::string config_data;
- base::JSONWriter::Write(config.get(), &config_data);
- ShowPreferencePane(config_data, done);
-}
-
-void DaemonControllerMac::DoUpdateConfig(
- scoped_ptr<base::DictionaryValue> config,
- const CompletionCallback& done_callback) {
- FilePath config_file_path(kHostConfigFilePath);
- JsonHostConfig config_file(config_file_path);
- if (!config_file.Read()) {
- done_callback.Run(RESULT_FAILED);
- return;
- }
- if (!config_file.CopyFrom(config.get())) {
- LOG(ERROR) << "Failed to update configuration.";
- done_callback.Run(RESULT_FAILED);
- return;
- }
-
- std::string config_data = config_file.GetSerializedData();
- ShowPreferencePane(config_data, done_callback);
-}
-
-void DaemonControllerMac::ShowPreferencePane(
- const std::string& config_data, const CompletionCallback& done_callback) {
- if (DoShowPreferencePane(config_data)) {
- RegisterForPreferencePaneNotifications(done_callback);
- } else {
- done_callback.Run(RESULT_FAILED);
- }
-}
-
-bool DaemonControllerMac::DoShowPreferencePane(const std::string& config_data) {
- if (!config_data.empty()) {
- FilePath config_path;
- if (!file_util::GetTempDir(&config_path)) {
- LOG(ERROR) << "Failed to get filename for saving configuration data.";
- return false;
- }
- config_path = config_path.Append(kHostConfigFileName);
-
- int written = file_util::WriteFile(config_path, config_data.data(),
- config_data.size());
- if (written != static_cast<int>(config_data.size())) {
- LOG(ERROR) << "Failed to save configuration data to: "
- << config_path.value();
- return false;
- }
- }
-
- FilePath pane_path;
- // TODO(lambroslambrou): Use NSPreferencePanesDirectory once we start
- // building against SDK 10.6.
- if (!base::mac::GetLocalDirectory(NSLibraryDirectory, &pane_path)) {
- LOG(ERROR) << "Failed to get directory for local preference panes.";
- return false;
- }
- pane_path = pane_path.Append("PreferencePanes").Append(kPrefPaneFileName);
-
- FSRef pane_path_ref;
- if (!base::mac::FSRefFromPath(pane_path.value(), &pane_path_ref)) {
- LOG(ERROR) << "Failed to create FSRef";
- return false;
- }
- OSStatus status = LSOpenFSRef(&pane_path_ref, NULL);
- if (status != noErr) {
- OSSTATUS_LOG(ERROR, status) << "LSOpenFSRef failed for path: "
- << pane_path.value();
- return false;
- }
-
- CFNotificationCenterRef center =
- CFNotificationCenterGetDistributedCenter();
- base::mac::ScopedCFTypeRef<CFStringRef> service_name(
- CFStringCreateWithCString(kCFAllocatorDefault, remoting::kServiceName,
- kCFStringEncodingUTF8));
- CFNotificationCenterPostNotification(center, service_name, NULL, NULL,
- TRUE);
- return true;
-}
-
-void DaemonControllerMac::DoStop(const CompletionCallback& done_callback) {
- ShowPreferencePane("", done_callback);
-}
-
-// CFNotificationCenterAddObserver ties the thread on which distributed
-// notifications are received to the one on which it is first called.
-// This is safe because HostNPScriptObject::InvokeAsyncResultCallback
-// bounces the invocation to the correct thread, so it doesn't matter
-// which thread CompletionCallbacks are called on.
-void DaemonControllerMac::RegisterForPreferencePaneNotifications(
- const CompletionCallback& done_callback) {
- // We can only have one callback registered at a time. This is enforced by the
- // UX flow of the web-app.
- DCHECK(current_callback_.is_null());
- current_callback_ = done_callback;
-
- CFNotificationCenterAddObserver(
- CFNotificationCenterGetDistributedCenter(),
- this,
- &DaemonControllerMac::PreferencePaneCallback,
- CFSTR(UPDATE_SUCCEEDED_NOTIFICATION_NAME),
- NULL,
- CFNotificationSuspensionBehaviorDeliverImmediately);
- CFNotificationCenterAddObserver(
- CFNotificationCenterGetDistributedCenter(),
- this,
- &DaemonControllerMac::PreferencePaneCallback,
- CFSTR(UPDATE_FAILED_NOTIFICATION_NAME),
- NULL,
- CFNotificationSuspensionBehaviorDeliverImmediately);
-}
-
-void DaemonControllerMac::PreferencePaneCallbackDelegate(CFStringRef name) {
- AsyncResult result = RESULT_FAILED;
- if (CFStringCompare(name, CFSTR(UPDATE_SUCCEEDED_NOTIFICATION_NAME), 0) ==
- kCFCompareEqualTo) {
- result = RESULT_OK;
- } else if (CFStringCompare(name, CFSTR(UPDATE_FAILED_NOTIFICATION_NAME), 0) ==
- kCFCompareEqualTo) {
- result = RESULT_FAILED;
- } else {
- LOG(WARNING) << "Ignoring unexpected notification: " << name;
- return;
- }
- DCHECK(!current_callback_.is_null());
- current_callback_.Run(result);
- current_callback_.Reset();
- DeregisterForPreferencePaneNotifications();
-}
-
-void DaemonControllerMac::PreferencePaneCallback(CFNotificationCenterRef center,
- void* observer,
- CFStringRef name,
- const void* object,
- CFDictionaryRef user_info) {
- DaemonControllerMac* self = reinterpret_cast<DaemonControllerMac*>(observer);
- if (self) {
- self->PreferencePaneCallbackDelegate(name);
- } else {
- LOG(WARNING) << "Ignoring notification with NULL observer: " << name;
- }
-}
-
-} // namespace
-
-scoped_ptr<DaemonController> remoting::DaemonController::Create() {
- return scoped_ptr<DaemonController>(new DaemonControllerMac());
-}
-
-} // namespace remoting
diff --git a/remoting/host/plugin/daemon_controller_win.cc b/remoting/host/plugin/daemon_controller_win.cc
deleted file mode 100644
index 2985652..0000000
--- a/remoting/host/plugin/daemon_controller_win.cc
+++ /dev/null
@@ -1,698 +0,0 @@
-// Copyright (c) 2012 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/plugin/daemon_controller.h"
-
-#include <objbase.h>
-
-#include "base/basictypes.h"
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/compiler_specific.h"
-#include "base/file_path.h"
-#include "base/file_util.h"
-#include "base/json/json_reader.h"
-#include "base/json/json_writer.h"
-#include "base/logging.h"
-#include "base/string16.h"
-#include "base/threading/thread.h"
-#include "base/time.h"
-#include "base/timer.h"
-#include "base/utf_string_conversions.h"
-#include "base/values.h"
-#include "base/win/scoped_bstr.h"
-#include "base/win/scoped_comptr.h"
-#include "base/win/windows_version.h"
-#include "remoting/base/scoped_sc_handle_win.h"
-#include "remoting/host/branding.h"
-#include "remoting/host/plugin/daemon_installer_win.h"
-#include "remoting/host/usage_stats_consent.h"
-
-// MIDL-generated declarations and definitions.
-#include "remoting/host/elevated_controller.h"
-
-using base::win::ScopedBstr;
-using base::win::ScopedComPtr;
-
-namespace remoting {
-
-namespace {
-
-// ProgID of the daemon controller.
-const wchar_t kDaemonController[] =
- L"ChromotingElevatedController.ElevatedController";
-
-// The COM elevation moniker for the Elevated Controller.
-const wchar_t kDaemonControllerElevationMoniker[] =
- L"Elevation:Administrator!new:"
- L"ChromotingElevatedController.ElevatedController";
-
-// Name of the Daemon Controller's worker thread.
-const char kDaemonControllerThreadName[] = "Daemon Controller thread";
-
-// The maximum duration of keeping a reference to a privileged instance of
-// the Daemon Controller. This effectively reduces number of UAC prompts a user
-// sees.
-const int kPrivilegedTimeoutSec = 5 * 60;
-
-// The maximum duration of keeping a reference to an unprivileged instance of
-// the Daemon Controller. This interval should not be too long. If upgrade
-// happens while there is a live reference to a Daemon Controller instance
-// the old binary still can be used. So dropping the references often makes sure
-// that the old binary will go away sooner.
-const int kUnprivilegedTimeoutSec = 60;
-
-// A base::Thread implementation that initializes COM on the new thread.
-class ComThread : public base::Thread {
- public:
- explicit ComThread(const char* name);
-
- bool Start();
-
- protected:
- virtual void Init() OVERRIDE;
- virtual void CleanUp() OVERRIDE;
-
- DISALLOW_COPY_AND_ASSIGN(ComThread);
-};
-
-class DaemonControllerWin : public remoting::DaemonController {
- public:
- DaemonControllerWin();
- virtual ~DaemonControllerWin();
-
- virtual State GetState() OVERRIDE;
- virtual void GetConfig(const GetConfigCallback& callback) OVERRIDE;
- virtual void SetConfigAndStart(
- scoped_ptr<base::DictionaryValue> config,
- bool consent,
- const CompletionCallback& done) OVERRIDE;
- virtual void UpdateConfig(scoped_ptr<base::DictionaryValue> config,
- const CompletionCallback& done_callback) OVERRIDE;
- virtual void Stop(const CompletionCallback& done_callback) OVERRIDE;
- virtual void SetWindow(void* window_handle) OVERRIDE;
- virtual void GetVersion(const GetVersionCallback& done_callback) OVERRIDE;
- virtual void GetUsageStatsConsent(
- const GetUsageStatsConsentCallback& done) 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 CompletionCallback& done,
- HRESULT result);
-
- // Opens the Chromoting service returning its handle in |service_out|.
- DWORD OpenService(ScopedScHandle* service_out);
-
- // Converts a config dictionary to a scoped BSTR.
- static void ConfigToString(const base::DictionaryValue& config,
- ScopedBstr* out);
-
- // Converts a Windows service status code to a Daemon state.
- static State ConvertToDaemonState(DWORD service_state);
-
- // Converts HRESULT to the AsyncResult.
- static AsyncResult HResultToAsyncResult(HRESULT hr);
-
- // The functions that actually do the work. They should be called in
- // the context of |worker_thread_|;
- void DoGetConfig(const GetConfigCallback& callback);
- void DoInstallAsNeededAndStart(scoped_ptr<base::DictionaryValue> config,
- bool consent,
- const CompletionCallback& done_callback);
- void DoSetConfigAndStart(scoped_ptr<base::DictionaryValue> config,
- bool consent,
- const CompletionCallback& done);
- void DoUpdateConfig(scoped_ptr<base::DictionaryValue> config,
- const CompletionCallback& done_callback);
- void DoStop(const CompletionCallback& done_callback);
- void DoSetWindow(void* window_handle);
- void DoGetVersion(const GetVersionCallback& callback);
- void DoGetUsageStatsConsent(
- const GetUsageStatsConsentCallback& done);
-
- // |control_| and |control2_| hold references to an instance of the daemon
- // controller to prevent a UAC prompt on every operation.
- ScopedComPtr<IDaemonControl> control_;
- 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<DaemonControllerWin> > release_timer_;
-
- // Handle of the plugin window.
- HWND window_handle_;
-
- // The worker thread used for servicing long running operations.
- ComThread worker_thread_;
-
- scoped_ptr<DaemonInstallerWin> installer_;
-
- DISALLOW_COPY_AND_ASSIGN(DaemonControllerWin);
-};
-
-ComThread::ComThread(const char* name) : base::Thread(name) {
-}
-
-bool ComThread::Start() {
- // N.B. The single threaded COM apartment must be run on a UI message loop.
- base::Thread::Options thread_options(MessageLoop::TYPE_UI, 0);
- return StartWithOptions(thread_options);
-}
-
-void ComThread::Init() {
- CoInitialize(NULL);
-}
-
-void ComThread::CleanUp() {
- CoUninitialize();
-}
-
-DaemonControllerWin::DaemonControllerWin()
- : control_is_elevated_(false),
- window_handle_(NULL),
- worker_thread_(kDaemonControllerThreadName) {
- if (!worker_thread_.Start()) {
- LOG(FATAL) << "Failed to start the Daemon Controller worker thread.";
- }
-}
-
-DaemonControllerWin::~DaemonControllerWin() {
- // Clean up resources allocated on the worker thread.
- worker_thread_.message_loop_proxy()->PostTask(
- FROM_HERE,
- base::Bind(&DaemonControllerWin::ReleaseController,
- base::Unretained(this)));
- worker_thread_.Stop();
-}
-
-remoting::DaemonController::State DaemonControllerWin::GetState() {
- if (base::win::GetVersion() < base::win::VERSION_XP) {
- return STATE_NOT_IMPLEMENTED;
- }
- // TODO(alexeypa): Make the thread alertable, so we can switch to APC
- // notifications rather than polling.
- ScopedScHandle service;
- DWORD error = OpenService(&service);
-
- switch (error) {
- case ERROR_SUCCESS: {
- SERVICE_STATUS status;
- if (::QueryServiceStatus(service, &status)) {
- return ConvertToDaemonState(status.dwCurrentState);
- } else {
- LOG_GETLASTERROR(ERROR)
- << "Failed to query the state of the '" << kWindowsServiceName
- << "' service";
- return STATE_UNKNOWN;
- }
- break;
- }
- case ERROR_SERVICE_DOES_NOT_EXIST:
- return STATE_NOT_INSTALLED;
- default:
- return STATE_UNKNOWN;
- }
-}
-
-void DaemonControllerWin::GetConfig(const GetConfigCallback& callback) {
- worker_thread_.message_loop_proxy()->PostTask(
- FROM_HERE,
- base::Bind(&DaemonControllerWin::DoGetConfig,
- base::Unretained(this), callback));
-}
-
-void DaemonControllerWin::SetConfigAndStart(
- scoped_ptr<base::DictionaryValue> config,
- bool consent,
- const CompletionCallback& done) {
- worker_thread_.message_loop_proxy()->PostTask(
- FROM_HERE, base::Bind(
- &DaemonControllerWin::DoInstallAsNeededAndStart,
- base::Unretained(this), base::Passed(&config), consent, done));
-}
-
-void DaemonControllerWin::UpdateConfig(
- scoped_ptr<base::DictionaryValue> config,
- const CompletionCallback& done_callback) {
- worker_thread_.message_loop_proxy()->PostTask(
- FROM_HERE, base::Bind(
- &DaemonControllerWin::DoUpdateConfig,
- base::Unretained(this), base::Passed(&config), done_callback));
-}
-
-void DaemonControllerWin::Stop(const CompletionCallback& done_callback) {
- worker_thread_.message_loop_proxy()->PostTask(
- FROM_HERE, base::Bind(
- &DaemonControllerWin::DoStop, base::Unretained(this),
- done_callback));
-}
-
-void DaemonControllerWin::SetWindow(void* window_handle) {
- worker_thread_.message_loop_proxy()->PostTask(
- FROM_HERE, base::Bind(
- &DaemonControllerWin::DoSetWindow, base::Unretained(this),
- window_handle));
-}
-
-void DaemonControllerWin::GetVersion(const GetVersionCallback& callback) {
- worker_thread_.message_loop_proxy()->PostTask(
- FROM_HERE,
- base::Bind(&DaemonControllerWin::DoGetVersion,
- base::Unretained(this), callback));
-}
-
-void DaemonControllerWin::GetUsageStatsConsent(
- const GetUsageStatsConsentCallback& done) {
- worker_thread_.message_loop_proxy()->PostTask(
- FROM_HERE,
- base::Bind(&DaemonControllerWin::DoGetUsageStatsConsent,
- base::Unretained(this), done));
-}
-
-HRESULT DaemonControllerWin::ActivateController() {
- DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread());
-
- if (control_.get() == NULL) {
- CLSID class_id;
- HRESULT hr = CLSIDFromProgID(kDaemonController, &class_id);
- if (FAILED(hr)) {
- return hr;
- }
-
- hr = CoCreateInstance(class_id, NULL, CLSCTX_LOCAL_SERVER,
- IID_IDaemonControl, control_.ReceiveVoid());
- if (FAILED(hr)) {
- return hr;
- }
-
- // Ignore the error. IID_IDaemonControl2 is optional.
- control_.QueryInterface(IID_IDaemonControl2, control2_.ReceiveVoid());
-
- // Release |control_| upon expiration of the timeout.
- release_timer_.reset(new base::OneShotTimer<DaemonControllerWin>());
- release_timer_->Start(FROM_HERE,
- base::TimeDelta::FromSeconds(kUnprivilegedTimeoutSec),
- this,
- &DaemonControllerWin::ReleaseController);
- }
-
- return S_OK;
-}
-
-HRESULT DaemonControllerWin::ActivateElevatedController() {
- DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread());
-
- // The COM elevation is supported on Vista and above.
- if (base::win::GetVersion() < base::win::VERSION_VISTA) {
- return ActivateController();
- }
-
- // Release an unprivileged instance of the daemon controller if any.
- if (!control_is_elevated_) {
- ReleaseController();
- }
-
- if (control_.get() == NULL) {
- BIND_OPTS3 bind_options;
- memset(&bind_options, 0, sizeof(bind_options));
- bind_options.cbStruct = sizeof(bind_options);
- bind_options.hwnd = GetTopLevelWindow(window_handle_);
- bind_options.dwClassContext = CLSCTX_LOCAL_SERVER;
-
- HRESULT hr = ::CoGetObject(
- kDaemonControllerElevationMoniker,
- &bind_options,
- IID_IDaemonControl,
- control_.ReceiveVoid());
- if (FAILED(hr)) {
- return hr;
- }
-
- // Ignore the error. IID_IDaemonControl2 is optional.
- control_.QueryInterface(IID_IDaemonControl2, control2_.ReceiveVoid());
-
- // Note that we hold a reference to an elevated instance now.
- control_is_elevated_ = true;
-
- // Release |control_| upon expiration of the timeout.
- release_timer_.reset(new base::OneShotTimer<DaemonControllerWin>());
- release_timer_->Start(FROM_HERE,
- base::TimeDelta::FromSeconds(kPrivilegedTimeoutSec),
- this,
- &DaemonControllerWin::ReleaseController);
- }
-
- return S_OK;
-}
-
-void DaemonControllerWin::ReleaseController() {
- DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread());
-
- control_.Release();
- control2_.Release();
- release_timer_.reset();
- control_is_elevated_ = false;
-}
-
-void DaemonControllerWin::OnInstallationComplete(
- scoped_ptr<base::DictionaryValue> config,
- bool consent,
- const CompletionCallback& done,
- HRESULT result) {
- DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread());
-
- if (SUCCEEDED(result)) {
- DoSetConfigAndStart(config.Pass(), consent, done);
- } else {
- LOG(ERROR) << "Failed to install the Chromoting Host "
- << "(error: 0x" << std::hex << result << std::dec << ").";
- done.Run(HResultToAsyncResult(result));
- }
-
- DCHECK(installer_.get() != NULL);
- installer_.reset();
-}
-
-DWORD DaemonControllerWin::OpenService(ScopedScHandle* service_out) {
- // Open the service and query its current state.
- ScopedScHandle scmanager(
- ::OpenSCManagerW(NULL, SERVICES_ACTIVE_DATABASE,
- SC_MANAGER_CONNECT | SC_MANAGER_ENUMERATE_SERVICE));
- if (!scmanager.IsValid()) {
- DWORD error = GetLastError();
- LOG_GETLASTERROR(ERROR)
- << "Failed to connect to the service control manager";
- return error;
- }
-
- ScopedScHandle service(
- ::OpenServiceW(scmanager, kWindowsServiceName, SERVICE_QUERY_STATUS));
- if (!service.IsValid()) {
- DWORD error = GetLastError();
- if (error != ERROR_SERVICE_DOES_NOT_EXIST) {
- LOG_GETLASTERROR(ERROR)
- << "Failed to open to the '" << kWindowsServiceName << "' service";
- }
- return error;
- }
-
- service_out->Set(service.Take());
- return ERROR_SUCCESS;
-}
-
-// static
-void DaemonControllerWin::ConfigToString(const base::DictionaryValue& config,
- ScopedBstr* out) {
- std::string config_str;
- base::JSONWriter::Write(&config, &config_str);
- ScopedBstr config_scoped_bstr(UTF8ToUTF16(config_str).c_str());
- out->Swap(config_scoped_bstr);
-}
-
-// static
-remoting::DaemonController::State DaemonControllerWin::ConvertToDaemonState(
- DWORD service_state) {
- switch (service_state) {
- case SERVICE_RUNNING:
- return STATE_STARTED;
-
- case SERVICE_CONTINUE_PENDING:
- case SERVICE_START_PENDING:
- return STATE_STARTING;
- break;
-
- case SERVICE_PAUSE_PENDING:
- case SERVICE_STOP_PENDING:
- return STATE_STOPPING;
- break;
-
- case SERVICE_PAUSED:
- case SERVICE_STOPPED:
- return STATE_STOPPED;
- break;
-
- default:
- NOTREACHED();
- return STATE_UNKNOWN;
- }
-}
-
-// static
-DaemonController::AsyncResult DaemonControllerWin::HResultToAsyncResult(
- HRESULT hr) {
- // TODO(sergeyu): Report other errors to the webapp once it knows
- // how to handle them.
- return FAILED(hr) ? RESULT_FAILED : RESULT_OK;
-}
-
-void DaemonControllerWin::DoGetConfig(const GetConfigCallback& callback) {
- DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread());
-
- scoped_ptr<base::DictionaryValue> dictionary_null(NULL);
-
- // Configure and start the Daemon Controller if it is installed already.
- HRESULT hr = ActivateController();
- if (FAILED(hr)) {
- callback.Run(dictionary_null.Pass());
- return;
- }
-
- // Get the host configuration.
- ScopedBstr host_config;
- hr = control_->GetConfig(host_config.Receive());
- if (FAILED(hr)) {
- callback.Run(dictionary_null.Pass());
- return;
- }
-
- // Parse the string into a dictionary.
- string16 file_content(static_cast<BSTR>(host_config), host_config.Length());
- scoped_ptr<base::Value> config(
- base::JSONReader::Read(UTF16ToUTF8(file_content),
- base::JSON_ALLOW_TRAILING_COMMAS));
-
- base::DictionaryValue* dictionary;
- if (config.get() == NULL || !config->GetAsDictionary(&dictionary)) {
- callback.Run(dictionary_null.Pass());
- return;
- }
- // Release |config|, because dictionary points to the same object.
- config.release();
-
- callback.Run(scoped_ptr<base::DictionaryValue>(dictionary));
-}
-
-void DaemonControllerWin::DoInstallAsNeededAndStart(
- scoped_ptr<base::DictionaryValue> config,
- bool consent,
- const CompletionCallback& done) {
- DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread());
-
- // Configure and start the Daemon Controller if it is installed already.
- HRESULT hr = ActivateElevatedController();
- if (SUCCEEDED(hr)) {
- DoSetConfigAndStart(config.Pass(), consent, done);
- return;
- }
-
- // Otherwise, install it if its COM registration entry is missing.
- if (hr == CO_E_CLASSSTRING) {
- scoped_ptr<DaemonInstallerWin> installer = DaemonInstallerWin::Create(
- GetTopLevelWindow(window_handle_),
- base::Bind(&DaemonControllerWin::OnInstallationComplete,
- base::Unretained(this),
- base::Passed(&config),
- consent,
- done));
- if (installer.get()) {
- DCHECK(!installer_.get());
- installer_ = installer.Pass();
- installer_->Install();
- }
- } else {
- LOG(ERROR) << "Failed to initiate the Chromoting Host installation "
- << "(error: 0x" << std::hex << hr << std::dec << ").";
- done.Run(HResultToAsyncResult(hr));
- }
-}
-
-void DaemonControllerWin::DoSetConfigAndStart(
- scoped_ptr<base::DictionaryValue> config,
- bool consent,
- const CompletionCallback& done) {
- DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread());
-
- HRESULT hr = ActivateElevatedController();
- if (FAILED(hr)) {
- done.Run(HResultToAsyncResult(hr));
- return;
- }
-
- // Record the user's consent.
- if (control2_.get()) {
- hr = control2_->SetUsageStatsConsent(consent);
- if (FAILED(hr)) {
- done.Run(HResultToAsyncResult(hr));
- return;
- }
- }
-
- // Set the configuration.
- ScopedBstr config_str(NULL);
- ConfigToString(*config, &config_str);
- if (config_str == NULL) {
- done.Run(HResultToAsyncResult(E_OUTOFMEMORY));
- return;
- }
-
- hr = control_->SetOwnerWindow(
- reinterpret_cast<LONG_PTR>(GetTopLevelWindow(window_handle_)));
- if (FAILED(hr)) {
- done.Run(HResultToAsyncResult(hr));
- return;
- }
-
- hr = control_->SetConfig(config_str);
- if (FAILED(hr)) {
- done.Run(HResultToAsyncResult(hr));
- return;
- }
-
- // Start daemon.
- hr = control_->StartDaemon();
- done.Run(HResultToAsyncResult(hr));
-}
-
-void DaemonControllerWin::DoUpdateConfig(
- scoped_ptr<base::DictionaryValue> config,
- const CompletionCallback& done_callback) {
- DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread());
-
- HRESULT hr = ActivateElevatedController();
- if (FAILED(hr)) {
- done_callback.Run(HResultToAsyncResult(hr));
- return;
- }
-
- // Update the configuration.
- ScopedBstr config_str(NULL);
- ConfigToString(*config, &config_str);
- if (config_str == NULL) {
- done_callback.Run(HResultToAsyncResult(E_OUTOFMEMORY));
- return;
- }
-
- // Make sure that the PIN confirmation dialog is focused properly.
- hr = control_->SetOwnerWindow(
- reinterpret_cast<LONG_PTR>(GetTopLevelWindow(window_handle_)));
- if (FAILED(hr)) {
- done_callback.Run(HResultToAsyncResult(hr));
- return;
- }
-
- hr = control_->UpdateConfig(config_str);
- done_callback.Run(HResultToAsyncResult(hr));
-}
-
-void DaemonControllerWin::DoStop(const CompletionCallback& done_callback) {
- DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread());
-
- HRESULT hr = ActivateElevatedController();
- if (FAILED(hr)) {
- done_callback.Run(HResultToAsyncResult(hr));
- return;
- }
-
- hr = control_->StopDaemon();
- done_callback.Run(HResultToAsyncResult(hr));
-}
-
-void DaemonControllerWin::DoSetWindow(void* window_handle) {
- window_handle_ = reinterpret_cast<HWND>(window_handle);
-}
-
-void DaemonControllerWin::DoGetVersion(const GetVersionCallback& callback) {
- DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread());
-
- std::string version_null;
-
- // Configure and start the Daemon Controller if it is installed already.
- HRESULT hr = ActivateController();
- if (FAILED(hr)) {
- callback.Run(version_null);
- return;
- }
-
- // Get the version string.
- ScopedBstr version;
- hr = control_->GetVersion(version.Receive());
- if (FAILED(hr)) {
- callback.Run(version_null);
- return;
- }
-
- callback.Run(UTF16ToUTF8(
- string16(static_cast<BSTR>(version), version.Length())));
-}
-
-void DaemonControllerWin::DoGetUsageStatsConsent(
- const GetUsageStatsConsentCallback& done) {
- DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread());
-
- // Activate the Daemon Controller and see if it supports |IDaemonControl2|.
- HRESULT hr = ActivateController();
- if (FAILED(hr)) {
- // The host is not installed yet. Assume that the user's consent is not
- // recorded yet and set the default value to true. This value will not come
- // into effect until the user installs the host and agrees to crash
- // dump reporting.
- done.Run(true, true, false);
- return;
- }
-
- if (control2_.get() == NULL) {
- // The host is installed and does not support crash dump reporting.
- done.Run(false, false, false);
- return;
- }
-
- // Get the recorded user's consent.
- BOOL allowed;
- BOOL set_by_policy;
- hr = control2_->GetUsageStatsConsent(&allowed, &set_by_policy);
- if (FAILED(hr)) {
- // If the user's consent is not recorded yet, set the default value to true.
- // This value will not come into effect until the user agrees to crash
- // dump reporting.
- done.Run(true, true, false);
- return;
- }
-
- done.Run(true, !!allowed, !!set_by_policy);
-}
-
-} // namespace
-
-scoped_ptr<DaemonController> remoting::DaemonController::Create() {
- return scoped_ptr<DaemonController>(new DaemonControllerWin());
-}
-
-} // namespace remoting
diff --git a/remoting/host/plugin/daemon_installer_win.h b/remoting/host/plugin/daemon_installer_win.h
index bff134c..3709982 100644
--- a/remoting/host/plugin/daemon_installer_win.h
+++ b/remoting/host/plugin/daemon_installer_win.h
@@ -10,7 +10,6 @@
#include "base/basictypes.h"
#include "base/callback.h"
#include "base/memory/scoped_ptr.h"
-#include "remoting/host/plugin/daemon_controller.h"
namespace remoting {
diff --git a/remoting/host/plugin/host_script_object.cc b/remoting/host/plugin/host_script_object.cc
index 15b5cee..6af792f 100644
--- a/remoting/host/plugin/host_script_object.cc
+++ b/remoting/host/plugin/host_script_object.cc
@@ -27,7 +27,6 @@
#include "remoting/host/it2me_host_user_interface.h"
#include "remoting/host/network_settings.h"
#include "remoting/host/pin_hash.h"
-#include "remoting/host/plugin/daemon_controller.h"
#include "remoting/host/plugin/host_log_handler.h"
#include "remoting/host/policy_hack/policy_watcher.h"
#include "remoting/host/register_support_host_request.h"
diff --git a/remoting/host/plugin/host_script_object.h b/remoting/host/plugin/host_script_object.h
index db452cf..c9bd1ec5 100644
--- a/remoting/host/plugin/host_script_object.h
+++ b/remoting/host/plugin/host_script_object.h
@@ -23,8 +23,8 @@
#include "remoting/host/host_key_pair.h"
#include "remoting/host/host_status_observer.h"
#include "remoting/host/log_to_server.h"
-#include "remoting/host/plugin/daemon_controller.h"
#include "remoting/host/plugin/host_plugin_utils.h"
+#include "remoting/host/setup/daemon_controller.h"
#include "remoting/host/ui_strings.h"
#include "third_party/npapi/bindings/npapi.h"
#include "third_party/npapi/bindings/npfunctions.h"