[Chromoting] Add host support for SelectSource message from client.
This message is piped through to WebRtc's SelectSource to select
which display to show.
Bug: 915411
Change-Id: I30f10c8f94b15ebcff1c0fc0981385cbb8b7bc74
Reviewed-on: https://chromium-review.googlesource.com/c/1410229
Commit-Queue: Gary Kacmarcik <garykac@chromium.org>
Reviewed-by: Dominick Ng <dominickn@chromium.org>
Reviewed-by: Joe Downing <joedow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#623544}
diff --git a/remoting/host/chromoting_messages.h b/remoting/host/chromoting_messages.h
index 21b79729..3747a37 100644
--- a/remoting/host/chromoting_messages.h
+++ b/remoting/host/chromoting_messages.h
@@ -228,6 +228,9 @@
IPC_MESSAGE_CONTROL(ChromotingNetworkDesktopMsg_CaptureFrame)
+IPC_MESSAGE_CONTROL(ChromotingNetworkDesktopMsg_SelectSource,
+ int /* desktop_display_id */)
+
// Carries a clipboard event from the client to the desktop session agent.
// |serialized_event| is a serialized protocol::ClipboardEvent.
IPC_MESSAGE_CONTROL(ChromotingNetworkDesktopMsg_InjectClipboardEvent,
diff --git a/remoting/host/client_session.cc b/remoting/host/client_session.cc
index f53c161..4e921d36 100644
--- a/remoting/host/client_session.cc
+++ b/remoting/host/client_session.cc
@@ -10,6 +10,7 @@
#include "base/command_line.h"
#include "base/optional.h"
#include "base/single_thread_task_runner.h"
+#include "base/strings/string_number_conversions.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
#include "remoting/base/capabilities.h"
@@ -237,6 +238,18 @@
}
}
+void ClientSession::SelectDesktopDisplay(
+ const protocol::SelectDesktopDisplayRequest& select_display) {
+ int id = webrtc::kFullDesktopScreenId;
+ if (select_display.id() != "all") {
+ if (!base::StringToInt(select_display.id().c_str(), &id)) {
+ // Default to fullscreen if unable to parse id.
+ id = webrtc::kFullDesktopScreenId;
+ }
+ }
+ video_stream_->SelectSource(id);
+}
+
void ClientSession::OnConnectionAuthenticating() {
event_handler_->OnSessionAuthenticating(this);
}
diff --git a/remoting/host/client_session.h b/remoting/host/client_session.h
index 7e42bdd..283bb463 100644
--- a/remoting/host/client_session.h
+++ b/remoting/host/client_session.h
@@ -113,6 +113,8 @@
void RequestPairing(
const remoting::protocol::PairingRequest& pairing_request) override;
void DeliverClientMessage(const protocol::ExtensionMessage& message) override;
+ void SelectDesktopDisplay(
+ const protocol::SelectDesktopDisplayRequest& select_display) override;
// protocol::ConnectionToClient::EventHandler interface.
void OnConnectionAuthenticating() override;
diff --git a/remoting/host/desktop_capturer_proxy.cc b/remoting/host/desktop_capturer_proxy.cc
index 5600b29e..af68571a 100644
--- a/remoting/host/desktop_capturer_proxy.cc
+++ b/remoting/host/desktop_capturer_proxy.cc
@@ -42,6 +42,7 @@
void Start();
void SetSharedMemoryFactory(
std::unique_ptr<webrtc::SharedMemoryFactory> shared_memory_factory);
+ void SelectSource(SourceId id);
void CaptureFrame();
private:
@@ -96,6 +97,13 @@
}
}
+void DesktopCapturerProxy::Core::SelectSource(SourceId id) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ if (capturer_) {
+ capturer_->SelectSource(id);
+ }
+}
+
void DesktopCapturerProxy::Core::CaptureFrame() {
DCHECK(thread_checker_.CalledOnValidThread());
if (capturer_) {
@@ -175,7 +183,10 @@
}
bool DesktopCapturerProxy::SelectSource(SourceId id) {
- NOTIMPLEMENTED();
+ DCHECK(thread_checker_.CalledOnValidThread());
+ capture_task_runner_->PostTask(
+ FROM_HERE,
+ base::BindOnce(&Core::SelectSource, base::Unretained(core_.get()), id));
return false;
}
diff --git a/remoting/host/desktop_session_agent.cc b/remoting/host/desktop_session_agent.cc
index a9dd0b98a..9ea3c1ef 100644
--- a/remoting/host/desktop_session_agent.cc
+++ b/remoting/host/desktop_session_agent.cc
@@ -181,6 +181,8 @@
IPC_BEGIN_MESSAGE_MAP(DesktopSessionAgent, message)
IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_CaptureFrame,
OnCaptureFrame)
+ IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_SelectSource,
+ OnSelectSource)
IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_InjectClipboardEvent,
OnInjectClipboardEvent)
IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_InjectKeyEvent,
@@ -518,6 +520,11 @@
video_capturer_->CaptureFrame();
}
+void DesktopSessionAgent::OnSelectSource(int id) {
+ DCHECK(caller_task_runner_->BelongsToCurrentThread());
+ video_capturer_->SelectSource(id);
+}
+
void DesktopSessionAgent::OnInjectClipboardEvent(
const std::string& serialized_event) {
DCHECK(caller_task_runner_->BelongsToCurrentThread());
diff --git a/remoting/host/desktop_session_agent.h b/remoting/host/desktop_session_agent.h
index bbee154..81aac89 100644
--- a/remoting/host/desktop_session_agent.h
+++ b/remoting/host/desktop_session_agent.h
@@ -140,6 +140,9 @@
// Handles CaptureFrame requests from the client.
void OnCaptureFrame();
+ // Handles desktop display selection requests from the client.
+ void OnSelectSource(int id);
+
// Handles event executor requests from the client.
void OnInjectClipboardEvent(const std::string& serialized_event);
void OnInjectKeyEvent(const std::string& serialized_event);
diff --git a/remoting/host/desktop_session_proxy.cc b/remoting/host/desktop_session_proxy.cc
index 8eace611..3fd812e 100644
--- a/remoting/host/desktop_session_proxy.cc
+++ b/remoting/host/desktop_session_proxy.cc
@@ -293,6 +293,12 @@
}
}
+bool DesktopSessionProxy::SelectSource(webrtc::DesktopCapturer::SourceId id) {
+ DCHECK(caller_task_runner_->BelongsToCurrentThread());
+ SendToDesktop(new ChromotingNetworkDesktopMsg_SelectSource(id));
+ return true;
+}
+
void DesktopSessionProxy::SetVideoCapturer(
const base::WeakPtr<IpcVideoFrameCapturer> video_capturer) {
DCHECK(caller_task_runner_->BelongsToCurrentThread());
diff --git a/remoting/host/desktop_session_proxy.h b/remoting/host/desktop_session_proxy.h
index 2eeafb2f..ccaa367 100644
--- a/remoting/host/desktop_session_proxy.h
+++ b/remoting/host/desktop_session_proxy.h
@@ -115,6 +115,7 @@
// APIs used to implement the webrtc::DesktopCapturer interface. These must be
// called on the |video_capture_task_runner_| thread.
void CaptureFrame();
+ bool SelectSource(webrtc::DesktopCapturer::SourceId id);
// Stores |video_capturer| to be used to post captured video frames. Called on
// the |video_capture_task_runner_| thread.
diff --git a/remoting/host/ipc_video_frame_capturer.cc b/remoting/host/ipc_video_frame_capturer.cc
index c3f9435..a6044f6b 100644
--- a/remoting/host/ipc_video_frame_capturer.cc
+++ b/remoting/host/ipc_video_frame_capturer.cc
@@ -47,8 +47,8 @@
}
bool IpcVideoFrameCapturer::SelectSource(SourceId id) {
- NOTIMPLEMENTED();
- return false;
+ desktop_session_proxy_->SelectSource(id);
+ return true;
}
} // namespace remoting
diff --git a/remoting/proto/control.proto b/remoting/proto/control.proto
index 4b50cfa..1829b30 100644
--- a/remoting/proto/control.proto
+++ b/remoting/proto/control.proto
@@ -106,3 +106,9 @@
// Layout for each video track.
repeated VideoTrackLayout video_track = 1;
}
+
+message SelectDesktopDisplayRequest {
+ // Identifier for display to select. Valid strings are "0", "1", ...
+ // The "all" string is used to select the entire desktop.
+ optional string id = 1;
+}
diff --git a/remoting/proto/internal.proto b/remoting/proto/internal.proto
index a02f551..e6f9c81 100644
--- a/remoting/proto/internal.proto
+++ b/remoting/proto/internal.proto
@@ -26,6 +26,7 @@
optional PairingResponse pairing_response = 8;
optional ExtensionMessage extension_message = 9;
optional VideoLayout video_layout = 10;
+ optional SelectDesktopDisplayRequest select_display = 11;
}
// Defines an event message on the event channel.
diff --git a/remoting/protocol/client_control_dispatcher.cc b/remoting/protocol/client_control_dispatcher.cc
index c7837ec..ffc6beb 100644
--- a/remoting/protocol/client_control_dispatcher.cc
+++ b/remoting/protocol/client_control_dispatcher.cc
@@ -111,6 +111,13 @@
message_pipe()->Send(&control_message, base::Closure());
}
+void ClientControlDispatcher::SelectDesktopDisplay(
+ const SelectDesktopDisplayRequest& select_display) {
+ ControlMessage message;
+ message.mutable_select_display()->CopyFrom(select_display);
+ message_pipe()->Send(&message, base::Closure());
+}
+
void ClientControlDispatcher::OnIncomingMessage(
std::unique_ptr<CompoundBuffer> buffer) {
DCHECK(client_stub_);
diff --git a/remoting/protocol/client_control_dispatcher.h b/remoting/protocol/client_control_dispatcher.h
index 2fd8456..c915ad9 100644
--- a/remoting/protocol/client_control_dispatcher.h
+++ b/remoting/protocol/client_control_dispatcher.h
@@ -37,6 +37,8 @@
void SetCapabilities(const Capabilities& capabilities) override;
void RequestPairing(const PairingRequest& pairing_request) override;
void DeliverClientMessage(const ExtensionMessage& message) override;
+ void SelectDesktopDisplay(
+ const SelectDesktopDisplayRequest& select_display) override;
// Sets the ClientStub that will be called for each incoming control
// message. |client_stub| must outlive this object.
diff --git a/remoting/protocol/fake_connection_to_client.cc b/remoting/protocol/fake_connection_to_client.cc
index 910c18a..69edc4fd 100644
--- a/remoting/protocol/fake_connection_to_client.cc
+++ b/remoting/protocol/fake_connection_to_client.cc
@@ -32,6 +32,8 @@
observer_ = observer;
}
+void FakeVideoStream::SelectSource(int id) {};
+
base::WeakPtr<FakeVideoStream> FakeVideoStream::GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
diff --git a/remoting/protocol/fake_connection_to_client.h b/remoting/protocol/fake_connection_to_client.h
index 39440af..5078cb14 100644
--- a/remoting/protocol/fake_connection_to_client.h
+++ b/remoting/protocol/fake_connection_to_client.h
@@ -32,6 +32,7 @@
void SetLosslessEncode(bool want_lossless) override;
void SetLosslessColor(bool want_lossless) override;
void SetObserver(Observer* observer) override;
+ void SelectSource(int id) override;
Observer* observer() { return observer_; }
diff --git a/remoting/protocol/host_control_dispatcher.cc b/remoting/protocol/host_control_dispatcher.cc
index a4142c6..2b86a9f 100644
--- a/remoting/protocol/host_control_dispatcher.cc
+++ b/remoting/protocol/host_control_dispatcher.cc
@@ -93,6 +93,8 @@
host_stub_->RequestPairing(message->pairing_request());
} else if (message->has_extension_message()) {
host_stub_->DeliverClientMessage(message->extension_message());
+ } else if (message->has_select_display()) {
+ host_stub_->SelectDesktopDisplay(message->select_display());
} else {
LOG(WARNING) << "Unknown control message received.";
}
diff --git a/remoting/protocol/host_stub.h b/remoting/protocol/host_stub.h
index f312ab5..cf75777 100644
--- a/remoting/protocol/host_stub.h
+++ b/remoting/protocol/host_stub.h
@@ -19,6 +19,7 @@
class ClientResolution;
class ExtensionMessage;
class PairingRequest;
+class SelectDesktopDisplayRequest;
class VideoControl;
class HostStub {
@@ -46,6 +47,10 @@
// Deliver an extension message from the client to the host.
virtual void DeliverClientMessage(const ExtensionMessage& message) = 0;
+ // Select the specified host display.
+ virtual void SelectDesktopDisplay(
+ const SelectDesktopDisplayRequest& select_display) = 0;
+
protected:
virtual ~HostStub() {}
diff --git a/remoting/protocol/protocol_mock_objects.h b/remoting/protocol/protocol_mock_objects.h
index ffea02d..a9c0f16 100644
--- a/remoting/protocol/protocol_mock_objects.h
+++ b/remoting/protocol/protocol_mock_objects.h
@@ -133,6 +133,8 @@
MOCK_METHOD1(SetCapabilities, void(const Capabilities& capabilities));
MOCK_METHOD1(RequestPairing, void(const PairingRequest& pairing_request));
MOCK_METHOD1(DeliverClientMessage, void(const ExtensionMessage& message));
+ MOCK_METHOD1(SelectDesktopDisplay,
+ void(const SelectDesktopDisplayRequest& message));
private:
DISALLOW_COPY_AND_ASSIGN(MockHostStub);
diff --git a/remoting/protocol/video_frame_pump.cc b/remoting/protocol/video_frame_pump.cc
index 6ff904a8..91a812c8 100644
--- a/remoting/protocol/video_frame_pump.cc
+++ b/remoting/protocol/video_frame_pump.cc
@@ -102,6 +102,8 @@
observer_ = observer;
}
+void VideoFramePump::SelectSource(int id) {}
+
void VideoFramePump::OnCaptureResult(
webrtc::DesktopCapturer::Result result,
std::unique_ptr<webrtc::DesktopFrame> frame) {
diff --git a/remoting/protocol/video_frame_pump.h b/remoting/protocol/video_frame_pump.h
index 01c644e7b..91a1906 100644
--- a/remoting/protocol/video_frame_pump.h
+++ b/remoting/protocol/video_frame_pump.h
@@ -86,6 +86,7 @@
void SetLosslessEncode(bool want_lossless) override;
void SetLosslessColor(bool want_lossless) override;
void SetObserver(Observer* observer) override;
+ void SelectSource(int id) override;
protocol::VideoFeedbackStub* video_feedback_stub() {
return &capture_scheduler_;
diff --git a/remoting/protocol/video_stream.h b/remoting/protocol/video_stream.h
index e97bf2364..263c0fa 100644
--- a/remoting/protocol/video_stream.h
+++ b/remoting/protocol/video_stream.h
@@ -49,6 +49,9 @@
// Sets stream observer.
virtual void SetObserver(Observer* observer) = 0;
+
+ // Selects the current desktop display (if multiple displays).
+ virtual void SelectSource(int id) = 0;
};
} // namespace protocol
diff --git a/remoting/protocol/webrtc_video_stream.cc b/remoting/protocol/webrtc_video_stream.cc
index 51ef9d7e..b26fdb24 100644
--- a/remoting/protocol/webrtc_video_stream.cc
+++ b/remoting/protocol/webrtc_video_stream.cc
@@ -160,6 +160,10 @@
this);
}
+void WebrtcVideoStream::SelectSource(int id) {
+ capturer_->SelectSource(id);
+}
+
void WebrtcVideoStream::SetEventTimestampsSource(
scoped_refptr<InputEventTimestampsSource> event_timestamps_source) {
event_timestamps_source_ = event_timestamps_source;
diff --git a/remoting/protocol/webrtc_video_stream.h b/remoting/protocol/webrtc_video_stream.h
index 796a9d9..736b645 100644
--- a/remoting/protocol/webrtc_video_stream.h
+++ b/remoting/protocol/webrtc_video_stream.h
@@ -54,6 +54,7 @@
void SetLosslessEncode(bool want_lossless) override;
void SetLosslessColor(bool want_lossless) override;
void SetObserver(Observer* observer) override;
+ void SelectSource(int id) override;
private:
struct FrameStats;
diff --git a/remoting/test/fake_connection_event_logger.cc b/remoting/test/fake_connection_event_logger.cc
index f77a1a0..7ee1b37 100644
--- a/remoting/test/fake_connection_event_logger.cc
+++ b/remoting/test/fake_connection_event_logger.cc
@@ -229,6 +229,8 @@
void RequestPairing(
const protocol::PairingRequest& pairing_request) override {}
void SetCapabilities(const protocol::Capabilities& capabilities) override {}
+ void SelectDesktopDisplay(
+ const protocol::SelectDesktopDisplayRequest& select_display) override{};
};
FakeConnectionEventLogger::CounterHostStub::CounterHostStub()