| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "remoting/host/chromoting_host.h" | 5 #include "remoting/host/chromoting_host.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/callback.h" | 8 #include "base/callback.h" |
| 9 #include "build/build_config.h" | 9 #include "build/build_config.h" |
| 10 #include "remoting/base/constants.h" | 10 #include "remoting/base/constants.h" |
| 11 #include "remoting/base/encoder.h" | 11 #include "remoting/base/encoder.h" |
| 12 #include "remoting/base/encoder_row_based.h" | 12 #include "remoting/base/encoder_row_based.h" |
| 13 #include "remoting/base/encoder_vp8.h" | 13 #include "remoting/base/encoder_vp8.h" |
| 14 #include "remoting/host/capturer.h" | |
| 15 #include "remoting/host/chromoting_host_context.h" | 14 #include "remoting/host/chromoting_host_context.h" |
| 16 #include "remoting/host/continue_window.h" | |
| 17 #include "remoting/host/curtain.h" | 15 #include "remoting/host/curtain.h" |
| 18 #include "remoting/host/desktop_environment.h" | 16 #include "remoting/host/desktop_environment.h" |
| 19 #include "remoting/host/disconnect_window.h" | |
| 20 #include "remoting/host/event_executor.h" | 17 #include "remoting/host/event_executor.h" |
| 21 #include "remoting/host/host_config.h" | 18 #include "remoting/host/host_config.h" |
| 22 #include "remoting/host/host_key_pair.h" | 19 #include "remoting/host/host_key_pair.h" |
| 23 #include "remoting/host/local_input_monitor.h" | |
| 24 #include "remoting/host/screen_recorder.h" | 20 #include "remoting/host/screen_recorder.h" |
| 25 #include "remoting/host/user_authenticator.h" | 21 #include "remoting/host/user_authenticator.h" |
| 26 #include "remoting/jingle_glue/xmpp_signal_strategy.h" | 22 #include "remoting/jingle_glue/xmpp_signal_strategy.h" |
| 27 #include "remoting/proto/auth.pb.h" | 23 #include "remoting/proto/auth.pb.h" |
| 28 #include "remoting/protocol/connection_to_client.h" | 24 #include "remoting/protocol/connection_to_client.h" |
| 29 #include "remoting/protocol/client_stub.h" | 25 #include "remoting/protocol/client_stub.h" |
| 30 #include "remoting/protocol/host_stub.h" | 26 #include "remoting/protocol/host_stub.h" |
| 31 #include "remoting/protocol/input_stub.h" | 27 #include "remoting/protocol/input_stub.h" |
| 32 #include "remoting/protocol/jingle_session_manager.h" | 28 #include "remoting/protocol/jingle_session_manager.h" |
| 33 #include "remoting/protocol/session_config.h" | 29 #include "remoting/protocol/session_config.h" |
| 34 | 30 |
| 35 using remoting::protocol::ConnectionToClient; | 31 using remoting::protocol::ConnectionToClient; |
| 36 using remoting::protocol::InputStub; | 32 using remoting::protocol::InputStub; |
| 37 | 33 |
| 38 static const int kContinueWindowTimeoutSecs = 10 * 60; | |
| 39 | |
| 40 namespace remoting { | 34 namespace remoting { |
| 41 | 35 |
| 42 // static | 36 // static |
| 43 ChromotingHost* ChromotingHost::Create(ChromotingHostContext* context, | 37 ChromotingHost* ChromotingHost::Create(ChromotingHostContext* context, |
| 44 MutableHostConfig* config, | 38 MutableHostConfig* config, |
| 45 AccessVerifier* access_verifier) { | 39 AccessVerifier* access_verifier) { |
| 46 Capturer* capturer = Capturer::Create(); | 40 DesktopEnvironment* desktop_env = DesktopEnvironment::Create(context); |
| 47 EventExecutor* event_executor = | 41 return Create(context, config, desktop_env, access_verifier); |
| 48 EventExecutor::Create(context->desktop_message_loop(), capturer); | |
| 49 Curtain* curtain = Curtain::Create(); | |
| 50 DisconnectWindow* disconnect_window = DisconnectWindow::Create(); | |
| 51 ContinueWindow* continue_window = ContinueWindow::Create(); | |
| 52 LocalInputMonitor* local_input_monitor = LocalInputMonitor::Create(); | |
| 53 return Create(context, config, | |
| 54 new DesktopEnvironment(capturer, event_executor, curtain, | |
| 55 disconnect_window, continue_window, | |
| 56 local_input_monitor), | |
| 57 access_verifier); | |
| 58 } | 42 } |
| 59 | 43 |
| 60 // static | 44 // static |
| 61 ChromotingHost* ChromotingHost::Create(ChromotingHostContext* context, | 45 ChromotingHost* ChromotingHost::Create(ChromotingHostContext* context, |
| 62 MutableHostConfig* config, | 46 MutableHostConfig* config, |
| 63 DesktopEnvironment* environment, | 47 DesktopEnvironment* environment, |
| 64 AccessVerifier* access_verifier) { | 48 AccessVerifier* access_verifier) { |
| 65 return new ChromotingHost(context, config, environment, access_verifier); | 49 return new ChromotingHost(context, config, environment, access_verifier); |
| 66 } | 50 } |
| 67 | 51 |
| 68 ChromotingHost::ChromotingHost(ChromotingHostContext* context, | 52 ChromotingHost::ChromotingHost(ChromotingHostContext* context, |
| 69 MutableHostConfig* config, | 53 MutableHostConfig* config, |
| 70 DesktopEnvironment* environment, | 54 DesktopEnvironment* environment, |
| 71 AccessVerifier* access_verifier) | 55 AccessVerifier* access_verifier) |
| 72 : context_(context), | 56 : context_(context), |
| 73 config_(config), | 57 config_(config), |
| 74 desktop_environment_(environment), | 58 desktop_environment_(environment), |
| 75 access_verifier_(access_verifier), | 59 access_verifier_(access_verifier), |
| 76 state_(kInitial), | 60 state_(kInitial), |
| 77 protocol_config_(protocol::CandidateSessionConfig::CreateDefault()), | 61 protocol_config_(protocol::CandidateSessionConfig::CreateDefault()), |
| 78 is_curtained_(false), | 62 is_curtained_(false), |
| 79 is_monitoring_local_inputs_(false), | |
| 80 is_it2me_(false) { | 63 is_it2me_(false) { |
| 81 DCHECK(desktop_environment_.get()); | 64 DCHECK(desktop_environment_.get()); |
| 65 desktop_environment_->set_host(this); |
| 82 } | 66 } |
| 83 | 67 |
| 84 ChromotingHost::~ChromotingHost() { | 68 ChromotingHost::~ChromotingHost() { |
| 85 } | 69 } |
| 86 | 70 |
| 87 void ChromotingHost::Start() { | 71 void ChromotingHost::Start() { |
| 88 if (MessageLoop::current() != context_->network_message_loop()) { | 72 if (MessageLoop::current() != context_->network_message_loop()) { |
| 89 context_->network_message_loop()->PostTask( | 73 context_->network_message_loop()->PostTask( |
| 90 FROM_HERE, base::Bind(&ChromotingHost::Start, this)); | 74 FROM_HERE, base::Bind(&ChromotingHost::Start, this)); |
| 91 return; | 75 return; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 143 if (state_ == kStopping) | 127 if (state_ == kStopping) |
| 144 return; | 128 return; |
| 145 state_ = kStopping; | 129 state_ = kStopping; |
| 146 } | 130 } |
| 147 | 131 |
| 148 // Make sure ScreenRecorder doesn't write to the connection. | 132 // Make sure ScreenRecorder doesn't write to the connection. |
| 149 if (recorder_.get()) { | 133 if (recorder_.get()) { |
| 150 recorder_->RemoveAllConnections(); | 134 recorder_->RemoveAllConnections(); |
| 151 } | 135 } |
| 152 | 136 |
| 153 // Stop local inputs monitor. | 137 // Stop all desktop interaction. |
| 154 MonitorLocalInputs(false); | 138 desktop_environment_->OnLastDisconnect(); |
| 155 | 139 |
| 156 // Disconnect the clients. | 140 // Disconnect the clients. |
| 157 for (size_t i = 0; i < clients_.size(); i++) { | 141 for (size_t i = 0; i < clients_.size(); i++) { |
| 158 clients_[i]->Disconnect(); | 142 clients_[i]->Disconnect(); |
| 159 } | 143 } |
| 160 clients_.clear(); | 144 clients_.clear(); |
| 161 | 145 |
| 162 ShutdownNetwork(); | 146 ShutdownNetwork(); |
| 163 } | 147 } |
| 164 | 148 |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 355 FROM_HERE, | 339 FROM_HERE, |
| 356 NewRunnableMethod(this, | 340 NewRunnableMethod(this, |
| 357 &ChromotingHost::PauseSession, | 341 &ChromotingHost::PauseSession, |
| 358 pause)); | 342 pause)); |
| 359 return; | 343 return; |
| 360 } | 344 } |
| 361 ClientList::iterator client; | 345 ClientList::iterator client; |
| 362 for (client = clients_.begin(); client != clients_.end(); ++client) { | 346 for (client = clients_.begin(); client != clients_.end(); ++client) { |
| 363 client->get()->set_awaiting_continue_approval(pause); | 347 client->get()->set_awaiting_continue_approval(pause); |
| 364 } | 348 } |
| 365 StartContinueWindowTimer(!pause); | 349 desktop_environment_->OnPause(!pause); |
| 366 } | 350 } |
| 367 | 351 |
| 368 void ChromotingHost::OnClientDisconnected(ConnectionToClient* connection) { | 352 void ChromotingHost::OnClientDisconnected(ConnectionToClient* connection) { |
| 369 DCHECK_EQ(context_->main_message_loop(), MessageLoop::current()); | 353 DCHECK_EQ(context_->main_message_loop(), MessageLoop::current()); |
| 370 | 354 |
| 371 // Find the client session corresponding to the given connection. | 355 // Find the client session corresponding to the given connection. |
| 372 ClientList::iterator client; | 356 ClientList::iterator client; |
| 373 for (client = clients_.begin(); client != clients_.end(); ++client) { | 357 for (client = clients_.begin(); client != clients_.end(); ++client) { |
| 374 if (client->get()->connection() == connection) | 358 if (client->get()->connection() == connection) |
| 375 break; | 359 break; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 402 for (StatusObserverList::iterator it = status_observers_.begin(); | 386 for (StatusObserverList::iterator it = status_observers_.begin(); |
| 403 it != status_observers_.end(); ++it) { | 387 it != status_observers_.end(); ++it) { |
| 404 (*it)->OnAuthenticatedClientsChanged(authenticated_clients); | 388 (*it)->OnAuthenticatedClientsChanged(authenticated_clients); |
| 405 } | 389 } |
| 406 } | 390 } |
| 407 | 391 |
| 408 // Disable the "curtain" if there are no more active clients. | 392 // Disable the "curtain" if there are no more active clients. |
| 409 if (AuthenticatedClientsCount() == 0) { | 393 if (AuthenticatedClientsCount() == 0) { |
| 410 EnableCurtainMode(false); | 394 EnableCurtainMode(false); |
| 411 if (is_it2me_) { | 395 if (is_it2me_) { |
| 412 MonitorLocalInputs(false); | 396 desktop_environment_->OnLastDisconnect(); |
| 413 ShowDisconnectWindow(false, std::string()); | |
| 414 ShowContinueWindow(false); | |
| 415 StartContinueWindowTimer(false); | |
| 416 } | 397 } |
| 417 } | 398 } |
| 418 } | 399 } |
| 419 | 400 |
| 420 // TODO(sergeyu): Move this to SessionManager? | 401 // TODO(sergeyu): Move this to SessionManager? |
| 421 Encoder* ChromotingHost::CreateEncoder(const protocol::SessionConfig* config) { | 402 Encoder* ChromotingHost::CreateEncoder(const protocol::SessionConfig* config) { |
| 422 const protocol::ChannelConfig& video_config = config->video_config(); | 403 const protocol::ChannelConfig& video_config = config->video_config(); |
| 423 | 404 |
| 424 if (video_config.codec == protocol::ChannelConfig::CODEC_VERBATIM) { | 405 if (video_config.codec == protocol::ChannelConfig::CODEC_VERBATIM) { |
| 425 return EncoderRowBased::CreateVerbatimEncoder(); | 406 return EncoderRowBased::CreateVerbatimEncoder(); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 455 void ChromotingHost::EnableCurtainMode(bool enable) { | 436 void ChromotingHost::EnableCurtainMode(bool enable) { |
| 456 // TODO(jamiewalch): This will need to be more sophisticated when we think | 437 // TODO(jamiewalch): This will need to be more sophisticated when we think |
| 457 // about proper crash recovery and daemon mode. | 438 // about proper crash recovery and daemon mode. |
| 458 // TODO(wez): CurtainMode shouldn't be driven directly by ChromotingHost. | 439 // TODO(wez): CurtainMode shouldn't be driven directly by ChromotingHost. |
| 459 if (is_it2me_ || enable == is_curtained_) | 440 if (is_it2me_ || enable == is_curtained_) |
| 460 return; | 441 return; |
| 461 desktop_environment_->curtain()->EnableCurtainMode(enable); | 442 desktop_environment_->curtain()->EnableCurtainMode(enable); |
| 462 is_curtained_ = enable; | 443 is_curtained_ = enable; |
| 463 } | 444 } |
| 464 | 445 |
| 465 void ChromotingHost::MonitorLocalInputs(bool enable) { | |
| 466 if (enable == is_monitoring_local_inputs_) | |
| 467 return; | |
| 468 if (enable) { | |
| 469 desktop_environment_->local_input_monitor()->Start(this); | |
| 470 } else { | |
| 471 desktop_environment_->local_input_monitor()->Stop(); | |
| 472 } | |
| 473 is_monitoring_local_inputs_ = enable; | |
| 474 } | |
| 475 | |
| 476 void ChromotingHost::LocalLoginSucceeded( | 446 void ChromotingHost::LocalLoginSucceeded( |
| 477 scoped_refptr<ConnectionToClient> connection) { | 447 scoped_refptr<ConnectionToClient> connection) { |
| 478 if (MessageLoop::current() != context_->main_message_loop()) { | 448 if (MessageLoop::current() != context_->main_message_loop()) { |
| 479 context_->main_message_loop()->PostTask( | 449 context_->main_message_loop()->PostTask( |
| 480 FROM_HERE, base::Bind(&ChromotingHost::LocalLoginSucceeded, this, | 450 FROM_HERE, base::Bind(&ChromotingHost::LocalLoginSucceeded, this, |
| 481 connection)); | 451 connection)); |
| 482 return; | 452 return; |
| 483 } | 453 } |
| 484 | 454 |
| 485 protocol::LocalLoginStatus* status = new protocol::LocalLoginStatus(); | 455 protocol::LocalLoginStatus* status = new protocol::LocalLoginStatus(); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 514 encoder); | 484 encoder); |
| 515 } | 485 } |
| 516 | 486 |
| 517 // Immediately add the connection and start the session. | 487 // Immediately add the connection and start the session. |
| 518 recorder_->AddConnection(connection); | 488 recorder_->AddConnection(connection); |
| 519 recorder_->Start(); | 489 recorder_->Start(); |
| 520 // TODO(jamiewalch): Tidy up actions to be taken on connect/disconnect, | 490 // TODO(jamiewalch): Tidy up actions to be taken on connect/disconnect, |
| 521 // including closing the connection on failure of a critical operation. | 491 // including closing the connection on failure of a critical operation. |
| 522 EnableCurtainMode(true); | 492 EnableCurtainMode(true); |
| 523 if (is_it2me_) { | 493 if (is_it2me_) { |
| 524 MonitorLocalInputs(true); | |
| 525 std::string username = connection->session()->jid(); | 494 std::string username = connection->session()->jid(); |
| 526 size_t pos = username.find('/'); | 495 size_t pos = username.find('/'); |
| 527 if (pos != std::string::npos) | 496 if (pos != std::string::npos) |
| 528 username.replace(pos, std::string::npos, ""); | 497 username.replace(pos, std::string::npos, ""); |
| 529 ShowDisconnectWindow(true, username); | 498 desktop_environment_->OnConnect(username); |
| 530 StartContinueWindowTimer(true); | |
| 531 } | 499 } |
| 532 | 500 |
| 533 // Notify observers that there is at least one authenticated client. | 501 // Notify observers that there is at least one authenticated client. |
| 534 for (StatusObserverList::iterator it = status_observers_.begin(); | 502 for (StatusObserverList::iterator it = status_observers_.begin(); |
| 535 it != status_observers_.end(); ++it) { | 503 it != status_observers_.end(); ++it) { |
| 536 (*it)->OnAuthenticatedClientsChanged(AuthenticatedClientsCount()); | 504 (*it)->OnAuthenticatedClientsChanged(AuthenticatedClientsCount()); |
| 537 } | 505 } |
| 538 } | 506 } |
| 539 | 507 |
| 540 void ChromotingHost::LocalLoginFailed( | 508 void ChromotingHost::LocalLoginFailed( |
| (...skipping 17 matching lines...) Expand all Loading... |
| 558 // Find the client session corresponding to the given connection. | 526 // Find the client session corresponding to the given connection. |
| 559 ClientList::iterator client; | 527 ClientList::iterator client; |
| 560 for (client = clients_.begin(); client != clients_.end(); ++client) { | 528 for (client = clients_.begin(); client != clients_.end(); ++client) { |
| 561 if (client->get()->connection() == connection) | 529 if (client->get()->connection() == connection) |
| 562 break; | 530 break; |
| 563 } | 531 } |
| 564 CHECK(client != clients_.end()); | 532 CHECK(client != clients_.end()); |
| 565 client->get()->OnAuthorizationComplete(true); | 533 client->get()->OnAuthorizationComplete(true); |
| 566 } | 534 } |
| 567 | 535 |
| 568 void ChromotingHost::ShowDisconnectWindow(bool show, | |
| 569 const std::string& username) { | |
| 570 if (!context_->IsUIThread()) { | |
| 571 context_->PostToUIThread( | |
| 572 FROM_HERE, | |
| 573 NewRunnableMethod(this, &ChromotingHost::ShowDisconnectWindow, | |
| 574 show, username)); | |
| 575 return; | |
| 576 } | |
| 577 | |
| 578 if (show) { | |
| 579 desktop_environment_->disconnect_window()->Show(this, username); | |
| 580 } else { | |
| 581 desktop_environment_->disconnect_window()->Hide(); | |
| 582 } | |
| 583 } | |
| 584 | |
| 585 void ChromotingHost::ShowContinueWindow(bool show) { | |
| 586 if (!context_->IsUIThread()) { | |
| 587 context_->PostToUIThread( | |
| 588 FROM_HERE, | |
| 589 NewRunnableMethod(this, &ChromotingHost::ShowContinueWindow, show)); | |
| 590 return; | |
| 591 } | |
| 592 | |
| 593 if (show) { | |
| 594 desktop_environment_->continue_window()->Show(this); | |
| 595 } else { | |
| 596 desktop_environment_->continue_window()->Hide(); | |
| 597 } | |
| 598 } | |
| 599 | |
| 600 void ChromotingHost::StartContinueWindowTimer(bool start) { | |
| 601 if (context_->main_message_loop() != MessageLoop::current()) { | |
| 602 context_->main_message_loop()->PostTask( | |
| 603 FROM_HERE, | |
| 604 NewRunnableMethod(this, | |
| 605 &ChromotingHost::StartContinueWindowTimer, | |
| 606 start)); | |
| 607 return; | |
| 608 } | |
| 609 if (continue_window_timer_.IsRunning() == start) | |
| 610 return; | |
| 611 if (start) { | |
| 612 continue_window_timer_.Start( | |
| 613 base::TimeDelta::FromSeconds(kContinueWindowTimeoutSecs), | |
| 614 this, &ChromotingHost::ContinueWindowTimerFunc); | |
| 615 } else { | |
| 616 continue_window_timer_.Stop(); | |
| 617 } | |
| 618 } | |
| 619 | |
| 620 void ChromotingHost::ContinueWindowTimerFunc() { | |
| 621 PauseSession(true); | |
| 622 ShowContinueWindow(true); | |
| 623 } | |
| 624 | |
| 625 void ChromotingHost::ShutdownNetwork() { | 536 void ChromotingHost::ShutdownNetwork() { |
| 626 if (MessageLoop::current() != context_->network_message_loop()) { | 537 if (MessageLoop::current() != context_->network_message_loop()) { |
| 627 context_->network_message_loop()->PostTask( | 538 context_->network_message_loop()->PostTask( |
| 628 FROM_HERE, base::Bind(&ChromotingHost::ShutdownNetwork, this)); | 539 FROM_HERE, base::Bind(&ChromotingHost::ShutdownNetwork, this)); |
| 629 return; | 540 return; |
| 630 } | 541 } |
| 631 | 542 |
| 632 // Stop chromotocol session manager. | 543 // Stop chromotocol session manager. |
| 633 if (session_manager_.get()) { | 544 if (session_manager_.get()) { |
| 634 session_manager_->Close(); | 545 session_manager_->Close(); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 683 | 594 |
| 684 for (std::vector<Task*>::iterator it = shutdown_tasks_.begin(); | 595 for (std::vector<Task*>::iterator it = shutdown_tasks_.begin(); |
| 685 it != shutdown_tasks_.end(); ++it) { | 596 it != shutdown_tasks_.end(); ++it) { |
| 686 (*it)->Run(); | 597 (*it)->Run(); |
| 687 delete *it; | 598 delete *it; |
| 688 } | 599 } |
| 689 shutdown_tasks_.clear(); | 600 shutdown_tasks_.clear(); |
| 690 } | 601 } |
| 691 | 602 |
| 692 } // namespace remoting | 603 } // namespace remoting |
| OLD | NEW |