| 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 // Stop chromotocol session manager. | 146 // Stop chromotocol session manager. |
| 163 if (session_manager_.get()) { | 147 if (session_manager_.get()) { |
| 164 session_manager_->Close(); | 148 session_manager_->Close(); |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 372 FROM_HERE, | 356 FROM_HERE, |
| 373 NewRunnableMethod(this, | 357 NewRunnableMethod(this, |
| 374 &ChromotingHost::PauseSession, | 358 &ChromotingHost::PauseSession, |
| 375 pause)); | 359 pause)); |
| 376 return; | 360 return; |
| 377 } | 361 } |
| 378 ClientList::iterator client; | 362 ClientList::iterator client; |
| 379 for (client = clients_.begin(); client != clients_.end(); ++client) { | 363 for (client = clients_.begin(); client != clients_.end(); ++client) { |
| 380 client->get()->set_awaiting_continue_approval(pause); | 364 client->get()->set_awaiting_continue_approval(pause); |
| 381 } | 365 } |
| 382 StartContinueWindowTimer(!pause); | 366 desktop_environment_->OnPause(!pause); |
| 383 } | 367 } |
| 384 | 368 |
| 385 void ChromotingHost::OnClientDisconnected(ConnectionToClient* connection) { | 369 void ChromotingHost::OnClientDisconnected(ConnectionToClient* connection) { |
| 386 DCHECK_EQ(context_->main_message_loop(), MessageLoop::current()); | 370 DCHECK_EQ(context_->main_message_loop(), MessageLoop::current()); |
| 387 | 371 |
| 388 // Find the client session corresponding to the given connection. | 372 // Find the client session corresponding to the given connection. |
| 389 ClientList::iterator client; | 373 ClientList::iterator client; |
| 390 for (client = clients_.begin(); client != clients_.end(); ++client) { | 374 for (client = clients_.begin(); client != clients_.end(); ++client) { |
| 391 if (client->get()->connection() == connection) | 375 if (client->get()->connection() == connection) |
| 392 break; | 376 break; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 419 for (StatusObserverList::iterator it = status_observers_.begin(); | 403 for (StatusObserverList::iterator it = status_observers_.begin(); |
| 420 it != status_observers_.end(); ++it) { | 404 it != status_observers_.end(); ++it) { |
| 421 (*it)->OnAuthenticatedClientsChanged(authenticated_clients); | 405 (*it)->OnAuthenticatedClientsChanged(authenticated_clients); |
| 422 } | 406 } |
| 423 } | 407 } |
| 424 | 408 |
| 425 // Disable the "curtain" if there are no more active clients. | 409 // Disable the "curtain" if there are no more active clients. |
| 426 if (AuthenticatedClientsCount() == 0) { | 410 if (AuthenticatedClientsCount() == 0) { |
| 427 EnableCurtainMode(false); | 411 EnableCurtainMode(false); |
| 428 if (is_it2me_) { | 412 if (is_it2me_) { |
| 429 MonitorLocalInputs(false); | 413 desktop_environment_->OnLastDisconnect(); |
| 430 ShowDisconnectWindow(false, std::string()); | |
| 431 ShowContinueWindow(false); | |
| 432 StartContinueWindowTimer(false); | |
| 433 } | 414 } |
| 434 } | 415 } |
| 435 } | 416 } |
| 436 | 417 |
| 437 // TODO(sergeyu): Move this to SessionManager? | 418 // TODO(sergeyu): Move this to SessionManager? |
| 438 Encoder* ChromotingHost::CreateEncoder(const protocol::SessionConfig* config) { | 419 Encoder* ChromotingHost::CreateEncoder(const protocol::SessionConfig* config) { |
| 439 const protocol::ChannelConfig& video_config = config->video_config(); | 420 const protocol::ChannelConfig& video_config = config->video_config(); |
| 440 | 421 |
| 441 if (video_config.codec == protocol::ChannelConfig::CODEC_VERBATIM) { | 422 if (video_config.codec == protocol::ChannelConfig::CODEC_VERBATIM) { |
| 442 return EncoderRowBased::CreateVerbatimEncoder(); | 423 return EncoderRowBased::CreateVerbatimEncoder(); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 472 void ChromotingHost::EnableCurtainMode(bool enable) { | 453 void ChromotingHost::EnableCurtainMode(bool enable) { |
| 473 // TODO(jamiewalch): This will need to be more sophisticated when we think | 454 // TODO(jamiewalch): This will need to be more sophisticated when we think |
| 474 // about proper crash recovery and daemon mode. | 455 // about proper crash recovery and daemon mode. |
| 475 // TODO(wez): CurtainMode shouldn't be driven directly by ChromotingHost. | 456 // TODO(wez): CurtainMode shouldn't be driven directly by ChromotingHost. |
| 476 if (is_it2me_ || enable == is_curtained_) | 457 if (is_it2me_ || enable == is_curtained_) |
| 477 return; | 458 return; |
| 478 desktop_environment_->curtain()->EnableCurtainMode(enable); | 459 desktop_environment_->curtain()->EnableCurtainMode(enable); |
| 479 is_curtained_ = enable; | 460 is_curtained_ = enable; |
| 480 } | 461 } |
| 481 | 462 |
| 482 void ChromotingHost::MonitorLocalInputs(bool enable) { | |
| 483 if (enable == is_monitoring_local_inputs_) | |
| 484 return; | |
| 485 if (enable) { | |
| 486 desktop_environment_->local_input_monitor()->Start(this); | |
| 487 } else { | |
| 488 desktop_environment_->local_input_monitor()->Stop(); | |
| 489 } | |
| 490 is_monitoring_local_inputs_ = enable; | |
| 491 } | |
| 492 | |
| 493 void ChromotingHost::LocalLoginSucceeded( | 463 void ChromotingHost::LocalLoginSucceeded( |
| 494 scoped_refptr<ConnectionToClient> connection) { | 464 scoped_refptr<ConnectionToClient> connection) { |
| 495 if (MessageLoop::current() != context_->main_message_loop()) { | 465 if (MessageLoop::current() != context_->main_message_loop()) { |
| 496 context_->main_message_loop()->PostTask( | 466 context_->main_message_loop()->PostTask( |
| 497 FROM_HERE, base::Bind(&ChromotingHost::LocalLoginSucceeded, this, | 467 FROM_HERE, base::Bind(&ChromotingHost::LocalLoginSucceeded, this, |
| 498 connection)); | 468 connection)); |
| 499 return; | 469 return; |
| 500 } | 470 } |
| 501 | 471 |
| 502 protocol::LocalLoginStatus* status = new protocol::LocalLoginStatus(); | 472 protocol::LocalLoginStatus* status = new protocol::LocalLoginStatus(); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 531 encoder); | 501 encoder); |
| 532 } | 502 } |
| 533 | 503 |
| 534 // Immediately add the connection and start the session. | 504 // Immediately add the connection and start the session. |
| 535 recorder_->AddConnection(connection); | 505 recorder_->AddConnection(connection); |
| 536 recorder_->Start(); | 506 recorder_->Start(); |
| 537 // TODO(jamiewalch): Tidy up actions to be taken on connect/disconnect, | 507 // TODO(jamiewalch): Tidy up actions to be taken on connect/disconnect, |
| 538 // including closing the connection on failure of a critical operation. | 508 // including closing the connection on failure of a critical operation. |
| 539 EnableCurtainMode(true); | 509 EnableCurtainMode(true); |
| 540 if (is_it2me_) { | 510 if (is_it2me_) { |
| 541 MonitorLocalInputs(true); | |
| 542 std::string username = connection->session()->jid(); | 511 std::string username = connection->session()->jid(); |
| 543 size_t pos = username.find('/'); | 512 size_t pos = username.find('/'); |
| 544 if (pos != std::string::npos) | 513 if (pos != std::string::npos) |
| 545 username.replace(pos, std::string::npos, ""); | 514 username.replace(pos, std::string::npos, ""); |
| 546 ShowDisconnectWindow(true, username); | 515 desktop_environment_->OnConnect(username); |
| 547 StartContinueWindowTimer(true); | |
| 548 } | 516 } |
| 549 | 517 |
| 550 // Notify observers that there is at least one authenticated client. | 518 // Notify observers that there is at least one authenticated client. |
| 551 for (StatusObserverList::iterator it = status_observers_.begin(); | 519 for (StatusObserverList::iterator it = status_observers_.begin(); |
| 552 it != status_observers_.end(); ++it) { | 520 it != status_observers_.end(); ++it) { |
| 553 (*it)->OnAuthenticatedClientsChanged(AuthenticatedClientsCount()); | 521 (*it)->OnAuthenticatedClientsChanged(AuthenticatedClientsCount()); |
| 554 } | 522 } |
| 555 } | 523 } |
| 556 | 524 |
| 557 void ChromotingHost::LocalLoginFailed( | 525 void ChromotingHost::LocalLoginFailed( |
| (...skipping 17 matching lines...) Expand all Loading... |
| 575 // Find the client session corresponding to the given connection. | 543 // Find the client session corresponding to the given connection. |
| 576 ClientList::iterator client; | 544 ClientList::iterator client; |
| 577 for (client = clients_.begin(); client != clients_.end(); ++client) { | 545 for (client = clients_.begin(); client != clients_.end(); ++client) { |
| 578 if (client->get()->connection() == connection) | 546 if (client->get()->connection() == connection) |
| 579 break; | 547 break; |
| 580 } | 548 } |
| 581 CHECK(client != clients_.end()); | 549 CHECK(client != clients_.end()); |
| 582 client->get()->OnAuthorizationComplete(true); | 550 client->get()->OnAuthorizationComplete(true); |
| 583 } | 551 } |
| 584 | 552 |
| 585 void ChromotingHost::ShowDisconnectWindow(bool show, | |
| 586 const std::string& username) { | |
| 587 if (!context_->IsUIThread()) { | |
| 588 context_->PostToUIThread( | |
| 589 FROM_HERE, | |
| 590 NewRunnableMethod(this, &ChromotingHost::ShowDisconnectWindow, | |
| 591 show, username)); | |
| 592 return; | |
| 593 } | |
| 594 | |
| 595 if (show) { | |
| 596 desktop_environment_->disconnect_window()->Show(this, username); | |
| 597 } else { | |
| 598 desktop_environment_->disconnect_window()->Hide(); | |
| 599 } | |
| 600 } | |
| 601 | |
| 602 void ChromotingHost::ShowContinueWindow(bool show) { | |
| 603 if (!context_->IsUIThread()) { | |
| 604 context_->PostToUIThread( | |
| 605 FROM_HERE, | |
| 606 NewRunnableMethod(this, &ChromotingHost::ShowContinueWindow, show)); | |
| 607 return; | |
| 608 } | |
| 609 | |
| 610 if (show) { | |
| 611 desktop_environment_->continue_window()->Show(this); | |
| 612 } else { | |
| 613 desktop_environment_->continue_window()->Hide(); | |
| 614 } | |
| 615 } | |
| 616 | |
| 617 void ChromotingHost::StartContinueWindowTimer(bool start) { | |
| 618 if (context_->main_message_loop() != MessageLoop::current()) { | |
| 619 context_->main_message_loop()->PostTask( | |
| 620 FROM_HERE, | |
| 621 NewRunnableMethod(this, | |
| 622 &ChromotingHost::StartContinueWindowTimer, | |
| 623 start)); | |
| 624 return; | |
| 625 } | |
| 626 if (continue_window_timer_.IsRunning() == start) | |
| 627 return; | |
| 628 if (start) { | |
| 629 continue_window_timer_.Start( | |
| 630 base::TimeDelta::FromSeconds(kContinueWindowTimeoutSecs), | |
| 631 this, &ChromotingHost::ContinueWindowTimerFunc); | |
| 632 } else { | |
| 633 continue_window_timer_.Stop(); | |
| 634 } | |
| 635 } | |
| 636 | |
| 637 void ChromotingHost::ContinueWindowTimerFunc() { | |
| 638 PauseSession(true); | |
| 639 ShowContinueWindow(true); | |
| 640 } | |
| 641 | |
| 642 void ChromotingHost::ShutdownRecorder() { | 553 void ChromotingHost::ShutdownRecorder() { |
| 643 if (MessageLoop::current() != context_->main_message_loop()) { | 554 if (MessageLoop::current() != context_->main_message_loop()) { |
| 644 context_->main_message_loop()->PostTask( | 555 context_->main_message_loop()->PostTask( |
| 645 FROM_HERE, base::Bind(&ChromotingHost::ShutdownRecorder, this)); | 556 FROM_HERE, base::Bind(&ChromotingHost::ShutdownRecorder, this)); |
| 646 return; | 557 return; |
| 647 } | 558 } |
| 648 | 559 |
| 649 if (recorder_.get()) { | 560 if (recorder_.get()) { |
| 650 recorder_->Stop(NewRunnableMethod(this, &ChromotingHost::ShutdownFinish)); | 561 recorder_->Stop(NewRunnableMethod(this, &ChromotingHost::ShutdownFinish)); |
| 651 } else { | 562 } else { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 673 | 584 |
| 674 for (std::vector<Task*>::iterator it = shutdown_tasks_.begin(); | 585 for (std::vector<Task*>::iterator it = shutdown_tasks_.begin(); |
| 675 it != shutdown_tasks_.end(); ++it) { | 586 it != shutdown_tasks_.end(); ++it) { |
| 676 (*it)->Run(); | 587 (*it)->Run(); |
| 677 delete *it; | 588 delete *it; |
| 678 } | 589 } |
| 679 shutdown_tasks_.clear(); | 590 shutdown_tasks_.clear(); |
| 680 } | 591 } |
| 681 | 592 |
| 682 } // namespace remoting | 593 } // namespace remoting |
| OLD | NEW |