| Index: remoting/host/plugin/daemon_controller_win.cc
|
| diff --git a/remoting/host/plugin/daemon_controller_win.cc b/remoting/host/plugin/daemon_controller_win.cc
|
| index 86e7d66644cea80c422e83a96039488a595791af..0cb41a9aeddc1a9325d5a24b3babfade6c3f4a17 100644
|
| --- a/remoting/host/plugin/daemon_controller_win.cc
|
| +++ b/remoting/host/plugin/daemon_controller_win.cc
|
| @@ -27,6 +27,7 @@
|
| #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"
|
| @@ -76,12 +77,15 @@ class DaemonControllerWin : public remoting::DaemonController {
|
| virtual void GetConfig(const GetConfigCallback& callback) OVERRIDE;
|
| virtual void SetConfigAndStart(
|
| scoped_ptr<base::DictionaryValue> config,
|
| - const CompletionCallback& done_callback) OVERRIDE;
|
| + 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.
|
| @@ -96,7 +100,8 @@ class DaemonControllerWin : public remoting::DaemonController {
|
| // Procedes with the daemon configuration if the installation succeeded,
|
| // otherwise reports the error.
|
| void OnInstallationComplete(scoped_ptr<base::DictionaryValue> config,
|
| - const CompletionCallback& done_callback,
|
| + bool consent,
|
| + const CompletionCallback& done,
|
| HRESULT result);
|
|
|
| // Opens the Chromoting service returning its handle in |service_out|.
|
| @@ -116,18 +121,23 @@ class DaemonControllerWin : public remoting::DaemonController {
|
| // 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,
|
| - const CompletionCallback& done_callback);
|
| + 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_| holds a reference to an instance of the daemon controller
|
| - // to prevent a UAC prompt on every operation.
|
| + // |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.
|
| @@ -220,11 +230,12 @@ void DaemonControllerWin::GetConfig(const GetConfigCallback& callback) {
|
|
|
| void DaemonControllerWin::SetConfigAndStart(
|
| scoped_ptr<base::DictionaryValue> config,
|
| - const CompletionCallback& done_callback) {
|
| + bool consent,
|
| + const CompletionCallback& done) {
|
| worker_thread_.message_loop_proxy()->PostTask(
|
| FROM_HERE, base::Bind(
|
| &DaemonControllerWin::DoInstallAsNeededAndStart,
|
| - base::Unretained(this), base::Passed(&config), done_callback));
|
| + base::Unretained(this), base::Passed(&config), consent, done));
|
| }
|
|
|
| void DaemonControllerWin::UpdateConfig(
|
| @@ -257,6 +268,14 @@ void DaemonControllerWin::GetVersion(const GetVersionCallback& callback) {
|
| 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());
|
|
|
| @@ -272,6 +291,9 @@ HRESULT DaemonControllerWin::ActivateController() {
|
| if (FAILED(hr)) {
|
| return hr;
|
| }
|
| +
|
| + // Ignore the error. IID_IDaemonControl2 is optional.
|
| + control_.QueryInterface(IID_IDaemonControl2, control2_.ReceiveVoid());
|
| }
|
|
|
| return S_OK;
|
| @@ -301,6 +323,9 @@ HRESULT DaemonControllerWin::ActivateElevatedController() {
|
| 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;
|
|
|
| @@ -319,22 +344,24 @@ 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,
|
| - const CompletionCallback& done_callback,
|
| + bool consent,
|
| + const CompletionCallback& done,
|
| HRESULT result) {
|
| DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread());
|
|
|
| if (SUCCEEDED(result)) {
|
| - DoSetConfigAndStart(config.Pass(), done_callback);
|
| + DoSetConfigAndStart(config.Pass(), consent, done);
|
| } else {
|
| LOG(ERROR) << "Failed to install the Chromoting Host "
|
| << "(error: 0x" << std::hex << result << std::dec << ").";
|
| - done_callback.Run(HResultToAsyncResult(result));
|
| + done.Run(HResultToAsyncResult(result));
|
| }
|
|
|
| DCHECK(installer_.get() != NULL);
|
| @@ -452,13 +479,14 @@ void DaemonControllerWin::DoGetConfig(const GetConfigCallback& callback) {
|
|
|
| void DaemonControllerWin::DoInstallAsNeededAndStart(
|
| scoped_ptr<base::DictionaryValue> config,
|
| - const CompletionCallback& done_callback) {
|
| + 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(), done_callback);
|
| + DoSetConfigAndStart(config.Pass(), consent, done);
|
| return;
|
| }
|
|
|
| @@ -469,7 +497,8 @@ void DaemonControllerWin::DoInstallAsNeededAndStart(
|
| base::Bind(&DaemonControllerWin::OnInstallationComplete,
|
| base::Unretained(this),
|
| base::Passed(&config),
|
| - done_callback));
|
| + consent,
|
| + done));
|
| if (installer.get()) {
|
| DCHECK(!installer_.get());
|
| installer_ = installer.Pass();
|
| @@ -478,45 +507,55 @@ void DaemonControllerWin::DoInstallAsNeededAndStart(
|
| } else {
|
| LOG(ERROR) << "Failed to initiate the Chromoting Host installation "
|
| << "(error: 0x" << std::hex << hr << std::dec << ").";
|
| - done_callback.Run(HResultToAsyncResult(hr));
|
| + done.Run(HResultToAsyncResult(hr));
|
| }
|
| }
|
|
|
| void DaemonControllerWin::DoSetConfigAndStart(
|
| scoped_ptr<base::DictionaryValue> config,
|
| - const CompletionCallback& done_callback) {
|
| + bool consent,
|
| + const CompletionCallback& done) {
|
| DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread());
|
|
|
| HRESULT hr = ActivateElevatedController();
|
| if (FAILED(hr)) {
|
| - done_callback.Run(HResultToAsyncResult(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_callback.Run(HResultToAsyncResult(E_OUTOFMEMORY));
|
| + done.Run(HResultToAsyncResult(E_OUTOFMEMORY));
|
| return;
|
| }
|
|
|
| hr = control_->SetOwnerWindow(
|
| reinterpret_cast<LONG_PTR>(GetTopLevelWindow(window_handle_)));
|
| if (FAILED(hr)) {
|
| - done_callback.Run(HResultToAsyncResult(hr));
|
| + done.Run(HResultToAsyncResult(hr));
|
| return;
|
| }
|
|
|
| hr = control_->SetConfig(config_str);
|
| if (FAILED(hr)) {
|
| - done_callback.Run(HResultToAsyncResult(hr));
|
| + done.Run(HResultToAsyncResult(hr));
|
| return;
|
| }
|
|
|
| // Start daemon.
|
| hr = control_->StartDaemon();
|
| - done_callback.Run(HResultToAsyncResult(hr));
|
| + done.Run(HResultToAsyncResult(hr));
|
| }
|
|
|
| void DaemonControllerWin::DoUpdateConfig(
|
| @@ -591,6 +630,32 @@ void DaemonControllerWin::DoGetVersion(const GetVersionCallback& callback) {
|
| 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) || control2_.get() == NULL) {
|
| + 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 while starting the host.
|
| + done.Run(true, true, false);
|
| + return;
|
| + }
|
| +
|
| + done.Run(true, !!allowed, !!set_by_policy);
|
| +}
|
| +
|
| } // namespace
|
|
|
| scoped_ptr<DaemonController> remoting::DaemonController::Create() {
|
|
|