diff options
author | alexeypa@chromium.org <alexeypa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-01-16 17:23:53 +0000 |
---|---|---|
committer | alexeypa@chromium.org <alexeypa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-01-16 17:23:53 +0000 |
commit | ce404cae8c35d9c39b328e2f7207b852f482a15f (patch) | |
tree | 99624ecd8daa98c28eb35323aa465ca8819fd480 | |
parent | e921967a10108d9751709ff4f35abd67b49103f8 (diff) | |
download | chromium_src-ce404cae8c35d9c39b328e2f7207b852f482a15f.zip chromium_src-ce404cae8c35d9c39b328e2f7207b852f482a15f.tar.gz chromium_src-ce404cae8c35d9c39b328e2f7207b852f482a15f.tar.bz2 |
Making DesktopEnvironment a factory class used by ClientSession to create audio/video capturers and event executor for a pacticular desktop environment.
Other related changes:
- AudioCapturer and VideoFrameCapturer are owned by AudioScheduler and VideoScheduler correspondingly.
- Both AudioScheduler and VideoScheduler can now be stopped completely asynchronously.
- AudioScheduler::SetEnabled() changed to Pause() to match the corresponding method provided by VideoScheduler.
- ClientSession::Stop() is synchronous now.
BUG=104544
Review URL: https://chromiumcodereview.appspot.com/11778049
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@177161 0039d316-1c4b-4281-b951-d872f2087c98
33 files changed, 937 insertions, 809 deletions
diff --git a/remoting/host/audio_scheduler.cc b/remoting/host/audio_scheduler.cc index 38f1073..5d777d5 100644 --- a/remoting/host/audio_scheduler.cc +++ b/remoting/host/audio_scheduler.cc @@ -5,7 +5,6 @@ #include "remoting/host/audio_scheduler.h" #include "base/bind.h" -#include "base/callback.h" #include "base/location.h" #include "base/logging.h" #include "base/single_thread_task_runner.h" @@ -20,7 +19,7 @@ namespace remoting { scoped_refptr<AudioScheduler> AudioScheduler::Create( scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner, scoped_refptr<base::SingleThreadTaskRunner> network_task_runner, - AudioCapturer* audio_capturer, + scoped_ptr<AudioCapturer> audio_capturer, scoped_ptr<AudioEncoder> audio_encoder, protocol::AudioStub* audio_stub) { DCHECK(network_task_runner->BelongsToCurrentThread()); @@ -30,16 +29,15 @@ scoped_refptr<AudioScheduler> AudioScheduler::Create( scoped_refptr<AudioScheduler> scheduler = new AudioScheduler( audio_task_runner, network_task_runner, - audio_capturer, audio_encoder.Pass(), audio_stub); + audio_capturer.Pass(), audio_encoder.Pass(), audio_stub); audio_task_runner->PostTask( FROM_HERE, base::Bind(&AudioScheduler::StartOnAudioThread, scheduler)); return scheduler; } -void AudioScheduler::Stop(const base::Closure& done_task) { +void AudioScheduler::Stop() { DCHECK(network_task_runner_->BelongsToCurrentThread()); - DCHECK(!done_task.is_null()); DCHECK(audio_stub_); // Clear |audio_stub_| to prevent audio packets being delivered to the client. @@ -47,18 +45,18 @@ void AudioScheduler::Stop(const base::Closure& done_task) { audio_task_runner_->PostTask( FROM_HERE, - base::Bind(&AudioScheduler::StopOnAudioThread, this, done_task)); + base::Bind(&AudioScheduler::StopOnAudioThread, this)); } AudioScheduler::AudioScheduler( scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner, scoped_refptr<base::SingleThreadTaskRunner> network_task_runner, - AudioCapturer* audio_capturer, + scoped_ptr<AudioCapturer> audio_capturer, scoped_ptr<AudioEncoder> audio_encoder, protocol::AudioStub* audio_stub) : audio_task_runner_(audio_task_runner), network_task_runner_(network_task_runner), - audio_capturer_(audio_capturer), + audio_capturer_(audio_capturer.Pass()), audio_encoder_(audio_encoder.Pass()), audio_stub_(audio_stub), network_stopped_(false), @@ -76,21 +74,19 @@ void AudioScheduler::StartOnAudioThread() { base::Bind(&AudioScheduler::EncodeAudioPacket, this)); } -void AudioScheduler::StopOnAudioThread(const base::Closure& done_task) { +void AudioScheduler::StopOnAudioThread() { DCHECK(audio_task_runner_->BelongsToCurrentThread()); audio_capturer_->Stop(); - - network_task_runner_->PostTask(FROM_HERE, done_task); } -void AudioScheduler::SetEnabled(bool enabled) { +void AudioScheduler::Pause(bool pause) { if (!audio_task_runner_->BelongsToCurrentThread()) { audio_task_runner_->PostTask( - FROM_HERE, base::Bind(&AudioScheduler::SetEnabled, this, enabled)); + FROM_HERE, base::Bind(&AudioScheduler::Pause, this, pause)); return; } - enabled_ = enabled; + enabled_ = !pause; } void AudioScheduler::EncodeAudioPacket(scoped_ptr<AudioPacket> packet) { diff --git a/remoting/host/audio_scheduler.h b/remoting/host/audio_scheduler.h index 43fb397..ae1a1e5 100644 --- a/remoting/host/audio_scheduler.h +++ b/remoting/host/audio_scheduler.h @@ -5,7 +5,6 @@ #ifndef REMOTING_HOST_AUDIO_SCHEDULER_H_ #define REMOTING_HOST_AUDIO_SCHEDULER_H_ -#include "base/callback_forward.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" @@ -36,17 +35,17 @@ class AudioScheduler : public base::RefCountedThreadSafe<AudioScheduler> { static scoped_refptr<AudioScheduler> Create( scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner, scoped_refptr<base::SingleThreadTaskRunner> network_task_runner, - AudioCapturer* audio_capturer, + scoped_ptr<AudioCapturer> audio_capturer, scoped_ptr<AudioEncoder> audio_encoder, protocol::AudioStub* audio_stub); - // Stop the recording session. - void Stop(const base::Closure& done_task); + // Stops the recording session. + void Stop(); - // Enable or disable audio on a running session. - // This leaves the audio capturer running, and only affects whether or not the - // captured audio is encoded and sent on the wire. - void SetEnabled(bool enabled); + // Pauses or resumes audio on a running session. This leaves the audio + // capturer running, and only affects whether or not the captured audio is + // encoded and sent on the wire. + void Pause(bool pause); private: friend class base::RefCountedThreadSafe<AudioScheduler>; @@ -54,7 +53,7 @@ class AudioScheduler : public base::RefCountedThreadSafe<AudioScheduler> { AudioScheduler( scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner, scoped_refptr<base::SingleThreadTaskRunner> network_task_runner, - AudioCapturer* audio_capturer, + scoped_ptr<AudioCapturer> audio_capturer, scoped_ptr<AudioEncoder> audio_encoder, protocol::AudioStub* audio_stub); virtual ~AudioScheduler(); @@ -63,7 +62,7 @@ class AudioScheduler : public base::RefCountedThreadSafe<AudioScheduler> { void StartOnAudioThread(); // Called on the audio thread to stop capturing. - void StopOnAudioThread(const base::Closure& done_task); + void StopOnAudioThread(); // Called on the audio thread when a new audio packet is available. void EncodeAudioPacket(scoped_ptr<AudioPacket> packet); @@ -74,7 +73,7 @@ class AudioScheduler : public base::RefCountedThreadSafe<AudioScheduler> { scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner_; scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_; - AudioCapturer* audio_capturer_; + scoped_ptr<AudioCapturer> audio_capturer_; scoped_ptr<AudioEncoder> audio_encoder_; diff --git a/remoting/host/basic_desktop_environment.cc b/remoting/host/basic_desktop_environment.cc new file mode 100644 index 0000000..040fe88 --- /dev/null +++ b/remoting/host/basic_desktop_environment.cc @@ -0,0 +1,60 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "remoting/host/basic_desktop_environment.h" + +#include "base/logging.h" +#include "remoting/capturer/video_frame_capturer.h" +#include "remoting/host/audio_capturer.h" +#include "remoting/host/event_executor.h" + +namespace remoting { + +BasicDesktopEnvironment::BasicDesktopEnvironment() { +} + +BasicDesktopEnvironment::~BasicDesktopEnvironment() { + DCHECK(CalledOnValidThread()); +} + +scoped_ptr<AudioCapturer> BasicDesktopEnvironment::CreateAudioCapturer( + scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner) { + DCHECK(CalledOnValidThread()); + + return AudioCapturer::Create(); +} + +scoped_ptr<EventExecutor> BasicDesktopEnvironment::CreateEventExecutor( + scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) { + DCHECK(CalledOnValidThread()); + + return EventExecutor::Create(input_task_runner, ui_task_runner); +} + +scoped_ptr<VideoFrameCapturer> BasicDesktopEnvironment::CreateVideoCapturer( + scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> encode_task_runner) { + DCHECK(CalledOnValidThread()); + + return VideoFrameCapturer::Create(); +} + +BasicDesktopEnvironmentFactory::BasicDesktopEnvironmentFactory() { +} + +BasicDesktopEnvironmentFactory::~BasicDesktopEnvironmentFactory() { +} + +scoped_ptr<DesktopEnvironment> BasicDesktopEnvironmentFactory::Create( + const std::string& client_jid, + const base::Closure& disconnect_callback) { + return scoped_ptr<DesktopEnvironment>(new BasicDesktopEnvironment()); +} + +bool BasicDesktopEnvironmentFactory::SupportsAudioCapture() const { + return AudioCapturer::IsSupported(); +} + +} // namespace remoting diff --git a/remoting/host/basic_desktop_environment.h b/remoting/host/basic_desktop_environment.h new file mode 100644 index 0000000..4d0c08e --- /dev/null +++ b/remoting/host/basic_desktop_environment.h @@ -0,0 +1,58 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef REMOTING_HOST_BASIC_DESKTOP_ENVIRONMENT_H_ +#define REMOTING_HOST_BASIC_DESKTOP_ENVIRONMENT_H_ + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "base/memory/ref_counted.h" +#include "base/single_thread_task_runner.h" +#include "base/threading/non_thread_safe.h" +#include "remoting/host/desktop_environment.h" + +namespace remoting { + +// Used to create audio/video capturers and event executor that work with +// the local console. +class BasicDesktopEnvironment + : public base::NonThreadSafe, + public DesktopEnvironment { + public: + BasicDesktopEnvironment(); + virtual ~BasicDesktopEnvironment(); + + // DesktopEnvironment implementation. + virtual scoped_ptr<AudioCapturer> CreateAudioCapturer( + scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner) OVERRIDE; + virtual scoped_ptr<EventExecutor> CreateEventExecutor( + scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) OVERRIDE; + virtual scoped_ptr<VideoFrameCapturer> CreateVideoCapturer( + scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> encode_task_runner) OVERRIDE; + + private: + DISALLOW_COPY_AND_ASSIGN(BasicDesktopEnvironment); +}; + +// Used to create |BasicDesktopEnvironment| instances. +class BasicDesktopEnvironmentFactory : public DesktopEnvironmentFactory { + public: + BasicDesktopEnvironmentFactory(); + virtual ~BasicDesktopEnvironmentFactory(); + + // DesktopEnvironmentFactory implementation. + virtual scoped_ptr<DesktopEnvironment> Create( + const std::string& client_jid, + const base::Closure& disconnect_callback) OVERRIDE; + virtual bool SupportsAudioCapture() const OVERRIDE; + + private: + DISALLOW_COPY_AND_ASSIGN(BasicDesktopEnvironmentFactory); +}; + +} // namespace remoting + +#endif // REMOTING_HOST_BASIC_DESKTOP_ENVIRONMENT_H_ diff --git a/remoting/host/chromoting_host.cc b/remoting/host/chromoting_host.cc index 9216fb0..9ac490b 100644 --- a/remoting/host/chromoting_host.cc +++ b/remoting/host/chromoting_host.cc @@ -11,7 +11,7 @@ #include "build/build_config.h" #include "remoting/base/constants.h" #include "remoting/host/chromoting_host_context.h" -#include "remoting/host/desktop_environment_factory.h" +#include "remoting/host/desktop_environment.h" #include "remoting/host/event_executor.h" #include "remoting/host/host_config.h" #include "remoting/protocol/connection_to_client.h" @@ -60,17 +60,20 @@ ChromotingHost::ChromotingHost( DesktopEnvironmentFactory* desktop_environment_factory, scoped_ptr<protocol::SessionManager> session_manager, scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner, scoped_refptr<base::SingleThreadTaskRunner> video_encode_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> network_task_runner) + scoped_refptr<base::SingleThreadTaskRunner> network_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) : desktop_environment_factory_(desktop_environment_factory), session_manager_(session_manager.Pass()), audio_task_runner_(audio_task_runner), + input_task_runner_(input_task_runner), video_capture_task_runner_(video_capture_task_runner), video_encode_task_runner_(video_encode_task_runner), network_task_runner_(network_task_runner), + ui_task_runner_(ui_task_runner), signal_strategy_(signal_strategy), - clients_count_(0), state_(kInitial), protocol_config_(protocol::CandidateSessionConfig::CreateDefault()), login_backoff_(&kDefaultBackoffPolicy), @@ -140,7 +143,7 @@ void ChromotingHost::Shutdown(const base::Closure& shutdown_task) { } // Run the remaining shutdown tasks. - if (state_ == kStopping && !clients_count_) + if (state_ == kStopping) ShutdownFinish(); break; @@ -241,8 +244,11 @@ void ChromotingHost::OnSessionClosed(ClientSession* client) { OnClientDisconnected(client->client_jid())); } - client->Stop(base::Bind(&ChromotingHost::OnClientStopped, this)); + client->Stop(); clients_.erase(it); + + if (state_ == kStopping && clients_.empty()) + ShutdownFinish(); } void ChromotingHost::OnSessionSequenceNumber(ClientSession* session, @@ -314,14 +320,15 @@ void ChromotingHost::OnIncomingSession( scoped_refptr<ClientSession> client = new ClientSession( this, audio_task_runner_, + input_task_runner_, video_capture_task_runner_, video_encode_task_runner_, network_task_runner_, + ui_task_runner_, connection.Pass(), desktop_environment_factory_, max_session_duration_); clients_.push_back(client); - clients_count_++; } void ChromotingHost::set_protocol_config( @@ -380,14 +387,6 @@ void ChromotingHost::SetUiStrings(const UiStrings& ui_strings) { ui_strings_ = ui_strings; } -void ChromotingHost::OnClientStopped() { - DCHECK(network_task_runner_->BelongsToCurrentThread()); - - --clients_count_; - if (state_ == kStopping && !clients_count_) - ShutdownFinish(); -} - void ChromotingHost::ShutdownFinish() { DCHECK(network_task_runner_->BelongsToCurrentThread()); DCHECK_EQ(state_, kStopping); diff --git a/remoting/host/chromoting_host.h b/remoting/host/chromoting_host.h index 5a0975e..a62da33 100644 --- a/remoting/host/chromoting_host.h +++ b/remoting/host/chromoting_host.h @@ -73,9 +73,11 @@ class ChromotingHost : public base::RefCountedThreadSafe<ChromotingHost>, DesktopEnvironmentFactory* desktop_environment_factory, scoped_ptr<protocol::SessionManager> session_manager, scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner, scoped_refptr<base::SingleThreadTaskRunner> video_encode_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> network_task_runner); + scoped_refptr<base::SingleThreadTaskRunner> network_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner); // Asynchronously start the host process. // @@ -169,9 +171,6 @@ class ChromotingHost : public base::RefCountedThreadSafe<ChromotingHost>, virtual ~ChromotingHost(); - // Called when a client session is stopped completely. - void OnClientStopped(); - // Called from Shutdown() to finish shutdown. void ShutdownFinish(); @@ -182,9 +181,11 @@ class ChromotingHost : public base::RefCountedThreadSafe<ChromotingHost>, DesktopEnvironmentFactory* desktop_environment_factory_; scoped_ptr<protocol::SessionManager> session_manager_; scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner_; + scoped_refptr<base::SingleThreadTaskRunner> input_task_runner_; scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner_; scoped_refptr<base::SingleThreadTaskRunner> video_encode_task_runner_; scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_; + scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_; // Connection objects. SignalStrategy* signal_strategy_; @@ -195,11 +196,6 @@ class ChromotingHost : public base::RefCountedThreadSafe<ChromotingHost>, // The connections to remote clients. ClientList clients_; - // The number of allocated |ClientSession| objects. |clients_count_| can be - // greater than |clients_.size()| because it also includes the objects that - // are about to be deleted. - int clients_count_; - // Tracks the internal state of the host. State state_; diff --git a/remoting/host/chromoting_host_unittest.cc b/remoting/host/chromoting_host_unittest.cc index 0235512..56a0b0a 100644 --- a/remoting/host/chromoting_host_unittest.cc +++ b/remoting/host/chromoting_host_unittest.cc @@ -12,8 +12,6 @@ #include "remoting/host/chromoting_host.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_fake.h" #include "remoting/host/host_mock_objects.h" #include "remoting/host/it2me_host_user_interface.h" #include "remoting/jingle_glue/mock_objects.h" @@ -123,6 +121,9 @@ class ChromotingHostTest : public testing::Test { .Times(AnyNumber()) .WillRepeatedly(Invoke(this, &ChromotingHostTest::CreateDesktopEnvironment)); + EXPECT_CALL(*desktop_environment_factory_, SupportsAudioCapture()) + .Times(AnyNumber()) + .WillRepeatedly(Return(false)); session_manager_ = new protocol::MockSessionManager(); @@ -131,9 +132,11 @@ class ChromotingHostTest : public testing::Test { desktop_environment_factory_.get(), scoped_ptr<protocol::SessionManager>(session_manager_), ui_task_runner_, // Audio + ui_task_runner_, // Input ui_task_runner_, // Video capture ui_task_runner_, // Video encode - ui_task_runner_); // Network + ui_task_runner_, // Network + ui_task_runner_); // UI host_->AddStatusObserver(&host_status_observer_); disconnect_window_ = new MockDisconnectWindow(); @@ -237,9 +240,11 @@ class ChromotingHostTest : public testing::Test { scoped_refptr<ClientSession> client = new ClientSession( host_.get(), ui_task_runner_, // Audio + ui_task_runner_, // Input ui_task_runner_, // Video capture ui_task_runner_, // Video encode ui_task_runner_, // Network + ui_task_runner_, // UI connection.Pass(), desktop_environment_factory_.get(), base::TimeDelta()); @@ -280,12 +285,38 @@ class ChromotingHostTest : public testing::Test { host_->OnSessionRouteChange(get_client(0), channel_name, route); } + // Creates a DesktopEnvironment with a fake VideoFrameCapturer, to mock + // DesktopEnvironmentFactory::Create(). DesktopEnvironment* CreateDesktopEnvironment() { - scoped_ptr<EventExecutor> event_executor(new EventExecutorFake()); - scoped_ptr<VideoFrameCapturer> video_capturer(new VideoFrameCapturerFake()); - return new DesktopEnvironment(scoped_ptr<AudioCapturer>(NULL), - event_executor.Pass(), - video_capturer.Pass()); + MockDesktopEnvironment* desktop_environment = new MockDesktopEnvironment(); + EXPECT_CALL(*desktop_environment, CreateAudioCapturerPtr(_)) + .Times(0); + EXPECT_CALL(*desktop_environment, CreateEventExecutorPtr(_, _)) + .Times(AnyNumber()) + .WillRepeatedly(Invoke(this, &ChromotingHostTest::CreateEventExecutor)); + EXPECT_CALL(*desktop_environment, CreateVideoCapturerPtr(_, _)) + .Times(AnyNumber()) + .WillRepeatedly(Invoke(this, &ChromotingHostTest::CreateVideoCapturer)); + + return desktop_environment; + } + + // Creates a dummy EventExecutor, to mock + // DesktopEnvironment::CreateEventExecutor(). + EventExecutor* CreateEventExecutor( + scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) { + MockEventExecutor* event_executor = new MockEventExecutor(); + EXPECT_CALL(*event_executor, StartPtr(_)); + return event_executor; + } + + // Creates a fake VideoFrameCapturer, to mock + // DesktopEnvironment::CreateVideoCapturer(). + VideoFrameCapturer* CreateVideoCapturer( + scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> encode_task_runner) { + return new VideoFrameCapturerFake(); } void DisconnectAllClients() { @@ -321,7 +352,6 @@ class ChromotingHostTest : public testing::Test { static void AddClientToHost(scoped_refptr<ChromotingHost> host, ClientSession* session) { host->clients_.push_back(session); - host->clients_count_++; } void ShutdownHost() { @@ -336,6 +366,7 @@ class ChromotingHostTest : public testing::Test { it2me_host_user_interface_.reset(); ui_task_runner_ = NULL; host_ = NULL; + desktop_environment_factory_.reset(); } void QuitMainMessageLoop() { diff --git a/remoting/host/client_session.cc b/remoting/host/client_session.cc index 63764e8..1e27128 100644 --- a/remoting/host/client_session.cc +++ b/remoting/host/client_session.cc @@ -15,9 +15,9 @@ #include "remoting/codec/video_encoder.h" #include "remoting/codec/video_encoder_verbatim.h" #include "remoting/codec/video_encoder_vp8.h" +#include "remoting/host/audio_capturer.h" #include "remoting/host/audio_scheduler.h" #include "remoting/host/desktop_environment.h" -#include "remoting/host/desktop_environment_factory.h" #include "remoting/host/event_executor.h" #include "remoting/host/video_scheduler.h" #include "remoting/proto/control.pb.h" @@ -30,17 +30,22 @@ namespace remoting { ClientSession::ClientSession( EventHandler* event_handler, scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner, scoped_refptr<base::SingleThreadTaskRunner> video_encode_task_runner, scoped_refptr<base::SingleThreadTaskRunner> network_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, scoped_ptr<protocol::ConnectionToClient> connection, DesktopEnvironmentFactory* desktop_environment_factory, const base::TimeDelta& max_duration) : event_handler_(event_handler), connection_(connection.Pass()), connection_factory_(connection_.get()), - desktop_environment_(desktop_environment_factory->Create()), client_jid_(connection_->session()->jid()), + desktop_environment_(desktop_environment_factory->Create( + client_jid_, + base::Bind(&protocol::ConnectionToClient::Disconnect, + connection_factory_.GetWeakPtr()))), input_tracker_(&host_input_filter_), remote_input_filter_(&input_tracker_), mouse_clamping_filter_(&remote_input_filter_), @@ -51,10 +56,11 @@ ClientSession::ClientSession( client_clipboard_factory_(clipboard_echo_filter_.client_filter()), max_duration_(max_duration), audio_task_runner_(audio_task_runner), + input_task_runner_(input_task_runner), video_capture_task_runner_(video_capture_task_runner), video_encode_task_runner_(video_encode_task_runner), network_task_runner_(network_task_runner), - active_recorders_(0) { + ui_task_runner_(ui_task_runner) { connection_->SetEventHandler(this); // TODO(sergeyu): Currently ConnectionToClient expects stubs to be @@ -83,9 +89,8 @@ void ClientSession::ControlVideo(const protocol::VideoControl& video_control) { if (video_control.has_enable()) { VLOG(1) << "Received VideoControl (enable=" << video_control.enable() << ")"; - if (video_scheduler_.get()) { + if (video_scheduler_) video_scheduler_->Pause(!video_control.enable()); - } } } @@ -93,9 +98,8 @@ void ClientSession::ControlAudio(const protocol::AudioControl& audio_control) { if (audio_control.has_enable()) { VLOG(1) << "Received AudioControl (enable=" << audio_control.enable() << ")"; - if (audio_scheduler_.get()) { - audio_scheduler_->SetEnabled(audio_control.enable()); - } + if (audio_scheduler_) + audio_scheduler_->Pause(!audio_control.enable()); } } @@ -124,20 +128,21 @@ void ClientSession::OnConnectionChannelsConnected( protocol::ConnectionToClient* connection) { DCHECK(CalledOnValidThread()); DCHECK_EQ(connection_.get(), connection); + DCHECK(!audio_scheduler_); + DCHECK(!event_executor_); + DCHECK(!video_scheduler_); + + // Create and start the event executor. + event_executor_ = desktop_environment_->CreateEventExecutor( + input_task_runner_, ui_task_runner_); + event_executor_->Start(CreateClipboardProxy()); // Connect the host clipboard and input stubs. - host_input_filter_.set_input_stub(desktop_environment_->event_executor()); - clipboard_echo_filter_.set_host_stub(desktop_environment_->event_executor()); + host_input_filter_.set_input_stub(event_executor_.get()); + clipboard_echo_filter_.set_host_stub(event_executor_.get()); SetDisableInputs(false); - // Let the desktop environment notify us of local clipboard changes. - desktop_environment_->Start( - CreateClipboardProxy(), - client_jid(), - base::Bind(&protocol::ConnectionToClient::Disconnect, - connection_factory_.GetWeakPtr())); - // Create a VideoEncoder based on the session's video channel configuration. scoped_ptr<VideoEncoder> video_encoder = CreateVideoEncoder(connection_->session()->config()); @@ -147,11 +152,11 @@ void ClientSession::OnConnectionChannelsConnected( video_capture_task_runner_, video_encode_task_runner_, network_task_runner_, - desktop_environment_->video_capturer(), + desktop_environment_->CreateVideoCapturer(video_capture_task_runner_, + video_encode_task_runner_), video_encoder.Pass(), connection_->client_stub(), &mouse_clamping_filter_); - ++active_recorders_; // Create an AudioScheduler if audio is enabled, to pump audio samples. if (connection_->session()->config().is_audio_enabled()) { @@ -160,10 +165,9 @@ void ClientSession::OnConnectionChannelsConnected( audio_scheduler_ = AudioScheduler::Create( audio_task_runner_, network_task_runner_, - desktop_environment_->audio_capturer(), + desktop_environment_->CreateAudioCapturer(audio_task_runner_), audio_encoder.Pass(), connection_->audio_stub()); - ++active_recorders_; } // Notify the event handler that all our channels are now connected. @@ -194,15 +198,17 @@ void ClientSession::OnConnectionClosed( // Stop components access the client, audio or video stubs, which are no // longer valid once ConnectionToClient calls OnConnectionClosed(). - if (audio_scheduler_.get()) { - audio_scheduler_->Stop(base::Bind(&ClientSession::OnRecorderStopped, this)); + if (audio_scheduler_) { + audio_scheduler_->Stop(); audio_scheduler_ = NULL; } - if (video_scheduler_.get()) { - video_scheduler_->Stop(base::Bind(&ClientSession::OnRecorderStopped, this)); + if (video_scheduler_) { + video_scheduler_->Stop(); video_scheduler_ = NULL; } + client_clipboard_factory_.InvalidateWeakPtrs(); + event_executor_.reset(); // Notify the ChromotingHost that this client is disconnected. // TODO(sergeyu): Log failure reason? @@ -214,7 +220,7 @@ void ClientSession::OnSequenceNumberUpdated( DCHECK(CalledOnValidThread()); DCHECK_EQ(connection_.get(), connection); - if (video_scheduler_.get()) + if (video_scheduler_) video_scheduler_->UpdateSequenceNumber(sequence_number); event_handler_->OnSessionSequenceNumber(this, sequence_number); @@ -240,21 +246,13 @@ void ClientSession::Disconnect() { connection_->Disconnect(); } -void ClientSession::Stop(const base::Closure& stopped_task) { +void ClientSession::Stop() { DCHECK(CalledOnValidThread()); - DCHECK(stopped_task_.is_null()); - DCHECK(!stopped_task.is_null()); - DCHECK(audio_scheduler_.get() == NULL); - DCHECK(video_scheduler_.get() == NULL); - - stopped_task_ = stopped_task; - - if (active_recorders_ == 0) { - // |stopped_task_| may tear down the signalling layer, so tear-down - // |connection_| before invoking it. - connection_.reset(); - stopped_task_.Run(); - } + DCHECK(!audio_scheduler_); + DCHECK(!event_executor_); + DCHECK(!video_scheduler_); + + connection_.reset(); } void ClientSession::LocalMouseMoved(const SkIPoint& mouse_pos) { @@ -273,9 +271,10 @@ void ClientSession::SetDisableInputs(bool disable_inputs) { } ClientSession::~ClientSession() { - DCHECK_EQ(active_recorders_, 0); - DCHECK(audio_scheduler_.get() == NULL); - DCHECK(video_scheduler_.get() == NULL); + DCHECK(CalledOnValidThread()); + DCHECK(!audio_scheduler_); + DCHECK(!event_executor_); + DCHECK(!video_scheduler_); } scoped_ptr<protocol::ClipboardStub> ClientSession::CreateClipboardProxy() { @@ -287,25 +286,6 @@ scoped_ptr<protocol::ClipboardStub> ClientSession::CreateClipboardProxy() { base::MessageLoopProxy::current())); } -void ClientSession::OnRecorderStopped() { - if (!network_task_runner_->BelongsToCurrentThread()) { - network_task_runner_->PostTask( - FROM_HERE, base::Bind(&ClientSession::OnRecorderStopped, this)); - return; - } - - --active_recorders_; - DCHECK_GE(active_recorders_, 0); - - DCHECK(!stopped_task_.is_null()); - if (active_recorders_ == 0) { - // |stopped_task_| may result in the signalling layer being torn down, so - // tear down the ConnectionToClient first. - connection_.reset(); - stopped_task_.Run(); - } -} - // TODO(sergeyu): Move this to SessionManager? // static scoped_ptr<VideoEncoder> ClientSession::CreateVideoEncoder( diff --git a/remoting/host/client_session.h b/remoting/host/client_session.h index f61cb53..6d32adf 100644 --- a/remoting/host/client_session.h +++ b/remoting/host/client_session.h @@ -8,6 +8,7 @@ #include <list> #include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" #include "base/sequenced_task_runner_helpers.h" #include "base/time.h" #include "base/timer.h" @@ -36,8 +37,8 @@ class AudioScheduler; struct ClientSessionTraits; class DesktopEnvironment; class DesktopEnvironmentFactory; +class EventExecutor; class VideoEncoder; -class VideoFrameCapturer; class VideoScheduler; // A ClientSession keeps a reference to a connection to a client, and maintains @@ -91,9 +92,11 @@ class ClientSession ClientSession( EventHandler* event_handler, scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner, scoped_refptr<base::SingleThreadTaskRunner> video_encode_task_runner, scoped_refptr<base::SingleThreadTaskRunner> network_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, scoped_ptr<protocol::ConnectionToClient> connection, DesktopEnvironmentFactory* desktop_environment_factory, const base::TimeDelta& max_duration); @@ -125,9 +128,9 @@ class ClientSession // method returns. void Disconnect(); - // Stops the ClientSession, and calls |stopped_task| on |network_task_runner_| - // when fully stopped. - void Stop(const base::Closure& stopped_task); + // Stops the ClientSession. The caller can safely release its reference to + // the client session once Stop() returns. + void Stop(); protocol::ConnectionToClient* connection() const { return connection_.get(); @@ -154,8 +157,6 @@ class ClientSession // Creates a proxy for sending clipboard events to the client. scoped_ptr<protocol::ClipboardStub> CreateClipboardProxy(); - void OnRecorderStopped(); - // Creates an audio encoder for the specified configuration. static scoped_ptr<AudioEncoder> CreateAudioEncoder( const protocol::SessionConfig& config); @@ -172,11 +173,11 @@ class ClientSession // Used to disable callbacks to |connection_| once it is disconnected. base::WeakPtrFactory<protocol::ConnectionToClient> connection_factory_; + std::string client_jid_; + // The desktop environment used by this session. scoped_ptr<DesktopEnvironment> desktop_environment_; - std::string client_jid_; - // Filter used as the final element in the input pipeline. protocol::InputFilter host_input_filter_; @@ -216,21 +217,17 @@ class ClientSession base::OneShotTimer<ClientSession> max_duration_timer_; scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner_; + scoped_refptr<base::SingleThreadTaskRunner> input_task_runner_; scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner_; scoped_refptr<base::SingleThreadTaskRunner> video_encode_task_runner_; scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_; + scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_; // Schedulers for audio and video capture. scoped_refptr<AudioScheduler> audio_scheduler_; scoped_refptr<VideoScheduler> video_scheduler_; - // Number of screen recorders and audio schedulers that are currently being - // used or shutdown. Used to delay shutdown if one or more - // recorders/schedulers are asynchronously shutting down. - int active_recorders_; - - // Task to execute once the session is completely stopped. - base::Closure stopped_task_; + scoped_ptr<EventExecutor> event_executor_; DISALLOW_COPY_AND_ASSIGN(ClientSession); }; diff --git a/remoting/host/client_session_unittest.cc b/remoting/host/client_session_unittest.cc index 285bf4a..1720382 100644 --- a/remoting/host/client_session_unittest.cc +++ b/remoting/host/client_session_unittest.cc @@ -55,9 +55,7 @@ ACTION_P2(LocalMouseMoved, client_session, event) { class ClientSessionTest : public testing::Test { public: - ClientSessionTest() - : client_jid_("user@domain/rest-of-jid"), - event_executor_(NULL) {} + ClientSessionTest() : client_jid_("user@domain/rest-of-jid") {} virtual void SetUp() OVERRIDE; virtual void TearDown() OVERRIDE; @@ -65,8 +63,7 @@ class ClientSessionTest : public testing::Test { // Disconnects the client session. void DisconnectClientSession(); - // Asynchronously stops the client session. OnClientStopped() will be called - // once the client session is fully stopped. + // Stops and releases the ClientSession, allowing the MessageLoop to quit. void StopClientSession(); protected: @@ -74,6 +71,18 @@ class ClientSessionTest : public testing::Test { // DesktopEnvironmentFactory::Create(). DesktopEnvironment* CreateDesktopEnvironment(); + // Returns |event_executor_| created and initialized by SetUp(), to mock + // DesktopEnvironment::CreateEventExecutor(). + EventExecutor* CreateEventExecutor( + scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner); + + // Creates a fake VideoFrameCapturer, to mock + // DesktopEnvironment::CreateVideoCapturer(). + VideoFrameCapturer* CreateVideoCapturer( + scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> encode_task_runner); + // Notifies the client session that the client connection has been // authenticated and channels have been connected. This effectively enables // the input pipe line and starts video capturing. @@ -83,10 +92,6 @@ class ClientSessionTest : public testing::Test { // released and quits the message loop to finish the test. void QuitMainMessageLoop(); - // Releases the ClientSession when it has been fully stopped, allowing - // the MessageLoop to quit. - void OnClientStopped(); - // Message loop passed to |client_session_| to perform all functions on. MessageLoop message_loop_; @@ -106,7 +111,7 @@ class ClientSessionTest : public testing::Test { // DesktopEnvironment owns |event_executor_|, but input injection tests need // to express expectations on it. - MockEventExecutor* event_executor_; + scoped_ptr<MockEventExecutor> event_executor_; // ClientSession owns |connection_| but tests need it to inject fake events. MockConnectionToClient* connection_; @@ -126,6 +131,11 @@ void ClientSessionTest::SetUp() { .Times(AnyNumber()) .WillRepeatedly(Invoke(this, &ClientSessionTest::CreateDesktopEnvironment)); + EXPECT_CALL(*desktop_environment_factory_, SupportsAudioCapture()) + .Times(AnyNumber()) + .WillRepeatedly(Return(false)); + + event_executor_.reset(new MockEventExecutor()); session_config_ = SessionConfig::ForTest(); @@ -149,9 +159,11 @@ void ClientSessionTest::SetUp() { client_session_ = new ClientSession( &session_event_handler_, ui_task_runner, // Audio thread. + ui_task_runner, // Input thread. ui_task_runner, // Capture thread. ui_task_runner, // Encode thread. ui_task_runner, // Network thread. + ui_task_runner, // UI thread. connection.PassAs<protocol::ConnectionToClient>(), desktop_environment_factory_.get(), base::TimeDelta()); @@ -171,18 +183,35 @@ void ClientSessionTest::DisconnectClientSession() { void ClientSessionTest::StopClientSession() { // MockClientSessionEventHandler won't trigger Stop, so fake it. - client_session_->Stop(base::Bind( - &ClientSessionTest::OnClientStopped, base::Unretained(this))); + client_session_->Stop(); + client_session_ = NULL; + + desktop_environment_factory_.reset(); } DesktopEnvironment* ClientSessionTest::CreateDesktopEnvironment() { - scoped_ptr<VideoFrameCapturer> video_capturer(new VideoFrameCapturerFake()); + MockDesktopEnvironment* desktop_environment = new MockDesktopEnvironment(); + EXPECT_CALL(*desktop_environment, CreateAudioCapturerPtr(_)) + .Times(0); + EXPECT_CALL(*desktop_environment, CreateEventExecutorPtr(_, _)) + .WillOnce(Invoke(this, &ClientSessionTest::CreateEventExecutor)); + EXPECT_CALL(*desktop_environment, CreateVideoCapturerPtr(_, _)) + .WillOnce(Invoke(this, &ClientSessionTest::CreateVideoCapturer)); + + return desktop_environment; +} + +EventExecutor* ClientSessionTest::CreateEventExecutor( + scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) { + EXPECT_TRUE(event_executor_); + return event_executor_.release(); +} - EXPECT_TRUE(!event_executor_); - event_executor_ = new MockEventExecutor(); - return new DesktopEnvironment(scoped_ptr<AudioCapturer>(NULL), - scoped_ptr<EventExecutor>(event_executor_), - video_capturer.Pass()); +VideoFrameCapturer* ClientSessionTest::CreateVideoCapturer( + scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> encode_task_runner) { + return new VideoFrameCapturerFake(); } void ClientSessionTest::ConnectClientSession() { @@ -194,10 +223,6 @@ void ClientSessionTest::QuitMainMessageLoop() { message_loop_.PostTask(FROM_HERE, MessageLoop::QuitClosure()); } -void ClientSessionTest::OnClientStopped() { - client_session_ = NULL; -} - MATCHER_P2(EqualsClipboardEvent, m, d, "") { return (strcmp(arg.mime_type().c_str(), m) == 0 && memcmp(arg.data().data(), d, arg.data().size()) == 0); @@ -416,22 +441,22 @@ TEST_F(ClientSessionTest, ClampMouseEvents) { int input_y[3] = { -999, 50, 999 }; int expected_y[3] = { 0, 50, VideoFrameCapturerFake::kHeight - 1 }; - // Inject the 1st event once a video packet has been received. - protocol::MouseEvent injected_event; - injected_event.set_x(input_x[0]); - injected_event.set_y(input_y[0]); - connected = - EXPECT_CALL(video_stub_, ProcessVideoPacketPtr(_, _)) - .After(connected) - .WillOnce(InjectMouseEvent(connection_, injected_event)); - protocol::MouseEvent expected_event; for (int j = 0; j < 3; j++) { for (int i = 0; i < 3; i++) { - // Skip the first iteration since the 1st event has been injected already. - if (i > 0 || j > 0) { - injected_event.set_x(input_x[i]); - injected_event.set_y(input_y[j]); + protocol::MouseEvent injected_event; + injected_event.set_x(input_x[i]); + injected_event.set_y(input_y[j]); + + if (i == 0 && j == 0) { + // Inject the 1st event once a video packet has been received. + connected = + EXPECT_CALL(video_stub_, ProcessVideoPacketPtr(_, _)) + .After(connected) + .WillOnce(InjectMouseEvent(connection_, injected_event)); + } else { + // Every next event is injected once the previous event has been + // received. connected = EXPECT_CALL(*event_executor_, InjectMouseEvent(EqualsMouseEvent(expected_event.x(), diff --git a/remoting/host/desktop_environment.cc b/remoting/host/desktop_environment.cc deleted file mode 100644 index d862e48..0000000 --- a/remoting/host/desktop_environment.cc +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "remoting/host/desktop_environment.h" - -#include "base/callback.h" -#include "base/compiler_specific.h" -#include "remoting/capturer/video_frame_capturer.h" -#include "remoting/host/audio_capturer.h" -#include "remoting/host/desktop_environment.h" -#include "remoting/host/event_executor.h" - -namespace remoting { - -DesktopEnvironment::DesktopEnvironment( - scoped_ptr<AudioCapturer> audio_capturer, - scoped_ptr<EventExecutor> event_executor, - scoped_ptr<VideoFrameCapturer> video_capturer) - : audio_capturer_(audio_capturer.Pass()), - event_executor_(event_executor.Pass()), - video_capturer_(video_capturer.Pass()) { -} - -DesktopEnvironment::~DesktopEnvironment() { -} - -void DesktopEnvironment::Start( - scoped_ptr<protocol::ClipboardStub> client_clipboard, - const std::string& client_jid, - const base::Closure& disconnect_callback) { - event_executor_->Start(client_clipboard.Pass()); -} - -} // namespace remoting diff --git a/remoting/host/desktop_environment.h b/remoting/host/desktop_environment.h index 74b1d8e..06b0b373 100644 --- a/remoting/host/desktop_environment.h +++ b/remoting/host/desktop_environment.h @@ -9,51 +9,51 @@ #include "base/basictypes.h" #include "base/callback_forward.h" +#include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" +namespace base { +class SingleThreadTaskRunner; +} // namespace base + namespace remoting { class AudioCapturer; class EventExecutor; class VideoFrameCapturer; -namespace protocol { -class ClipboardStub; -} - +// Provides factory methods for creation of audio/video capturers and event +// executor for a given desktop environment. class DesktopEnvironment { public: - DesktopEnvironment(scoped_ptr<AudioCapturer> audio_capturer, - scoped_ptr<EventExecutor> event_executor, - scoped_ptr<VideoFrameCapturer> video_capturer); - virtual ~DesktopEnvironment(); - - AudioCapturer* audio_capturer() const { return audio_capturer_.get(); } - EventExecutor* event_executor() const { return event_executor_.get(); } - VideoFrameCapturer* video_capturer() const { return video_capturer_.get(); } - - // Starts the desktop environment passing |client_jid| of the attached - // authenticated session. Registers |client_clipboard| to receive - // notifications about local clipboard changes. |disconnect_callback| can be - // invoked by the DesktopEnvironment to request the client session to be - // disconnected. |disconnect_callback| is invoked on the same thread Start() - // has been called on. - virtual void Start( - scoped_ptr<protocol::ClipboardStub> client_clipboard, - const std::string& client_jid, - const base::Closure& disconnect_callback); - - private: - // Used to capture audio to deliver to clients. - scoped_ptr<AudioCapturer> audio_capturer_; + virtual ~DesktopEnvironment() {} + + // Factory methods used to create audio/video capturers and event executor for + // a particular desktop environment. + virtual scoped_ptr<AudioCapturer> CreateAudioCapturer( + scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner) = 0; + virtual scoped_ptr<EventExecutor> CreateEventExecutor( + scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) = 0; + virtual scoped_ptr<VideoFrameCapturer> CreateVideoCapturer( + scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> encode_task_runner) = 0; +}; - // Executes input and clipboard events received from the client. - scoped_ptr<EventExecutor> event_executor_; +// Used to create |DesktopEnvironment| instances. +class DesktopEnvironmentFactory { + public: + virtual ~DesktopEnvironmentFactory() {} - // Used to capture video to deliver to clients. - scoped_ptr<VideoFrameCapturer> video_capturer_; + // Creates an instance of |DesktopEnvironment|. |disconnect_callback| may be + // used by the DesktopEnvironment to disconnect the client session. + virtual scoped_ptr<DesktopEnvironment> Create( + const std::string& client_jid, + const base::Closure& disconnect_callback) = 0; - DISALLOW_COPY_AND_ASSIGN(DesktopEnvironment); + // Returns |true| if created |DesktopEnvironment| instances support audio + // capture. + virtual bool SupportsAudioCapture() const = 0; }; } // namespace remoting diff --git a/remoting/host/desktop_environment_factory.cc b/remoting/host/desktop_environment_factory.cc deleted file mode 100644 index 893c0cc..0000000 --- a/remoting/host/desktop_environment_factory.cc +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "remoting/host/desktop_environment_factory.h" - -#include "base/single_thread_task_runner.h" -#include "remoting/capturer/video_frame_capturer.h" -#include "remoting/host/audio_capturer.h" -#include "remoting/host/chromoting_host_context.h" -#include "remoting/host/desktop_environment.h" -#include "remoting/host/event_executor.h" - -namespace remoting { - -DesktopEnvironmentFactory::DesktopEnvironmentFactory( - scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) - : input_task_runner_(input_task_runner), - ui_task_runner_(ui_task_runner) { -} - -DesktopEnvironmentFactory::~DesktopEnvironmentFactory() { -} - -scoped_ptr<DesktopEnvironment> DesktopEnvironmentFactory::Create() { - scoped_ptr<DesktopEnvironment> environment(new DesktopEnvironment( - AudioCapturer::Create(), - EventExecutor::Create(input_task_runner_, ui_task_runner_), - VideoFrameCapturer::Create())); - return environment.Pass(); -} - -bool DesktopEnvironmentFactory::SupportsAudioCapture() const { - return AudioCapturer::IsSupported(); -} - -} // namespace remoting diff --git a/remoting/host/desktop_environment_factory.h b/remoting/host/desktop_environment_factory.h deleted file mode 100644 index 3a25437..0000000 --- a/remoting/host/desktop_environment_factory.h +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef REMOTING_HOST_DESKTOP_ENVIRONMENT_FACTORY_H_ -#define REMOTING_HOST_DESKTOP_ENVIRONMENT_FACTORY_H_ - -#include "base/basictypes.h" -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" - -namespace base { -class SingleThreadTaskRunner; -} // namespace base - -namespace remoting { - -class DesktopEnvironment; - -class DesktopEnvironmentFactory { - public: - DesktopEnvironmentFactory( - scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner); - virtual ~DesktopEnvironmentFactory(); - - // Creates an instance of |DesktopEnvironment|. - virtual scoped_ptr<DesktopEnvironment> Create(); - - // Returns |true| if created |DesktopEnvironment| instances support audio - // capture. - virtual bool SupportsAudioCapture() const; - - protected: - scoped_refptr<base::SingleThreadTaskRunner> input_task_runner_; - scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_; - - DISALLOW_COPY_AND_ASSIGN(DesktopEnvironmentFactory); -}; - -} // namespace remoting - -#endif // REMOTING_HOST_DESKTOP_ENVIRONMENT_FACTORY_H_ diff --git a/remoting/host/desktop_session_proxy.cc b/remoting/host/desktop_session_proxy.cc index 59a567f..48e1547 100644 --- a/remoting/host/desktop_session_proxy.cc +++ b/remoting/host/desktop_session_proxy.cc @@ -15,6 +15,7 @@ #include "remoting/host/chromoting_messages.h" #include "remoting/host/client_session.h" #include "remoting/host/ipc_audio_capturer.h" +#include "remoting/host/ipc_event_executor.h" #include "remoting/host/ipc_video_frame_capturer.h" #include "remoting/proto/audio.pb.h" #include "remoting/proto/control.pb.h" @@ -27,16 +28,45 @@ namespace remoting { DesktopSessionProxy::DesktopSessionProxy( - scoped_refptr<base::SingleThreadTaskRunner> audio_capture_task_runner, scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner) - : audio_capture_task_runner_(audio_capture_task_runner), - caller_task_runner_(caller_task_runner), - video_capture_task_runner_(video_capture_task_runner), + const std::string& client_jid, + const base::Closure& disconnect_callback) + : caller_task_runner_(caller_task_runner), audio_capturer_(NULL), + client_jid_(client_jid), + disconnect_callback_(disconnect_callback), pending_capture_frame_requests_(0), video_capturer_(NULL) { DCHECK(caller_task_runner_->BelongsToCurrentThread()); + DCHECK(!client_jid_.empty()); + DCHECK(!disconnect_callback_.is_null()); +} + +scoped_ptr<AudioCapturer> DesktopSessionProxy::CreateAudioCapturer( + scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner) { + DCHECK(caller_task_runner_->BelongsToCurrentThread()); + DCHECK(!audio_capture_task_runner_.get()); + + audio_capture_task_runner_ = audio_task_runner; + return scoped_ptr<AudioCapturer>(new IpcAudioCapturer(this)); +} + +scoped_ptr<EventExecutor> DesktopSessionProxy::CreateEventExecutor( + scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) { + DCHECK(caller_task_runner_->BelongsToCurrentThread()); + + return scoped_ptr<EventExecutor>(new IpcEventExecutor(this)); +} + +scoped_ptr<VideoFrameCapturer> DesktopSessionProxy::CreateVideoCapturer( + scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> encode_task_runner) { + DCHECK(caller_task_runner_->BelongsToCurrentThread()); + DCHECK(!video_capture_task_runner_.get()); + + video_capture_task_runner_ = capture_task_runner; + return scoped_ptr<VideoFrameCapturer>(new IpcVideoFrameCapturer(this)); } bool DesktopSessionProxy::OnMessageReceived(const IPC::Message& message) { @@ -75,18 +105,6 @@ void DesktopSessionProxy::OnChannelError() { DetachFromDesktop(); } -void DesktopSessionProxy::Initialize(const std::string& client_jid, - const base::Closure& disconnect_callback) { - DCHECK(caller_task_runner_->BelongsToCurrentThread()); - DCHECK(client_jid_.empty()); - DCHECK(!client_jid.empty()); - DCHECK(disconnect_callback_.is_null()); - DCHECK(!disconnect_callback.is_null()); - - client_jid_ = client_jid; - disconnect_callback_ = disconnect_callback; -} - bool DesktopSessionProxy::AttachToDesktop( IPC::PlatformFileForTransit desktop_process, IPC::PlatformFileForTransit desktop_pipe) { @@ -155,6 +173,60 @@ void DesktopSessionProxy::DetachFromDesktop() { } } +void DesktopSessionProxy::StartAudioCapturer(IpcAudioCapturer* audio_capturer) { + DCHECK(audio_capture_task_runner_->BelongsToCurrentThread()); + DCHECK(audio_capturer_ == NULL); + + audio_capturer_ = audio_capturer; +} + +void DesktopSessionProxy::StopAudioCapturer() { + DCHECK(audio_capture_task_runner_->BelongsToCurrentThread()); + + audio_capturer_ = NULL; +} + +void DesktopSessionProxy::InvalidateRegion(const SkRegion& invalid_region) { + if (!caller_task_runner_->BelongsToCurrentThread()) { + caller_task_runner_->PostTask( + FROM_HERE, base::Bind(&DesktopSessionProxy::InvalidateRegion, this, + invalid_region)); + return; + } + + std::vector<SkIRect> invalid_rects; + for (SkRegion::Iterator i(invalid_region); !i.done(); i.next()) + invalid_rects.push_back(i.rect()); + + SendToDesktop( + new ChromotingNetworkDesktopMsg_InvalidateRegion(invalid_rects)); +} + +void DesktopSessionProxy::CaptureFrame() { + if (!caller_task_runner_->BelongsToCurrentThread()) { + caller_task_runner_->PostTask( + FROM_HERE, base::Bind(&DesktopSessionProxy::CaptureFrame, this)); + return; + } + + ++pending_capture_frame_requests_; + SendToDesktop(new ChromotingNetworkDesktopMsg_CaptureFrame()); +} + +void DesktopSessionProxy::StartVideoCapturer( + IpcVideoFrameCapturer* video_capturer) { + DCHECK(video_capture_task_runner_->BelongsToCurrentThread()); + DCHECK(video_capturer_ == NULL); + + video_capturer_ = video_capturer; +} + +void DesktopSessionProxy::StopVideoCapturer() { + DCHECK(video_capture_task_runner_->BelongsToCurrentThread()); + + video_capturer_ = NULL; +} + void DesktopSessionProxy::DisconnectSession() { DCHECK(caller_task_runner_->BelongsToCurrentThread()); @@ -209,60 +281,6 @@ void DesktopSessionProxy::StartEventExecutor( client_clipboard_ = client_clipboard.Pass(); } -void DesktopSessionProxy::InvalidateRegion(const SkRegion& invalid_region) { - if (!caller_task_runner_->BelongsToCurrentThread()) { - caller_task_runner_->PostTask( - FROM_HERE, base::Bind(&DesktopSessionProxy::InvalidateRegion, this, - invalid_region)); - return; - } - - std::vector<SkIRect> invalid_rects; - for (SkRegion::Iterator i(invalid_region); !i.done(); i.next()) - invalid_rects.push_back(i.rect()); - - SendToDesktop( - new ChromotingNetworkDesktopMsg_InvalidateRegion(invalid_rects)); -} - -void DesktopSessionProxy::CaptureFrame() { - if (!caller_task_runner_->BelongsToCurrentThread()) { - caller_task_runner_->PostTask( - FROM_HERE, base::Bind(&DesktopSessionProxy::CaptureFrame, this)); - return; - } - - ++pending_capture_frame_requests_; - SendToDesktop(new ChromotingNetworkDesktopMsg_CaptureFrame()); -} - -void DesktopSessionProxy::StartAudioCapturer(IpcAudioCapturer* audio_capturer) { - DCHECK(audio_capture_task_runner_->BelongsToCurrentThread()); - DCHECK(audio_capturer_ == NULL); - - audio_capturer_ = audio_capturer; -} - -void DesktopSessionProxy::StopAudioCapturer() { - DCHECK(audio_capture_task_runner_->BelongsToCurrentThread()); - - audio_capturer_ = NULL; -} - -void DesktopSessionProxy::StartVideoCapturer( - IpcVideoFrameCapturer* video_capturer) { - DCHECK(video_capture_task_runner_->BelongsToCurrentThread()); - DCHECK(video_capturer_ == NULL); - - video_capturer_ = video_capturer; -} - -void DesktopSessionProxy::StopVideoCapturer() { - DCHECK(video_capture_task_runner_->BelongsToCurrentThread()); - - video_capturer_ = NULL; -} - DesktopSessionProxy::~DesktopSessionProxy() { } @@ -380,13 +398,15 @@ void DesktopSessionProxy::OnInjectClipboardEvent( const std::string& serialized_event) { DCHECK(caller_task_runner_->BelongsToCurrentThread()); - protocol::ClipboardEvent event; - if (!event.ParseFromString(serialized_event)) { - LOG(ERROR) << "Failed to parse protocol::ClipboardEvent."; - return; - } + if (client_clipboard_) { + protocol::ClipboardEvent event; + if (!event.ParseFromString(serialized_event)) { + LOG(ERROR) << "Failed to parse protocol::ClipboardEvent."; + return; + } - client_clipboard_->InjectClipboardEvent(event); + client_clipboard_->InjectClipboardEvent(event); + } } void DesktopSessionProxy::PostAudioPacket(scoped_ptr<AudioPacket> packet) { diff --git a/remoting/host/desktop_session_proxy.h b/remoting/host/desktop_session_proxy.h index fd0d0a7..9b6d461 100644 --- a/remoting/host/desktop_session_proxy.h +++ b/remoting/host/desktop_session_proxy.h @@ -15,6 +15,7 @@ #include "ipc/ipc_platform_file.h" #include "remoting/capturer/shared_buffer.h" #include "remoting/capturer/video_frame_capturer.h" +#include "remoting/host/desktop_environment.h" #include "remoting/proto/event.pb.h" #include "remoting/protocol/clipboard_stub.h" #include "third_party/skia/include/core/SkRegion.h" @@ -46,25 +47,29 @@ class IpcVideoFrameCapturer; // integration process. class DesktopSessionProxy : public base::RefCountedThreadSafe<DesktopSessionProxy>, + public DesktopEnvironment, public IPC::Listener { public: DesktopSessionProxy( - scoped_refptr<base::SingleThreadTaskRunner> audio_capture_task_runner, scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner); + const std::string& client_jid, + const base::Closure& disconnect_callback); + + // DesktopEnvironment implementation. + virtual scoped_ptr<AudioCapturer> CreateAudioCapturer( + scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner) OVERRIDE; + virtual scoped_ptr<EventExecutor> CreateEventExecutor( + scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) OVERRIDE; + virtual scoped_ptr<VideoFrameCapturer> CreateVideoCapturer( + scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> encode_task_runner) OVERRIDE; // IPC::Listener implementation. virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; virtual void OnChannelConnected(int32 peer_pid) OVERRIDE; virtual void OnChannelError() OVERRIDE; - // Initializes the object. |client_jid| specifies the client session's JID. - // |disconnect_callback| specifies a callback that disconnects the client - // session when invoked. - // Initialize() should be called before AttachToDesktop() is called. - void Initialize(const std::string& client_jid, - const base::Closure& disconnect_callback); - // Connects to the desktop session agent. bool AttachToDesktop(IPC::PlatformFileForTransit desktop_process, IPC::PlatformFileForTransit desktop_pipe); @@ -76,11 +81,6 @@ class DesktopSessionProxy // Disconnects the client session that owns |this|. void DisconnectSession(); - // APIs used to implement the VideoFrameCapturer interface. These must be - // called on |video_capture_task_runner_|. - void InvalidateRegion(const SkRegion& invalid_region); - void CaptureFrame(); - // Stores |audio_capturer| to be used to post captured audio packets. // |audio_capturer| must be valid until StopAudioCapturer() is called. void StartAudioCapturer(IpcAudioCapturer* audio_capturer); @@ -89,6 +89,11 @@ class DesktopSessionProxy // StopAudioCapturer() has been called will be silently dropped. void StopAudioCapturer(); + // APIs used to implement the VideoFrameCapturer interface. These must be + // called on |video_capture_task_runner_|. + void InvalidateRegion(const SkRegion& invalid_region); + void CaptureFrame(); + // Stores |video_capturer| to be used to post captured video frames. // |video_capturer| must be valid until StopVideoCapturer() is called. void StartVideoCapturer(IpcVideoFrameCapturer* video_capturer); diff --git a/remoting/host/host_mock_objects.cc b/remoting/host/host_mock_objects.cc index f9b6c52..2fa3d8f 100644 --- a/remoting/host/host_mock_objects.cc +++ b/remoting/host/host_mock_objects.cc @@ -5,20 +5,49 @@ #include "remoting/host/host_mock_objects.h" #include "base/message_loop_proxy.h" +#include "base/single_thread_task_runner.h" #include "net/base/ip_endpoint.h" #include "remoting/base/auto_thread_task_runner.h" +#include "remoting/capturer/video_frame_capturer.h" +#include "remoting/codec/audio_encoder.h" +#include "remoting/codec/video_encoder.h" +#include "remoting/host/audio_capturer.h" +#include "remoting/host/event_executor.h" #include "remoting/proto/event.pb.h" #include "remoting/protocol/transport.h" namespace remoting { -MockDesktopEnvironmentFactory::MockDesktopEnvironmentFactory() - : DesktopEnvironmentFactory(NULL, NULL) { +MockDesktopEnvironment::MockDesktopEnvironment() {} + +MockDesktopEnvironment::~MockDesktopEnvironment() {} + +scoped_ptr<AudioCapturer> MockDesktopEnvironment::CreateAudioCapturer( + scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner) { + return scoped_ptr<AudioCapturer>(CreateAudioCapturerPtr(audio_task_runner)); +} + +scoped_ptr<EventExecutor> MockDesktopEnvironment::CreateEventExecutor( + scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) { + return scoped_ptr<EventExecutor>(CreateEventExecutorPtr(input_task_runner, + ui_task_runner)); } +scoped_ptr<VideoFrameCapturer> MockDesktopEnvironment::CreateVideoCapturer( + scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> encode_task_runner) { + return scoped_ptr<VideoFrameCapturer>(CreateVideoCapturerPtr( + capture_task_runner, encode_task_runner)); +} + +MockDesktopEnvironmentFactory::MockDesktopEnvironmentFactory() {} + MockDesktopEnvironmentFactory::~MockDesktopEnvironmentFactory() {} -scoped_ptr<DesktopEnvironment> MockDesktopEnvironmentFactory::Create() { +scoped_ptr<DesktopEnvironment> MockDesktopEnvironmentFactory::Create( + const std::string& client_jid, + const base::Closure& disconnect_callback) { return scoped_ptr<DesktopEnvironment>(CreatePtr()); } diff --git a/remoting/host/host_mock_objects.h b/remoting/host/host_mock_objects.h index e8dd33a..93ef0d6 100644 --- a/remoting/host/host_mock_objects.h +++ b/remoting/host/host_mock_objects.h @@ -10,7 +10,6 @@ #include "remoting/host/client_session.h" #include "remoting/host/continue_window.h" #include "remoting/host/desktop_environment.h" -#include "remoting/host/desktop_environment_factory.h" #include "remoting/host/disconnect_window.h" #include "remoting/host/event_executor.h" #include "remoting/host/host_status_observer.h" @@ -19,8 +18,38 @@ #include "remoting/proto/control.pb.h" #include "testing/gmock/include/gmock/gmock.h" +namespace base { +class SingleThreadTaskRunner; +} // namespace base + namespace remoting { +class MockDesktopEnvironment : public DesktopEnvironment { + public: + MockDesktopEnvironment(); + virtual ~MockDesktopEnvironment(); + + MOCK_METHOD1(CreateAudioCapturerPtr, + AudioCapturer*(scoped_refptr<base::SingleThreadTaskRunner>)); + MOCK_METHOD2(CreateEventExecutorPtr, + EventExecutor*(scoped_refptr<base::SingleThreadTaskRunner>, + scoped_refptr<base::SingleThreadTaskRunner>)); + MOCK_METHOD2( + CreateVideoCapturerPtr, + VideoFrameCapturer*(scoped_refptr<base::SingleThreadTaskRunner>, + scoped_refptr<base::SingleThreadTaskRunner>)); + + // DesktopEnvironment implementation. + virtual scoped_ptr<AudioCapturer> CreateAudioCapturer( + scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner) OVERRIDE; + virtual scoped_ptr<EventExecutor> CreateEventExecutor( + scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) OVERRIDE; + virtual scoped_ptr<VideoFrameCapturer> CreateVideoCapturer( + scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> encode_task_runner) OVERRIDE; +}; + class MockDisconnectWindow : public DisconnectWindow { public: MockDisconnectWindow(); @@ -81,8 +110,11 @@ class MockDesktopEnvironmentFactory : public DesktopEnvironmentFactory { virtual ~MockDesktopEnvironmentFactory(); MOCK_METHOD0(CreatePtr, DesktopEnvironment*()); + MOCK_CONST_METHOD0(SupportsAudioCapture, bool()); - virtual scoped_ptr<DesktopEnvironment> Create() OVERRIDE; + virtual scoped_ptr<DesktopEnvironment> Create( + const std::string& client_jid, + const base::Closure& disconnect_callback) OVERRIDE; private: DISALLOW_COPY_AND_ASSIGN(MockDesktopEnvironmentFactory); diff --git a/remoting/host/ipc_audio_capturer.h b/remoting/host/ipc_audio_capturer.h index f6048b4..cdbae59 100644 --- a/remoting/host/ipc_audio_capturer.h +++ b/remoting/host/ipc_audio_capturer.h @@ -18,7 +18,8 @@ class DesktopSessionProxy; class IpcAudioCapturer : public AudioCapturer { public: - IpcAudioCapturer(scoped_refptr<DesktopSessionProxy> desktop_session_proxy); + explicit IpcAudioCapturer( + scoped_refptr<DesktopSessionProxy> desktop_session_proxy); virtual ~IpcAudioCapturer(); // AudioCapturer interface. diff --git a/remoting/host/ipc_desktop_environment.cc b/remoting/host/ipc_desktop_environment.cc index 699f06a..bc657a5 100644 --- a/remoting/host/ipc_desktop_environment.cc +++ b/remoting/host/ipc_desktop_environment.cc @@ -4,73 +4,184 @@ #include "remoting/host/ipc_desktop_environment.h" +#include <utility> + #include "base/callback.h" #include "base/compiler_specific.h" #include "base/logging.h" -#include "base/platform_file.h" #include "base/single_thread_task_runner.h" #include "ipc/ipc_channel_proxy.h" -#include "ipc/ipc_message_macros.h" -#include "remoting/capturer/capture_data.h" #include "remoting/capturer/video_frame_capturer.h" #include "remoting/host/audio_capturer.h" #include "remoting/host/chromoting_messages.h" -#include "remoting/host/client_session.h" -#include "remoting/host/desktop_session_connector.h" #include "remoting/host/desktop_session_proxy.h" #include "remoting/host/event_executor.h" -#include "remoting/host/ipc_audio_capturer.h" -#include "remoting/host/ipc_event_executor.h" -#include "remoting/host/ipc_video_frame_capturer.h" - -#if defined(OS_WIN) -#include "base/win/scoped_handle.h" -#endif // defined(OS_WIN) namespace remoting { IpcDesktopEnvironment::IpcDesktopEnvironment( - scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> network_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, - DesktopSessionConnector* desktop_session_connector, - scoped_refptr<DesktopSessionProxy> desktop_session_proxy) - : DesktopEnvironment( - scoped_ptr<AudioCapturer>( - new IpcAudioCapturer(desktop_session_proxy)), - scoped_ptr<EventExecutor>( - new IpcEventExecutor(desktop_session_proxy)), - scoped_ptr<VideoFrameCapturer>( - new IpcVideoFrameCapturer(desktop_session_proxy))), - network_task_runner_(network_task_runner), + scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, + const std::string& client_jid, + const base::Closure& disconnect_callback, + base::WeakPtr<DesktopSessionConnector> desktop_session_connector) + : caller_task_runner_(caller_task_runner), + connected_(false), desktop_session_connector_(desktop_session_connector), - desktop_session_proxy_(desktop_session_proxy), - connected_(false) { + desktop_session_proxy_(new DesktopSessionProxy(caller_task_runner, + client_jid, + disconnect_callback)) { + DCHECK(caller_task_runner_->BelongsToCurrentThread()); } IpcDesktopEnvironment::~IpcDesktopEnvironment() { - if (connected_) { - connected_ = false; + DCHECK(caller_task_runner_->BelongsToCurrentThread()); + + if (connected_ && desktop_session_connector_) desktop_session_connector_->DisconnectTerminal(desktop_session_proxy_); +} + +scoped_ptr<AudioCapturer> IpcDesktopEnvironment::CreateAudioCapturer( + scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner) { + DCHECK(caller_task_runner_->BelongsToCurrentThread()); + + ConnectToDesktopSession(); + return desktop_session_proxy_->CreateAudioCapturer(audio_task_runner); +} + +scoped_ptr<EventExecutor> IpcDesktopEnvironment::CreateEventExecutor( + scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) { + DCHECK(caller_task_runner_->BelongsToCurrentThread()); + + ConnectToDesktopSession(); + return desktop_session_proxy_->CreateEventExecutor(input_task_runner, + ui_task_runner); +} + +scoped_ptr<VideoFrameCapturer> IpcDesktopEnvironment::CreateVideoCapturer( + scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> encode_task_runner) { + DCHECK(caller_task_runner_->BelongsToCurrentThread()); + + ConnectToDesktopSession(); + return desktop_session_proxy_->CreateVideoCapturer(capture_task_runner, + encode_task_runner); +} + +void IpcDesktopEnvironment::ConnectToDesktopSession() { + DCHECK(caller_task_runner_->BelongsToCurrentThread()); + + if (!connected_) { + connected_ = true; + desktop_session_connector_->ConnectTerminal(desktop_session_proxy_); } } -void IpcDesktopEnvironment::Start( - scoped_ptr<protocol::ClipboardStub> client_clipboard, +IpcDesktopEnvironmentFactory::IpcDesktopEnvironmentFactory( + scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, + IPC::ChannelProxy* daemon_channel) + : caller_task_runner_(caller_task_runner), + daemon_channel_(daemon_channel), + connector_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), + next_id_(0) { +} + +IpcDesktopEnvironmentFactory::~IpcDesktopEnvironmentFactory() { + DCHECK(caller_task_runner_->BelongsToCurrentThread()); +} + +scoped_ptr<DesktopEnvironment> IpcDesktopEnvironmentFactory::Create( const std::string& client_jid, const base::Closure& disconnect_callback) { - DCHECK(network_task_runner_->BelongsToCurrentThread()); - DCHECK(!connected_); + DCHECK(caller_task_runner_->BelongsToCurrentThread()); + + return scoped_ptr<DesktopEnvironment>(new IpcDesktopEnvironment( + caller_task_runner_, client_jid, disconnect_callback, + connector_factory_.GetWeakPtr())); +} + +bool IpcDesktopEnvironmentFactory::SupportsAudioCapture() const { + DCHECK(caller_task_runner_->BelongsToCurrentThread()); + + return AudioCapturer::IsSupported(); +} + +void IpcDesktopEnvironmentFactory::ConnectTerminal( + scoped_refptr<DesktopSessionProxy> desktop_session_proxy) { + DCHECK(caller_task_runner_->BelongsToCurrentThread()); + + int id = next_id_++; + bool inserted = active_connections_.insert( + std::make_pair(id, desktop_session_proxy)).second; + CHECK(inserted); + + VLOG(1) << "Network: registered desktop environment " << id; + daemon_channel_->Send(new ChromotingNetworkHostMsg_ConnectTerminal(id)); +} + +void IpcDesktopEnvironmentFactory::DisconnectTerminal( + scoped_refptr<DesktopSessionProxy> desktop_session_proxy) { + DCHECK(caller_task_runner_->BelongsToCurrentThread()); + + ActiveConnectionsList::iterator i; + for (i = active_connections_.begin(); i != active_connections_.end(); ++i) { + if (i->second.get() == desktop_session_proxy.get()) + break; + } + + if (i != active_connections_.end()) { + int id = i->first; + active_connections_.erase(i); - desktop_session_proxy_->Initialize(client_jid, disconnect_callback); + VLOG(1) << "Network: unregistered desktop environment " << id; + daemon_channel_->Send(new ChromotingNetworkHostMsg_DisconnectTerminal(id)); + } +} + +void IpcDesktopEnvironmentFactory::OnDesktopSessionAgentAttached( + int terminal_id, + IPC::PlatformFileForTransit desktop_process, + IPC::PlatformFileForTransit desktop_pipe) { + if (!caller_task_runner_->BelongsToCurrentThread()) { + caller_task_runner_->PostTask(FROM_HERE, base::Bind( + &IpcDesktopEnvironmentFactory::OnDesktopSessionAgentAttached, + base::Unretained(this), terminal_id, desktop_process, desktop_pipe)); + return; + } + + ActiveConnectionsList::iterator i = active_connections_.find(terminal_id); + if (i != active_connections_.end()) { + i->second->DetachFromDesktop(); + i->second->AttachToDesktop(desktop_process, desktop_pipe); + } else { +#if defined(OS_POSIX) + DCHECK(desktop_process.auto_close); + DCHECK(desktop_pipe.auto_close); + + base::ClosePlatformFile(desktop_process.fd); + base::ClosePlatformFile(desktop_pipe.fd); +#elif defined(OS_WIN) + base::ClosePlatformFile(desktop_process); +#endif // defined(OS_WIN) + } +} - // Register the proxy to receive AttachToDesktop() and DetachFromDesktop() - // notifications. - connected_ = true; - desktop_session_connector_->ConnectTerminal(desktop_session_proxy_); +void IpcDesktopEnvironmentFactory::OnTerminalDisconnected(int terminal_id) { + if (!caller_task_runner_->BelongsToCurrentThread()) { + caller_task_runner_->PostTask(FROM_HERE, base::Bind( + &IpcDesktopEnvironmentFactory::OnTerminalDisconnected, + base::Unretained(this), terminal_id)); + return; + } + + ActiveConnectionsList::iterator i = active_connections_.find(terminal_id); + if (i != active_connections_.end()) { + scoped_refptr<DesktopSessionProxy> desktop_session_proxy = i->second; + active_connections_.erase(i); - DesktopEnvironment::Start(client_clipboard.Pass(), client_jid, - disconnect_callback); + // Disconnect the client session. + desktop_session_proxy->DisconnectSession(); + } } } // namespace remoting diff --git a/remoting/host/ipc_desktop_environment.h b/remoting/host/ipc_desktop_environment.h index 53b5c0f..c851221 100644 --- a/remoting/host/ipc_desktop_environment.h +++ b/remoting/host/ipc_desktop_environment.h @@ -5,55 +5,123 @@ #ifndef REMOTING_HOST_IPC_DESKTOP_ENVIRONMENT_H_ #define REMOTING_HOST_IPC_DESKTOP_ENVIRONMENT_H_ +#include <map> +#include <string> + #include "base/basictypes.h" #include "base/callback_forward.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" -#include "ipc/ipc_platform_file.h" +#include "base/memory/weak_ptr.h" #include "remoting/host/desktop_environment.h" +#include "remoting/host/desktop_session_connector.h" namespace base { class SingleThreadTaskRunner; } // base +namespace IPC { +class ChannelProxy; +} // namespace IPC + namespace remoting { -class DesktopSessionConnector; class DesktopSessionProxy; // A variant of desktop environment integrating with the desktop by means of // a helper process and talking to that process via IPC. class IpcDesktopEnvironment : public DesktopEnvironment { public: - // |desktop_session_connector| is used to bind the IpcDesktopEnvironment to - // a desktop session, to be notified with a new IPC channel every time - // the desktop process is changed. |desktop_session_connector| must outlive - // |this|. |client| specifies the client session owning |this|. + // |desktop_session_connector| is used to bind DesktopSessionProxy to + // a desktop session, to be notified every time the desktop process is + // restarted. IpcDesktopEnvironment( - scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> network_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, - DesktopSessionConnector* desktop_session_connector, - scoped_refptr<DesktopSessionProxy> desktop_session_proxy); + scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, + const std::string& client_jid, + const base::Closure& disconnect_callback, + base::WeakPtr<DesktopSessionConnector> desktop_session_connector); virtual ~IpcDesktopEnvironment(); - virtual void Start( - scoped_ptr<protocol::ClipboardStub> client_clipboard, + // DesktopEnvironment implementation. + virtual scoped_ptr<AudioCapturer> CreateAudioCapturer( + scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner) OVERRIDE; + virtual scoped_ptr<EventExecutor> CreateEventExecutor( + scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) OVERRIDE; + virtual scoped_ptr<VideoFrameCapturer> CreateVideoCapturer( + scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> encode_task_runner) OVERRIDE; + + private: + // Binds DesktopSessionProxy to a desktop session if it is not bound already. + void ConnectToDesktopSession(); + + // Task runner on which public methods of this class should be called. + scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_; + + // True if |desktop_session_proxy_| is connected to a desktop session. + bool connected_; + + // Used to bind to a desktop session and receive notifications every time + // the desktop process is replaced. + base::WeakPtr<DesktopSessionConnector> desktop_session_connector_; + + scoped_refptr<DesktopSessionProxy> desktop_session_proxy_; + + DISALLOW_COPY_AND_ASSIGN(IpcDesktopEnvironment); +}; + +// Used to create IpcDesktopEnvironment objects integrating with the desktop via +// a helper process and talking to that process via IPC. +class IpcDesktopEnvironmentFactory + : public DesktopEnvironmentFactory, + public DesktopSessionConnector { + public: + // Passes a reference to the IPC channel connected to the daemon process and + // relevant task runners. |daemon_channel| must outlive this object. + IpcDesktopEnvironmentFactory( + scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, + IPC::ChannelProxy* daemon_channel); + virtual ~IpcDesktopEnvironmentFactory(); + + // DesktopEnvironmentFactory implementation. + virtual scoped_ptr<DesktopEnvironment> Create( const std::string& client_jid, const base::Closure& disconnect_callback) OVERRIDE; + virtual bool SupportsAudioCapture() const OVERRIDE; + + // DesktopSessionConnector implementation. + virtual void ConnectTerminal( + scoped_refptr<DesktopSessionProxy> desktop_session_proxy) OVERRIDE; + virtual void DisconnectTerminal( + scoped_refptr<DesktopSessionProxy> desktop_session_proxy) OVERRIDE; + virtual void OnDesktopSessionAgentAttached( + int terminal_id, + IPC::PlatformFileForTransit desktop_process, + IPC::PlatformFileForTransit desktop_pipe) OVERRIDE; + virtual void OnTerminalDisconnected(int terminal_id) OVERRIDE; private: - // Used for IPC I/O. - scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_; + // Task runner on which public methods of this class should be called. + scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_; - DesktopSessionConnector* desktop_session_connector_; + // IPC channel connected to the daemon process. + IPC::ChannelProxy* daemon_channel_; - scoped_refptr<DesktopSessionProxy> desktop_session_proxy_; + // List of DesktopEnvironment instances we've told the daemon process about. + typedef std::map<int, scoped_refptr<DesktopSessionProxy> > + ActiveConnectionsList; + ActiveConnectionsList active_connections_; - // True if |this| has been connected to a desktop session. - bool connected_; + // Factory for weak pointers to DesktopSessionConnector interface. + base::WeakPtrFactory<DesktopSessionConnector> connector_factory_; - DISALLOW_COPY_AND_ASSIGN(IpcDesktopEnvironment); + // Next desktop session ID. IDs are allocated sequentially starting from 0. + // This gives us more than 67 years of unique IDs assuming a new ID is + // allocated every second. + int next_id_; + + DISALLOW_COPY_AND_ASSIGN(IpcDesktopEnvironmentFactory); }; } // namespace remoting diff --git a/remoting/host/ipc_desktop_environment_factory.cc b/remoting/host/ipc_desktop_environment_factory.cc deleted file mode 100644 index 250b4f4..0000000 --- a/remoting/host/ipc_desktop_environment_factory.cc +++ /dev/null @@ -1,132 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "remoting/host/ipc_desktop_environment_factory.h" - -#include <utility> - -#include "ipc/ipc_channel_proxy.h" -#include "base/platform_file.h" -#include "remoting/capturer/video_frame_capturer.h" -#include "remoting/host/audio_capturer.h" -#include "remoting/host/chromoting_host.h" -#include "remoting/host/chromoting_host_context.h" -#include "remoting/host/chromoting_messages.h" -#include "remoting/host/desktop_session_connector.h" -#include "remoting/host/desktop_session_proxy.h" -#include "remoting/host/event_executor.h" -#include "remoting/host/ipc_desktop_environment.h" - -namespace remoting { - -IpcDesktopEnvironmentFactory::IpcDesktopEnvironmentFactory( - IPC::ChannelProxy* daemon_channel, - scoped_refptr<base::SingleThreadTaskRunner> audio_capture_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> network_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner) - : DesktopEnvironmentFactory(input_task_runner, ui_task_runner), - daemon_channel_(daemon_channel), - audio_capture_task_runner_(audio_capture_task_runner), - network_task_runner_(network_task_runner), - video_capture_task_runner_(video_capture_task_runner), - next_id_(0) { -} - -IpcDesktopEnvironmentFactory::~IpcDesktopEnvironmentFactory() { -} - -scoped_ptr<DesktopEnvironment> IpcDesktopEnvironmentFactory::Create() { - DCHECK(network_task_runner_->BelongsToCurrentThread()); - - scoped_refptr<DesktopSessionProxy> desktop_session_proxy( - new DesktopSessionProxy(audio_capture_task_runner_, - network_task_runner_, - video_capture_task_runner_)); - - return scoped_ptr<DesktopEnvironment>(new IpcDesktopEnvironment( - input_task_runner_, network_task_runner_, ui_task_runner_, - this, desktop_session_proxy)); -} - -void IpcDesktopEnvironmentFactory::ConnectTerminal( - scoped_refptr<DesktopSessionProxy> desktop_session_proxy) { - DCHECK(network_task_runner_->BelongsToCurrentThread()); - - int id = next_id_++; - bool inserted = active_connections_.insert( - std::make_pair(id, desktop_session_proxy)).second; - CHECK(inserted); - - VLOG(1) << "Network: registered desktop environment " << id; - daemon_channel_->Send(new ChromotingNetworkHostMsg_ConnectTerminal(id)); -} - -void IpcDesktopEnvironmentFactory::DisconnectTerminal( - scoped_refptr<DesktopSessionProxy> desktop_session_proxy) { - DCHECK(network_task_runner_->BelongsToCurrentThread()); - - ActiveConnectionsList::iterator i; - for (i = active_connections_.begin(); i != active_connections_.end(); ++i) { - if (i->second.get() == desktop_session_proxy.get()) - break; - } - - if (i != active_connections_.end()) { - int id = i->first; - active_connections_.erase(i); - - VLOG(1) << "Network: unregistered desktop environment " << id; - daemon_channel_->Send(new ChromotingNetworkHostMsg_DisconnectTerminal(id)); - } -} - -void IpcDesktopEnvironmentFactory::OnDesktopSessionAgentAttached( - int terminal_id, - IPC::PlatformFileForTransit desktop_process, - IPC::PlatformFileForTransit desktop_pipe) { - if (!network_task_runner_->BelongsToCurrentThread()) { - network_task_runner_->PostTask(FROM_HERE, base::Bind( - &IpcDesktopEnvironmentFactory::OnDesktopSessionAgentAttached, - base::Unretained(this), terminal_id, desktop_process, desktop_pipe)); - return; - } - - ActiveConnectionsList::iterator i = active_connections_.find(terminal_id); - if (i != active_connections_.end()) { - i->second->DetachFromDesktop(); - i->second->AttachToDesktop(desktop_process, desktop_pipe); - } else { -#if defined(OS_POSIX) - DCHECK(desktop_process.auto_close); - DCHECK(desktop_pipe.auto_close); - - base::ClosePlatformFile(desktop_process.fd); - base::ClosePlatformFile(desktop_pipe.fd); -#elif defined(OS_WIN) - base::ClosePlatformFile(desktop_process); -#endif // defined(OS_WIN) - } -} - -void IpcDesktopEnvironmentFactory::OnTerminalDisconnected(int terminal_id) { - if (!network_task_runner_->BelongsToCurrentThread()) { - network_task_runner_->PostTask(FROM_HERE, base::Bind( - &IpcDesktopEnvironmentFactory::OnTerminalDisconnected, - base::Unretained(this), terminal_id)); - return; - } - - ActiveConnectionsList::iterator i = active_connections_.find(terminal_id); - if (i != active_connections_.end()) { - scoped_refptr<DesktopSessionProxy> desktop_session_proxy = i->second; - active_connections_.erase(i); - - // Disconnect the client session. - desktop_session_proxy->DisconnectSession(); - } -} - -} // namespace remoting diff --git a/remoting/host/ipc_desktop_environment_factory.h b/remoting/host/ipc_desktop_environment_factory.h deleted file mode 100644 index 17ee314..0000000 --- a/remoting/host/ipc_desktop_environment_factory.h +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef REMOTING_HOST_IPC_DESKTOP_ENVIRONMENT_FACTORY_H_ -#define REMOTING_HOST_IPC_DESKTOP_ENVIRONMENT_FACTORY_H_ - -#include <map> - -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" -#include "remoting/host/desktop_environment_factory.h" -#include "remoting/host/desktop_session_connector.h" - -namespace IPC { -class ChannelProxy; -} // namespace IPC - -namespace remoting { - -class DesktopSessionConnector; -class DesktopSessionProxy; - -// Used to create IpcDesktopEnvironment objects intergating with the desktop via -// a helper process and talking to that process via IPC. -class IpcDesktopEnvironmentFactory - : public DesktopEnvironmentFactory, - public DesktopSessionConnector { - public: - // Passes a reference to the IPC channel connected to the daemon process and - // relevant task runners. |daemon_channel| must outlive this object. - IpcDesktopEnvironmentFactory( - IPC::ChannelProxy* daemon_channel, - scoped_refptr<base::SingleThreadTaskRunner> audio_capture_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> network_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner); - virtual ~IpcDesktopEnvironmentFactory(); - - virtual scoped_ptr<DesktopEnvironment> Create() OVERRIDE; - - // DesktopSessionConnector implementation. - virtual void ConnectTerminal( - scoped_refptr<DesktopSessionProxy> desktop_session_proxy) OVERRIDE; - virtual void DisconnectTerminal( - scoped_refptr<DesktopSessionProxy> desktop_session_proxy) OVERRIDE; - virtual void OnDesktopSessionAgentAttached( - int terminal_id, - IPC::PlatformFileForTransit desktop_process, - IPC::PlatformFileForTransit desktop_pipe) OVERRIDE; - virtual void OnTerminalDisconnected(int terminal_id) OVERRIDE; - - private: - // IPC channel connected to the daemon process. - IPC::ChannelProxy* daemon_channel_; - - // Task runner used to run the audio capturer. - scoped_refptr<base::SingleThreadTaskRunner> audio_capture_task_runner_; - - // Task runner used to service calls to the DesktopSessionConnector APIs. - scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_; - - // Task runner used to run the video capturer. - scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner_; - - // List of DesktopEnvironment instances we've told the daemon process about. - typedef std::map<int, scoped_refptr<DesktopSessionProxy> > - ActiveConnectionsList; - ActiveConnectionsList active_connections_; - - // Next desktop session ID. IDs are allocated sequentially starting from 0. - // This gives us more than 67 years of unique IDs assuming a new ID is - // allocated every second. - int next_id_; - - DISALLOW_COPY_AND_ASSIGN(IpcDesktopEnvironmentFactory); -}; - -} // namespace remoting - -#endif // REMOTING_HOST_IPC_DESKTOP_ENVIRONMENT_FACTORY_H_ diff --git a/remoting/host/ipc_event_executor.h b/remoting/host/ipc_event_executor.h index 5316783..184dee5 100644 --- a/remoting/host/ipc_event_executor.h +++ b/remoting/host/ipc_event_executor.h @@ -17,7 +17,8 @@ class DesktopSessionProxy; // agent running in the desktop integration process. class IpcEventExecutor : public EventExecutor { public: - IpcEventExecutor(scoped_refptr<DesktopSessionProxy> desktop_session_proxy); + explicit IpcEventExecutor( + scoped_refptr<DesktopSessionProxy> desktop_session_proxy); virtual ~IpcEventExecutor(); // ClipboardStub interface. diff --git a/remoting/host/plugin/host_script_object.cc b/remoting/host/plugin/host_script_object.cc index d863899..2133b60 100644 --- a/remoting/host/plugin/host_script_object.cc +++ b/remoting/host/plugin/host_script_object.cc @@ -17,9 +17,9 @@ #include "net/base/net_util.h" #include "remoting/base/auth_token_util.h" #include "remoting/base/auto_thread.h" +#include "remoting/host/basic_desktop_environment.h" #include "remoting/host/chromoting_host.h" #include "remoting/host/chromoting_host_context.h" -#include "remoting/host/desktop_environment_factory.h" #include "remoting/host/host_config.h" #include "remoting/host/host_event_logger.h" #include "remoting/host/host_key_pair.h" @@ -214,8 +214,7 @@ void HostNPScriptObject::It2MeImpl::Connect( } // Create the desktop environment factory. - desktop_environment_factory_.reset(new DesktopEnvironmentFactory( - host_context_->input_task_runner(), host_context_->ui_task_runner())); + desktop_environment_factory_.reset(new BasicDesktopEnvironmentFactory()); // Start monitoring configured policies. policy_watcher_.reset( @@ -366,9 +365,11 @@ void HostNPScriptObject::It2MeImpl::FinishConnect( CreateHostSessionManager(network_settings, host_context_->url_request_context_getter()), host_context_->audio_task_runner(), + host_context_->input_task_runner(), host_context_->video_capture_task_runner(), host_context_->video_encode_task_runner(), - host_context_->network_task_runner()); + host_context_->network_task_runner(), + host_context_->ui_task_runner()); host_->AddStatusObserver(this); log_to_server_.reset( new LogToServer(host_, ServerLogEntry::IT2ME, signal_strategy_.get())); diff --git a/remoting/host/remoting_me2me_host.cc b/remoting/host/remoting_me2me_host.cc index 65bd8cc..01a9175 100644 --- a/remoting/host/remoting_me2me_host.cc +++ b/remoting/host/remoting_me2me_host.cc @@ -34,6 +34,7 @@ #include "remoting/base/breakpad.h" #include "remoting/base/constants.h" #include "remoting/capturer/video_frame_capturer.h" +#include "remoting/host/basic_desktop_environment.h" #include "remoting/host/branding.h" #include "remoting/host/chromoting_host.h" #include "remoting/host/chromoting_host_context.h" @@ -41,7 +42,7 @@ #include "remoting/host/config_file_watcher.h" #include "remoting/host/curtain_mode.h" #include "remoting/host/curtaining_host_observer.h" -#include "remoting/host/desktop_environment_factory.h" +#include "remoting/host/desktop_environment.h" #include "remoting/host/desktop_resizer.h" #include "remoting/host/desktop_session_connector.h" #include "remoting/host/dns_blackhole_checker.h" @@ -52,7 +53,7 @@ #include "remoting/host/host_exit_codes.h" #include "remoting/host/host_user_interface.h" #include "remoting/host/ipc_constants.h" -#include "remoting/host/ipc_desktop_environment_factory.h" +#include "remoting/host/ipc_desktop_environment.h" #include "remoting/host/json_host_config.h" #include "remoting/host/log_to_server.h" #include "remoting/host/logging.h" @@ -85,7 +86,7 @@ #if defined(OS_WIN) #include <commctrl.h> #include "base/win/scoped_handle.h" -#include "remoting/host/win/session_desktop_environment_factory.h" +#include "remoting/host/win/session_desktop_environment.h" #endif // defined(OS_WIN) #if defined(TOOLKIT_GTK) @@ -569,24 +570,18 @@ void HostProcess::StartOnUiThread() { #if defined(REMOTING_MULTI_PROCESS) IpcDesktopEnvironmentFactory* desktop_environment_factory = new IpcDesktopEnvironmentFactory( - daemon_channel_.get(), - context_->audio_task_runner(), - context_->input_task_runner(), context_->network_task_runner(), - context_->ui_task_runner(), - context_->video_capture_task_runner()); + daemon_channel_.get()); desktop_session_connector_ = desktop_environment_factory; #else // !defined(REMOTING_MULTI_PROCESS) DesktopEnvironmentFactory* desktop_environment_factory = new SessionDesktopEnvironmentFactory( - context_->input_task_runner(), context_->ui_task_runner(), base::Bind(&HostProcess::SendSasToConsole, this)); #endif // !defined(REMOTING_MULTI_PROCESS) #else // !defined(OS_WIN) DesktopEnvironmentFactory* desktop_environment_factory = - new DesktopEnvironmentFactory( - context_->input_task_runner(), context_->ui_task_runner()); + new BasicDesktopEnvironmentFactory(); #endif // !defined(OS_WIN) desktop_environment_factory_.reset(desktop_environment_factory); @@ -894,9 +889,11 @@ void HostProcess::StartHost() { CreateHostSessionManager(network_settings, context_->url_request_context_getter()), context_->audio_task_runner(), + context_->input_task_runner(), context_->video_capture_task_runner(), context_->video_encode_task_runner(), - context_->network_task_runner()); + context_->network_task_runner(), + context_->ui_task_runner()); // TODO(simonmorris): Get the maximum session duration from a policy. #if defined(OS_LINUX) diff --git a/remoting/host/video_scheduler.cc b/remoting/host/video_scheduler.cc index 75c7c12..5f2acae 100644 --- a/remoting/host/video_scheduler.cc +++ b/remoting/host/video_scheduler.cc @@ -36,7 +36,7 @@ scoped_refptr<VideoScheduler> VideoScheduler::Create( scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner, scoped_refptr<base::SingleThreadTaskRunner> encode_task_runner, scoped_refptr<base::SingleThreadTaskRunner> network_task_runner, - VideoFrameCapturer* capturer, + scoped_ptr<VideoFrameCapturer> capturer, scoped_ptr<VideoEncoder> encoder, protocol::CursorShapeStub* cursor_stub, protocol::VideoStub* video_stub) { @@ -48,7 +48,7 @@ scoped_refptr<VideoScheduler> VideoScheduler::Create( scoped_refptr<VideoScheduler> scheduler = new VideoScheduler( capture_task_runner, encode_task_runner, network_task_runner, - capturer, encoder.Pass(), cursor_stub, video_stub); + capturer.Pass(), encoder.Pass(), cursor_stub, video_stub); capture_task_runner->PostTask( FROM_HERE, base::Bind(&VideoScheduler::StartOnCaptureThread, scheduler)); @@ -94,16 +94,15 @@ void VideoScheduler::OnCursorShapeChanged( base::Passed(&cursor_proto))); } -void VideoScheduler::Stop(const base::Closure& done_task) { +void VideoScheduler::Stop() { DCHECK(network_task_runner_->BelongsToCurrentThread()); - DCHECK(!done_task.is_null()); // Clear stubs to prevent further updates reaching the client. cursor_stub_ = NULL; video_stub_ = NULL; capture_task_runner_->PostTask(FROM_HERE, - base::Bind(&VideoScheduler::StopOnCaptureThread, this, done_task)); + base::Bind(&VideoScheduler::StopOnCaptureThread, this)); } void VideoScheduler::Pause(bool pause) { @@ -141,14 +140,14 @@ VideoScheduler::VideoScheduler( scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner, scoped_refptr<base::SingleThreadTaskRunner> encode_task_runner, scoped_refptr<base::SingleThreadTaskRunner> network_task_runner, - VideoFrameCapturer* capturer, + scoped_ptr<VideoFrameCapturer> capturer, scoped_ptr<VideoEncoder> encoder, protocol::CursorShapeStub* cursor_stub, protocol::VideoStub* video_stub) : capture_task_runner_(capture_task_runner), encode_task_runner_(encode_task_runner), network_task_runner_(network_task_runner), - capturer_(capturer), + capturer_(capturer.Pass()), encoder_(encoder.Pass()), cursor_stub_(cursor_stub), video_stub_(video_stub), @@ -175,22 +174,23 @@ void VideoScheduler::StartOnCaptureThread() { CaptureNextFrame(); } -void VideoScheduler::StopOnCaptureThread(const base::Closure& done_task) { +void VideoScheduler::StopOnCaptureThread() { DCHECK(capture_task_runner_->BelongsToCurrentThread()); // Stop |capturer_| and clear it to prevent pending tasks from using it. capturer_->Stop(); - capturer_ = NULL; // |capture_timer_| must be destroyed on the thread on which it is used. capture_timer_.reset(); - // Ensure that the encode thread is no longer processing capture data, - // otherwise tearing down |capturer_| will crash it. See crbug.com/163641. + // Schedule deletion of |capturer_| once the encode thread is no longer + // processing capture data. See http://crbug.com/163641. This also clears + // |capturer_| pointer to prevent pending tasks from using it. // TODO(wez): Make it safe to tear down capturer while buffers remain, and // remove this work-around. - encode_task_runner_->PostTask(FROM_HERE, - base::Bind(&VideoScheduler::StopOnEncodeThread, this, done_task)); + encode_task_runner_->PostTask( + FROM_HERE, base::Bind(&VideoScheduler::StopOnEncodeThread, this, + base::Passed(&capturer_))); } void VideoScheduler::ScheduleNextCapture() { @@ -278,6 +278,14 @@ void VideoScheduler::SendCursorShape( cursor_stub_->SetCursorShape(*cursor_shape); } +void VideoScheduler::StopOnNetworkThread( + scoped_ptr<VideoFrameCapturer> capturer) { + DCHECK(network_task_runner_->BelongsToCurrentThread()); + + // This is posted by StopOnEncodeThread meaning that both capture and encode + // threads are stopped now and it is safe to delete |capturer|. +} + // Encoder thread -------------------------------------------------------------- void VideoScheduler::EncodeFrame( @@ -314,12 +322,16 @@ void VideoScheduler::EncodedDataAvailableCallback( base::Passed(&packet))); } -void VideoScheduler::StopOnEncodeThread(const base::Closure& done_task) { +void VideoScheduler::StopOnEncodeThread( + scoped_ptr<VideoFrameCapturer> capturer) { DCHECK(encode_task_runner_->BelongsToCurrentThread()); // This is posted by StopOnCaptureThread, so we know that by the time we - // process it there are no more encode tasks queued. - network_task_runner_->PostTask(FROM_HERE, done_task); + // process it there are no more encode tasks queued. Pass |capturer_| for + // deletion on the thread that created it. + network_task_runner_->PostTask( + FROM_HERE, base::Bind(&VideoScheduler::StopOnNetworkThread, this, + base::Passed(&capturer))); } } // namespace remoting diff --git a/remoting/host/video_scheduler.h b/remoting/host/video_scheduler.h index 61b9009..752dcbe 100644 --- a/remoting/host/video_scheduler.h +++ b/remoting/host/video_scheduler.h @@ -8,7 +8,6 @@ #include <vector> #include "base/basictypes.h" -#include "base/callback.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "base/time.h" @@ -17,6 +16,7 @@ #include "remoting/codec/video_encoder.h" #include "remoting/host/capture_scheduler.h" #include "remoting/proto/video.pb.h" +#include "third_party/skia/include/core/SkSize.h" namespace base { class SingleThreadTaskRunner; @@ -76,13 +76,12 @@ class VideoScheduler : public base::RefCountedThreadSafe<VideoScheduler>, // Creates a VideoScheduler running capture, encode and network tasks on the // supplied TaskRunners. Video and cursor shape updates will be pumped to // |video_stub| and |client_stub|, which must remain valid until Stop() is - // called. |capturer| is used to capture frames and must remain valid until - // the |done_task| supplied to Stop() is executed. + // called. |capturer| is used to capture frames. static scoped_refptr<VideoScheduler> Create( scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner, scoped_refptr<base::SingleThreadTaskRunner> encode_task_runner, scoped_refptr<base::SingleThreadTaskRunner> network_task_runner, - VideoFrameCapturer* capturer, + scoped_ptr<VideoFrameCapturer> capturer, scoped_ptr<VideoEncoder> encoder, protocol::CursorShapeStub* cursor_stub, protocol::VideoStub* video_stub); @@ -93,10 +92,9 @@ class VideoScheduler : public base::RefCountedThreadSafe<VideoScheduler>, virtual void OnCursorShapeChanged( scoped_ptr<MouseCursorShape> cursor_shape) OVERRIDE; - // Stop scheduling frame captures. |done_task| is executed on the network - // thread when capturing has stopped. This object cannot be re-used once + // Stop scheduling frame captures. This object cannot be re-used once // it has been stopped. - void Stop(const base::Closure& done_task); + void Stop(); // Pauses or resumes scheduling of frame captures. Pausing/resuming captures // only affects capture scheduling and does not stop/start the capturer. @@ -113,7 +111,7 @@ class VideoScheduler : public base::RefCountedThreadSafe<VideoScheduler>, scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner, scoped_refptr<base::SingleThreadTaskRunner> encode_task_runner, scoped_refptr<base::SingleThreadTaskRunner> network_task_runner, - VideoFrameCapturer* capturer, + scoped_ptr<VideoFrameCapturer> capturer, scoped_ptr<VideoEncoder> encoder, protocol::CursorShapeStub* cursor_stub, protocol::VideoStub* video_stub); @@ -125,8 +123,8 @@ class VideoScheduler : public base::RefCountedThreadSafe<VideoScheduler>, void StartOnCaptureThread(); // Stops scheduling frame captures on the capture thread, and posts - // |done_task| to the network thread when done. - void StopOnCaptureThread(const base::Closure& done_task); + // StopOnEncodeThread() to the network thread when done. + void StopOnCaptureThread(); // Schedules the next call to CaptureNextFrame. void ScheduleNextCapture(); @@ -149,6 +147,10 @@ class VideoScheduler : public base::RefCountedThreadSafe<VideoScheduler>, // Send updated cursor shape to client. void SendCursorShape(scoped_ptr<protocol::CursorShapeInfo> cursor_shape); + // Posted to the network thread to delete |capturer| on the thread that + // created it. + void StopOnNetworkThread(scoped_ptr<VideoFrameCapturer> capturer); + // Encoder thread ----------------------------------------------------------- // Encode a frame, passing generated VideoPackets to SendVideoPacket(). @@ -158,7 +160,7 @@ class VideoScheduler : public base::RefCountedThreadSafe<VideoScheduler>, // Used to synchronize capture and encode thread teardown, notifying the // network thread when done. - void StopOnEncodeThread(const base::Closure& done_task); + void StopOnEncodeThread(scoped_ptr<VideoFrameCapturer> capturer); // Task runners used by this class. scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner_; @@ -166,7 +168,7 @@ class VideoScheduler : public base::RefCountedThreadSafe<VideoScheduler>, scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_; // Used to capture frames. Always accessed on the capture thread. - VideoFrameCapturer* capturer_; + scoped_ptr<VideoFrameCapturer> capturer_; // Used to encode captured frames. Always accessed on the encode thread. scoped_ptr<VideoEncoder> encoder_; diff --git a/remoting/host/video_scheduler_unittest.cc b/remoting/host/video_scheduler_unittest.cc index 747c8a1..1126233 100644 --- a/remoting/host/video_scheduler_unittest.cc +++ b/remoting/host/video_scheduler_unittest.cc @@ -7,6 +7,7 @@ #include "base/bind.h" #include "base/message_loop.h" #include "base/run_loop.h" +#include "remoting/base/auto_thread_task_runner.h" #include "remoting/capturer/capture_data.h" #include "remoting/capturer/video_capturer_mock_objects.h" #include "remoting/codec/video_encoder.h" @@ -44,10 +45,6 @@ ACTION(FinishSend) { arg1.Run(); } -ACTION_P2(StopVideoScheduler, scheduler, task) { - scheduler->get()->Stop(task); -} - } // namespace static const int kWidth = 640; @@ -77,15 +74,18 @@ class VideoSchedulerTest : public testing::Test { } virtual void SetUp() OVERRIDE { + task_runner_ = new AutoThreadTaskRunner( + message_loop_.message_loop_proxy(), run_loop_.QuitClosure()); + encoder_ = new MockVideoEncoder(); } - void StartVideoScheduler() { + void StartVideoScheduler(scoped_ptr<VideoFrameCapturer> capturer) { scheduler_ = VideoScheduler::Create( - message_loop_.message_loop_proxy(), - message_loop_.message_loop_proxy(), - message_loop_.message_loop_proxy(), - &capturer_, + task_runner_, // Capture + task_runner_, // Encode + task_runner_, // Network + capturer.Pass(), scoped_ptr<VideoEncoder>(encoder_), &client_stub_, &video_stub_); @@ -93,13 +93,16 @@ class VideoSchedulerTest : public testing::Test { void GenerateOnCaptureCompleted(); + void StopVideoScheduler(); + protected: MessageLoop message_loop_; + base::RunLoop run_loop_; + scoped_refptr<AutoThreadTaskRunner> task_runner_; scoped_refptr<VideoScheduler> scheduler_; MockClientStub client_stub_; MockVideoStub video_stub_; - MockVideoFrameCapturer capturer_; // The following mock objects are owned by VideoScheduler. MockVideoEncoder* encoder_; @@ -117,21 +120,24 @@ void VideoSchedulerTest::GenerateOnCaptureCompleted() { scheduler_->OnCaptureCompleted(data_); } +void VideoSchedulerTest::StopVideoScheduler() { + scheduler_->Stop(); + scheduler_ = NULL; +} + // This test mocks capturer, encoder and network layer to simulate one capture // cycle. When the first encoded packet is submitted to the network // VideoScheduler is instructed to come to a complete stop. We expect the stop // sequence to be executed successfully. TEST_F(VideoSchedulerTest, StartAndStop) { - Expectation capturer_start = EXPECT_CALL(capturer_, Start(_)); + scoped_ptr<MockVideoFrameCapturer> capturer_(new MockVideoFrameCapturer()); + Expectation capturer_start = EXPECT_CALL(*capturer_, Start(_)); data_ = new CaptureData(NULL, kWidth * CaptureData::kBytesPerPixel, SkISize::Make(kWidth, kHeight)); - // Create a RunLoop through which to drive |message_loop_|. - base::RunLoop run_loop; - // First the capturer is called. - Expectation capturer_capture = EXPECT_CALL(capturer_, CaptureFrame()) + Expectation capturer_capture = EXPECT_CALL(*capturer_, CaptureFrame()) .After(capturer_start) .WillRepeatedly(InvokeWithoutArgs( this, &VideoSchedulerTest::GenerateOnCaptureCompleted)); @@ -149,15 +155,17 @@ TEST_F(VideoSchedulerTest, StartAndStop) { EXPECT_CALL(video_stub_, ProcessVideoPacketPtr(_, _)) .WillOnce(DoAll( FinishSend(), - StopVideoScheduler(&scheduler_, run_loop.QuitClosure()))) + InvokeWithoutArgs(this, &VideoSchedulerTest::StopVideoScheduler))) .RetiresOnSaturation(); - EXPECT_CALL(capturer_, Stop()) + EXPECT_CALL(*capturer_, Stop()) .After(capturer_capture); // Start video frame capture. - StartVideoScheduler(); - run_loop.Run(); + StartVideoScheduler(capturer_.PassAs<VideoFrameCapturer>()); + + task_runner_ = NULL; + run_loop_.Run(); } } // namespace remoting diff --git a/remoting/host/win/session_desktop_environment_factory.cc b/remoting/host/win/session_desktop_environment.cc index e0c8fb7..35e28bf 100644 --- a/remoting/host/win/session_desktop_environment_factory.cc +++ b/remoting/host/win/session_desktop_environment.cc @@ -2,40 +2,50 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "remoting/host/win/session_desktop_environment_factory.h" +#include "remoting/host/win/session_desktop_environment.h" +#include "base/logging.h" #include "base/single_thread_task_runner.h" #include "remoting/capturer/video_frame_capturer.h" #include "remoting/host/audio_capturer.h" -#include "remoting/host/chromoting_host_context.h" -#include "remoting/host/desktop_environment.h" #include "remoting/host/event_executor.h" #include "remoting/host/win/session_event_executor.h" namespace remoting { -SessionDesktopEnvironmentFactory::SessionDesktopEnvironmentFactory( - scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, +SessionDesktopEnvironment::SessionDesktopEnvironment( const base::Closure& inject_sas) - : DesktopEnvironmentFactory(input_task_runner, ui_task_runner), - inject_sas_(inject_sas) { + : inject_sas_(inject_sas){ } -SessionDesktopEnvironmentFactory::~SessionDesktopEnvironmentFactory() { +SessionDesktopEnvironment::~SessionDesktopEnvironment() { } -scoped_ptr<DesktopEnvironment> SessionDesktopEnvironmentFactory::Create() { - scoped_ptr<AudioCapturer> audio_capturer = AudioCapturer::Create(); +scoped_ptr<EventExecutor> SessionDesktopEnvironment::CreateEventExecutor( + scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) { + DCHECK(CalledOnValidThread()); + scoped_ptr<EventExecutor> event_executor = EventExecutor::Create( - input_task_runner_, ui_task_runner_); + input_task_runner, ui_task_runner); event_executor.reset(new SessionEventExecutorWin( - input_task_runner_, event_executor.Pass(), ui_task_runner_, inject_sas_)); - scoped_ptr<VideoFrameCapturer> video_capturer(VideoFrameCapturer::Create()); - return scoped_ptr<DesktopEnvironment>(new DesktopEnvironment( - audio_capturer.Pass(), - event_executor.Pass(), - video_capturer.Pass())); + input_task_runner, event_executor.Pass(), ui_task_runner, inject_sas_)); + return event_executor.Pass(); +} + +SessionDesktopEnvironmentFactory::SessionDesktopEnvironmentFactory( + const base::Closure& inject_sas) + : inject_sas_(inject_sas) { +} + +SessionDesktopEnvironmentFactory::~SessionDesktopEnvironmentFactory() { +} + +scoped_ptr<DesktopEnvironment> SessionDesktopEnvironmentFactory::Create( + const std::string& client_jid, + const base::Closure& disconnect_callback) { + return scoped_ptr<DesktopEnvironment>( + new SessionDesktopEnvironment(inject_sas_)); } } // namespace remoting diff --git a/remoting/host/win/session_desktop_environment.h b/remoting/host/win/session_desktop_environment.h new file mode 100644 index 0000000..85eaf34 --- /dev/null +++ b/remoting/host/win/session_desktop_environment.h @@ -0,0 +1,55 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef REMOTING_HOST_WIN_SESSION_DESKTOP_ENVIRONMENT_H_ +#define REMOTING_HOST_WIN_SESSION_DESKTOP_ENVIRONMENT_H_ + +#include "base/basictypes.h" +#include "base/callback.h" +#include "base/compiler_specific.h" +#include "base/memory/ref_counted.h" +#include "remoting/host/basic_desktop_environment.h" + +namespace remoting { + +// Used to create audio/video capturers and event executor that are compatible +// with Windows sessions. +class SessionDesktopEnvironment : public BasicDesktopEnvironment { + public: + explicit SessionDesktopEnvironment(const base::Closure& inject_sas); + virtual ~SessionDesktopEnvironment(); + + // DesktopEnvironment implementation. + virtual scoped_ptr<EventExecutor> CreateEventExecutor( + scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) OVERRIDE; + + private: + // Used to ask the daemon to inject Secure Attention Sequence. + base::Closure inject_sas_; + + DISALLOW_COPY_AND_ASSIGN(SessionDesktopEnvironment); +}; + +// Used to create |SessionDesktopEnvironment| instances. +class SessionDesktopEnvironmentFactory : public BasicDesktopEnvironmentFactory { + public: + explicit SessionDesktopEnvironmentFactory(const base::Closure& inject_sas); + virtual ~SessionDesktopEnvironmentFactory(); + + // DesktopEnvironmentFactory implementation. + virtual scoped_ptr<DesktopEnvironment> Create( + const std::string& client_jid, + const base::Closure& disconnect_callback) OVERRIDE; + + private: + // Used to ask the daemon to inject Secure Attention Sequence. + base::Closure inject_sas_; + + DISALLOW_COPY_AND_ASSIGN(SessionDesktopEnvironmentFactory); +}; + +} // namespace remoting + +#endif // REMOTING_HOST_WIN_SESSION_DESKTOP_ENVIRONMENT_H_ diff --git a/remoting/host/win/session_desktop_environment_factory.h b/remoting/host/win/session_desktop_environment_factory.h deleted file mode 100644 index 99998fb6..0000000 --- a/remoting/host/win/session_desktop_environment_factory.h +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef REMOTING_HOST_WIN_SESSION_DESKTOP_ENVIRONMENT_FACTORY_H_ -#define REMOTING_HOST_WIN_SESSION_DESKTOP_ENVIRONMENT_FACTORY_H_ - -#include "base/callback.h" -#include "remoting/host/desktop_environment_factory.h" - -namespace remoting { - -class SessionDesktopEnvironmentFactory : public DesktopEnvironmentFactory { - public: - SessionDesktopEnvironmentFactory( - scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, - const base::Closure& inject_sas); - virtual ~SessionDesktopEnvironmentFactory(); - - virtual scoped_ptr<DesktopEnvironment> Create() OVERRIDE; - - private: - // Used to ask the daemon to inject Secure Attention Sequence. - base::Closure inject_sas_; - - DISALLOW_COPY_AND_ASSIGN(SessionDesktopEnvironmentFactory); -}; - -} // namespace remoting - -#endif // REMOTING_HOST_WIN_SESSION_DESKTOP_ENVIRONMENT_FACTORY_H_ diff --git a/remoting/remoting.gyp b/remoting/remoting.gyp index 4b7c2dd..abd4d0ce8 100644 --- a/remoting/remoting.gyp +++ b/remoting/remoting.gyp @@ -346,6 +346,8 @@ 'host/audio_scheduler.h', 'host/audio_silence_detector.cc', 'host/audio_silence_detector.h', + 'host/basic_desktop_environment.cc', + 'host/basic_desktop_environment.h', 'host/capture_scheduler.cc', 'host/capture_scheduler.h', 'host/chromoting_host.cc', @@ -366,10 +368,7 @@ 'host/continue_window_gtk.cc', 'host/continue_window_mac.mm', 'host/continue_window_win.cc', - 'host/desktop_environment.cc', 'host/desktop_environment.h', - 'host/desktop_environment_factory.cc', - 'host/desktop_environment_factory.h', 'host/desktop_resizer.h', 'host/desktop_resizer_linux.cc', 'host/desktop_resizer_win.cc', @@ -410,8 +409,6 @@ 'host/ipc_audio_capturer.h', 'host/ipc_constants.cc', 'host/ipc_constants.h', - 'host/ipc_desktop_environment_factory.cc', - 'host/ipc_desktop_environment_factory.h', 'host/ipc_desktop_environment.cc', 'host/ipc_desktop_environment.h', 'host/ipc_event_executor.cc', @@ -482,8 +479,8 @@ 'host/win/omaha.h', 'host/win/security_descriptor.cc', 'host/win/security_descriptor.h', - 'host/win/session_desktop_environment_factory.cc', - 'host/win/session_desktop_environment_factory.h', + 'host/win/session_desktop_environment.cc', + 'host/win/session_desktop_environment.h', 'host/win/session_event_executor.cc', 'host/win/session_event_executor.h', 'host/win/window_station_and_desktop.cc', |