| Index: remoting/host/desktop_session_proxy.cc
|
| diff --git a/remoting/host/desktop_session_proxy.cc b/remoting/host/desktop_session_proxy.cc
|
| index 59a567f2f75dbda8ec381672e865c7dd1e32cf3b..c59fd12552fcfe806a572443c1c93dc4d85ae448 100644
|
| --- a/remoting/host/desktop_session_proxy.cc
|
| +++ b/remoting/host/desktop_session_proxy.cc
|
| @@ -11,11 +11,14 @@
|
| #include "ipc/ipc_channel_proxy.h"
|
| #include "ipc/ipc_message_macros.h"
|
| #include "remoting/capturer/capture_data.h"
|
| -#include "remoting/host/audio_capturer.h"
|
| +#include "remoting/codec/audio_encoder.h"
|
| +#include "remoting/codec/video_encoder.h"
|
| +#include "remoting/host/audio_scheduler.h"
|
| #include "remoting/host/chromoting_messages.h"
|
| #include "remoting/host/client_session.h"
|
| #include "remoting/host/ipc_audio_capturer.h"
|
| #include "remoting/host/ipc_video_frame_capturer.h"
|
| +#include "remoting/host/video_scheduler.h"
|
| #include "remoting/proto/audio.pb.h"
|
| #include "remoting/proto/control.pb.h"
|
| #include "remoting/proto/event.pb.h"
|
| @@ -27,16 +30,144 @@
|
| 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),
|
| - audio_capturer_(NULL),
|
| + const std::string& client_jid,
|
| + const base::Closure& disconnect_callback)
|
| + : caller_task_runner_(caller_task_runner),
|
| + clipboard_stub_(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());
|
| +}
|
| +
|
| +void DesktopSessionProxy::InjectClipboardEvent(
|
| + const protocol::ClipboardEvent& event) {
|
| + DCHECK(caller_task_runner_->BelongsToCurrentThread());
|
| +
|
| + std::string serialized_event;
|
| + if (!event.SerializeToString(&serialized_event)) {
|
| + LOG(ERROR) << "Failed to serialize protocol::ClipboardEvent.";
|
| + return;
|
| + }
|
| +
|
| + SendToDesktop(
|
| + new ChromotingNetworkDesktopMsg_InjectClipboardEvent(serialized_event));
|
| +}
|
| +
|
| +void DesktopSessionProxy::InjectKeyEvent(const protocol::KeyEvent& event) {
|
| + DCHECK(caller_task_runner_->BelongsToCurrentThread());
|
| +
|
| + std::string serialized_event;
|
| + if (!event.SerializeToString(&serialized_event)) {
|
| + LOG(ERROR) << "Failed to serialize protocol::KeyEvent.";
|
| + return;
|
| + }
|
| +
|
| + SendToDesktop(
|
| + new ChromotingNetworkDesktopMsg_InjectKeyEvent(serialized_event));
|
| +}
|
| +
|
| +void DesktopSessionProxy::InjectMouseEvent(
|
| + const protocol::MouseEvent& event) {
|
| + DCHECK(caller_task_runner_->BelongsToCurrentThread());
|
| +
|
| + std::string serialized_event;
|
| + if (!event.SerializeToString(&serialized_event)) {
|
| + LOG(ERROR) << "Failed to serialize protocol::MouseEvent.";
|
| + return;
|
| + }
|
| +
|
| + SendToDesktop(
|
| + new ChromotingNetworkDesktopMsg_InjectMouseEvent(serialized_event));
|
| +}
|
| +
|
| +void DesktopSessionProxy::StartAudio(
|
| + scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner,
|
| + scoped_ptr<AudioEncoder> audio_encoder,
|
| + protocol::AudioStub* audio_stub) {
|
| + DCHECK(caller_task_runner_->BelongsToCurrentThread());
|
| + DCHECK(!audio_scheduler_.get());
|
| + DCHECK(!audio_capture_task_runner_.get());
|
| +
|
| + audio_capture_task_runner_ = audio_task_runner;
|
| +
|
| + // Create and start the audio scheduler. The |audio_stub| reference is cleared
|
| + // by Stop().
|
| + scoped_ptr<AudioCapturer> audio_capturer(new IpcAudioCapturer(this));
|
| + audio_scheduler_ = AudioScheduler::Create(audio_task_runner,
|
| + caller_task_runner_,
|
| + audio_capturer.Pass(),
|
| + audio_encoder.Pass(),
|
| + audio_stub);
|
| +}
|
| +
|
| +void DesktopSessionProxy::PauseAudio(bool pause) {
|
| + DCHECK(caller_task_runner_->BelongsToCurrentThread());
|
| +
|
| + if (audio_scheduler_.get())
|
| + audio_scheduler_->Pause(pause);
|
| +}
|
| +
|
| +void DesktopSessionProxy::StartInput(
|
| + scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
|
| + scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
|
| + protocol::ClipboardStub* clipboard_stub) {
|
| + DCHECK(caller_task_runner_->BelongsToCurrentThread());
|
| + DCHECK(!clipboard_stub_);
|
| + DCHECK(clipboard_stub);
|
| +
|
| + // |clipboard_stub_| reference is cleared by Stop().
|
| + clipboard_stub_ = clipboard_stub;
|
| +}
|
| +
|
| +void DesktopSessionProxy::StartVideo(
|
| + scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner,
|
| + scoped_refptr<base::SingleThreadTaskRunner> encode_task_runner,
|
| + scoped_ptr<VideoEncoder> video_encoder,
|
| + protocol::CursorShapeStub* cursor_shape_stub,
|
| + protocol::VideoStub* video_stub) {
|
| + DCHECK(caller_task_runner_->BelongsToCurrentThread());
|
| + DCHECK(!video_scheduler_.get());
|
| + DCHECK(!video_capture_task_runner_.get());
|
| +
|
| + video_capture_task_runner_ = capture_task_runner;
|
| +
|
| + // Create and start video scheduler. The |cursor_shape_stub| and |video_stub|
|
| + // references are cleared by Stop().
|
| + scoped_ptr<VideoFrameCapturer> video_capturer(
|
| + new IpcVideoFrameCapturer(this));
|
| + video_scheduler_ = VideoScheduler::Create(capture_task_runner,
|
| + encode_task_runner,
|
| + caller_task_runner_,
|
| + video_capturer.Pass(),
|
| + video_encoder.Pass(),
|
| + cursor_shape_stub,
|
| + video_stub);
|
| +}
|
| +
|
| +SkISize DesktopSessionProxy::GetScreenSize() const {
|
| + if (video_scheduler_.get())
|
| + return video_scheduler_->size_most_recent();
|
| + else
|
| + return SkISize::Make(0, 0);
|
| +}
|
| +
|
| +void DesktopSessionProxy::PauseVideo(bool pause) {
|
| + DCHECK(caller_task_runner_->BelongsToCurrentThread());
|
| +
|
| + if (video_scheduler_.get())
|
| + video_scheduler_->Pause(pause);
|
| +}
|
| +
|
| +void DesktopSessionProxy::UpdateSequenceNumber(int64 sequence_number) {
|
| + DCHECK(caller_task_runner_->BelongsToCurrentThread());
|
| +
|
| + if (video_scheduler_.get())
|
| + video_scheduler_->UpdateSequenceNumber(sequence_number);
|
| }
|
|
|
| bool DesktopSessionProxy::OnMessageReceived(const IPC::Message& message) {
|
| @@ -75,16 +206,22 @@ void DesktopSessionProxy::OnChannelError() {
|
| DetachFromDesktop();
|
| }
|
|
|
| -void DesktopSessionProxy::Initialize(const std::string& client_jid,
|
| - const base::Closure& disconnect_callback) {
|
| +void DesktopSessionProxy::Stop() {
|
| 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;
|
| + clipboard_stub_ = NULL;
|
| +
|
| + // Stop the video scheduler and clear references to the client's stubs.
|
| + if (video_scheduler_.get()) {
|
| + video_scheduler_->Stop();
|
| + video_scheduler_ = NULL;
|
| + }
|
| +
|
| + // Stop the audio scheduler and clear references to the client's stubs.
|
| + if (audio_scheduler_.get()) {
|
| + audio_scheduler_->Stop();
|
| + audio_scheduler_ = NULL;
|
| + }
|
| }
|
|
|
| bool DesktopSessionProxy::AttachToDesktop(
|
| @@ -162,53 +299,6 @@ void DesktopSessionProxy::DisconnectSession() {
|
| disconnect_callback_.Run();
|
| }
|
|
|
| -void DesktopSessionProxy::InjectClipboardEvent(
|
| - const protocol::ClipboardEvent& event) {
|
| - DCHECK(caller_task_runner_->BelongsToCurrentThread());
|
| -
|
| - std::string serialized_event;
|
| - if (!event.SerializeToString(&serialized_event)) {
|
| - LOG(ERROR) << "Failed to serialize protocol::ClipboardEvent.";
|
| - return;
|
| - }
|
| -
|
| - SendToDesktop(
|
| - new ChromotingNetworkDesktopMsg_InjectClipboardEvent(serialized_event));
|
| -}
|
| -
|
| -void DesktopSessionProxy::InjectKeyEvent(const protocol::KeyEvent& event) {
|
| - DCHECK(caller_task_runner_->BelongsToCurrentThread());
|
| -
|
| - std::string serialized_event;
|
| - if (!event.SerializeToString(&serialized_event)) {
|
| - LOG(ERROR) << "Failed to serialize protocol::KeyEvent.";
|
| - return;
|
| - }
|
| -
|
| - SendToDesktop(
|
| - new ChromotingNetworkDesktopMsg_InjectKeyEvent(serialized_event));
|
| -}
|
| -
|
| -void DesktopSessionProxy::InjectMouseEvent(const protocol::MouseEvent& event) {
|
| - DCHECK(caller_task_runner_->BelongsToCurrentThread());
|
| -
|
| - std::string serialized_event;
|
| - if (!event.SerializeToString(&serialized_event)) {
|
| - LOG(ERROR) << "Failed to serialize protocol::MouseEvent.";
|
| - return;
|
| - }
|
| -
|
| - SendToDesktop(
|
| - new ChromotingNetworkDesktopMsg_InjectMouseEvent(serialized_event));
|
| -}
|
| -
|
| -void DesktopSessionProxy::StartEventExecutor(
|
| - scoped_ptr<protocol::ClipboardStub> client_clipboard) {
|
| - DCHECK(caller_task_runner_->BelongsToCurrentThread());
|
| -
|
| - client_clipboard_ = client_clipboard.Pass();
|
| -}
|
| -
|
| void DesktopSessionProxy::InvalidateRegion(const SkRegion& invalid_region) {
|
| if (!caller_task_runner_->BelongsToCurrentThread()) {
|
| caller_task_runner_->PostTask(
|
| @@ -236,17 +326,19 @@ void DesktopSessionProxy::CaptureFrame() {
|
| SendToDesktop(new ChromotingNetworkDesktopMsg_CaptureFrame());
|
| }
|
|
|
| -void DesktopSessionProxy::StartAudioCapturer(IpcAudioCapturer* audio_capturer) {
|
| +void DesktopSessionProxy::StartAudioCapturer(
|
| + const AudioCapturer::PacketCapturedCallback& audio_packet_callback) {
|
| DCHECK(audio_capture_task_runner_->BelongsToCurrentThread());
|
| - DCHECK(audio_capturer_ == NULL);
|
| + DCHECK(audio_packet_callback_.is_null());
|
| + DCHECK(!audio_packet_callback.is_null());
|
|
|
| - audio_capturer_ = audio_capturer;
|
| + audio_packet_callback_ = audio_packet_callback;
|
| }
|
|
|
| void DesktopSessionProxy::StopAudioCapturer() {
|
| DCHECK(audio_capture_task_runner_->BelongsToCurrentThread());
|
|
|
| - audio_capturer_ = NULL;
|
| + audio_packet_callback_.Reset();
|
| }
|
|
|
| void DesktopSessionProxy::StartVideoCapturer(
|
| @@ -380,13 +472,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 (clipboard_stub_) {
|
| + protocol::ClipboardEvent event;
|
| + if (!event.ParseFromString(serialized_event)) {
|
| + LOG(ERROR) << "Failed to parse protocol::ClipboardEvent.";
|
| + return;
|
| + }
|
|
|
| - client_clipboard_->InjectClipboardEvent(event);
|
| + clipboard_stub_->InjectClipboardEvent(event);
|
| + }
|
| }
|
|
|
| void DesktopSessionProxy::PostAudioPacket(scoped_ptr<AudioPacket> packet) {
|
| @@ -397,8 +491,8 @@ void DesktopSessionProxy::PostAudioPacket(scoped_ptr<AudioPacket> packet) {
|
| return;
|
| }
|
|
|
| - if (audio_capturer_)
|
| - audio_capturer_->OnAudioPacket(packet.Pass());
|
| + if (!audio_packet_callback_.is_null())
|
| + audio_packet_callback_.Run(packet.Pass());
|
| }
|
|
|
| void DesktopSessionProxy::PostCaptureCompleted(
|
|
|