diff options
Diffstat (limited to 'remoting/host/chromoting_host.cc')
-rw-r--r-- | remoting/host/chromoting_host.cc | 157 |
1 files changed, 28 insertions, 129 deletions
diff --git a/remoting/host/chromoting_host.cc b/remoting/host/chromoting_host.cc index 7dae872..8540217 100644 --- a/remoting/host/chromoting_host.cc +++ b/remoting/host/chromoting_host.cc @@ -19,9 +19,9 @@ #include "remoting/host/audio_scheduler.h" #include "remoting/host/chromoting_host_context.h" #include "remoting/host/desktop_environment.h" +#include "remoting/host/desktop_environment_factory.h" #include "remoting/host/event_executor.h" #include "remoting/host/host_config.h" -#include "remoting/host/screen_recorder.h" #include "remoting/protocol/connection_to_client.h" #include "remoting/protocol/client_stub.h" #include "remoting/protocol/host_stub.h" @@ -66,13 +66,13 @@ const net::BackoffEntry::Policy kDefaultBackoffPolicy = { ChromotingHost::ChromotingHost( ChromotingHostContext* context, SignalStrategy* signal_strategy, - DesktopEnvironment* environment, + DesktopEnvironmentFactory* desktop_environment_factory, scoped_ptr<protocol::SessionManager> session_manager) : context_(context), - desktop_environment_(environment), + desktop_environment_factory_(desktop_environment_factory), session_manager_(session_manager.Pass()), signal_strategy_(signal_strategy), - stopping_recorders_(0), + clients_count_(0), state_(kInitial), protocol_config_(protocol::CandidateSessionConfig::CreateDefault()), login_backoff_(&kDefaultBackoffPolicy), @@ -80,10 +80,9 @@ ChromotingHost::ChromotingHost( reject_authenticating_client_(false) { DCHECK(context_); DCHECK(signal_strategy); - DCHECK(desktop_environment_); DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); - if (!desktop_environment_->audio_capturer()) { + if (!desktop_environment_factory_->SupportsAudioCapture()) { // Disable audio by replacing our list of supported audio configurations // with the NONE config. protocol_config_->mutable_audio_configs()->clear(); @@ -141,18 +140,15 @@ void ChromotingHost::Shutdown(const base::Closure& shutdown_task) { shutdown_tasks_.push_back(shutdown_task); state_ = kStopping; - // Disconnect all of the clients, implicitly stopping the ScreenRecorder. + // Disconnect all of the clients. while (!clients_.empty()) { clients_.front()->Disconnect(); } - DCHECK(!recorder_.get()); - DCHECK(!audio_scheduler_.get()); - // Destroy session manager. - session_manager_.reset(); - - if (!stopping_recorders_) + // Run the remaining shutdown tasks. + if (state_ == kStopping && !clients_count_) ShutdownFinish(); + break; } } @@ -203,8 +199,6 @@ void ChromotingHost::OnSessionAuthenticated(ClientSession* client) { // Disconnects above must have destroyed all other clients and |recorder_|. DCHECK_EQ(clients_.size(), 1U); - DCHECK(!recorder_.get()); - DCHECK(!audio_scheduler_.get()); // Notify observers that there is at least one authenticated client. const std::string& jid = client->client_jid(); @@ -224,32 +218,7 @@ void ChromotingHost::OnSessionAuthenticated(ClientSession* client) { void ChromotingHost::OnSessionChannelsConnected(ClientSession* client) { DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); - // Then we create a ScreenRecorder passing the message loops that - // it should run on. - VideoEncoder* video_encoder = - CreateVideoEncoder(client->connection()->session()->config()); - - recorder_ = new ScreenRecorder(context_->capture_task_runner(), - context_->encode_task_runner(), - context_->network_task_runner(), - desktop_environment_->capturer(), - video_encoder); - if (client->connection()->session()->config().is_audio_enabled()) { - scoped_ptr<AudioEncoder> audio_encoder = - CreateAudioEncoder(client->connection()->session()->config()); - audio_scheduler_ = new AudioScheduler( - context_->audio_task_runner(), - context_->network_task_runner(), - desktop_environment_->audio_capturer(), - audio_encoder.Pass(), - client->connection()->audio_stub()); - } - - // Immediately add the connection and start the session. - recorder_->AddConnection(client->connection()); - recorder_->Start(); - desktop_environment_->OnSessionStarted(client->CreateClipboardProxy()); - + // Notify observers. FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, OnClientConnected(client->client_jid())); } @@ -265,42 +234,21 @@ void ChromotingHost::OnSessionAuthenticationFailed(ClientSession* client) { void ChromotingHost::OnSessionClosed(ClientSession* client) { DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); - scoped_ptr<ClientSession> client_destroyer(client); - ClientList::iterator it = std::find(clients_.begin(), clients_.end(), client); CHECK(it != clients_.end()); clients_.erase(it); - if (recorder_.get()) { - recorder_->RemoveConnection(client->connection()); - } - - if (audio_scheduler_.get()) { - audio_scheduler_->OnClientDisconnected(); - StopAudioScheduler(); - } - if (client->is_authenticated()) { FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, OnClientDisconnected(client->client_jid())); - - // TODO(sergeyu): This teardown logic belongs to ClientSession - // class. It should start/stop screen recorder or tell the host - // when to do it. - if (recorder_.get()) { - // Currently we don't allow more than one simultaneous connection, - // so we need to shutdown recorder when a client disconnects. - StopScreenRecorder(); - } - desktop_environment_->OnSessionFinished(); } + + client->StopAndDelete(base::Bind(&ChromotingHost::OnClientStopped, this)); } void ChromotingHost::OnSessionSequenceNumber(ClientSession* session, int64 sequence_number) { DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); - if (recorder_.get()) - recorder_->UpdateSequenceNumber(sequence_number); } void ChromotingHost::OnSessionRouteChange( @@ -354,17 +302,23 @@ void ChromotingHost::OnIncomingSession( LOG(INFO) << "Client connected: " << session->jid(); + // Create the desktop integration implementation for the client to use. + scoped_ptr<DesktopEnvironment> desktop_environment = + desktop_environment_factory_->Create(context_); + // Create a client object. scoped_ptr<protocol::ConnectionToClient> connection( new protocol::ConnectionToClient(session)); ClientSession* client = new ClientSession( this, + context_->capture_task_runner(), + context_->encode_task_runner(), + context_->network_task_runner(), connection.Pass(), - desktop_environment_->event_executor(), - desktop_environment_->event_executor(), - desktop_environment_->capturer(), + desktop_environment.Pass(), max_session_duration_); clients_.push_back(client); + ++clients_count_; } void ChromotingHost::set_protocol_config( @@ -423,75 +377,20 @@ void ChromotingHost::SetUiStrings(const UiStrings& ui_strings) { ui_strings_ = ui_strings; } -// TODO(sergeyu): Move this to SessionManager? -// static -VideoEncoder* ChromotingHost::CreateVideoEncoder( - const protocol::SessionConfig& config) { - const protocol::ChannelConfig& video_config = config.video_config(); - - if (video_config.codec == protocol::ChannelConfig::CODEC_VERBATIM) { - return VideoEncoderRowBased::CreateVerbatimEncoder(); - } else if (video_config.codec == protocol::ChannelConfig::CODEC_ZIP) { - return VideoEncoderRowBased::CreateZlibEncoder(); - } else if (video_config.codec == protocol::ChannelConfig::CODEC_VP8) { - return new remoting::VideoEncoderVp8(); - } - - return NULL; -} - -// static -scoped_ptr<AudioEncoder> ChromotingHost::CreateAudioEncoder( - const protocol::SessionConfig& config) { - const protocol::ChannelConfig& audio_config = config.audio_config(); - - if (audio_config.codec == protocol::ChannelConfig::CODEC_VERBATIM) { - return scoped_ptr<AudioEncoder>(new AudioEncoderVerbatim()); - } else if (audio_config.codec == protocol::ChannelConfig::CODEC_SPEEX) { - return scoped_ptr<AudioEncoder>(new AudioEncoderSpeex()); - } - - NOTIMPLEMENTED(); - return scoped_ptr<AudioEncoder>(NULL); -} - -void ChromotingHost::StopScreenRecorder() { - DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); - DCHECK(recorder_.get()); - - ++stopping_recorders_; - scoped_refptr<ScreenRecorder> recorder = recorder_; - recorder_ = NULL; - recorder->Stop(base::Bind(&ChromotingHost::OnRecorderStopped, this)); -} - -void ChromotingHost::StopAudioScheduler() { +void ChromotingHost::OnClientStopped() { DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); - DCHECK(audio_scheduler_.get()); - ++stopping_recorders_; - scoped_refptr<AudioScheduler> recorder = audio_scheduler_; - audio_scheduler_ = NULL; - recorder->Stop(base::Bind(&ChromotingHost::OnRecorderStopped, this)); -} - -void ChromotingHost::OnRecorderStopped() { - if (!context_->network_task_runner()->BelongsToCurrentThread()) { - context_->network_task_runner()->PostTask( - FROM_HERE, base::Bind(&ChromotingHost::OnRecorderStopped, this)); - return; - } - - --stopping_recorders_; - DCHECK_GE(stopping_recorders_, 0); - - if (!stopping_recorders_ && state_ == kStopping) + --clients_count_; + if (state_ == kStopping && !clients_count_) ShutdownFinish(); } void ChromotingHost::ShutdownFinish() { DCHECK(context_->network_task_runner()->BelongsToCurrentThread()); - DCHECK(!stopping_recorders_); + DCHECK_EQ(state_, kStopping); + + // Destroy session manager. + session_manager_.reset(); state_ = kStopped; |