OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "remoting/host/plugin/daemon_controller.h" | 5 #include "remoting/host/plugin/daemon_controller.h" |
6 | 6 |
7 #include <objbase.h> | 7 #include <objbase.h> |
8 | 8 |
9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
11 #include "base/bind_helpers.h" | 11 #include "base/bind_helpers.h" |
12 #include "base/compiler_specific.h" | 12 #include "base/compiler_specific.h" |
13 #include "base/file_path.h" | 13 #include "base/file_path.h" |
14 #include "base/file_util.h" | 14 #include "base/file_util.h" |
15 #include "base/json/json_reader.h" | 15 #include "base/json/json_reader.h" |
16 #include "base/json/json_writer.h" | 16 #include "base/json/json_writer.h" |
17 #include "base/logging.h" | 17 #include "base/logging.h" |
18 #include "base/string16.h" | 18 #include "base/string16.h" |
19 #include "base/threading/thread.h" | 19 #include "base/threading/thread.h" |
20 #include "base/time.h" | 20 #include "base/time.h" |
21 #include "base/timer.h" | 21 #include "base/timer.h" |
22 #include "base/utf_string_conversions.h" | 22 #include "base/utf_string_conversions.h" |
23 #include "base/values.h" | 23 #include "base/values.h" |
24 #include "base/win/scoped_bstr.h" | 24 #include "base/win/scoped_bstr.h" |
25 #include "base/win/scoped_comptr.h" | 25 #include "base/win/scoped_comptr.h" |
26 #include "base/win/windows_version.h" | 26 #include "base/win/windows_version.h" |
27 #include "remoting/base/scoped_sc_handle_win.h" | 27 #include "remoting/base/scoped_sc_handle_win.h" |
28 #include "remoting/host/branding.h" | 28 #include "remoting/host/branding.h" |
29 #include "remoting/host/plugin/daemon_installer_win.h" | 29 #include "remoting/host/plugin/daemon_installer_win.h" |
| 30 #include "remoting/host/usage_stats_consent.h" |
30 | 31 |
31 // MIDL-generated declarations and definitions. | 32 // MIDL-generated declarations and definitions. |
32 #include "remoting/host/elevated_controller.h" | 33 #include "remoting/host/elevated_controller.h" |
33 | 34 |
34 using base::win::ScopedBstr; | 35 using base::win::ScopedBstr; |
35 using base::win::ScopedComPtr; | 36 using base::win::ScopedComPtr; |
36 | 37 |
37 namespace remoting { | 38 namespace remoting { |
38 | 39 |
39 namespace { | 40 namespace { |
(...skipping 29 matching lines...) Expand all Loading... |
69 | 70 |
70 class DaemonControllerWin : public remoting::DaemonController { | 71 class DaemonControllerWin : public remoting::DaemonController { |
71 public: | 72 public: |
72 DaemonControllerWin(); | 73 DaemonControllerWin(); |
73 virtual ~DaemonControllerWin(); | 74 virtual ~DaemonControllerWin(); |
74 | 75 |
75 virtual State GetState() OVERRIDE; | 76 virtual State GetState() OVERRIDE; |
76 virtual void GetConfig(const GetConfigCallback& callback) OVERRIDE; | 77 virtual void GetConfig(const GetConfigCallback& callback) OVERRIDE; |
77 virtual void SetConfigAndStart( | 78 virtual void SetConfigAndStart( |
78 scoped_ptr<base::DictionaryValue> config, | 79 scoped_ptr<base::DictionaryValue> config, |
79 const CompletionCallback& done_callback) OVERRIDE; | 80 bool consent, |
| 81 const CompletionCallback& done) OVERRIDE; |
80 virtual void UpdateConfig(scoped_ptr<base::DictionaryValue> config, | 82 virtual void UpdateConfig(scoped_ptr<base::DictionaryValue> config, |
81 const CompletionCallback& done_callback) OVERRIDE; | 83 const CompletionCallback& done_callback) OVERRIDE; |
82 virtual void Stop(const CompletionCallback& done_callback) OVERRIDE; | 84 virtual void Stop(const CompletionCallback& done_callback) OVERRIDE; |
83 virtual void SetWindow(void* window_handle) OVERRIDE; | 85 virtual void SetWindow(void* window_handle) OVERRIDE; |
84 virtual void GetVersion(const GetVersionCallback& done_callback) OVERRIDE; | 86 virtual void GetVersion(const GetVersionCallback& done_callback) OVERRIDE; |
| 87 virtual void GetUsageStatsConsent( |
| 88 const GetUsageStatsConsentCallback& done) OVERRIDE; |
85 | 89 |
86 private: | 90 private: |
87 // Activates an unprivileged instance of the daemon controller and caches it. | 91 // Activates an unprivileged instance of the daemon controller and caches it. |
88 HRESULT ActivateController(); | 92 HRESULT ActivateController(); |
89 | 93 |
90 // Activates an elevated instance of the daemon controller and caches it. | 94 // Activates an elevated instance of the daemon controller and caches it. |
91 HRESULT ActivateElevatedController(); | 95 HRESULT ActivateElevatedController(); |
92 | 96 |
93 // Releases the cached instance of the controller. | 97 // Releases the cached instance of the controller. |
94 void ReleaseController(); | 98 void ReleaseController(); |
95 | 99 |
96 // Procedes with the daemon configuration if the installation succeeded, | 100 // Procedes with the daemon configuration if the installation succeeded, |
97 // otherwise reports the error. | 101 // otherwise reports the error. |
98 void OnInstallationComplete(scoped_ptr<base::DictionaryValue> config, | 102 void OnInstallationComplete(scoped_ptr<base::DictionaryValue> config, |
99 const CompletionCallback& done_callback, | 103 bool consent, |
| 104 const CompletionCallback& done, |
100 HRESULT result); | 105 HRESULT result); |
101 | 106 |
102 // Opens the Chromoting service returning its handle in |service_out|. | 107 // Opens the Chromoting service returning its handle in |service_out|. |
103 DWORD OpenService(ScopedScHandle* service_out); | 108 DWORD OpenService(ScopedScHandle* service_out); |
104 | 109 |
105 // Converts a config dictionary to a scoped BSTR. | 110 // Converts a config dictionary to a scoped BSTR. |
106 static void ConfigToString(const base::DictionaryValue& config, | 111 static void ConfigToString(const base::DictionaryValue& config, |
107 ScopedBstr* out); | 112 ScopedBstr* out); |
108 | 113 |
109 // Converts a Windows service status code to a Daemon state. | 114 // Converts a Windows service status code to a Daemon state. |
110 static State ConvertToDaemonState(DWORD service_state); | 115 static State ConvertToDaemonState(DWORD service_state); |
111 | 116 |
112 // Converts HRESULT to the AsyncResult. | 117 // Converts HRESULT to the AsyncResult. |
113 static AsyncResult HResultToAsyncResult(HRESULT hr); | 118 static AsyncResult HResultToAsyncResult(HRESULT hr); |
114 | 119 |
115 // The functions that actually do the work. They should be called in | 120 // The functions that actually do the work. They should be called in |
116 // the context of |worker_thread_|; | 121 // the context of |worker_thread_|; |
117 void DoGetConfig(const GetConfigCallback& callback); | 122 void DoGetConfig(const GetConfigCallback& callback); |
118 void DoInstallAsNeededAndStart(scoped_ptr<base::DictionaryValue> config, | 123 void DoInstallAsNeededAndStart(scoped_ptr<base::DictionaryValue> config, |
| 124 bool consent, |
119 const CompletionCallback& done_callback); | 125 const CompletionCallback& done_callback); |
120 void DoSetConfigAndStart(scoped_ptr<base::DictionaryValue> config, | 126 void DoSetConfigAndStart(scoped_ptr<base::DictionaryValue> config, |
121 const CompletionCallback& done_callback); | 127 bool consent, |
| 128 const CompletionCallback& done); |
122 void DoUpdateConfig(scoped_ptr<base::DictionaryValue> config, | 129 void DoUpdateConfig(scoped_ptr<base::DictionaryValue> config, |
123 const CompletionCallback& done_callback); | 130 const CompletionCallback& done_callback); |
124 void DoStop(const CompletionCallback& done_callback); | 131 void DoStop(const CompletionCallback& done_callback); |
125 void DoSetWindow(void* window_handle); | 132 void DoSetWindow(void* window_handle); |
126 void DoGetVersion(const GetVersionCallback& callback); | 133 void DoGetVersion(const GetVersionCallback& callback); |
| 134 void DoGetUsageStatsConsent( |
| 135 const GetUsageStatsConsentCallback& done); |
127 | 136 |
128 // |control_| holds a reference to an instance of the daemon controller | 137 // |control_| and |control2_| hold references to an instance of the daemon |
129 // to prevent a UAC prompt on every operation. | 138 // controller to prevent a UAC prompt on every operation. |
130 ScopedComPtr<IDaemonControl> control_; | 139 ScopedComPtr<IDaemonControl> control_; |
| 140 ScopedComPtr<IDaemonControl2> control2_; |
131 | 141 |
132 // True if |control_| holds a reference to an elevated instance of the daemon | 142 // True if |control_| holds a reference to an elevated instance of the daemon |
133 // controller. | 143 // controller. |
134 bool control_is_elevated_; | 144 bool control_is_elevated_; |
135 | 145 |
136 // This timer is used to release |control_| after a timeout. | 146 // This timer is used to release |control_| after a timeout. |
137 scoped_ptr<base::OneShotTimer<DaemonControllerWin> > release_timer_; | 147 scoped_ptr<base::OneShotTimer<DaemonControllerWin> > release_timer_; |
138 | 148 |
139 // Handle of the plugin window. | 149 // Handle of the plugin window. |
140 HWND window_handle_; | 150 HWND window_handle_; |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
213 | 223 |
214 void DaemonControllerWin::GetConfig(const GetConfigCallback& callback) { | 224 void DaemonControllerWin::GetConfig(const GetConfigCallback& callback) { |
215 worker_thread_.message_loop_proxy()->PostTask( | 225 worker_thread_.message_loop_proxy()->PostTask( |
216 FROM_HERE, | 226 FROM_HERE, |
217 base::Bind(&DaemonControllerWin::DoGetConfig, | 227 base::Bind(&DaemonControllerWin::DoGetConfig, |
218 base::Unretained(this), callback)); | 228 base::Unretained(this), callback)); |
219 } | 229 } |
220 | 230 |
221 void DaemonControllerWin::SetConfigAndStart( | 231 void DaemonControllerWin::SetConfigAndStart( |
222 scoped_ptr<base::DictionaryValue> config, | 232 scoped_ptr<base::DictionaryValue> config, |
223 const CompletionCallback& done_callback) { | 233 bool consent, |
| 234 const CompletionCallback& done) { |
224 worker_thread_.message_loop_proxy()->PostTask( | 235 worker_thread_.message_loop_proxy()->PostTask( |
225 FROM_HERE, base::Bind( | 236 FROM_HERE, base::Bind( |
226 &DaemonControllerWin::DoInstallAsNeededAndStart, | 237 &DaemonControllerWin::DoInstallAsNeededAndStart, |
227 base::Unretained(this), base::Passed(&config), done_callback)); | 238 base::Unretained(this), base::Passed(&config), consent, done)); |
228 } | 239 } |
229 | 240 |
230 void DaemonControllerWin::UpdateConfig( | 241 void DaemonControllerWin::UpdateConfig( |
231 scoped_ptr<base::DictionaryValue> config, | 242 scoped_ptr<base::DictionaryValue> config, |
232 const CompletionCallback& done_callback) { | 243 const CompletionCallback& done_callback) { |
233 worker_thread_.message_loop_proxy()->PostTask( | 244 worker_thread_.message_loop_proxy()->PostTask( |
234 FROM_HERE, base::Bind( | 245 FROM_HERE, base::Bind( |
235 &DaemonControllerWin::DoUpdateConfig, | 246 &DaemonControllerWin::DoUpdateConfig, |
236 base::Unretained(this), base::Passed(&config), done_callback)); | 247 base::Unretained(this), base::Passed(&config), done_callback)); |
237 } | 248 } |
(...skipping 12 matching lines...) Expand all Loading... |
250 window_handle)); | 261 window_handle)); |
251 } | 262 } |
252 | 263 |
253 void DaemonControllerWin::GetVersion(const GetVersionCallback& callback) { | 264 void DaemonControllerWin::GetVersion(const GetVersionCallback& callback) { |
254 worker_thread_.message_loop_proxy()->PostTask( | 265 worker_thread_.message_loop_proxy()->PostTask( |
255 FROM_HERE, | 266 FROM_HERE, |
256 base::Bind(&DaemonControllerWin::DoGetVersion, | 267 base::Bind(&DaemonControllerWin::DoGetVersion, |
257 base::Unretained(this), callback)); | 268 base::Unretained(this), callback)); |
258 } | 269 } |
259 | 270 |
| 271 void DaemonControllerWin::GetUsageStatsConsent( |
| 272 const GetUsageStatsConsentCallback& done) { |
| 273 worker_thread_.message_loop_proxy()->PostTask( |
| 274 FROM_HERE, |
| 275 base::Bind(&DaemonControllerWin::DoGetUsageStatsConsent, |
| 276 base::Unretained(this), done)); |
| 277 } |
| 278 |
260 HRESULT DaemonControllerWin::ActivateController() { | 279 HRESULT DaemonControllerWin::ActivateController() { |
261 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread()); | 280 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread()); |
262 | 281 |
263 if (control_.get() == NULL) { | 282 if (control_.get() == NULL) { |
264 CLSID class_id; | 283 CLSID class_id; |
265 HRESULT hr = CLSIDFromProgID(kDaemonController, &class_id); | 284 HRESULT hr = CLSIDFromProgID(kDaemonController, &class_id); |
266 if (FAILED(hr)) { | 285 if (FAILED(hr)) { |
267 return hr; | 286 return hr; |
268 } | 287 } |
269 | 288 |
270 hr = CoCreateInstance(class_id, NULL, CLSCTX_LOCAL_SERVER, | 289 hr = CoCreateInstance(class_id, NULL, CLSCTX_LOCAL_SERVER, |
271 IID_IDaemonControl, control_.ReceiveVoid()); | 290 IID_IDaemonControl, control_.ReceiveVoid()); |
272 if (FAILED(hr)) { | 291 if (FAILED(hr)) { |
273 return hr; | 292 return hr; |
274 } | 293 } |
| 294 |
| 295 // Ignore the error. IID_IDaemonControl2 is optional. |
| 296 control_.QueryInterface(IID_IDaemonControl2, control2_.ReceiveVoid()); |
275 } | 297 } |
276 | 298 |
277 return S_OK; | 299 return S_OK; |
278 } | 300 } |
279 | 301 |
280 HRESULT DaemonControllerWin::ActivateElevatedController() { | 302 HRESULT DaemonControllerWin::ActivateElevatedController() { |
281 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread()); | 303 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread()); |
282 | 304 |
283 // Release an unprivileged instance of the daemon controller if any. | 305 // Release an unprivileged instance of the daemon controller if any. |
284 if (!control_is_elevated_) { | 306 if (!control_is_elevated_) { |
285 ReleaseController(); | 307 ReleaseController(); |
286 } | 308 } |
287 | 309 |
288 if (control_.get() == NULL) { | 310 if (control_.get() == NULL) { |
289 BIND_OPTS3 bind_options; | 311 BIND_OPTS3 bind_options; |
290 memset(&bind_options, 0, sizeof(bind_options)); | 312 memset(&bind_options, 0, sizeof(bind_options)); |
291 bind_options.cbStruct = sizeof(bind_options); | 313 bind_options.cbStruct = sizeof(bind_options); |
292 bind_options.hwnd = GetTopLevelWindow(window_handle_); | 314 bind_options.hwnd = GetTopLevelWindow(window_handle_); |
293 bind_options.dwClassContext = CLSCTX_LOCAL_SERVER; | 315 bind_options.dwClassContext = CLSCTX_LOCAL_SERVER; |
294 | 316 |
295 HRESULT hr = ::CoGetObject( | 317 HRESULT hr = ::CoGetObject( |
296 kDaemonControllerElevationMoniker, | 318 kDaemonControllerElevationMoniker, |
297 &bind_options, | 319 &bind_options, |
298 IID_IDaemonControl, | 320 IID_IDaemonControl, |
299 control_.ReceiveVoid()); | 321 control_.ReceiveVoid()); |
300 if (FAILED(hr)) { | 322 if (FAILED(hr)) { |
301 return hr; | 323 return hr; |
302 } | 324 } |
303 | 325 |
| 326 // Ignore the error. IID_IDaemonControl2 is optional. |
| 327 control_.QueryInterface(IID_IDaemonControl2, control2_.ReceiveVoid()); |
| 328 |
304 // Note that we hold a reference to an elevated instance now. | 329 // Note that we hold a reference to an elevated instance now. |
305 control_is_elevated_ = true; | 330 control_is_elevated_ = true; |
306 | 331 |
307 // Release |control_| upon expiration of the timeout. | 332 // Release |control_| upon expiration of the timeout. |
308 release_timer_.reset(new base::OneShotTimer<DaemonControllerWin>()); | 333 release_timer_.reset(new base::OneShotTimer<DaemonControllerWin>()); |
309 release_timer_->Start(FROM_HERE, | 334 release_timer_->Start(FROM_HERE, |
310 base::TimeDelta::FromSeconds(kUacTimeoutSec), | 335 base::TimeDelta::FromSeconds(kUacTimeoutSec), |
311 this, | 336 this, |
312 &DaemonControllerWin::ReleaseController); | 337 &DaemonControllerWin::ReleaseController); |
313 } | 338 } |
314 | 339 |
315 return S_OK; | 340 return S_OK; |
316 } | 341 } |
317 | 342 |
318 void DaemonControllerWin::ReleaseController() { | 343 void DaemonControllerWin::ReleaseController() { |
319 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread()); | 344 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread()); |
320 | 345 |
321 control_.Release(); | 346 control_.Release(); |
| 347 control2_.Release(); |
322 release_timer_.reset(); | 348 release_timer_.reset(); |
323 control_is_elevated_ = false; | 349 control_is_elevated_ = false; |
324 } | 350 } |
325 | 351 |
326 void DaemonControllerWin::OnInstallationComplete( | 352 void DaemonControllerWin::OnInstallationComplete( |
327 scoped_ptr<base::DictionaryValue> config, | 353 scoped_ptr<base::DictionaryValue> config, |
328 const CompletionCallback& done_callback, | 354 bool consent, |
| 355 const CompletionCallback& done, |
329 HRESULT result) { | 356 HRESULT result) { |
330 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread()); | 357 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread()); |
331 | 358 |
332 if (SUCCEEDED(result)) { | 359 if (SUCCEEDED(result)) { |
333 DoSetConfigAndStart(config.Pass(), done_callback); | 360 DoSetConfigAndStart(config.Pass(), consent, done); |
334 } else { | 361 } else { |
335 LOG(ERROR) << "Failed to install the Chromoting Host " | 362 LOG(ERROR) << "Failed to install the Chromoting Host " |
336 << "(error: 0x" << std::hex << result << std::dec << ")."; | 363 << "(error: 0x" << std::hex << result << std::dec << ")."; |
337 done_callback.Run(HResultToAsyncResult(result)); | 364 done.Run(HResultToAsyncResult(result)); |
338 } | 365 } |
339 | 366 |
340 DCHECK(installer_.get() != NULL); | 367 DCHECK(installer_.get() != NULL); |
341 installer_.reset(); | 368 installer_.reset(); |
342 } | 369 } |
343 | 370 |
344 DWORD DaemonControllerWin::OpenService(ScopedScHandle* service_out) { | 371 DWORD DaemonControllerWin::OpenService(ScopedScHandle* service_out) { |
345 // Open the service and query its current state. | 372 // Open the service and query its current state. |
346 ScopedScHandle scmanager( | 373 ScopedScHandle scmanager( |
347 ::OpenSCManagerW(NULL, SERVICES_ACTIVE_DATABASE, | 374 ::OpenSCManagerW(NULL, SERVICES_ACTIVE_DATABASE, |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
445 return; | 472 return; |
446 } | 473 } |
447 // Release |config|, because dictionary points to the same object. | 474 // Release |config|, because dictionary points to the same object. |
448 config.release(); | 475 config.release(); |
449 | 476 |
450 callback.Run(scoped_ptr<base::DictionaryValue>(dictionary)); | 477 callback.Run(scoped_ptr<base::DictionaryValue>(dictionary)); |
451 } | 478 } |
452 | 479 |
453 void DaemonControllerWin::DoInstallAsNeededAndStart( | 480 void DaemonControllerWin::DoInstallAsNeededAndStart( |
454 scoped_ptr<base::DictionaryValue> config, | 481 scoped_ptr<base::DictionaryValue> config, |
455 const CompletionCallback& done_callback) { | 482 bool consent, |
| 483 const CompletionCallback& done) { |
456 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread()); | 484 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread()); |
457 | 485 |
458 // Configure and start the Daemon Controller if it is installed already. | 486 // Configure and start the Daemon Controller if it is installed already. |
459 HRESULT hr = ActivateElevatedController(); | 487 HRESULT hr = ActivateElevatedController(); |
460 if (SUCCEEDED(hr)) { | 488 if (SUCCEEDED(hr)) { |
461 DoSetConfigAndStart(config.Pass(), done_callback); | 489 DoSetConfigAndStart(config.Pass(), consent, done); |
462 return; | 490 return; |
463 } | 491 } |
464 | 492 |
465 // Otherwise, install it if its COM registration entry is missing. | 493 // Otherwise, install it if its COM registration entry is missing. |
466 if (hr == CO_E_CLASSSTRING) { | 494 if (hr == CO_E_CLASSSTRING) { |
467 scoped_ptr<DaemonInstallerWin> installer = DaemonInstallerWin::Create( | 495 scoped_ptr<DaemonInstallerWin> installer = DaemonInstallerWin::Create( |
468 GetTopLevelWindow(window_handle_), | 496 GetTopLevelWindow(window_handle_), |
469 base::Bind(&DaemonControllerWin::OnInstallationComplete, | 497 base::Bind(&DaemonControllerWin::OnInstallationComplete, |
470 base::Unretained(this), | 498 base::Unretained(this), |
471 base::Passed(&config), | 499 base::Passed(&config), |
472 done_callback)); | 500 consent, |
| 501 done)); |
473 if (installer.get()) { | 502 if (installer.get()) { |
474 DCHECK(!installer_.get()); | 503 DCHECK(!installer_.get()); |
475 installer_ = installer.Pass(); | 504 installer_ = installer.Pass(); |
476 installer_->Install(); | 505 installer_->Install(); |
477 } | 506 } |
478 } else { | 507 } else { |
479 LOG(ERROR) << "Failed to initiate the Chromoting Host installation " | 508 LOG(ERROR) << "Failed to initiate the Chromoting Host installation " |
480 << "(error: 0x" << std::hex << hr << std::dec << ")."; | 509 << "(error: 0x" << std::hex << hr << std::dec << ")."; |
481 done_callback.Run(HResultToAsyncResult(hr)); | 510 done.Run(HResultToAsyncResult(hr)); |
482 } | 511 } |
483 } | 512 } |
484 | 513 |
485 void DaemonControllerWin::DoSetConfigAndStart( | 514 void DaemonControllerWin::DoSetConfigAndStart( |
486 scoped_ptr<base::DictionaryValue> config, | 515 scoped_ptr<base::DictionaryValue> config, |
487 const CompletionCallback& done_callback) { | 516 bool consent, |
| 517 const CompletionCallback& done) { |
488 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread()); | 518 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread()); |
489 | 519 |
490 HRESULT hr = ActivateElevatedController(); | 520 HRESULT hr = ActivateElevatedController(); |
491 if (FAILED(hr)) { | 521 if (FAILED(hr)) { |
492 done_callback.Run(HResultToAsyncResult(hr)); | 522 done.Run(HResultToAsyncResult(hr)); |
493 return; | 523 return; |
494 } | 524 } |
495 | 525 |
| 526 // Record the user's consent. |
| 527 if (control2_.get()) { |
| 528 hr = control2_->SetUsageStatsConsent(consent); |
| 529 if (FAILED(hr)) { |
| 530 done.Run(HResultToAsyncResult(hr)); |
| 531 return; |
| 532 } |
| 533 } |
| 534 |
496 // Set the configuration. | 535 // Set the configuration. |
497 ScopedBstr config_str(NULL); | 536 ScopedBstr config_str(NULL); |
498 ConfigToString(*config, &config_str); | 537 ConfigToString(*config, &config_str); |
499 if (config_str == NULL) { | 538 if (config_str == NULL) { |
500 done_callback.Run(HResultToAsyncResult(E_OUTOFMEMORY)); | 539 done.Run(HResultToAsyncResult(E_OUTOFMEMORY)); |
501 return; | 540 return; |
502 } | 541 } |
503 | 542 |
504 hr = control_->SetOwnerWindow( | 543 hr = control_->SetOwnerWindow( |
505 reinterpret_cast<LONG_PTR>(GetTopLevelWindow(window_handle_))); | 544 reinterpret_cast<LONG_PTR>(GetTopLevelWindow(window_handle_))); |
506 if (FAILED(hr)) { | 545 if (FAILED(hr)) { |
507 done_callback.Run(HResultToAsyncResult(hr)); | 546 done.Run(HResultToAsyncResult(hr)); |
508 return; | 547 return; |
509 } | 548 } |
510 | 549 |
511 hr = control_->SetConfig(config_str); | 550 hr = control_->SetConfig(config_str); |
512 if (FAILED(hr)) { | 551 if (FAILED(hr)) { |
513 done_callback.Run(HResultToAsyncResult(hr)); | 552 done.Run(HResultToAsyncResult(hr)); |
514 return; | 553 return; |
515 } | 554 } |
516 | 555 |
517 // Start daemon. | 556 // Start daemon. |
518 hr = control_->StartDaemon(); | 557 hr = control_->StartDaemon(); |
519 done_callback.Run(HResultToAsyncResult(hr)); | 558 done.Run(HResultToAsyncResult(hr)); |
520 } | 559 } |
521 | 560 |
522 void DaemonControllerWin::DoUpdateConfig( | 561 void DaemonControllerWin::DoUpdateConfig( |
523 scoped_ptr<base::DictionaryValue> config, | 562 scoped_ptr<base::DictionaryValue> config, |
524 const CompletionCallback& done_callback) { | 563 const CompletionCallback& done_callback) { |
525 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread()); | 564 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread()); |
526 | 565 |
527 HRESULT hr = ActivateElevatedController(); | 566 HRESULT hr = ActivateElevatedController(); |
528 if (FAILED(hr)) { | 567 if (FAILED(hr)) { |
529 done_callback.Run(HResultToAsyncResult(hr)); | 568 done_callback.Run(HResultToAsyncResult(hr)); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
584 hr = control_->GetVersion(version.Receive()); | 623 hr = control_->GetVersion(version.Receive()); |
585 if (FAILED(hr)) { | 624 if (FAILED(hr)) { |
586 callback.Run(version_null); | 625 callback.Run(version_null); |
587 return; | 626 return; |
588 } | 627 } |
589 | 628 |
590 callback.Run(UTF16ToUTF8( | 629 callback.Run(UTF16ToUTF8( |
591 string16(static_cast<BSTR>(version), version.Length()))); | 630 string16(static_cast<BSTR>(version), version.Length()))); |
592 } | 631 } |
593 | 632 |
| 633 void DaemonControllerWin::DoGetUsageStatsConsent( |
| 634 const GetUsageStatsConsentCallback& done) { |
| 635 DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread()); |
| 636 |
| 637 // Activate the Daemon Controller and see if it supports |IDaemonControl2|. |
| 638 HRESULT hr = ActivateController(); |
| 639 if (FAILED(hr) || control2_.get() == NULL) { |
| 640 done.Run(false, false, false); |
| 641 return; |
| 642 } |
| 643 |
| 644 // Get the recorded user's consent. |
| 645 BOOL allowed; |
| 646 BOOL set_by_policy; |
| 647 hr = control2_->GetUsageStatsConsent(&allowed, &set_by_policy); |
| 648 if (FAILED(hr)) { |
| 649 // If the user's consent is not recorded yet, set the default value to true. |
| 650 // This value will not come into effect until the user agrees to crash |
| 651 // dump reporting while starting the host. |
| 652 done.Run(true, true, false); |
| 653 return; |
| 654 } |
| 655 |
| 656 done.Run(true, !!allowed, !!set_by_policy); |
| 657 } |
| 658 |
594 } // namespace | 659 } // namespace |
595 | 660 |
596 scoped_ptr<DaemonController> remoting::DaemonController::Create() { | 661 scoped_ptr<DaemonController> remoting::DaemonController::Create() { |
597 return scoped_ptr<DaemonController>(new DaemonControllerWin()); | 662 return scoped_ptr<DaemonController>(new DaemonControllerWin()); |
598 } | 663 } |
599 | 664 |
600 } // namespace remoting | 665 } // namespace remoting |
OLD | NEW |