| 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 // This file implements a standalone host process for Me2Me. | 5 // This file implements a standalone host process for Me2Me. |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/at_exit.h" | 9 #include "base/at_exit.h" |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 159 virtual void OnConfigWatcherError() OVERRIDE; | 159 virtual void OnConfigWatcherError() OVERRIDE; |
| 160 | 160 |
| 161 // IPC::Listener implementation. | 161 // IPC::Listener implementation. |
| 162 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; | 162 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; |
| 163 virtual void OnChannelError() OVERRIDE; | 163 virtual void OnChannelError() OVERRIDE; |
| 164 | 164 |
| 165 // HeartbeatSender::Listener overrides. | 165 // HeartbeatSender::Listener overrides. |
| 166 virtual void OnUnknownHostIdError() OVERRIDE; | 166 virtual void OnUnknownHostIdError() OVERRIDE; |
| 167 | 167 |
| 168 private: | 168 private: |
| 169 enum HostState { |
| 170 // Host process has just been started. Waiting for config and policies to be |
| 171 // read from the disk. |
| 172 HOST_INITIALIZING, |
| 173 |
| 174 // Host is started and running. |
| 175 HOST_STARTED, |
| 176 |
| 177 // Host is being stopped and will need to be started again. |
| 178 HOST_STOPPING_TO_RESTART, |
| 179 |
| 180 // Host is being stopped. |
| 181 HOST_STOPPING, |
| 182 |
| 183 // Host has been stopped. |
| 184 HOST_STOPPED, |
| 185 |
| 186 // Allowed state transitions: |
| 187 // INITIALIZING->STARTED |
| 188 // INITIALIZING->STOPPED |
| 189 // STARTED->STOPPING_TO_RESTART |
| 190 // STARTED->STOPPING |
| 191 // STOPPING_TO_RESTART->STARTED |
| 192 // STOPPING_TO_RESTART->STOPPING |
| 193 // STOPPING->STOPPED |
| 194 // STOPPED->STARTED |
| 195 // |
| 196 // |host_| must be NULL in INITIALIZING and STOPPED states and not-NULL in |
| 197 // all other states. |
| 198 }; |
| 199 |
| 169 friend class base::RefCountedThreadSafe<HostProcess>; | 200 friend class base::RefCountedThreadSafe<HostProcess>; |
| 170 virtual ~HostProcess(); | 201 virtual ~HostProcess(); |
| 171 | 202 |
| 203 void StartOnNetworkThread(); |
| 204 |
| 172 #if defined(OS_POSIX) | 205 #if defined(OS_POSIX) |
| 173 // Registers a SIGTERM handler on the network thread, to shutdown the host. | |
| 174 void ListenForShutdownSignal(); | |
| 175 | |
| 176 // Callback passed to RegisterSignalHandler() to handle SIGTERM events. | 206 // Callback passed to RegisterSignalHandler() to handle SIGTERM events. |
| 177 void SigTermHandler(int signal_number); | 207 void SigTermHandler(int signal_number); |
| 178 #endif | 208 #endif |
| 179 | 209 |
| 180 // Called to initialize resources on the UI thread. | 210 // Called to initialize resources on the UI thread. |
| 181 void StartOnUiThread(); | 211 void StartOnUiThread(); |
| 182 | 212 |
| 183 // Initializes IPC control channel and config file path from |cmd_line|. | 213 // Initializes IPC control channel and config file path from |cmd_line|. |
| 184 // Called on the UI thread. | 214 // Called on the UI thread. |
| 185 bool InitWithCommandLine(const CommandLine* cmd_line); | 215 bool InitWithCommandLine(const CommandLine* cmd_line); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 199 // Applies the host config, returning true if successful. | 229 // Applies the host config, returning true if successful. |
| 200 bool ApplyConfig(scoped_ptr<JsonHostConfig> config); | 230 bool ApplyConfig(scoped_ptr<JsonHostConfig> config); |
| 201 | 231 |
| 202 void OnPolicyUpdate(scoped_ptr<base::DictionaryValue> policies); | 232 void OnPolicyUpdate(scoped_ptr<base::DictionaryValue> policies); |
| 203 bool OnHostDomainPolicyUpdate(const std::string& host_domain); | 233 bool OnHostDomainPolicyUpdate(const std::string& host_domain); |
| 204 bool OnUsernamePolicyUpdate(bool username_match_required); | 234 bool OnUsernamePolicyUpdate(bool username_match_required); |
| 205 bool OnNatPolicyUpdate(bool nat_traversal_enabled); | 235 bool OnNatPolicyUpdate(bool nat_traversal_enabled); |
| 206 bool OnCurtainPolicyUpdate(bool curtain_required); | 236 bool OnCurtainPolicyUpdate(bool curtain_required); |
| 207 bool OnHostTalkGadgetPrefixPolicyUpdate(const std::string& talkgadget_prefix); | 237 bool OnHostTalkGadgetPrefixPolicyUpdate(const std::string& talkgadget_prefix); |
| 208 | 238 |
| 209 void StartHostStatusService(); | |
| 210 | |
| 211 void StartHost(); | 239 void StartHost(); |
| 212 | 240 |
| 213 void OnAuthFailed(); | 241 void OnAuthFailed(); |
| 214 | 242 |
| 215 void OnCurtainModeFailed(); | 243 void OnCurtainModeFailed(); |
| 216 | 244 |
| 217 void OnRemoteSessionSwitchedToConsole(); | 245 void OnRemoteSessionSwitchedToConsole(); |
| 218 | 246 |
| 219 // Invoked when the user uses the Disconnect windows to terminate | 247 // Invoked when the user uses the Disconnect windows to terminate |
| 220 // the sessions, or when the local session is activated in curtain mode. | 248 // the sessions, or when the local session is activated in curtain mode. |
| 221 void OnDisconnectRequested(); | 249 void OnDisconnectRequested(); |
| 222 | 250 |
| 223 void RestartHost(); | 251 void RestartHost(); |
| 224 | 252 |
| 225 void RestartOnHostShutdown(); | 253 // Stops the host and shuts down the process with the specified |exit_code|. |
| 226 | 254 void ShutdownHost(int exit_code); |
| 227 void Shutdown(int exit_code); | |
| 228 | 255 |
| 229 void ShutdownOnNetworkThread(); | 256 void ShutdownOnNetworkThread(); |
| 230 | 257 |
| 231 void ResetHost(); | |
| 232 | |
| 233 // Crashes the process in response to a daemon's request. The daemon passes | 258 // Crashes the process in response to a daemon's request. The daemon passes |
| 234 // the location of the code that detected the fatal error resulted in this | 259 // the location of the code that detected the fatal error resulted in this |
| 235 // request. | 260 // request. |
| 236 void OnCrash(const std::string& function_name, | 261 void OnCrash(const std::string& function_name, |
| 237 const std::string& file_name, | 262 const std::string& file_name, |
| 238 const int& line_number); | 263 const int& line_number); |
| 239 | 264 |
| 240 scoped_ptr<ChromotingHostContext> context_; | 265 scoped_ptr<ChromotingHostContext> context_; |
| 241 | 266 |
| 242 // Created on the UI thread but used from the network thread. | 267 // Created on the UI thread but used from the network thread. |
| 243 scoped_ptr<net::NetworkChangeNotifier> network_change_notifier_; | 268 scoped_ptr<net::NetworkChangeNotifier> network_change_notifier_; |
| 244 | 269 |
| 245 // Accessed on the UI thread. | 270 // Accessed on the UI thread. |
| 246 scoped_ptr<IPC::ChannelProxy> daemon_channel_; | 271 scoped_ptr<IPC::ChannelProxy> daemon_channel_; |
| 247 FilePath host_config_path_; | 272 FilePath host_config_path_; |
| 248 scoped_ptr<ConfigFileWatcher> config_watcher_; | |
| 249 scoped_ptr<DesktopEnvironmentFactory> desktop_environment_factory_; | 273 scoped_ptr<DesktopEnvironmentFactory> desktop_environment_factory_; |
| 250 | 274 |
| 251 // Accessed on the network thread. | 275 // Accessed on the network thread. |
| 276 HostState state_; |
| 252 | 277 |
| 278 scoped_ptr<ConfigFileWatcher> config_watcher_; |
| 253 scoped_ptr<HostStatusService> status_service_; | 279 scoped_ptr<HostStatusService> status_service_; |
| 254 | 280 |
| 255 std::string host_id_; | 281 std::string host_id_; |
| 256 protocol::SharedSecretHash host_secret_hash_; | 282 protocol::SharedSecretHash host_secret_hash_; |
| 257 HostKeyPair key_pair_; | 283 HostKeyPair key_pair_; |
| 258 std::string oauth_refresh_token_; | 284 std::string oauth_refresh_token_; |
| 259 std::string serialized_config_; | 285 std::string serialized_config_; |
| 260 std::string xmpp_login_; | 286 std::string xmpp_login_; |
| 261 std::string xmpp_auth_token_; | 287 std::string xmpp_auth_token_; |
| 262 std::string xmpp_auth_service_; | 288 std::string xmpp_auth_service_; |
| 263 | 289 |
| 264 scoped_ptr<policy_hack::PolicyWatcher> policy_watcher_; | 290 scoped_ptr<policy_hack::PolicyWatcher> policy_watcher_; |
| 265 bool allow_nat_traversal_; | 291 bool allow_nat_traversal_; |
| 266 std::string talkgadget_prefix_; | 292 std::string talkgadget_prefix_; |
| 267 | 293 |
| 268 scoped_ptr<CurtainMode> curtain_; | 294 scoped_ptr<CurtainMode> curtain_; |
| 269 scoped_ptr<CurtainingHostObserver> curtaining_host_observer_; | 295 scoped_ptr<CurtainingHostObserver> curtaining_host_observer_; |
| 270 bool curtain_required_; | 296 bool curtain_required_; |
| 271 | 297 |
| 272 bool restarting_; | |
| 273 bool shutting_down_; | |
| 274 | |
| 275 scoped_ptr<DesktopResizer> desktop_resizer_; | 298 scoped_ptr<DesktopResizer> desktop_resizer_; |
| 276 scoped_ptr<ResizingHostObserver> resizing_host_observer_; | 299 scoped_ptr<ResizingHostObserver> resizing_host_observer_; |
| 277 scoped_ptr<XmppSignalStrategy> signal_strategy_; | 300 scoped_ptr<XmppSignalStrategy> signal_strategy_; |
| 278 scoped_ptr<SignalingConnector> signaling_connector_; | 301 scoped_ptr<SignalingConnector> signaling_connector_; |
| 279 scoped_ptr<HeartbeatSender> heartbeat_sender_; | 302 scoped_ptr<HeartbeatSender> heartbeat_sender_; |
| 280 scoped_ptr<LogToServer> log_to_server_; | 303 scoped_ptr<LogToServer> log_to_server_; |
| 281 scoped_ptr<HostEventLogger> host_event_logger_; | 304 scoped_ptr<HostEventLogger> host_event_logger_; |
| 282 | 305 |
| 283 // Created on the UI thread and used on the network thread. | 306 // Created on the UI thread and used on the network thread. |
| 284 scoped_ptr<HostUserInterface> host_user_interface_; | 307 scoped_ptr<HostUserInterface> host_user_interface_; |
| 285 | 308 |
| 286 scoped_refptr<ChromotingHost> host_; | 309 scoped_refptr<ChromotingHost> host_; |
| 287 | 310 |
| 288 // Used to keep this HostProcess alive until it is shutdown. | 311 // Used to keep this HostProcess alive until it is shutdown. |
| 289 scoped_refptr<HostProcess> self_; | 312 scoped_refptr<HostProcess> self_; |
| 290 | 313 |
| 291 #if defined(REMOTING_MULTI_PROCESS) | 314 #if defined(REMOTING_MULTI_PROCESS) |
| 292 DesktopSessionConnector* desktop_session_connector_; | 315 DesktopSessionConnector* desktop_session_connector_; |
| 293 #endif // defined(REMOTING_MULTI_PROCESS) | 316 #endif // defined(REMOTING_MULTI_PROCESS) |
| 294 | 317 |
| 295 int* exit_code_out_; | 318 int* exit_code_out_; |
| 296 }; | 319 }; |
| 297 | 320 |
| 298 HostProcess::HostProcess(scoped_ptr<ChromotingHostContext> context, | 321 HostProcess::HostProcess(scoped_ptr<ChromotingHostContext> context, |
| 299 int* exit_code_out) | 322 int* exit_code_out) |
| 300 : context_(context.Pass()), | 323 : context_(context.Pass()), |
| 324 state_(HOST_INITIALIZING), |
| 301 allow_nat_traversal_(true), | 325 allow_nat_traversal_(true), |
| 302 curtain_required_(false), | 326 curtain_required_(false), |
| 303 restarting_(false), | |
| 304 shutting_down_(false), | |
| 305 desktop_resizer_(DesktopResizer::Create()), | 327 desktop_resizer_(DesktopResizer::Create()), |
| 306 #if defined(REMOTING_MULTI_PROCESS) | 328 #if defined(REMOTING_MULTI_PROCESS) |
| 307 desktop_session_connector_(NULL), | 329 desktop_session_connector_(NULL), |
| 308 #endif // defined(REMOTING_MULTI_PROCESS) | 330 #endif // defined(REMOTING_MULTI_PROCESS) |
| 309 ALLOW_THIS_IN_INITIALIZER_LIST(self_(this)), | 331 ALLOW_THIS_IN_INITIALIZER_LIST(self_(this)), |
| 310 exit_code_out_(exit_code_out) { | 332 exit_code_out_(exit_code_out) { |
| 311 // Create a NetworkChangeNotifier for use by the signalling connector. | 333 // Create a NetworkChangeNotifier for use by the signalling connector. |
| 312 network_change_notifier_.reset(net::NetworkChangeNotifier::Create()); | 334 network_change_notifier_.reset(net::NetworkChangeNotifier::Create()); |
| 313 | 335 |
| 314 // Create the platform-specific curtain-mode implementation. | 336 // Create the platform-specific curtain-mode implementation. |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 398 // Filter out duplicates. | 420 // Filter out duplicates. |
| 399 if (serialized_config_ == serialized_config) | 421 if (serialized_config_ == serialized_config) |
| 400 return; | 422 return; |
| 401 | 423 |
| 402 LOG(INFO) << "Processing new host configuration."; | 424 LOG(INFO) << "Processing new host configuration."; |
| 403 | 425 |
| 404 serialized_config_ = serialized_config; | 426 serialized_config_ = serialized_config; |
| 405 scoped_ptr<JsonHostConfig> config(new JsonHostConfig(FilePath())); | 427 scoped_ptr<JsonHostConfig> config(new JsonHostConfig(FilePath())); |
| 406 if (!config->SetSerializedData(serialized_config)) { | 428 if (!config->SetSerializedData(serialized_config)) { |
| 407 LOG(ERROR) << "Invalid configuration."; | 429 LOG(ERROR) << "Invalid configuration."; |
| 408 Shutdown(kInvalidHostConfigurationExitCode); | 430 ShutdownHost(kInvalidHostConfigurationExitCode); |
| 409 return; | 431 return; |
| 410 } | 432 } |
| 411 | 433 |
| 412 if (!ApplyConfig(config.Pass())) { | 434 if (!ApplyConfig(config.Pass())) { |
| 413 LOG(ERROR) << "Failed to apply the configuration."; | 435 LOG(ERROR) << "Failed to apply the configuration."; |
| 414 Shutdown(kInvalidHostConfigurationExitCode); | 436 ShutdownHost(kInvalidHostConfigurationExitCode); |
| 415 return; | 437 return; |
| 416 } | 438 } |
| 417 | 439 |
| 418 // Start watching the policy (and eventually start the host) if this is | 440 if (state_ == HOST_INITIALIZING) { |
| 419 // the first configuration update. Otherwise, create new authenticator | 441 // TODO(sergeyu): Currently OnPolicyUpdate() assumes that host config is |
| 420 // factory in case PIN has changed. | 442 // already loaded so PolicyWatcher has to be started here. Separate policy |
| 421 if (!policy_watcher_) { | 443 // loading from policy verifications and move |policy_watcher_| |
| 444 // initialization to StartOnNetworkThread(). |
| 422 policy_watcher_.reset( | 445 policy_watcher_.reset( |
| 423 policy_hack::PolicyWatcher::Create(context_->file_task_runner())); | 446 policy_hack::PolicyWatcher::Create(context_->file_task_runner())); |
| 424 policy_watcher_->StartWatching( | 447 policy_watcher_->StartWatching( |
| 425 base::Bind(&HostProcess::OnPolicyUpdate, base::Unretained(this))); | 448 base::Bind(&HostProcess::OnPolicyUpdate, base::Unretained(this))); |
| 426 } else { | 449 } else if (state_ == HOST_STARTED) { |
| 450 // TODO(sergeyu): Here we assume that PIN is the only part of the config |
| 451 // that may change while the service is running. Change ApplyConfig() to |
| 452 // detect other changes in the config and restart host if necessary here. |
| 427 CreateAuthenticatorFactory(); | 453 CreateAuthenticatorFactory(); |
| 428 } | 454 } |
| 429 } | 455 } |
| 430 | 456 |
| 431 void HostProcess::OnConfigWatcherError() { | 457 void HostProcess::OnConfigWatcherError() { |
| 432 DCHECK(context_->ui_task_runner()->BelongsToCurrentThread()); | 458 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
| 433 | 459 ShutdownHost(kInvalidHostConfigurationExitCode); |
| 434 context_->network_task_runner()->PostTask(FROM_HERE, | |
| 435 base::Bind(&HostProcess::Shutdown, this, | |
| 436 kInvalidHostConfigurationExitCode)); | |
| 437 } | 460 } |
| 438 | 461 |
| 439 void HostProcess::StartWatchingConfigChanges() { | 462 void HostProcess::StartOnNetworkThread() { |
| 440 DCHECK(context_->ui_task_runner()->BelongsToCurrentThread()); | 463 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
| 464 |
| 465 if (CommandLine::ForCurrentProcess()->HasSwitch( |
| 466 kEnableStatusServiceSwitchName)) { |
| 467 status_service_.reset(new HostStatusService()); |
| 468 } |
| 441 | 469 |
| 442 #if !defined(REMOTING_MULTI_PROCESS) | 470 #if !defined(REMOTING_MULTI_PROCESS) |
| 443 // Start watching the host configuration file. | 471 // Start watching the host configuration file. |
| 444 config_watcher_.reset(new ConfigFileWatcher(context_->ui_task_runner(), | 472 config_watcher_.reset(new ConfigFileWatcher(context_->network_task_runner(), |
| 445 context_->file_task_runner(), | 473 context_->file_task_runner(), |
| 446 this)); | 474 this)); |
| 447 config_watcher_->Watch(host_config_path_); | 475 config_watcher_->Watch(host_config_path_); |
| 448 #endif // !defined(REMOTING_MULTI_PROCESS) | 476 #endif // !defined(REMOTING_MULTI_PROCESS) |
| 477 |
| 478 #if defined(OS_POSIX) |
| 479 remoting::RegisterSignalHandler( |
| 480 SIGTERM, |
| 481 base::Bind(&HostProcess::SigTermHandler, base::Unretained(this))); |
| 482 #endif // defined(OS_POSIX) |
| 449 } | 483 } |
| 450 | 484 |
| 451 #if defined(OS_POSIX) | 485 #if defined(OS_POSIX) |
| 452 void HostProcess::ListenForShutdownSignal() { | |
| 453 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | |
| 454 | |
| 455 remoting::RegisterSignalHandler( | |
| 456 SIGTERM, | |
| 457 base::Bind(&HostProcess::SigTermHandler, base::Unretained(this))); | |
| 458 } | |
| 459 | |
| 460 void HostProcess::SigTermHandler(int signal_number) { | 486 void HostProcess::SigTermHandler(int signal_number) { |
| 461 DCHECK(signal_number == SIGTERM); | 487 DCHECK(signal_number == SIGTERM); |
| 462 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 488 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
| 463 LOG(INFO) << "Caught SIGTERM: Shutting down..."; | 489 LOG(INFO) << "Caught SIGTERM: Shutting down..."; |
| 464 Shutdown(kSuccessExitCode); | 490 ShutdownHost(kSuccessExitCode); |
| 465 } | 491 } |
| 466 #endif // OS_POSIX | 492 #endif // OS_POSIX |
| 467 | 493 |
| 468 void HostProcess::CreateAuthenticatorFactory() { | 494 void HostProcess::CreateAuthenticatorFactory() { |
| 469 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 495 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
| 470 | 496 |
| 471 if (!host_ || shutting_down_) | 497 if (state_ != HOST_STARTED) |
| 472 return; | 498 return; |
| 473 | 499 |
| 474 std::string local_certificate = key_pair_.GenerateCertificate(); | 500 std::string local_certificate = key_pair_.GenerateCertificate(); |
| 475 if (local_certificate.empty()) { | 501 if (local_certificate.empty()) { |
| 476 LOG(ERROR) << "Failed to generate host certificate."; | 502 LOG(ERROR) << "Failed to generate host certificate."; |
| 477 Shutdown(kInitializationFailed); | 503 ShutdownHost(kInitializationFailed); |
| 478 return; | 504 return; |
| 479 } | 505 } |
| 480 | 506 |
| 481 scoped_ptr<protocol::AuthenticatorFactory> factory( | 507 scoped_ptr<protocol::AuthenticatorFactory> factory( |
| 482 new protocol::Me2MeHostAuthenticatorFactory( | 508 new protocol::Me2MeHostAuthenticatorFactory( |
| 483 local_certificate, *key_pair_.private_key(), host_secret_hash_)); | 509 local_certificate, *key_pair_.private_key(), host_secret_hash_)); |
| 484 #if defined(OS_POSIX) | 510 #if defined(OS_POSIX) |
| 485 // On Linux and Mac, perform a PAM authorization step after authentication. | 511 // On Linux and Mac, perform a PAM authorization step after authentication. |
| 486 factory.reset(new PamAuthorizationFactory(factory.Pass())); | 512 factory.reset(new PamAuthorizationFactory(factory.Pass())); |
| 487 #endif | 513 #endif |
| (...skipping 25 matching lines...) Expand all Loading... |
| 513 return false; | 539 return false; |
| 514 #endif // !defined(REMOTING_MULTI_PROCESS) | 540 #endif // !defined(REMOTING_MULTI_PROCESS) |
| 515 } | 541 } |
| 516 | 542 |
| 517 void HostProcess::OnChannelError() { | 543 void HostProcess::OnChannelError() { |
| 518 DCHECK(context_->ui_task_runner()->BelongsToCurrentThread()); | 544 DCHECK(context_->ui_task_runner()->BelongsToCurrentThread()); |
| 519 | 545 |
| 520 // Shutdown the host if the daemon process disconnects the IPC channel. | 546 // Shutdown the host if the daemon process disconnects the IPC channel. |
| 521 context_->network_task_runner()->PostTask( | 547 context_->network_task_runner()->PostTask( |
| 522 FROM_HERE, | 548 FROM_HERE, |
| 523 base::Bind(&HostProcess::Shutdown, this, kSuccessExitCode)); | 549 base::Bind(&HostProcess::ShutdownHost, this, kSuccessExitCode)); |
| 524 } | 550 } |
| 525 | 551 |
| 526 void HostProcess::StartOnUiThread() { | 552 void HostProcess::StartOnUiThread() { |
| 527 DCHECK(context_->ui_task_runner()->BelongsToCurrentThread()); | 553 DCHECK(context_->ui_task_runner()->BelongsToCurrentThread()); |
| 528 | 554 |
| 529 if (!InitWithCommandLine(CommandLine::ForCurrentProcess())) { | 555 if (!InitWithCommandLine(CommandLine::ForCurrentProcess())) { |
| 530 OnConfigWatcherError(); | 556 OnConfigWatcherError(); |
| 531 return; | 557 return; |
| 532 } | 558 } |
| 533 | 559 |
| 534 #if defined(OS_LINUX) | 560 #if defined(OS_LINUX) |
| 535 // TODO(sergeyu): Pass configuration parameters to the Linux-specific version | 561 // TODO(sergeyu): Pass configuration parameters to the Linux-specific version |
| 536 // of DesktopEnvironmentFactory when we have it. | 562 // of DesktopEnvironmentFactory when we have it. |
| 537 remoting::VideoFrameCapturer::EnableXDamage(true); | 563 remoting::VideoFrameCapturer::EnableXDamage(true); |
| 538 | 564 |
| 539 // If an audio pipe is specific on the command-line then initialize | 565 // If an audio pipe is specific on the command-line then initialize |
| 540 // AudioCapturerLinux to capture from it. | 566 // AudioCapturerLinux to capture from it. |
| 541 FilePath audio_pipe_name = CommandLine::ForCurrentProcess()-> | 567 FilePath audio_pipe_name = CommandLine::ForCurrentProcess()-> |
| 542 GetSwitchValuePath(kAudioPipeSwitchName); | 568 GetSwitchValuePath(kAudioPipeSwitchName); |
| 543 if (!audio_pipe_name.empty()) { | 569 if (!audio_pipe_name.empty()) { |
| 544 remoting::AudioCapturerLinux::InitializePipeReader( | 570 remoting::AudioCapturerLinux::InitializePipeReader( |
| 545 context_->audio_task_runner(), audio_pipe_name); | 571 context_->audio_task_runner(), audio_pipe_name); |
| 546 } | 572 } |
| 547 #endif // defined(OS_LINUX) | 573 #endif // defined(OS_LINUX) |
| 548 | 574 |
| 549 if (CommandLine::ForCurrentProcess()->HasSwitch( | |
| 550 kEnableStatusServiceSwitchName)) { | |
| 551 context_->network_task_runner()->PostTask( | |
| 552 FROM_HERE, | |
| 553 base::Bind(&HostProcess::StartHostStatusService, | |
| 554 base::Unretained(this))); | |
| 555 } | |
| 556 | |
| 557 // Create a desktop environment factory appropriate to the build type & | 575 // Create a desktop environment factory appropriate to the build type & |
| 558 // platform. | 576 // platform. |
| 559 #if defined(OS_WIN) | 577 #if defined(OS_WIN) |
| 560 | 578 |
| 561 #if defined(REMOTING_MULTI_PROCESS) | 579 #if defined(REMOTING_MULTI_PROCESS) |
| 562 IpcDesktopEnvironmentFactory* desktop_environment_factory = | 580 IpcDesktopEnvironmentFactory* desktop_environment_factory = |
| 563 new IpcDesktopEnvironmentFactory( | 581 new IpcDesktopEnvironmentFactory( |
| 564 daemon_channel_.get(), | 582 daemon_channel_.get(), |
| 565 context_->input_task_runner(), | 583 context_->input_task_runner(), |
| 566 context_->network_task_runner(), | 584 context_->network_task_runner(), |
| 567 context_->ui_task_runner(), | 585 context_->ui_task_runner(), |
| 568 context_->video_capture_task_runner()); | 586 context_->video_capture_task_runner()); |
| 569 desktop_session_connector_ = desktop_environment_factory; | 587 desktop_session_connector_ = desktop_environment_factory; |
| 570 #else // !defined(REMOTING_MULTI_PROCESS) | 588 #else // !defined(REMOTING_MULTI_PROCESS) |
| 571 DesktopEnvironmentFactory* desktop_environment_factory = | 589 DesktopEnvironmentFactory* desktop_environment_factory = |
| 572 new SessionDesktopEnvironmentFactory( | 590 new SessionDesktopEnvironmentFactory( |
| 573 context_->input_task_runner(), context_->ui_task_runner(), | 591 context_->input_task_runner(), context_->ui_task_runner(), |
| 574 base::Bind(&HostProcess::SendSasToConsole, this)); | 592 base::Bind(&HostProcess::SendSasToConsole, this)); |
| 575 #endif // !defined(REMOTING_MULTI_PROCESS) | 593 #endif // !defined(REMOTING_MULTI_PROCESS) |
| 576 | 594 |
| 577 #else // !defined(OS_WIN) | 595 #else // !defined(OS_WIN) |
| 578 DesktopEnvironmentFactory* desktop_environment_factory = | 596 DesktopEnvironmentFactory* desktop_environment_factory = |
| 579 new DesktopEnvironmentFactory( | 597 new DesktopEnvironmentFactory( |
| 580 context_->input_task_runner(), context_->ui_task_runner()); | 598 context_->input_task_runner(), context_->ui_task_runner()); |
| 581 #endif // !defined(OS_WIN) | 599 #endif // !defined(OS_WIN) |
| 582 | 600 |
| 583 desktop_environment_factory_.reset(desktop_environment_factory); | 601 desktop_environment_factory_.reset(desktop_environment_factory); |
| 584 | 602 |
| 585 #if defined(OS_POSIX) | |
| 586 context_->network_task_runner()->PostTask( | |
| 587 FROM_HERE, base::Bind(&HostProcess::ListenForShutdownSignal, this)); | |
| 588 #endif // OS_POSIX | |
| 589 | |
| 590 // The host UI should be created on the UI thread. | 603 // The host UI should be created on the UI thread. |
| 591 bool want_user_interface = true; | 604 bool want_user_interface = true; |
| 592 #if defined(OS_LINUX) | 605 #if defined(OS_LINUX) |
| 593 want_user_interface = false; | 606 want_user_interface = false; |
| 594 #elif defined(OS_MACOSX) | 607 #elif defined(OS_MACOSX) |
| 595 // Don't try to display any UI on top of the system's login screen as this | 608 // Don't try to display any UI on top of the system's login screen as this |
| 596 // is rejected by the Window Server on OS X 10.7.4, and prevents the | 609 // is rejected by the Window Server on OS X 10.7.4, and prevents the |
| 597 // capturer from working (http://crbug.com/140984). | 610 // capturer from working (http://crbug.com/140984). |
| 598 | 611 |
| 599 // TODO(lambroslambrou): Use a better technique of detecting whether we're | 612 // TODO(lambroslambrou): Use a better technique of detecting whether we're |
| 600 // running in the LoginWindow context, and refactor this into a separate | 613 // running in the LoginWindow context, and refactor this into a separate |
| 601 // function to be used here and in CurtainMode::ActivateCurtain(). | 614 // function to be used here and in CurtainMode::ActivateCurtain(). |
| 602 want_user_interface = getuid() != 0; | 615 want_user_interface = getuid() != 0; |
| 603 #endif // OS_MACOSX | 616 #endif // OS_MACOSX |
| 604 | 617 |
| 605 if (want_user_interface) { | 618 if (want_user_interface) { |
| 606 host_user_interface_.reset( | 619 host_user_interface_.reset( |
| 607 new HostUserInterface(context_->network_task_runner(), | 620 new HostUserInterface(context_->network_task_runner(), |
| 608 context_->ui_task_runner())); | 621 context_->ui_task_runner())); |
| 609 host_user_interface_->Init(); | 622 host_user_interface_->Init(); |
| 610 } | 623 } |
| 611 | 624 |
| 612 StartWatchingConfigChanges(); | 625 context_->network_task_runner()->PostTask( |
| 626 FROM_HERE, |
| 627 base::Bind(&HostProcess::StartOnNetworkThread, this)); |
| 613 } | 628 } |
| 614 | 629 |
| 615 void HostProcess::SendSasToConsole() { | 630 void HostProcess::SendSasToConsole() { |
| 616 DCHECK(context_->ui_task_runner()->BelongsToCurrentThread()); | 631 DCHECK(context_->ui_task_runner()->BelongsToCurrentThread()); |
| 617 | 632 |
| 618 if (daemon_channel_) | 633 if (daemon_channel_) |
| 619 daemon_channel_->Send(new ChromotingNetworkDaemonMsg_SendSasToConsole()); | 634 daemon_channel_->Send(new ChromotingNetworkDaemonMsg_SendSasToConsole()); |
| 620 } | 635 } |
| 621 | 636 |
| 622 void HostProcess::ShutdownOnUiThread() { | 637 void HostProcess::ShutdownOnUiThread() { |
| 623 DCHECK(context_->ui_task_runner()->BelongsToCurrentThread()); | 638 DCHECK(context_->ui_task_runner()->BelongsToCurrentThread()); |
| 624 | 639 |
| 625 // Tear down resources that need to be torn down on the UI thread. | 640 // Tear down resources that need to be torn down on the UI thread. |
| 626 network_change_notifier_.reset(); | 641 network_change_notifier_.reset(); |
| 627 config_watcher_.reset(); | |
| 628 daemon_channel_.reset(); | 642 daemon_channel_.reset(); |
| 629 desktop_environment_factory_.reset(); | 643 desktop_environment_factory_.reset(); |
| 630 host_user_interface_.reset(); | 644 host_user_interface_.reset(); |
| 631 | 645 |
| 632 // It is now safe for the HostProcess to be deleted. | 646 // It is now safe for the HostProcess to be deleted. |
| 633 self_ = NULL; | 647 self_ = NULL; |
| 634 | 648 |
| 635 #if defined(OS_LINUX) | 649 #if defined(OS_LINUX) |
| 636 // Cause the global AudioPipeReader to be freed, otherwise the audio | 650 // Cause the global AudioPipeReader to be freed, otherwise the audio |
| 637 // thread will remain in-use and prevent the process from exiting. | 651 // thread will remain in-use and prevent the process from exiting. |
| 638 // TODO(wez): DesktopEnvironmentFactory should own the pipe reader. | 652 // TODO(wez): DesktopEnvironmentFactory should own the pipe reader. |
| 639 // See crbug.com/161373 and crbug.com/104544. | 653 // See crbug.com/161373 and crbug.com/104544. |
| 640 AudioCapturerLinux::InitializePipeReader(NULL, FilePath()); | 654 AudioCapturerLinux::InitializePipeReader(NULL, FilePath()); |
| 641 #endif | 655 #endif |
| 642 } | 656 } |
| 643 | 657 |
| 644 // Overridden from HeartbeatSender::Listener | 658 // Overridden from HeartbeatSender::Listener |
| 645 void HostProcess::OnUnknownHostIdError() { | 659 void HostProcess::OnUnknownHostIdError() { |
| 646 LOG(ERROR) << "Host ID not found."; | 660 LOG(ERROR) << "Host ID not found."; |
| 647 Shutdown(kInvalidHostIdExitCode); | 661 ShutdownHost(kInvalidHostIdExitCode); |
| 648 } | 662 } |
| 649 | 663 |
| 650 // Applies the host config, returning true if successful. | 664 // Applies the host config, returning true if successful. |
| 651 bool HostProcess::ApplyConfig(scoped_ptr<JsonHostConfig> config) { | 665 bool HostProcess::ApplyConfig(scoped_ptr<JsonHostConfig> config) { |
| 652 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 666 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
| 653 | 667 |
| 654 if (!config->GetString(kHostIdConfigPath, &host_id_)) { | 668 if (!config->GetString(kHostIdConfigPath, &host_id_)) { |
| 655 LOG(ERROR) << "host_id is not defined in the config."; | 669 LOG(ERROR) << "host_id is not defined in the config."; |
| 656 return false; | 670 return false; |
| 657 } | 671 } |
| (...skipping 30 matching lines...) Expand all Loading... |
| 688 // For the me2me host, we default to ClientLogin token for chromiumsync | 702 // For the me2me host, we default to ClientLogin token for chromiumsync |
| 689 // because earlier versions of the host had no HTTP stack with which to | 703 // because earlier versions of the host had no HTTP stack with which to |
| 690 // request an OAuth2 access token. | 704 // request an OAuth2 access token. |
| 691 xmpp_auth_service_ = kChromotingTokenDefaultServiceName; | 705 xmpp_auth_service_ = kChromotingTokenDefaultServiceName; |
| 692 } | 706 } |
| 693 return true; | 707 return true; |
| 694 } | 708 } |
| 695 | 709 |
| 696 void HostProcess::OnPolicyUpdate(scoped_ptr<base::DictionaryValue> policies) { | 710 void HostProcess::OnPolicyUpdate(scoped_ptr<base::DictionaryValue> policies) { |
| 697 // TODO(rmsousa): Consolidate all On*PolicyUpdate methods into this one. | 711 // TODO(rmsousa): Consolidate all On*PolicyUpdate methods into this one. |
| 712 // TODO(sergeyu): Currently polices are verified only when they are loaded. |
| 713 // Separate policy loading from policy verifications - this will allow to |
| 714 // check policies again later, e.g. when host config changes. |
| 715 |
| 698 if (!context_->network_task_runner()->BelongsToCurrentThread()) { | 716 if (!context_->network_task_runner()->BelongsToCurrentThread()) { |
| 699 context_->network_task_runner()->PostTask(FROM_HERE, base::Bind( | 717 context_->network_task_runner()->PostTask(FROM_HERE, base::Bind( |
| 700 &HostProcess::OnPolicyUpdate, this, base::Passed(&policies))); | 718 &HostProcess::OnPolicyUpdate, this, base::Passed(&policies))); |
| 701 return; | 719 return; |
| 702 } | 720 } |
| 703 | 721 |
| 704 bool restart_required = false; | 722 bool restart_required = false; |
| 705 bool bool_value; | 723 bool bool_value; |
| 706 std::string string_value; | 724 std::string string_value; |
| 707 if (policies->GetString(policy_hack::PolicyWatcher::kHostDomainPolicyName, | 725 if (policies->GetString(policy_hack::PolicyWatcher::kHostDomainPolicyName, |
| (...skipping 10 matching lines...) Expand all Loading... |
| 718 restart_required |= OnNatPolicyUpdate(bool_value); | 736 restart_required |= OnNatPolicyUpdate(bool_value); |
| 719 } | 737 } |
| 720 if (policies->GetString( | 738 if (policies->GetString( |
| 721 policy_hack::PolicyWatcher::kHostTalkGadgetPrefixPolicyName, | 739 policy_hack::PolicyWatcher::kHostTalkGadgetPrefixPolicyName, |
| 722 &string_value)) { | 740 &string_value)) { |
| 723 restart_required |= OnHostTalkGadgetPrefixPolicyUpdate(string_value); | 741 restart_required |= OnHostTalkGadgetPrefixPolicyUpdate(string_value); |
| 724 } | 742 } |
| 725 if (policies->GetBoolean( | 743 if (policies->GetBoolean( |
| 726 policy_hack::PolicyWatcher::kHostRequireCurtainPolicyName, | 744 policy_hack::PolicyWatcher::kHostRequireCurtainPolicyName, |
| 727 &bool_value)) { | 745 &bool_value)) { |
| 728 restart_required |= OnCurtainPolicyUpdate(bool_value); | 746 restart_required |= OnCurtainPolicyUpdate(bool_value); |
| 729 } | 747 } |
| 730 if (!host_) { | 748 |
| 749 if (state_ == HOST_INITIALIZING) { |
| 731 StartHost(); | 750 StartHost(); |
| 732 } else if (restart_required) { | 751 } else if (state_ == HOST_STARTED && restart_required) { |
| 733 RestartHost(); | 752 RestartHost(); |
| 734 } | 753 } |
| 735 } | 754 } |
| 736 | 755 |
| 737 bool HostProcess::OnHostDomainPolicyUpdate(const std::string& host_domain) { | 756 bool HostProcess::OnHostDomainPolicyUpdate(const std::string& host_domain) { |
| 738 // Returns true if the host has to be restarted after this policy update. | 757 // Returns true if the host has to be restarted after this policy update. |
| 739 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 758 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
| 740 | 759 |
| 741 LOG(INFO) << "Policy sets host domain: " << host_domain; | 760 LOG(INFO) << "Policy sets host domain: " << host_domain; |
| 742 | 761 |
| 743 if (!host_domain.empty() && | 762 if (!host_domain.empty() && |
| 744 !EndsWith(xmpp_login_, std::string("@") + host_domain, false)) { | 763 !EndsWith(xmpp_login_, std::string("@") + host_domain, false)) { |
| 745 Shutdown(kInvalidHostDomainExitCode); | 764 ShutdownHost(kInvalidHostDomainExitCode); |
| 746 } | 765 } |
| 747 return false; | 766 return false; |
| 748 } | 767 } |
| 749 | 768 |
| 750 bool HostProcess::OnUsernamePolicyUpdate(bool host_username_match_required) { | 769 bool HostProcess::OnUsernamePolicyUpdate(bool host_username_match_required) { |
| 751 // Returns false: never restart the host after this policy update. | 770 // Returns false: never restart the host after this policy update. |
| 752 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 771 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
| 753 | 772 |
| 754 if (host_username_match_required) { | 773 if (host_username_match_required) { |
| 755 LOG(INFO) << "Policy requires host username match."; | 774 LOG(INFO) << "Policy requires host username match."; |
| 756 bool shutdown = !CanGetUsername() || | 775 bool shutdown = !CanGetUsername() || |
| 757 !StartsWithASCII(xmpp_login_, GetUsername() + std::string("@"), | 776 !StartsWithASCII(xmpp_login_, GetUsername() + std::string("@"), |
| 758 false); | 777 false); |
| 759 | 778 |
| 760 #if defined(OS_MACOSX) | 779 #if defined(OS_MACOSX) |
| 761 // On Mac, we run as root at the login screen, so the username won't match. | 780 // On Mac, we run as root at the login screen, so the username won't match. |
| 762 // However, there's no need to enforce the policy at the login screen, as | 781 // However, there's no need to enforce the policy at the login screen, as |
| 763 // the client will have to reconnect if a login occurs. | 782 // the client will have to reconnect if a login occurs. |
| 764 if (shutdown && getuid() == 0) { | 783 if (shutdown && getuid() == 0) { |
| 765 shutdown = false; | 784 shutdown = false; |
| 766 } | 785 } |
| 767 #endif | 786 #endif |
| 768 | 787 |
| 769 if (shutdown) { | 788 if (shutdown) { |
| 770 Shutdown(kUsernameMismatchExitCode); | 789 ShutdownHost(kUsernameMismatchExitCode); |
| 771 } | 790 } |
| 772 } else { | 791 } else { |
| 773 LOG(INFO) << "Policy does not require host username match."; | 792 LOG(INFO) << "Policy does not require host username match."; |
| 774 } | 793 } |
| 775 | 794 |
| 776 return false; | 795 return false; |
| 777 } | 796 } |
| 778 | 797 |
| 779 bool HostProcess::OnNatPolicyUpdate(bool nat_traversal_enabled) { | 798 bool HostProcess::OnNatPolicyUpdate(bool nat_traversal_enabled) { |
| 780 // Returns true if the host has to be restarted after this policy update. | 799 // Returns true if the host has to be restarted after this policy update. |
| (...skipping 19 matching lines...) Expand all Loading... |
| 800 // When curtain mode is in effect on Mac, the host process runs in the | 819 // When curtain mode is in effect on Mac, the host process runs in the |
| 801 // user's switched-out session, but launchd will also run an instance at | 820 // user's switched-out session, but launchd will also run an instance at |
| 802 // the console login screen. Even if no user is currently logged-on, we | 821 // the console login screen. Even if no user is currently logged-on, we |
| 803 // can't support remote-access to the login screen because the current host | 822 // can't support remote-access to the login screen because the current host |
| 804 // process model disconnects the client during login, which would leave | 823 // process model disconnects the client during login, which would leave |
| 805 // the logged in session un-curtained on the console until they reconnect. | 824 // the logged in session un-curtained on the console until they reconnect. |
| 806 // | 825 // |
| 807 // TODO(jamiewalch): Fix this once we have implemented the multi-process | 826 // TODO(jamiewalch): Fix this once we have implemented the multi-process |
| 808 // daemon architecture (crbug.com/134894) | 827 // daemon architecture (crbug.com/134894) |
| 809 if (getuid() == 0) { | 828 if (getuid() == 0) { |
| 810 Shutdown(kLoginScreenNotSupportedExitCode); | 829 ShutdownHost(kLoginScreenNotSupportedExitCode); |
| 811 return false; | 830 return false; |
| 812 } | 831 } |
| 813 } | 832 } |
| 814 #endif | 833 #endif |
| 815 | 834 |
| 816 if (curtain_required_ != curtain_required) { | 835 if (curtain_required_ != curtain_required) { |
| 817 if (curtain_required) | 836 if (curtain_required) |
| 818 LOG(ERROR) << "Policy requires curtain-mode."; | 837 LOG(ERROR) << "Policy requires curtain-mode."; |
| 819 else | 838 else |
| 820 LOG(ERROR) << "Policy does not require curtain-mode."; | 839 LOG(ERROR) << "Policy does not require curtain-mode."; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 832 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 851 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
| 833 | 852 |
| 834 if (talkgadget_prefix != talkgadget_prefix_) { | 853 if (talkgadget_prefix != talkgadget_prefix_) { |
| 835 LOG(INFO) << "Policy sets talkgadget prefix: " << talkgadget_prefix; | 854 LOG(INFO) << "Policy sets talkgadget prefix: " << talkgadget_prefix; |
| 836 talkgadget_prefix_ = talkgadget_prefix; | 855 talkgadget_prefix_ = talkgadget_prefix; |
| 837 return true; | 856 return true; |
| 838 } | 857 } |
| 839 return false; | 858 return false; |
| 840 } | 859 } |
| 841 | 860 |
| 842 void HostProcess::StartHostStatusService() { | |
| 843 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | |
| 844 status_service_.reset(new HostStatusService()); | |
| 845 } | |
| 846 | |
| 847 void HostProcess::StartHost() { | 861 void HostProcess::StartHost() { |
| 848 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 862 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
| 849 DCHECK(!host_); | 863 DCHECK(!host_); |
| 850 DCHECK(!signal_strategy_.get()); | 864 DCHECK(!signal_strategy_.get()); |
| 851 | 865 DCHECK(state_ == HOST_INITIALIZING || state_ == HOST_STOPPING_TO_RESTART || |
| 852 if (shutting_down_) | 866 state_ == HOST_STOPPED) << state_; |
| 853 return; | 867 state_ = HOST_STARTED; |
| 854 | 868 |
| 855 signal_strategy_.reset( | 869 signal_strategy_.reset( |
| 856 new XmppSignalStrategy(context_->url_request_context_getter(), | 870 new XmppSignalStrategy(context_->url_request_context_getter(), |
| 857 xmpp_login_, xmpp_auth_token_, | 871 xmpp_login_, xmpp_auth_token_, |
| 858 xmpp_auth_service_)); | 872 xmpp_auth_service_)); |
| 859 | 873 |
| 860 scoped_ptr<DnsBlackholeChecker> dns_blackhole_checker( | 874 scoped_ptr<DnsBlackholeChecker> dns_blackhole_checker( |
| 861 new DnsBlackholeChecker(context_->url_request_context_getter(), | 875 new DnsBlackholeChecker(context_->url_request_context_getter(), |
| 862 talkgadget_prefix_)); | 876 talkgadget_prefix_)); |
| 863 | 877 |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 926 | 940 |
| 927 if (status_service_) | 941 if (status_service_) |
| 928 status_service_->SetHostIsUp(host_id_); | 942 status_service_->SetHostIsUp(host_id_); |
| 929 | 943 |
| 930 host_->Start(xmpp_login_); | 944 host_->Start(xmpp_login_); |
| 931 | 945 |
| 932 CreateAuthenticatorFactory(); | 946 CreateAuthenticatorFactory(); |
| 933 } | 947 } |
| 934 | 948 |
| 935 void HostProcess::OnAuthFailed() { | 949 void HostProcess::OnAuthFailed() { |
| 936 Shutdown(kInvalidOauthCredentialsExitCode); | 950 ShutdownHost(kInvalidOauthCredentialsExitCode); |
| 937 } | 951 } |
| 938 | 952 |
| 939 void HostProcess::OnCurtainModeFailed() { | 953 void HostProcess::OnCurtainModeFailed() { |
| 940 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 954 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
| 941 DCHECK(host_); | 955 DCHECK(host_); |
| 942 LOG(ERROR) << "Curtain mode failed to activate. Closing connection."; | 956 LOG(ERROR) << "Curtain mode failed to activate. Closing connection."; |
| 943 host_->RejectAuthenticatingClient(); | 957 host_->RejectAuthenticatingClient(); |
| 944 } | 958 } |
| 945 | 959 |
| 946 void HostProcess::OnRemoteSessionSwitchedToConsole() { | 960 void HostProcess::OnRemoteSessionSwitchedToConsole() { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 957 base::Bind(&HostProcess::OnDisconnectRequested, this)); | 971 base::Bind(&HostProcess::OnDisconnectRequested, this)); |
| 958 return; | 972 return; |
| 959 } | 973 } |
| 960 if (host_) { | 974 if (host_) { |
| 961 host_->DisconnectAllClients(); | 975 host_->DisconnectAllClients(); |
| 962 } | 976 } |
| 963 } | 977 } |
| 964 | 978 |
| 965 void HostProcess::RestartHost() { | 979 void HostProcess::RestartHost() { |
| 966 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 980 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
| 981 DCHECK_EQ(state_, HOST_STARTED); |
| 967 | 982 |
| 968 if (restarting_ || shutting_down_) | 983 state_ = HOST_STOPPING_TO_RESTART; |
| 969 return; | 984 host_->Shutdown(base::Bind(&HostProcess::ShutdownOnNetworkThread, this)); |
| 970 | |
| 971 restarting_ = true; | |
| 972 host_->Shutdown(base::Bind(&HostProcess::RestartOnHostShutdown, this)); | |
| 973 } | 985 } |
| 974 | 986 |
| 975 void HostProcess::RestartOnHostShutdown() { | 987 void HostProcess::ShutdownHost(int exit_code) { |
| 976 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 988 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
| 977 | 989 |
| 978 if (shutting_down_) | 990 *exit_code_out_ = exit_code; |
| 979 return; | |
| 980 | 991 |
| 981 restarting_ = false; | 992 switch (state_) { |
| 982 host_ = NULL; | 993 case HOST_INITIALIZING: |
| 983 ResetHost(); | 994 state_ = HOST_STOPPED; |
| 995 ShutdownOnNetworkThread(); |
| 996 break; |
| 984 | 997 |
| 985 StartHost(); | 998 case HOST_STARTED: |
| 986 } | 999 state_ = HOST_STOPPING; |
| 1000 if (status_service_) |
| 1001 status_service_->SetHostIsDown(); |
| 1002 host_->Shutdown(base::Bind(&HostProcess::ShutdownOnNetworkThread, this)); |
| 1003 break; |
| 987 | 1004 |
| 988 void HostProcess::Shutdown(int exit_code) { | 1005 case HOST_STOPPING_TO_RESTART: |
| 989 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 1006 state_ = HOST_STOPPING; |
| 1007 break; |
| 990 | 1008 |
| 991 if (shutting_down_) | 1009 case HOST_STOPPING: |
| 992 return; | 1010 case HOST_STOPPED: |
| 993 | 1011 // Host is already stopped or being stopped. No action is required. |
| 994 if (status_service_) | 1012 break; |
| 995 status_service_->SetHostIsDown(); | |
| 996 | |
| 997 shutting_down_ = true; | |
| 998 *exit_code_out_ = exit_code; | |
| 999 if (host_) { | |
| 1000 host_->Shutdown(base::Bind(&HostProcess::ShutdownOnNetworkThread, this)); | |
| 1001 } else { | |
| 1002 ShutdownOnNetworkThread(); | |
| 1003 } | 1013 } |
| 1004 } | 1014 } |
| 1005 | 1015 |
| 1006 void HostProcess::ShutdownOnNetworkThread() { | 1016 void HostProcess::ShutdownOnNetworkThread() { |
| 1007 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 1017 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
| 1008 | 1018 |
| 1009 // Destroy networking objects while we are on the network thread. | |
| 1010 host_ = NULL; | 1019 host_ = NULL; |
| 1011 ResetHost(); | |
| 1012 | |
| 1013 if (policy_watcher_.get()) { | |
| 1014 base::WaitableEvent done_event(true, false); | |
| 1015 policy_watcher_->StopWatching(&done_event); | |
| 1016 done_event.Wait(); | |
| 1017 policy_watcher_.reset(); | |
| 1018 } | |
| 1019 | |
| 1020 status_service_.reset(); | |
| 1021 | |
| 1022 // Complete the rest of shutdown on the main thread. | |
| 1023 context_->ui_task_runner()->PostTask(FROM_HERE, | |
| 1024 base::Bind(&HostProcess::ShutdownOnUiThread, this)); | |
| 1025 } | |
| 1026 | |
| 1027 void HostProcess::ResetHost() { | |
| 1028 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | |
| 1029 | |
| 1030 curtaining_host_observer_.reset(); | 1020 curtaining_host_observer_.reset(); |
| 1031 host_event_logger_.reset(); | 1021 host_event_logger_.reset(); |
| 1032 log_to_server_.reset(); | 1022 log_to_server_.reset(); |
| 1033 heartbeat_sender_.reset(); | 1023 heartbeat_sender_.reset(); |
| 1034 signaling_connector_.reset(); | 1024 signaling_connector_.reset(); |
| 1035 signal_strategy_.reset(); | 1025 signal_strategy_.reset(); |
| 1036 resizing_host_observer_.reset(); | 1026 resizing_host_observer_.reset(); |
| 1027 |
| 1028 if (state_ == HOST_STOPPING_TO_RESTART) { |
| 1029 StartHost(); |
| 1030 } else if (state_ == HOST_STOPPING) { |
| 1031 state_ = HOST_STOPPED; |
| 1032 |
| 1033 if (policy_watcher_.get()) { |
| 1034 base::WaitableEvent done_event(true, false); |
| 1035 policy_watcher_->StopWatching(&done_event); |
| 1036 done_event.Wait(); |
| 1037 policy_watcher_.reset(); |
| 1038 } |
| 1039 |
| 1040 config_watcher_.reset(); |
| 1041 status_service_.reset(); |
| 1042 |
| 1043 // Complete the rest of shutdown on the main thread. |
| 1044 context_->ui_task_runner()->PostTask( |
| 1045 FROM_HERE, |
| 1046 base::Bind(&HostProcess::ShutdownOnUiThread, this)); |
| 1047 } else { |
| 1048 // This method is used as a callback for ChromotingHost::Shutdown() which is |
| 1049 // called only in STOPPING_TO_RESTART and STOPPING states. |
| 1050 NOTREACHED(); |
| 1051 } |
| 1037 } | 1052 } |
| 1038 | 1053 |
| 1039 void HostProcess::OnCrash(const std::string& function_name, | 1054 void HostProcess::OnCrash(const std::string& function_name, |
| 1040 const std::string& file_name, | 1055 const std::string& file_name, |
| 1041 const int& line_number) { | 1056 const int& line_number) { |
| 1042 CHECK(false); | 1057 CHECK(false); |
| 1043 } | 1058 } |
| 1044 | 1059 |
| 1045 } // namespace remoting | 1060 } // namespace remoting |
| 1046 | 1061 |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1142 user32.GetFunctionPointer("SetProcessDPIAware")); | 1157 user32.GetFunctionPointer("SetProcessDPIAware")); |
| 1143 set_process_dpi_aware(); | 1158 set_process_dpi_aware(); |
| 1144 } | 1159 } |
| 1145 | 1160 |
| 1146 // CommandLine::Init() ignores the passed |argc| and |argv| on Windows getting | 1161 // CommandLine::Init() ignores the passed |argc| and |argv| on Windows getting |
| 1147 // the command line from GetCommandLineW(), so we can safely pass NULL here. | 1162 // the command line from GetCommandLineW(), so we can safely pass NULL here. |
| 1148 return main(0, NULL); | 1163 return main(0, NULL); |
| 1149 } | 1164 } |
| 1150 | 1165 |
| 1151 #endif // defined(OS_WIN) | 1166 #endif // defined(OS_WIN) |
| OLD | NEW |