Chromium Code Reviews| 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 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 152 public: | 152 public: |
| 153 explicit HostProcess(scoped_ptr<ChromotingHostContext> context); | 153 explicit HostProcess(scoped_ptr<ChromotingHostContext> context); |
| 154 | 154 |
| 155 // Initializes IPC control channel and config file path from |cmd_line|. | 155 // Initializes IPC control channel and config file path from |cmd_line|. |
| 156 bool InitWithCommandLine(const CommandLine* cmd_line); | 156 bool InitWithCommandLine(const CommandLine* cmd_line); |
| 157 | 157 |
| 158 // ConfigFileWatcher::Delegate interface. | 158 // ConfigFileWatcher::Delegate interface. |
| 159 virtual void OnConfigUpdated(const std::string& serialized_config) OVERRIDE; | 159 virtual void OnConfigUpdated(const std::string& serialized_config) OVERRIDE; |
| 160 virtual void OnConfigWatcherError() OVERRIDE; | 160 virtual void OnConfigWatcherError() OVERRIDE; |
| 161 | 161 |
| 162 void StartWatchingConfigChanges(); | |
| 163 void CreateAuthenticatorFactory(); | 162 void CreateAuthenticatorFactory(); |
| 164 | 163 |
| 165 // IPC::Listener implementation. | 164 // IPC::Listener implementation. |
| 166 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; | 165 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; |
| 167 virtual void OnChannelError() OVERRIDE; | 166 virtual void OnChannelError() OVERRIDE; |
| 168 | 167 |
| 169 // HeartbeatSender::Listener overrides. | 168 // HeartbeatSender::Listener overrides. |
| 170 virtual void OnUnknownHostIdError() OVERRIDE; | 169 virtual void OnUnknownHostIdError() OVERRIDE; |
| 171 | 170 |
| 172 void StartHostProcess(); | 171 void StartHostProcess(); |
| 173 | 172 |
| 174 int get_exit_code() const; | 173 int get_exit_code() const; |
| 175 | 174 |
| 176 private: | 175 private: |
| 176 enum HostState { | |
| 177 // Host process has just been started. Waiting for config and policies to be | |
| 178 // read from the disk. | |
| 179 HOST_INITIALIZING, | |
| 180 | |
| 181 // Host is started and running. | |
| 182 HOST_STARTED, | |
| 183 | |
| 184 // Host is being stopped and will need to be started again. | |
| 185 HOST_STOPPING_TO_RESTART, | |
| 186 | |
| 187 // Host is being stopped. | |
| 188 HOST_STOPPING, | |
| 189 | |
| 190 // Host has been stopped. | |
| 191 HOST_STOPPED, | |
| 192 | |
| 193 // Allowed state transitions: | |
| 194 // INITIALIZING->STARTED | |
| 195 // INITIALIZING->STOPPED | |
| 196 // STARTED->STOPPING_TO_RESTART | |
| 197 // STARTED->STOPPING | |
| 198 // STOPPING_TO_RESTART->STARTED | |
| 199 // STOPPING_TO_RESTART->STOPPING | |
| 200 // STOPPING->STOPPED | |
| 201 // STOPPED->STARTED | |
| 202 // | |
| 203 // |host_| must be NULL in INITIALIZING and STOPPED states and not-NULL in | |
| 204 // all other states. | |
| 205 }; | |
| 206 | |
| 207 void StartOnNetworkThread(); | |
| 208 | |
| 177 #if defined(OS_POSIX) | 209 #if defined(OS_POSIX) |
| 178 // Registers a SIGTERM handler on the network thread, to shutdown the host. | |
| 179 void ListenForShutdownSignal(); | |
| 180 | |
| 181 // Callback passed to RegisterSignalHandler() to handle SIGTERM events. | 210 // Callback passed to RegisterSignalHandler() to handle SIGTERM events. |
| 182 void SigTermHandler(int signal_number); | 211 void SigTermHandler(int signal_number); |
| 183 #endif | 212 #endif |
| 184 | 213 |
| 185 // Asks the daemon to inject Secure Attention Sequence to the console. | 214 // Asks the daemon to inject Secure Attention Sequence to the console. |
| 186 void SendSasToConsole(); | 215 void SendSasToConsole(); |
| 187 | 216 |
| 188 void ShutdownHostProcess(); | 217 void ShutdownHostProcess(); |
| 189 | 218 |
| 190 // Applies the host config, returning true if successful. | 219 // Applies the host config, returning true if successful. |
| 191 bool ApplyConfig(scoped_ptr<JsonHostConfig> config); | 220 bool ApplyConfig(scoped_ptr<JsonHostConfig> config); |
| 192 | 221 |
| 193 void OnPolicyUpdate(scoped_ptr<base::DictionaryValue> policies); | 222 void OnPolicyUpdate(scoped_ptr<base::DictionaryValue> policies); |
| 194 bool OnHostDomainPolicyUpdate(const std::string& host_domain); | 223 bool OnHostDomainPolicyUpdate(const std::string& host_domain); |
| 195 bool OnUsernamePolicyUpdate(bool username_match_required); | 224 bool OnUsernamePolicyUpdate(bool username_match_required); |
| 196 bool OnNatPolicyUpdate(bool nat_traversal_enabled); | 225 bool OnNatPolicyUpdate(bool nat_traversal_enabled); |
| 197 bool OnCurtainPolicyUpdate(bool curtain_required); | 226 bool OnCurtainPolicyUpdate(bool curtain_required); |
| 198 bool OnHostTalkGadgetPrefixPolicyUpdate(const std::string& talkgadget_prefix); | 227 bool OnHostTalkGadgetPrefixPolicyUpdate(const std::string& talkgadget_prefix); |
| 199 | 228 |
| 200 void StartHostStatusService(); | |
| 201 | |
| 202 void StartHost(); | 229 void StartHost(); |
| 203 | 230 |
| 204 void OnAuthFailed(); | 231 void OnAuthFailed(); |
| 205 | 232 |
| 206 void RejectAuthenticatingClient(); | 233 void RejectAuthenticatingClient(); |
| 207 | 234 |
| 208 // Invoked when the user uses the Disconnect windows to terminate | 235 // Invoked when the user uses the Disconnect windows to terminate |
| 209 // the sessions, or when the local session is activated in curtain mode. | 236 // the sessions, or when the local session is activated in curtain mode. |
| 210 void OnDisconnectRequested(); | 237 void OnDisconnectRequested(); |
| 211 | 238 |
| 212 void RestartHost(); | 239 void RestartHost(); |
| 213 | 240 |
| 214 void RestartOnHostShutdown(); | 241 // Stops the host and shuts down the process with the specified |exit_code|. |
| 215 | 242 void ShutdownHost(int exit_code); |
| 216 void Shutdown(int exit_code); | |
| 217 | 243 |
| 218 void OnShutdownFinished(); | 244 void OnShutdownFinished(); |
| 219 | 245 |
| 220 void ResetHost(); | |
| 221 | |
| 222 // Crashes the process in response to a daemon's request. The daemon passes | 246 // Crashes the process in response to a daemon's request. The daemon passes |
| 223 // the location of the code that detected the fatal error resulted in this | 247 // the location of the code that detected the fatal error resulted in this |
| 224 // request. | 248 // request. |
| 225 void OnCrash(const std::string& function_name, | 249 void OnCrash(const std::string& function_name, |
| 226 const std::string& file_name, | 250 const std::string& file_name, |
| 227 const int& line_number); | 251 const int& line_number); |
| 228 | 252 |
| 229 scoped_ptr<ChromotingHostContext> context_; | 253 scoped_ptr<ChromotingHostContext> context_; |
| 230 scoped_ptr<IPC::ChannelProxy> daemon_channel_; | 254 scoped_ptr<IPC::ChannelProxy> daemon_channel_; |
| 231 scoped_ptr<net::NetworkChangeNotifier> network_change_notifier_; | 255 scoped_ptr<net::NetworkChangeNotifier> network_change_notifier_; |
| 232 | 256 |
| 233 FilePath host_config_path_; | 257 FilePath host_config_path_; |
| 234 scoped_ptr<ConfigFileWatcher> config_watcher_; | |
| 235 | 258 |
| 236 // Accessed on the network thread. | 259 // Accessed on the network thread. |
| 237 | 260 |
|
alexeypa (please no reviews)
2012/11/21 23:53:48
nit: remove the empty line?
Sergey Ulanov
2012/11/27 01:04:38
Done.
| |
| 261 HostState state_; | |
| 262 | |
| 263 scoped_ptr<ConfigFileWatcher> config_watcher_; | |
| 238 scoped_ptr<HostStatusService> status_service_; | 264 scoped_ptr<HostStatusService> status_service_; |
| 239 | 265 |
| 240 std::string host_id_; | 266 std::string host_id_; |
| 241 protocol::SharedSecretHash host_secret_hash_; | 267 protocol::SharedSecretHash host_secret_hash_; |
| 242 HostKeyPair key_pair_; | 268 HostKeyPair key_pair_; |
| 243 std::string oauth_refresh_token_; | 269 std::string oauth_refresh_token_; |
| 244 std::string serialized_config_; | 270 std::string serialized_config_; |
| 245 std::string xmpp_login_; | 271 std::string xmpp_login_; |
| 246 std::string xmpp_auth_token_; | 272 std::string xmpp_auth_token_; |
| 247 std::string xmpp_auth_service_; | 273 std::string xmpp_auth_service_; |
| 248 | 274 |
| 249 scoped_ptr<policy_hack::PolicyWatcher> policy_watcher_; | 275 scoped_ptr<policy_hack::PolicyWatcher> policy_watcher_; |
| 250 bool allow_nat_traversal_; | 276 bool allow_nat_traversal_; |
| 251 std::string talkgadget_prefix_; | 277 std::string talkgadget_prefix_; |
| 252 | 278 |
| 253 scoped_ptr<CurtainMode> curtain_; | 279 scoped_ptr<CurtainMode> curtain_; |
| 254 scoped_ptr<CurtainingHostObserver> curtaining_host_observer_; | 280 scoped_ptr<CurtainingHostObserver> curtaining_host_observer_; |
| 255 bool curtain_required_; | 281 bool curtain_required_; |
| 256 | 282 |
| 257 bool restarting_; | |
| 258 bool shutting_down_; | |
| 259 | |
| 260 scoped_ptr<DesktopEnvironmentFactory> desktop_environment_factory_; | 283 scoped_ptr<DesktopEnvironmentFactory> desktop_environment_factory_; |
| 261 scoped_ptr<DesktopResizer> desktop_resizer_; | 284 scoped_ptr<DesktopResizer> desktop_resizer_; |
| 262 scoped_ptr<ResizingHostObserver> resizing_host_observer_; | 285 scoped_ptr<ResizingHostObserver> resizing_host_observer_; |
| 263 scoped_ptr<XmppSignalStrategy> signal_strategy_; | 286 scoped_ptr<XmppSignalStrategy> signal_strategy_; |
| 264 scoped_ptr<SignalingConnector> signaling_connector_; | 287 scoped_ptr<SignalingConnector> signaling_connector_; |
| 265 scoped_ptr<HeartbeatSender> heartbeat_sender_; | 288 scoped_ptr<HeartbeatSender> heartbeat_sender_; |
| 266 scoped_ptr<LogToServer> log_to_server_; | 289 scoped_ptr<LogToServer> log_to_server_; |
| 267 scoped_ptr<HostEventLogger> host_event_logger_; | 290 scoped_ptr<HostEventLogger> host_event_logger_; |
| 268 | 291 |
| 269 scoped_ptr<HostUserInterface> host_user_interface_; | 292 scoped_ptr<HostUserInterface> host_user_interface_; |
| 270 | 293 |
| 271 scoped_refptr<ChromotingHost> host_; | 294 scoped_refptr<ChromotingHost> host_; |
| 272 | 295 |
| 273 #if defined(REMOTING_MULTI_PROCESS) | 296 #if defined(REMOTING_MULTI_PROCESS) |
| 274 DesktopSessionConnector* desktop_session_connector_; | 297 DesktopSessionConnector* desktop_session_connector_; |
| 275 #endif // defined(REMOTING_MULTI_PROCESS) | 298 #endif // defined(REMOTING_MULTI_PROCESS) |
| 276 | 299 |
| 277 int exit_code_; | 300 int exit_code_; |
| 278 }; | 301 }; |
| 279 | 302 |
| 280 HostProcess::HostProcess(scoped_ptr<ChromotingHostContext> context) | 303 HostProcess::HostProcess(scoped_ptr<ChromotingHostContext> context) |
| 281 : context_(context.Pass()), | 304 : context_(context.Pass()), |
| 305 state_(HOST_INITIALIZING), | |
| 282 allow_nat_traversal_(true), | 306 allow_nat_traversal_(true), |
| 283 curtain_required_(false), | 307 curtain_required_(false), |
| 284 restarting_(false), | |
| 285 shutting_down_(false), | |
| 286 desktop_resizer_(DesktopResizer::Create()), | 308 desktop_resizer_(DesktopResizer::Create()), |
| 287 #if defined(REMOTING_MULTI_PROCESS) | 309 #if defined(REMOTING_MULTI_PROCESS) |
| 288 desktop_session_connector_(NULL), | 310 desktop_session_connector_(NULL), |
| 289 #endif // defined(REMOTING_MULTI_PROCESS) | 311 #endif // defined(REMOTING_MULTI_PROCESS) |
| 290 exit_code_(kSuccessExitCode) { | 312 exit_code_(kSuccessExitCode) { |
| 291 network_change_notifier_.reset(net::NetworkChangeNotifier::Create()); | 313 network_change_notifier_.reset(net::NetworkChangeNotifier::Create()); |
| 292 curtain_ = CurtainMode::Create( | 314 curtain_ = CurtainMode::Create( |
| 293 base::Bind(&HostProcess::OnDisconnectRequested, | 315 base::Bind(&HostProcess::OnDisconnectRequested, |
| 294 base::Unretained(this)), | 316 base::Unretained(this)), |
| 295 base::Bind(&HostProcess::RejectAuthenticatingClient, | 317 base::Bind(&HostProcess::RejectAuthenticatingClient, |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 356 // Filter out duplicates. | 378 // Filter out duplicates. |
| 357 if (serialized_config_ == serialized_config) | 379 if (serialized_config_ == serialized_config) |
| 358 return; | 380 return; |
| 359 | 381 |
| 360 LOG(INFO) << "Processing new host configuration."; | 382 LOG(INFO) << "Processing new host configuration."; |
| 361 | 383 |
| 362 serialized_config_ = serialized_config; | 384 serialized_config_ = serialized_config; |
| 363 scoped_ptr<JsonHostConfig> config(new JsonHostConfig(FilePath())); | 385 scoped_ptr<JsonHostConfig> config(new JsonHostConfig(FilePath())); |
| 364 if (!config->SetSerializedData(serialized_config)) { | 386 if (!config->SetSerializedData(serialized_config)) { |
| 365 LOG(ERROR) << "Invalid configuration."; | 387 LOG(ERROR) << "Invalid configuration."; |
| 366 Shutdown(kInvalidHostConfigurationExitCode); | 388 ShutdownHost(kInvalidHostConfigurationExitCode); |
| 367 return; | 389 return; |
| 368 } | 390 } |
| 369 | 391 |
| 370 if (!ApplyConfig(config.Pass())) { | 392 if (!ApplyConfig(config.Pass())) { |
| 371 LOG(ERROR) << "Failed to apply the configuration."; | 393 LOG(ERROR) << "Failed to apply the configuration."; |
| 372 Shutdown(kInvalidHostConfigurationExitCode); | 394 ShutdownHost(kInvalidHostConfigurationExitCode); |
| 373 return; | 395 return; |
| 374 } | 396 } |
| 375 | 397 |
| 376 // Start watching the policy (and eventually start the host) if this is | 398 if (state_ == HOST_INITIALIZING) { |
| 377 // the first configuration update. Otherwise, create new authenticator | 399 // TODO(sergeyu): Currently OnPolicyUpdate() assumes that host config is |
| 378 // factory in case PIN has changed. | 400 // already loaded so PolicyWatcher has to be started here. Separate policy |
| 379 if (!policy_watcher_) { | 401 // loading from policy verifications and move |policy_watcher_| |
| 402 // initialization to StartOnNetworkThread(). | |
| 380 policy_watcher_.reset( | 403 policy_watcher_.reset( |
| 381 policy_hack::PolicyWatcher::Create(context_->file_task_runner())); | 404 policy_hack::PolicyWatcher::Create(context_->file_task_runner())); |
| 382 policy_watcher_->StartWatching( | 405 policy_watcher_->StartWatching( |
| 383 base::Bind(&HostProcess::OnPolicyUpdate, base::Unretained(this))); | 406 base::Bind(&HostProcess::OnPolicyUpdate, base::Unretained(this))); |
| 384 } else { | 407 } else if (state_ == HOST_STARTED) { |
| 408 // TODO(sergeyu): Here we assume that PIN is the only part of the config | |
| 409 // that may change while the service is running. Change ApplyConfig() to | |
| 410 // detect other changes in the config and restart host if necessary here. | |
| 385 CreateAuthenticatorFactory(); | 411 CreateAuthenticatorFactory(); |
| 386 } | 412 } |
| 387 } | 413 } |
| 388 | 414 |
| 389 void HostProcess::OnConfigWatcherError() { | 415 void HostProcess::OnConfigWatcherError() { |
| 390 DCHECK(context_->ui_task_runner()->BelongsToCurrentThread()); | 416 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
| 391 | 417 ShutdownHost(kInvalidHostConfigurationExitCode); |
| 392 context_->network_task_runner()->PostTask( | |
| 393 FROM_HERE, | |
| 394 base::Bind(&HostProcess::Shutdown, base::Unretained(this), | |
| 395 kInvalidHostConfigurationExitCode)); | |
| 396 } | 418 } |
| 397 | 419 |
| 398 void HostProcess::StartWatchingConfigChanges() { | 420 void HostProcess::StartOnNetworkThread() { |
| 421 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | |
| 422 | |
| 423 if (CommandLine::ForCurrentProcess()->HasSwitch( | |
| 424 kEnableStatusServiceSwitchName)) { | |
| 425 status_service_.reset(new HostStatusService()); | |
| 426 } | |
| 427 | |
| 399 #if !defined(REMOTING_MULTI_PROCESS) | 428 #if !defined(REMOTING_MULTI_PROCESS) |
| 400 // Start watching the host configuration file. | 429 // Start watching the host configuration file. |
| 401 config_watcher_.reset(new ConfigFileWatcher(context_->ui_task_runner(), | 430 config_watcher_.reset(new ConfigFileWatcher(context_->network_task_runner(), |
| 402 context_->file_task_runner(), | 431 context_->file_task_runner(), |
| 403 this)); | 432 this)); |
| 404 config_watcher_->Watch(host_config_path_); | 433 config_watcher_->Watch(host_config_path_); |
| 405 #endif // !defined(REMOTING_MULTI_PROCESS) | 434 #endif // !defined(REMOTING_MULTI_PROCESS) |
| 435 | |
| 436 #if defined(OS_POSIX) | |
| 437 remoting::RegisterSignalHandler( | |
| 438 SIGTERM, | |
| 439 base::Bind(&HostProcess::SigTermHandler, base::Unretained(this))); | |
| 440 #endif // defined(OS_POSIX) | |
| 406 } | 441 } |
| 407 | 442 |
| 408 #if defined(OS_POSIX) | 443 #if defined(OS_POSIX) |
| 409 void HostProcess::ListenForShutdownSignal() { | |
| 410 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | |
| 411 | |
| 412 remoting::RegisterSignalHandler( | |
| 413 SIGTERM, | |
| 414 base::Bind(&HostProcess::SigTermHandler, base::Unretained(this))); | |
| 415 } | |
| 416 | |
| 417 void HostProcess::SigTermHandler(int signal_number) { | 444 void HostProcess::SigTermHandler(int signal_number) { |
| 418 DCHECK(signal_number == SIGTERM); | 445 DCHECK(signal_number == SIGTERM); |
| 419 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 446 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
| 420 LOG(INFO) << "Caught SIGTERM: Shutting down..."; | 447 LOG(INFO) << "Caught SIGTERM: Shutting down..."; |
| 421 Shutdown(kSuccessExitCode); | 448 ShutdownHost(kSuccessExitCode); |
| 422 } | 449 } |
| 423 #endif // OS_POSIX | 450 #endif // OS_POSIX |
| 424 | 451 |
| 425 void HostProcess::CreateAuthenticatorFactory() { | 452 void HostProcess::CreateAuthenticatorFactory() { |
| 426 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 453 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
| 427 | 454 |
| 428 if (!host_ || shutting_down_) | 455 if (state_ != HOST_STARTED) |
| 429 return; | 456 return; |
| 430 | 457 |
| 431 std::string local_certificate = key_pair_.GenerateCertificate(); | 458 std::string local_certificate = key_pair_.GenerateCertificate(); |
| 432 if (local_certificate.empty()) { | 459 if (local_certificate.empty()) { |
| 433 LOG(ERROR) << "Failed to generate host certificate."; | 460 LOG(ERROR) << "Failed to generate host certificate."; |
| 434 Shutdown(kInitializationFailed); | 461 ShutdownHost(kInitializationFailed); |
| 435 return; | 462 return; |
| 436 } | 463 } |
| 437 | 464 |
| 438 scoped_ptr<protocol::AuthenticatorFactory> factory( | 465 scoped_ptr<protocol::AuthenticatorFactory> factory( |
| 439 new protocol::Me2MeHostAuthenticatorFactory( | 466 new protocol::Me2MeHostAuthenticatorFactory( |
| 440 local_certificate, *key_pair_.private_key(), host_secret_hash_)); | 467 local_certificate, *key_pair_.private_key(), host_secret_hash_)); |
| 441 #if defined(OS_LINUX) | 468 #if defined(OS_LINUX) |
| 442 // On Linux, perform a PAM authorization step after authentication. | 469 // On Linux, perform a PAM authorization step after authentication. |
| 443 factory.reset(new PamAuthorizationFactory(factory.Pass())); | 470 factory.reset(new PamAuthorizationFactory(factory.Pass())); |
| 444 #endif | 471 #endif |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 470 return false; | 497 return false; |
| 471 #endif // !defined(REMOTING_MULTI_PROCESS) | 498 #endif // !defined(REMOTING_MULTI_PROCESS) |
| 472 } | 499 } |
| 473 | 500 |
| 474 void HostProcess::OnChannelError() { | 501 void HostProcess::OnChannelError() { |
| 475 DCHECK(context_->ui_task_runner()->BelongsToCurrentThread()); | 502 DCHECK(context_->ui_task_runner()->BelongsToCurrentThread()); |
| 476 | 503 |
| 477 // Shutdown the host if the daemon disconnected the channel. | 504 // Shutdown the host if the daemon disconnected the channel. |
| 478 context_->network_task_runner()->PostTask( | 505 context_->network_task_runner()->PostTask( |
| 479 FROM_HERE, | 506 FROM_HERE, |
| 480 base::Bind(&HostProcess::Shutdown, base::Unretained(this), | 507 base::Bind(&HostProcess::ShutdownHost, base::Unretained(this), |
| 481 kSuccessExitCode)); | 508 kSuccessExitCode)); |
| 482 } | 509 } |
| 483 | 510 |
| 484 void HostProcess::StartHostProcess() { | 511 void HostProcess::StartHostProcess() { |
| 485 DCHECK(context_->ui_task_runner()->BelongsToCurrentThread()); | 512 DCHECK(context_->ui_task_runner()->BelongsToCurrentThread()); |
| 486 | 513 |
| 487 if (!InitWithCommandLine(CommandLine::ForCurrentProcess())) { | 514 if (!InitWithCommandLine(CommandLine::ForCurrentProcess())) { |
| 488 OnConfigWatcherError(); | 515 OnConfigWatcherError(); |
| 489 return; | 516 return; |
| 490 } | 517 } |
| 491 | 518 |
| 492 #if defined(OS_LINUX) | 519 #if defined(OS_LINUX) |
| 493 // TODO(sergeyu): Pass configuration parameters to the Linux-specific version | 520 // TODO(sergeyu): Pass configuration parameters to the Linux-specific version |
| 494 // of DesktopEnvironmentFactory when we have it. | 521 // of DesktopEnvironmentFactory when we have it. |
| 495 remoting::VideoFrameCapturer::EnableXDamage(true); | 522 remoting::VideoFrameCapturer::EnableXDamage(true); |
| 496 | 523 |
| 497 // If an audio pipe is specific on the command-line then initialize | 524 // If an audio pipe is specific on the command-line then initialize |
| 498 // AudioCapturerLinux to capture from it. | 525 // AudioCapturerLinux to capture from it. |
| 499 FilePath audio_pipe_name = CommandLine::ForCurrentProcess()-> | 526 FilePath audio_pipe_name = CommandLine::ForCurrentProcess()-> |
| 500 GetSwitchValuePath(kAudioPipeSwitchName); | 527 GetSwitchValuePath(kAudioPipeSwitchName); |
| 501 if (!audio_pipe_name.empty()) { | 528 if (!audio_pipe_name.empty()) { |
| 502 remoting::AudioCapturerLinux::InitializePipeReader( | 529 remoting::AudioCapturerLinux::InitializePipeReader( |
| 503 context_->audio_task_runner(), audio_pipe_name); | 530 context_->audio_task_runner(), audio_pipe_name); |
| 504 } | 531 } |
| 505 #endif // defined(OS_LINUX) | 532 #endif // defined(OS_LINUX) |
| 506 | 533 |
| 507 if (CommandLine::ForCurrentProcess()->HasSwitch( | |
| 508 kEnableStatusServiceSwitchName)) { | |
| 509 context_->network_task_runner()->PostTask( | |
| 510 FROM_HERE, | |
| 511 base::Bind(&HostProcess::StartHostStatusService, | |
| 512 base::Unretained(this))); | |
| 513 } | |
| 514 | |
| 515 // Create a desktop environment factory appropriate to the build type & | 534 // Create a desktop environment factory appropriate to the build type & |
| 516 // platform. | 535 // platform. |
| 517 #if defined(OS_WIN) | 536 #if defined(OS_WIN) |
| 518 | 537 |
| 519 #if defined(REMOTING_MULTI_PROCESS) | 538 #if defined(REMOTING_MULTI_PROCESS) |
| 520 IpcDesktopEnvironmentFactory* desktop_environment_factory = | 539 IpcDesktopEnvironmentFactory* desktop_environment_factory = |
| 521 new IpcDesktopEnvironmentFactory( | 540 new IpcDesktopEnvironmentFactory( |
| 522 daemon_channel_.get(), | 541 daemon_channel_.get(), |
| 523 context_->input_task_runner(), | 542 context_->input_task_runner(), |
| 524 context_->network_task_runner(), | 543 context_->network_task_runner(), |
| 525 context_->ui_task_runner()); | 544 context_->ui_task_runner()); |
| 526 desktop_session_connector_ = desktop_environment_factory; | 545 desktop_session_connector_ = desktop_environment_factory; |
| 527 #else // !defined(REMOTING_MULTI_PROCESS) | 546 #else // !defined(REMOTING_MULTI_PROCESS) |
| 528 DesktopEnvironmentFactory* desktop_environment_factory = | 547 DesktopEnvironmentFactory* desktop_environment_factory = |
| 529 new SessionDesktopEnvironmentFactory( | 548 new SessionDesktopEnvironmentFactory( |
| 530 context_->input_task_runner(), context_->ui_task_runner(), | 549 context_->input_task_runner(), context_->ui_task_runner(), |
| 531 base::Bind(&HostProcess::SendSasToConsole, base::Unretained(this))); | 550 base::Bind(&HostProcess::SendSasToConsole, base::Unretained(this))); |
| 532 #endif // !defined(REMOTING_MULTI_PROCESS) | 551 #endif // !defined(REMOTING_MULTI_PROCESS) |
| 533 | 552 |
| 534 #else // !defined(OS_WIN) | 553 #else // !defined(OS_WIN) |
| 535 DesktopEnvironmentFactory* desktop_environment_factory = | 554 DesktopEnvironmentFactory* desktop_environment_factory = |
| 536 new DesktopEnvironmentFactory( | 555 new DesktopEnvironmentFactory( |
| 537 context_->input_task_runner(), context_->ui_task_runner()); | 556 context_->input_task_runner(), context_->ui_task_runner()); |
| 538 #endif // !defined(OS_WIN) | 557 #endif // !defined(OS_WIN) |
| 539 | 558 |
| 540 desktop_environment_factory_.reset(desktop_environment_factory); | 559 desktop_environment_factory_.reset(desktop_environment_factory); |
| 541 | 560 |
| 542 #if defined(OS_POSIX) | |
| 543 context_->network_task_runner()->PostTask( | |
| 544 FROM_HERE, | |
| 545 base::Bind(&HostProcess::ListenForShutdownSignal, | |
| 546 base::Unretained(this))); | |
| 547 #endif // OS_POSIX | |
| 548 | |
| 549 // The host UI should be created on the UI thread. | 561 // The host UI should be created on the UI thread. |
| 550 bool want_user_interface = true; | 562 bool want_user_interface = true; |
| 551 #if defined(OS_LINUX) | 563 #if defined(OS_LINUX) |
| 552 want_user_interface = false; | 564 want_user_interface = false; |
| 553 #elif defined(OS_MACOSX) | 565 #elif defined(OS_MACOSX) |
| 554 // Don't try to display any UI on top of the system's login screen as this | 566 // Don't try to display any UI on top of the system's login screen as this |
| 555 // is rejected by the Window Server on OS X 10.7.4, and prevents the | 567 // is rejected by the Window Server on OS X 10.7.4, and prevents the |
| 556 // capturer from working (http://crbug.com/140984). | 568 // capturer from working (http://crbug.com/140984). |
| 557 | 569 |
| 558 // TODO(lambroslambrou): Use a better technique of detecting whether we're | 570 // TODO(lambroslambrou): Use a better technique of detecting whether we're |
| 559 // running in the LoginWindow context, and refactor this into a separate | 571 // running in the LoginWindow context, and refactor this into a separate |
| 560 // function to be used here and in CurtainMode::ActivateCurtain(). | 572 // function to be used here and in CurtainMode::ActivateCurtain(). |
| 561 want_user_interface = getuid() != 0; | 573 want_user_interface = getuid() != 0; |
| 562 #endif // OS_MACOSX | 574 #endif // OS_MACOSX |
| 563 | 575 |
| 564 if (want_user_interface) { | 576 if (want_user_interface) { |
| 565 host_user_interface_.reset( | 577 host_user_interface_.reset( |
| 566 new HostUserInterface(context_->network_task_runner(), | 578 new HostUserInterface(context_->network_task_runner(), |
| 567 context_->ui_task_runner())); | 579 context_->ui_task_runner())); |
| 568 host_user_interface_->Init(); | 580 host_user_interface_->Init(); |
| 569 } | 581 } |
| 570 | 582 |
| 571 StartWatchingConfigChanges(); | 583 context_->network_task_runner()->PostTask( |
| 584 FROM_HERE, | |
| 585 base::Bind(&HostProcess::StartOnNetworkThread, | |
| 586 base::Unretained(this))); | |
| 572 } | 587 } |
| 573 | 588 |
| 574 int HostProcess::get_exit_code() const { | 589 int HostProcess::get_exit_code() const { |
| 575 return exit_code_; | 590 return exit_code_; |
| 576 } | 591 } |
| 577 | 592 |
| 578 void HostProcess::SendSasToConsole() { | 593 void HostProcess::SendSasToConsole() { |
| 579 DCHECK(context_->ui_task_runner()->BelongsToCurrentThread()); | 594 DCHECK(context_->ui_task_runner()->BelongsToCurrentThread()); |
| 580 | 595 |
| 581 if (daemon_channel_) | 596 if (daemon_channel_) |
| 582 daemon_channel_->Send(new ChromotingNetworkDaemonMsg_SendSasToConsole()); | 597 daemon_channel_->Send(new ChromotingNetworkDaemonMsg_SendSasToConsole()); |
| 583 } | 598 } |
| 584 | 599 |
| 585 void HostProcess::ShutdownHostProcess() { | 600 void HostProcess::ShutdownHostProcess() { |
| 586 DCHECK(context_->ui_task_runner()->BelongsToCurrentThread()); | 601 DCHECK(context_->ui_task_runner()->BelongsToCurrentThread()); |
| 587 | 602 |
| 588 // Tear down resources that use ChromotingHostContext threads. | 603 // Tear down resources that use ChromotingHostContext threads. |
| 589 config_watcher_.reset(); | |
| 590 daemon_channel_.reset(); | 604 daemon_channel_.reset(); |
| 591 desktop_environment_factory_.reset(); | 605 desktop_environment_factory_.reset(); |
| 592 host_user_interface_.reset(); | 606 host_user_interface_.reset(); |
| 593 | 607 |
| 594 context_.reset(); | 608 context_.reset(); |
| 595 } | 609 } |
| 596 | 610 |
| 597 // Overridden from HeartbeatSender::Listener | 611 // Overridden from HeartbeatSender::Listener |
| 598 void HostProcess::OnUnknownHostIdError() { | 612 void HostProcess::OnUnknownHostIdError() { |
| 599 LOG(ERROR) << "Host ID not found."; | 613 LOG(ERROR) << "Host ID not found."; |
| 600 Shutdown(kInvalidHostIdExitCode); | 614 ShutdownHost(kInvalidHostIdExitCode); |
| 601 } | 615 } |
| 602 | 616 |
| 603 // Applies the host config, returning true if successful. | 617 // Applies the host config, returning true if successful. |
| 604 bool HostProcess::ApplyConfig(scoped_ptr<JsonHostConfig> config) { | 618 bool HostProcess::ApplyConfig(scoped_ptr<JsonHostConfig> config) { |
| 605 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 619 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
| 606 | 620 |
| 607 if (!config->GetString(kHostIdConfigPath, &host_id_)) { | 621 if (!config->GetString(kHostIdConfigPath, &host_id_)) { |
| 608 LOG(ERROR) << "host_id is not defined in the config."; | 622 LOG(ERROR) << "host_id is not defined in the config."; |
| 609 return false; | 623 return false; |
| 610 } | 624 } |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 641 // For the me2me host, we default to ClientLogin token for chromiumsync | 655 // For the me2me host, we default to ClientLogin token for chromiumsync |
| 642 // because earlier versions of the host had no HTTP stack with which to | 656 // because earlier versions of the host had no HTTP stack with which to |
| 643 // request an OAuth2 access token. | 657 // request an OAuth2 access token. |
| 644 xmpp_auth_service_ = kChromotingTokenDefaultServiceName; | 658 xmpp_auth_service_ = kChromotingTokenDefaultServiceName; |
| 645 } | 659 } |
| 646 return true; | 660 return true; |
| 647 } | 661 } |
| 648 | 662 |
| 649 void HostProcess::OnPolicyUpdate(scoped_ptr<base::DictionaryValue> policies) { | 663 void HostProcess::OnPolicyUpdate(scoped_ptr<base::DictionaryValue> policies) { |
| 650 // TODO(rmsousa): Consolidate all On*PolicyUpdate methods into this one. | 664 // TODO(rmsousa): Consolidate all On*PolicyUpdate methods into this one. |
| 665 // TODO(sergeyu): Currently polices are verified only when they are loaded. | |
| 666 // Separate policy loading from policy verifications - this will allow to | |
| 667 // check policies again later, e.g. when host config changes. | |
| 668 | |
| 651 if (!context_->network_task_runner()->BelongsToCurrentThread()) { | 669 if (!context_->network_task_runner()->BelongsToCurrentThread()) { |
| 652 context_->network_task_runner()->PostTask(FROM_HERE, base::Bind( | 670 context_->network_task_runner()->PostTask(FROM_HERE, base::Bind( |
| 653 &HostProcess::OnPolicyUpdate, base::Unretained(this), | 671 &HostProcess::OnPolicyUpdate, base::Unretained(this), |
| 654 base::Passed(&policies))); | 672 base::Passed(&policies))); |
| 655 return; | 673 return; |
| 656 } | 674 } |
| 657 | 675 |
| 658 bool restart_required = false; | 676 bool restart_required = false; |
| 659 bool bool_value; | 677 bool bool_value; |
| 660 std::string string_value; | 678 std::string string_value; |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 672 restart_required |= OnNatPolicyUpdate(bool_value); | 690 restart_required |= OnNatPolicyUpdate(bool_value); |
| 673 } | 691 } |
| 674 if (policies->GetString( | 692 if (policies->GetString( |
| 675 policy_hack::PolicyWatcher::kHostTalkGadgetPrefixPolicyName, | 693 policy_hack::PolicyWatcher::kHostTalkGadgetPrefixPolicyName, |
| 676 &string_value)) { | 694 &string_value)) { |
| 677 restart_required |= OnHostTalkGadgetPrefixPolicyUpdate(string_value); | 695 restart_required |= OnHostTalkGadgetPrefixPolicyUpdate(string_value); |
| 678 } | 696 } |
| 679 if (policies->GetBoolean( | 697 if (policies->GetBoolean( |
| 680 policy_hack::PolicyWatcher::kHostRequireCurtainPolicyName, | 698 policy_hack::PolicyWatcher::kHostRequireCurtainPolicyName, |
| 681 &bool_value)) { | 699 &bool_value)) { |
| 682 restart_required |= OnCurtainPolicyUpdate(bool_value); | 700 restart_required |= OnCurtainPolicyUpdate(bool_value); |
| 683 } | 701 } |
| 684 if (!host_) { | 702 |
| 703 if (state_ == HOST_INITIALIZING) { | |
| 685 StartHost(); | 704 StartHost(); |
| 686 } else if (restart_required) { | 705 } else if (state_ == HOST_STARTED && restart_required) { |
| 687 RestartHost(); | 706 RestartHost(); |
| 688 } | 707 } |
| 689 } | 708 } |
| 690 | 709 |
| 691 bool HostProcess::OnHostDomainPolicyUpdate(const std::string& host_domain) { | 710 bool HostProcess::OnHostDomainPolicyUpdate(const std::string& host_domain) { |
| 692 // Returns true if the host has to be restarted after this policy update. | 711 // Returns true if the host has to be restarted after this policy update. |
| 693 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 712 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
| 694 | 713 |
| 695 LOG(INFO) << "Policy sets host domain: " << host_domain; | 714 LOG(INFO) << "Policy sets host domain: " << host_domain; |
| 696 | 715 |
| 697 if (!host_domain.empty() && | 716 if (!host_domain.empty() && |
| 698 !EndsWith(xmpp_login_, std::string("@") + host_domain, false)) { | 717 !EndsWith(xmpp_login_, std::string("@") + host_domain, false)) { |
| 699 Shutdown(kInvalidHostDomainExitCode); | 718 ShutdownHost(kInvalidHostDomainExitCode); |
| 700 } | 719 } |
| 701 return false; | 720 return false; |
| 702 } | 721 } |
| 703 | 722 |
| 704 bool HostProcess::OnUsernamePolicyUpdate(bool host_username_match_required) { | 723 bool HostProcess::OnUsernamePolicyUpdate(bool host_username_match_required) { |
| 705 // Returns false: never restart the host after this policy update. | 724 // Returns false: never restart the host after this policy update. |
| 706 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 725 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
| 707 | 726 |
| 708 if (host_username_match_required) { | 727 if (host_username_match_required) { |
| 709 LOG(INFO) << "Policy requires host username match."; | 728 LOG(INFO) << "Policy requires host username match."; |
| 710 if (!CanGetUsername() || | 729 if (!CanGetUsername() || |
| 711 !StartsWithASCII(xmpp_login_, GetUsername() + std::string("@"), | 730 !StartsWithASCII(xmpp_login_, GetUsername() + std::string("@"), |
| 712 false)) { | 731 false)) { |
| 713 Shutdown(kUsernameMismatchExitCode); | 732 ShutdownHost(kUsernameMismatchExitCode); |
| 714 } | 733 } |
| 715 } else { | 734 } else { |
| 716 LOG(INFO) << "Policy does not require host username match."; | 735 LOG(INFO) << "Policy does not require host username match."; |
| 717 } | 736 } |
| 718 | 737 |
| 719 return false; | 738 return false; |
| 720 } | 739 } |
| 721 | 740 |
| 722 bool HostProcess::OnNatPolicyUpdate(bool nat_traversal_enabled) { | 741 bool HostProcess::OnNatPolicyUpdate(bool nat_traversal_enabled) { |
| 723 // Returns true if the host has to be restarted after this policy update. | 742 // Returns true if the host has to be restarted after this policy update. |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 743 // When curtain mode is in effect on Mac, the host process runs in the | 762 // When curtain mode is in effect on Mac, the host process runs in the |
| 744 // user's switched-out session, but launchd will also run an instance at | 763 // user's switched-out session, but launchd will also run an instance at |
| 745 // the console login screen. Even if no user is currently logged-on, we | 764 // the console login screen. Even if no user is currently logged-on, we |
| 746 // can't support remote-access to the login screen because the current host | 765 // can't support remote-access to the login screen because the current host |
| 747 // process model disconnects the client during login, which would leave | 766 // process model disconnects the client during login, which would leave |
| 748 // the logged in session un-curtained on the console until they reconnect. | 767 // the logged in session un-curtained on the console until they reconnect. |
| 749 // | 768 // |
| 750 // TODO(jamiewalch): Fix this once we have implemented the multi-process | 769 // TODO(jamiewalch): Fix this once we have implemented the multi-process |
| 751 // daemon architecture (crbug.com/134894) | 770 // daemon architecture (crbug.com/134894) |
| 752 if (getuid() == 0) { | 771 if (getuid() == 0) { |
| 753 Shutdown(kLoginScreenNotSupportedExitCode); | 772 ShutdownHost(kLoginScreenNotSupportedExitCode); |
| 754 return false; | 773 return false; |
| 755 } | 774 } |
| 756 } | 775 } |
| 757 #endif | 776 #endif |
| 758 | 777 |
| 759 if (curtain_required_ != curtain_required) { | 778 if (curtain_required_ != curtain_required) { |
| 760 if (curtain_required) | 779 if (curtain_required) |
| 761 LOG(ERROR) << "Policy requires curtain-mode."; | 780 LOG(ERROR) << "Policy requires curtain-mode."; |
| 762 else | 781 else |
| 763 LOG(ERROR) << "Policy does not require curtain-mode."; | 782 LOG(ERROR) << "Policy does not require curtain-mode."; |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 775 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 794 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
| 776 | 795 |
| 777 if (talkgadget_prefix != talkgadget_prefix_) { | 796 if (talkgadget_prefix != talkgadget_prefix_) { |
| 778 LOG(INFO) << "Policy sets talkgadget prefix: " << talkgadget_prefix; | 797 LOG(INFO) << "Policy sets talkgadget prefix: " << talkgadget_prefix; |
| 779 talkgadget_prefix_ = talkgadget_prefix; | 798 talkgadget_prefix_ = talkgadget_prefix; |
| 780 return true; | 799 return true; |
| 781 } | 800 } |
| 782 return false; | 801 return false; |
| 783 } | 802 } |
| 784 | 803 |
| 785 void HostProcess::StartHostStatusService() { | |
| 786 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | |
| 787 status_service_.reset(new HostStatusService()); | |
| 788 } | |
| 789 | |
| 790 void HostProcess::StartHost() { | 804 void HostProcess::StartHost() { |
| 791 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 805 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
| 792 DCHECK(!host_); | 806 DCHECK(!host_); |
| 793 DCHECK(!signal_strategy_.get()); | 807 DCHECK(!signal_strategy_.get()); |
| 794 | 808 DCHECK(state_ == HOST_INITIALIZING || state_ == HOST_STOPPING_TO_RESTART || |
| 795 if (shutting_down_) | 809 state_ == HOST_STOPPED) << state_; |
| 796 return; | 810 state_ = HOST_STARTED; |
| 797 | 811 |
| 798 signal_strategy_.reset( | 812 signal_strategy_.reset( |
| 799 new XmppSignalStrategy(context_->url_request_context_getter(), | 813 new XmppSignalStrategy(context_->url_request_context_getter(), |
| 800 xmpp_login_, xmpp_auth_token_, | 814 xmpp_login_, xmpp_auth_token_, |
| 801 xmpp_auth_service_)); | 815 xmpp_auth_service_)); |
| 802 | 816 |
| 803 scoped_ptr<DnsBlackholeChecker> dns_blackhole_checker( | 817 scoped_ptr<DnsBlackholeChecker> dns_blackhole_checker( |
| 804 new DnsBlackholeChecker(context_->url_request_context_getter(), | 818 new DnsBlackholeChecker(context_->url_request_context_getter(), |
| 805 talkgadget_prefix_)); | 819 talkgadget_prefix_)); |
| 806 | 820 |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 870 | 884 |
| 871 if (status_service_) | 885 if (status_service_) |
| 872 status_service_->SetHostIsUp(host_id_); | 886 status_service_->SetHostIsUp(host_id_); |
| 873 | 887 |
| 874 host_->Start(xmpp_login_); | 888 host_->Start(xmpp_login_); |
| 875 | 889 |
| 876 CreateAuthenticatorFactory(); | 890 CreateAuthenticatorFactory(); |
| 877 } | 891 } |
| 878 | 892 |
| 879 void HostProcess::OnAuthFailed() { | 893 void HostProcess::OnAuthFailed() { |
| 880 Shutdown(kInvalidOauthCredentialsExitCode); | 894 ShutdownHost(kInvalidOauthCredentialsExitCode); |
| 881 } | 895 } |
| 882 | 896 |
| 883 void HostProcess::RejectAuthenticatingClient() { | 897 void HostProcess::RejectAuthenticatingClient() { |
| 884 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 898 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
| 885 DCHECK(host_); | 899 DCHECK(host_); |
| 886 host_->RejectAuthenticatingClient(); | 900 host_->RejectAuthenticatingClient(); |
| 887 } | 901 } |
| 888 | 902 |
| 889 // Invoked when the user uses the Disconnect windows to terminate | 903 // Invoked when the user uses the Disconnect windows to terminate |
| 890 // the sessions, or when the local session is activated in curtain mode. | 904 // the sessions, or when the local session is activated in curtain mode. |
| 891 void HostProcess::OnDisconnectRequested() { | 905 void HostProcess::OnDisconnectRequested() { |
| 892 if (!context_->network_task_runner()->BelongsToCurrentThread()) { | 906 if (!context_->network_task_runner()->BelongsToCurrentThread()) { |
| 893 context_->network_task_runner()->PostTask(FROM_HERE, base::Bind( | 907 context_->network_task_runner()->PostTask(FROM_HERE, base::Bind( |
| 894 &HostProcess::OnDisconnectRequested, base::Unretained(this))); | 908 &HostProcess::OnDisconnectRequested, base::Unretained(this))); |
| 895 return; | 909 return; |
| 896 } | 910 } |
| 897 if (host_) { | 911 if (host_) { |
| 898 host_->DisconnectAllClients(); | 912 host_->DisconnectAllClients(); |
| 899 } | 913 } |
| 900 } | 914 } |
| 901 | 915 |
| 902 void HostProcess::RestartHost() { | 916 void HostProcess::RestartHost() { |
| 903 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 917 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
| 918 DCHECK_EQ(state_, HOST_STARTED); | |
| 904 | 919 |
| 905 if (restarting_ || shutting_down_) | 920 state_ = HOST_STOPPING_TO_RESTART; |
| 906 return; | |
| 907 | |
| 908 restarting_ = true; | |
| 909 host_->Shutdown(base::Bind( | 921 host_->Shutdown(base::Bind( |
| 910 &HostProcess::RestartOnHostShutdown, base::Unretained(this))); | 922 &HostProcess::OnShutdownFinished, base::Unretained(this))); |
| 911 } | 923 } |
| 912 | 924 |
| 913 void HostProcess::RestartOnHostShutdown() { | 925 void HostProcess::ShutdownHost(int exit_code) { |
| 914 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 926 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
| 915 | 927 |
| 916 if (shutting_down_) | 928 exit_code_ = exit_code; |
| 917 return; | |
| 918 | 929 |
| 919 restarting_ = false; | 930 switch (state_) { |
| 920 host_ = NULL; | 931 case HOST_INITIALIZING: |
| 921 ResetHost(); | 932 state_ = HOST_STOPPED; |
| 933 OnShutdownFinished(); | |
| 934 break; | |
| 922 | 935 |
| 923 StartHost(); | 936 case HOST_STARTED: |
| 924 } | 937 if (status_service_) |
| 938 status_service_->SetHostIsDown(); | |
| 939 host_->Shutdown(base::Bind( | |
| 940 &HostProcess::OnShutdownFinished, base::Unretained(this))); | |
| 941 state_ = HOST_STOPPING; | |
| 942 break; | |
| 925 | 943 |
| 926 void HostProcess::Shutdown(int exit_code) { | 944 case HOST_STOPPING_TO_RESTART: |
| 927 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 945 state_ = HOST_STOPPING; |
| 946 break; | |
| 928 | 947 |
| 929 if (shutting_down_) | 948 case HOST_STOPPING: |
| 930 return; | 949 case HOST_STOPPED: |
| 931 | 950 // Host is already stopped or being stopped. No action is required. |
| 932 if (status_service_) | 951 break; |
| 933 status_service_->SetHostIsDown(); | |
| 934 | |
| 935 shutting_down_ = true; | |
| 936 exit_code_ = exit_code; | |
| 937 if (host_) { | |
| 938 host_->Shutdown(base::Bind( | |
| 939 &HostProcess::OnShutdownFinished, base::Unretained(this))); | |
| 940 } else { | |
| 941 OnShutdownFinished(); | |
| 942 } | 952 } |
| 943 } | 953 } |
| 944 | 954 |
| 945 void HostProcess::OnShutdownFinished() { | 955 void HostProcess::OnShutdownFinished() { |
| 946 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | 956 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); |
| 947 | 957 |
| 948 // Destroy networking objects while we are on the network thread. | |
| 949 host_ = NULL; | 958 host_ = NULL; |
| 950 ResetHost(); | |
| 951 | |
| 952 if (policy_watcher_.get()) { | |
| 953 base::WaitableEvent done_event(true, false); | |
| 954 policy_watcher_->StopWatching(&done_event); | |
| 955 done_event.Wait(); | |
| 956 policy_watcher_.reset(); | |
| 957 } | |
| 958 | |
| 959 status_service_.reset(); | |
| 960 | |
| 961 // Complete the rest of shutdown on the main thread. | |
| 962 context_->ui_task_runner()->PostTask( | |
| 963 FROM_HERE, | |
| 964 base::Bind(&HostProcess::ShutdownHostProcess, | |
| 965 base::Unretained(this))); | |
| 966 } | |
| 967 | |
| 968 void HostProcess::ResetHost() { | |
| 969 DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); | |
| 970 | |
| 971 curtaining_host_observer_.reset(); | 959 curtaining_host_observer_.reset(); |
| 972 host_event_logger_.reset(); | 960 host_event_logger_.reset(); |
| 973 log_to_server_.reset(); | 961 log_to_server_.reset(); |
| 974 heartbeat_sender_.reset(); | 962 heartbeat_sender_.reset(); |
| 975 signaling_connector_.reset(); | 963 signaling_connector_.reset(); |
| 976 signal_strategy_.reset(); | 964 signal_strategy_.reset(); |
| 977 resizing_host_observer_.reset(); | 965 resizing_host_observer_.reset(); |
| 966 | |
| 967 if (state_ == HOST_STOPPING_TO_RESTART) { | |
| 968 StartHost(); | |
| 969 } else if (state_ == HOST_STOPPING) { | |
| 970 state_ = HOST_STOPPED; | |
| 971 | |
| 972 if (policy_watcher_.get()) { | |
| 973 base::WaitableEvent done_event(true, false); | |
| 974 policy_watcher_->StopWatching(&done_event); | |
| 975 done_event.Wait(); | |
| 976 policy_watcher_.reset(); | |
| 977 } | |
| 978 | |
| 979 config_watcher_.reset(); | |
| 980 | |
|
alexeypa (please no reviews)
2012/11/21 23:53:48
nit: remove the empty line. Or two.
Sergey Ulanov
2012/11/27 01:04:38
Done.
| |
| 981 | |
| 982 status_service_.reset(); | |
| 983 | |
| 984 // Complete the rest of shutdown on the main thread. | |
| 985 context_->ui_task_runner()->PostTask( | |
| 986 FROM_HERE, | |
| 987 base::Bind(&HostProcess::ShutdownHostProcess, | |
| 988 base::Unretained(this))); | |
| 989 } else { | |
| 990 // This method is used as a callback for ChromotingHost::Shutdown() which is | |
| 991 // called only in STOPPING_TO_RESTART and STOPPING states. | |
| 992 NOTREACHED(); | |
| 993 } | |
| 978 } | 994 } |
| 979 | 995 |
| 980 void HostProcess::OnCrash(const std::string& function_name, | 996 void HostProcess::OnCrash(const std::string& function_name, |
| 981 const std::string& file_name, | 997 const std::string& file_name, |
| 982 const int& line_number) { | 998 const int& line_number) { |
| 983 CHECK(false); | 999 CHECK(false); |
| 984 } | 1000 } |
| 985 | 1001 |
| 986 } // namespace remoting | 1002 } // namespace remoting |
| 987 | 1003 |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1068 user32.GetFunctionPointer("SetProcessDPIAware")); | 1084 user32.GetFunctionPointer("SetProcessDPIAware")); |
| 1069 set_process_dpi_aware(); | 1085 set_process_dpi_aware(); |
| 1070 } | 1086 } |
| 1071 | 1087 |
| 1072 // CommandLine::Init() ignores the passed |argc| and |argv| on Windows getting | 1088 // CommandLine::Init() ignores the passed |argc| and |argv| on Windows getting |
| 1073 // the command line from GetCommandLineW(), so we can safely pass NULL here. | 1089 // the command line from GetCommandLineW(), so we can safely pass NULL here. |
| 1074 return main(0, NULL); | 1090 return main(0, NULL); |
| 1075 } | 1091 } |
| 1076 | 1092 |
| 1077 #endif // defined(OS_WIN) | 1093 #endif // defined(OS_WIN) |
| OLD | NEW |