summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoralexeypa@chromium.org <alexeypa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-16 17:23:53 +0000
committeralexeypa@chromium.org <alexeypa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-16 17:23:53 +0000
commitce404cae8c35d9c39b328e2f7207b852f482a15f (patch)
tree99624ecd8daa98c28eb35323aa465ca8819fd480
parente921967a10108d9751709ff4f35abd67b49103f8 (diff)
downloadchromium_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
-rw-r--r--remoting/host/audio_scheduler.cc24
-rw-r--r--remoting/host/audio_scheduler.h21
-rw-r--r--remoting/host/basic_desktop_environment.cc60
-rw-r--r--remoting/host/basic_desktop_environment.h58
-rw-r--r--remoting/host/chromoting_host.cc27
-rw-r--r--remoting/host/chromoting_host.h14
-rw-r--r--remoting/host/chromoting_host_unittest.cc49
-rw-r--r--remoting/host/client_session.cc104
-rw-r--r--remoting/host/client_session.h27
-rw-r--r--remoting/host/client_session_unittest.cc95
-rw-r--r--remoting/host/desktop_environment.cc35
-rw-r--r--remoting/host/desktop_environment.h64
-rw-r--r--remoting/host/desktop_environment_factory.cc38
-rw-r--r--remoting/host/desktop_environment_factory.h43
-rw-r--r--remoting/host/desktop_session_proxy.cc174
-rw-r--r--remoting/host/desktop_session_proxy.h33
-rw-r--r--remoting/host/host_mock_objects.cc35
-rw-r--r--remoting/host/host_mock_objects.h36
-rw-r--r--remoting/host/ipc_audio_capturer.h3
-rw-r--r--remoting/host/ipc_desktop_environment.cc191
-rw-r--r--remoting/host/ipc_desktop_environment.h108
-rw-r--r--remoting/host/ipc_desktop_environment_factory.cc132
-rw-r--r--remoting/host/ipc_desktop_environment_factory.h82
-rw-r--r--remoting/host/ipc_event_executor.h3
-rw-r--r--remoting/host/plugin/host_script_object.cc9
-rw-r--r--remoting/host/remoting_me2me_host.cc21
-rw-r--r--remoting/host/video_scheduler.cc44
-rw-r--r--remoting/host/video_scheduler.h26
-rw-r--r--remoting/host/video_scheduler_unittest.cc46
-rw-r--r--remoting/host/win/session_desktop_environment.cc (renamed from remoting/host/win/session_desktop_environment_factory.cc)46
-rw-r--r--remoting/host/win/session_desktop_environment.h55
-rw-r--r--remoting/host/win/session_desktop_environment_factory.h32
-rw-r--r--remoting/remoting.gyp11
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',