Commit 5dac99c1 authored by Gary Kacmarcik's avatar Gary Kacmarcik Committed by Commit Bot

Calc desktop geo and determine if full desktop capture is supported

Change-Id: I75d7a82c613c899a40dda56b61729c8e8b58ce90
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2071098Reviewed-by: default avatarJamie Walch <jamiewalch@chromium.org>
Commit-Queue: Jamie Walch <jamiewalch@chromium.org>
Auto-Submit: Gary Kacmarcik <garykac@chromium.org>
Cr-Commit-Position: refs/heads/master@{#747447}
parent 23a96dc1
...@@ -229,20 +229,42 @@ void ClientSession::DeliverClientMessage( ...@@ -229,20 +229,42 @@ void ClientSession::DeliverClientMessage(
void ClientSession::SelectDesktopDisplay( void ClientSession::SelectDesktopDisplay(
const protocol::SelectDesktopDisplayRequest& select_display) { const protocol::SelectDesktopDisplayRequest& select_display) {
int id = webrtc::kFullDesktopScreenId; LOG(INFO) << "SelectDesktopDisplay "
if (select_display.id() != "all") { << "'" << select_display.id() << "'";
// Parse the string with the selected display.
int id = webrtc::kInvalidScreenId;
if (select_display.id() == "all") {
id = webrtc::kFullDesktopScreenId;
} else {
if (!base::StringToInt(select_display.id().c_str(), &id)) { if (!base::StringToInt(select_display.id().c_str(), &id)) {
// Default to fullscreen if unable to parse id. LOG(ERROR) << " Unable to parse display id "
id = webrtc::kFullDesktopScreenId; << "'" << select_display.id() << "'";
id = webrtc::kInvalidScreenId;
} }
// Invalid display index defaults to showing all displays.
if (!desktop_display_info_.GetDisplayInfo(id)) { if (!desktop_display_info_.GetDisplayInfo(id)) {
id = webrtc::kFullDesktopScreenId; LOG(ERROR) << " Invalid display id "
<< "'" << select_display.id() << "'";
id = webrtc::kInvalidScreenId;
} }
} }
// Don't allow requests for fullscreen if not supported by the current
// display configuration.
if (!can_capture_full_desktop_ && id == webrtc::kFullDesktopScreenId) {
LOG(ERROR) << " Full desktop not supported";
id = webrtc::kInvalidScreenId;
}
// Fall back to default capture config if invalid request.
if (id == webrtc::kInvalidScreenId) {
LOG(ERROR) << " Invalid display specification, falling back to default";
id = can_capture_full_desktop_ ? webrtc::kFullDesktopScreenId : 0;
}
if (show_display_id_ == id) {
LOG(INFO) << " Display " << id << " is already selected. Ignoring";
return;
}
LOG(INFO) << "SelectDesktopDisplay " << id << " = '" << select_display.id()
<< "'";
video_stream_->SelectSource(id); video_stream_->SelectSource(id);
show_display_id_ = id; show_display_id_ = id;
...@@ -567,6 +589,9 @@ void ClientSession::SetMouseClampingFilter(const DisplaySize& size) { ...@@ -567,6 +589,9 @@ void ClientSession::SetMouseClampingFilter(const DisplaySize& size) {
} }
void ClientSession::UpdateMouseClampingFilterOffset() { void ClientSession::UpdateMouseClampingFilterOffset() {
if (show_display_id_ == webrtc::kInvalidScreenId)
return;
webrtc::DesktopVector origin; webrtc::DesktopVector origin;
origin = desktop_display_info_.CalcDisplayOffset(show_display_id_); origin = desktop_display_info_.CalcDisplayOffset(show_display_id_);
mouse_clamping_filter_.set_output_offset(origin); mouse_clamping_filter_.set_output_offset(origin);
...@@ -581,6 +606,18 @@ void ClientSession::OnVideoSizeChanged(protocol::VideoStream* video_stream, ...@@ -581,6 +606,18 @@ void ClientSession::OnVideoSizeChanged(protocol::VideoStream* video_stream,
DisplaySize::FromPixels(size_px.width(), size_px.height(), dpi.x()); DisplaySize::FromPixels(size_px.width(), size_px.height(), dpi.x());
LOG(INFO) << " DisplaySize: " << size; LOG(INFO) << " DisplaySize: " << size;
// The first video size message that we receive from WebRtc is the full
// desktop size (if supported). If full desktop capture is not supported,
// then this will be the size of the default display.
if (default_webrtc_desktop_size_.IsEmpty()) {
default_webrtc_desktop_size_ = size;
LOG(INFO) << " display id " << show_display_id_;
DCHECK(show_display_id_ == webrtc::kInvalidScreenId);
LOG(INFO) << " Recording default webrtc capture size "
<< default_webrtc_desktop_size_;
}
webrtc_capture_size_ = size;
SetMouseClampingFilter(size); SetMouseClampingFilter(size);
// Record default DPI in case a display reports 0 for DPI. // Record default DPI in case a display reports 0 for DPI.
...@@ -625,7 +662,7 @@ void ClientSession::OnDesktopDisplayChanged( ...@@ -625,7 +662,7 @@ void ClientSession::OnDesktopDisplayChanged(
int max_y = 0; int max_y = 0;
int dpi_x = 0; int dpi_x = 0;
int dpi_y = 0; int dpi_y = 0;
LOG(INFO) << " Scanning display info..."; LOG(INFO) << " Scanning display info... (dips)";
for (int display_id = 0; display_id < displays->video_track_size(); for (int display_id = 0; display_id < displays->video_track_size();
display_id++) { display_id++) {
protocol::VideoTrackLayout track = displays->video_track(display_id); protocol::VideoTrackLayout track = displays->video_track(display_id);
...@@ -638,17 +675,12 @@ void ClientSession::OnDesktopDisplayChanged( ...@@ -638,17 +675,12 @@ void ClientSession::OnDesktopDisplayChanged(
if (dpi_y == 0) if (dpi_y == 0)
dpi_y = track.y_dpi(); dpi_y = track.y_dpi();
// The WebRTC desktop only includes displays that match the main display's int x = track.position_x();
// DPI. Here, we filter out non-matching displays so that our desktop int y = track.position_y();
// geometry matches what WebRTC can handle. min_x = std::min(x, min_x);
if (dpi_x == track.x_dpi() && dpi_y == track.y_dpi()) { min_y = std::min(y, min_y);
int x = track.position_x(); max_x = std::max(x + track.width(), max_x);
int y = track.position_y(); max_y = std::max(y + track.height(), max_y);
min_x = std::min(x, min_x);
min_y = std::min(y, min_y);
max_x = std::max(x + track.width(), max_x);
max_y = std::max(y + track.height(), max_y);
}
} }
// TODO(garykac): Investigate why these DPI values are 0 for some users. // TODO(garykac): Investigate why these DPI values are 0 for some users.
...@@ -660,28 +692,42 @@ void ClientSession::OnDesktopDisplayChanged( ...@@ -660,28 +692,42 @@ void ClientSession::OnDesktopDisplayChanged(
// Calc desktop scaled geometry (in DIPs) // Calc desktop scaled geometry (in DIPs)
// See comment in OnVideoSizeChanged() for details. // See comment in OnVideoSizeChanged() for details.
const webrtc::DesktopSize size(max_x - min_x, max_y - min_y); const webrtc::DesktopSize size(max_x - min_x, max_y - min_y);
webrtc::DesktopSize size_dips =
DesktopDisplayInfo::CalcSizeDips(size, dpi_x, dpi_y); // If this is our first message, then we need to determine if the current
// display configuration supports capturing the entire desktop.
LOG(INFO) << " Webrtc desktop size " << default_webrtc_desktop_size_;
if (show_display_id_ == webrtc::kInvalidScreenId) {
if (size.width() == default_webrtc_desktop_size_.WidthAsDips() &&
size.height() == default_webrtc_desktop_size_.HeightAsDips()) {
LOG(INFO) << " Full desktop capture supported.";
can_capture_full_desktop_ = true;
} else {
LOG(INFO)
<< " This configuration does not support full desktop capture.";
can_capture_full_desktop_ = false;
}
}
// Generate and send VideoLayout message. // Generate and send VideoLayout message.
protocol::VideoLayout layout; protocol::VideoLayout layout;
layout.set_supports_full_desktop_capture(can_capture_full_desktop_);
protocol::VideoTrackLayout* video_track; protocol::VideoTrackLayout* video_track;
// Add scaled geometry for entire desktop (in DIPs). // The first layout must be the current webrtc capture size.
// The first layout must be the scaled geometry for backwards compatibility // This is required because we reuse the same message for both
// with the VideoLayout message. The scaled geometry is used for mouse // VideoSizeChanged (which is used to scale mouse coordinates)
// coordinates sent from the client. // and DisplayDesktopChanged.
video_track = layout.add_video_track(); video_track = layout.add_video_track();
video_track->set_position_x(0); video_track->set_position_x(0);
video_track->set_position_y(0); video_track->set_position_y(0);
video_track->set_width(size_dips.width()); video_track->set_width(webrtc_capture_size_.WidthAsDips());
video_track->set_height(size_dips.height()); video_track->set_height(webrtc_capture_size_.HeightAsDips());
video_track->set_x_dpi(dpi_x); video_track->set_x_dpi(dpi_x);
video_track->set_y_dpi(dpi_y); video_track->set_y_dpi(dpi_y);
LOG(INFO) << " Desktop (DIPS) = 0,0 " << size_dips.width() << "x" LOG(INFO) << " Webrtc capture size (DIPS) = 0,0 "
<< size_dips.height() << " [" << dpi_x << "," << dpi_y << "]"; << default_webrtc_desktop_size_;
// Add raw geometry for entire desktop (in pixels). // Add raw geometry for entire desktop (in DIPs).
video_track = layout.add_video_track(); video_track = layout.add_video_track();
video_track->set_position_x(0); video_track->set_position_x(0);
video_track->set_position_y(0); video_track->set_position_y(0);
...@@ -689,7 +735,7 @@ void ClientSession::OnDesktopDisplayChanged( ...@@ -689,7 +735,7 @@ void ClientSession::OnDesktopDisplayChanged(
video_track->set_height(size.height()); video_track->set_height(size.height());
video_track->set_x_dpi(dpi_x); video_track->set_x_dpi(dpi_x);
video_track->set_y_dpi(dpi_y); video_track->set_y_dpi(dpi_y);
LOG(INFO) << " Desktop (pixels) = 0,0 " << size.width() << "x" LOG(INFO) << " Full Desktop (DIPS) = 0,0 " << size.width() << "x"
<< size.height() << " [" << dpi_x << "," << dpi_y << "]"; << size.height() << " [" << dpi_x << "," << dpi_y << "]";
// Add a VideoTrackLayout entry for each separate display. // Add a VideoTrackLayout entry for each separate display.
...@@ -707,6 +753,18 @@ void ClientSession::OnDesktopDisplayChanged( ...@@ -707,6 +753,18 @@ void ClientSession::OnDesktopDisplayChanged(
<< display.y_dpi() << "]"; << display.y_dpi() << "]";
} }
// Set the display id, if this is the first message being processed.
if (show_display_id_ == webrtc::kInvalidScreenId) {
if (can_capture_full_desktop_) {
show_display_id_ = webrtc::kFullDesktopScreenId;
} else {
// Select the default display.
protocol::SelectDesktopDisplayRequest req;
req.set_id("0");
SelectDesktopDisplay(req);
}
}
// We need to update the input filters whenever the displays change. // We need to update the input filters whenever the displays change.
DisplaySize display_size = DisplaySize display_size =
DisplaySize::FromPixels(size.width(), size.height(), default_x_dpi_); DisplaySize::FromPixels(size.width(), size.height(), default_x_dpi_);
......
...@@ -275,8 +275,24 @@ class ClientSession : public protocol::HostStub, ...@@ -275,8 +275,24 @@ class ClientSession : public protocol::HostStub,
int default_y_dpi_; int default_y_dpi_;
// The id of the desktop display to show to the user. // The id of the desktop display to show to the user.
// Default is webrtc::kFullDesktopScreenId which shows all displays. // Default is webrtc::kInvalidScreenScreenId because we need to perform
webrtc::ScreenId show_display_id_ = webrtc::kFullDesktopScreenId; // an initial capture to determine if the current setup support capturing
// the entire desktop or if it is restricted to a single display.
webrtc::ScreenId show_display_id_ = webrtc::kInvalidScreenId;
// The initial video size captured by WebRTC.
// This will be the full desktop unless webrtc cannot capture the entire
// desktop (e.g., because the DPIs don't match). In that case, it will
// be equal to the dimensions of the default display.
DisplaySize default_webrtc_desktop_size_;
// The current size of the area being captured by webrtc. This will be
// equal to the size of the entire desktop, or to a single display.
DisplaySize webrtc_capture_size_;
// Set to true if the current display configuration supports capturing the
// entire desktop.
bool can_capture_full_desktop_ = true;
// The pairing registry for PIN-less authentication. // The pairing registry for PIN-less authentication.
scoped_refptr<protocol::PairingRegistry> pairing_registry_; scoped_refptr<protocol::PairingRegistry> pairing_registry_;
......
...@@ -136,7 +136,6 @@ class ClientSessionTest : public testing::Test { ...@@ -136,7 +136,6 @@ class ClientSessionTest : public testing::Test {
static const int kDisplay2Width = 1024; static const int kDisplay2Width = 1024;
static const int kDisplay2Height = 768; static const int kDisplay2Height = 768;
static const int kDisplay2YOffset = 35; static const int kDisplay2YOffset = 35;
static const int kInvalidDisplayIndex = -2;
// Creates the client session from a FakeSession instance. // Creates the client session from a FakeSession instance.
void CreateClientSession(std::unique_ptr<protocol::FakeSession> session); void CreateClientSession(std::unique_ptr<protocol::FakeSession> session);
...@@ -368,7 +367,7 @@ void ClientSessionTest::NotifySelectDesktopDisplay(std::string id) { ...@@ -368,7 +367,7 @@ void ClientSessionTest::NotifySelectDesktopDisplay(std::string id) {
void ClientSessionTest::ResetDisplayInfo() { void ClientSessionTest::ResetDisplayInfo() {
displays_.Reset(); displays_.Reset();
curr_display_ = kInvalidDisplayIndex; curr_display_ = webrtc::kInvalidScreenId;
} }
// Set up a single display (default size). // Set up a single display (default size).
...@@ -377,8 +376,8 @@ void ClientSessionTest::SetupSingleDisplay() { ...@@ -377,8 +376,8 @@ void ClientSessionTest::SetupSingleDisplay() {
auto displays = std::make_unique<protocol::VideoLayout>(); auto displays = std::make_unique<protocol::VideoLayout>();
AddDisplayToLayout(displays.get(), 0, 0, kDisplay1Width, kDisplay1Height, AddDisplayToLayout(displays.get(), 0, 0, kDisplay1Width, kDisplay1Height,
kDefaultDpi, kDefaultDpi); kDefaultDpi, kDefaultDpi);
NotifyDesktopDisplaySize(std::move(displays));
NotifyVideoSizeAll(); NotifyVideoSizeAll();
NotifyDesktopDisplaySize(std::move(displays));
} }
// Set up multiple displays: // Set up multiple displays:
...@@ -395,8 +394,8 @@ void ClientSessionTest::SetupMultiDisplay() { ...@@ -395,8 +394,8 @@ void ClientSessionTest::SetupMultiDisplay() {
kDefaultDpi, kDefaultDpi); kDefaultDpi, kDefaultDpi);
AddDisplayToLayout(displays.get(), kDisplay1Width, kDisplay2YOffset, AddDisplayToLayout(displays.get(), kDisplay1Width, kDisplay2YOffset,
kDisplay2Width, kDisplay2Height, kDefaultDpi, kDefaultDpi); kDisplay2Width, kDisplay2Height, kDefaultDpi, kDefaultDpi);
NotifyDesktopDisplaySize(std::move(displays));
NotifyVideoSizeAll(); NotifyVideoSizeAll();
NotifyDesktopDisplaySize(std::move(displays));
} }
// Set up multiple displays that are the same size: // Set up multiple displays that are the same size:
...@@ -412,8 +411,8 @@ void ClientSessionTest::SetupMultiDisplay_SameSize() { ...@@ -412,8 +411,8 @@ void ClientSessionTest::SetupMultiDisplay_SameSize() {
kDefaultDpi, kDefaultDpi); kDefaultDpi, kDefaultDpi);
AddDisplayToLayout(displays.get(), kDisplay1Width, kDisplay2YOffset, AddDisplayToLayout(displays.get(), kDisplay1Width, kDisplay2YOffset,
kDisplay1Width, kDisplay1Height, kDefaultDpi, kDefaultDpi); kDisplay1Width, kDisplay1Height, kDefaultDpi, kDefaultDpi);
NotifyDesktopDisplaySize(std::move(displays));
NotifyVideoSizeAll(); NotifyVideoSizeAll();
NotifyDesktopDisplaySize(std::move(displays));
} }
void ClientSessionTest::MultiMon_SelectFirstDisplay() { void ClientSessionTest::MultiMon_SelectFirstDisplay() {
......
...@@ -67,7 +67,7 @@ int DesktopDisplayInfo::NumDisplays() { ...@@ -67,7 +67,7 @@ int DesktopDisplayInfo::NumDisplays() {
} }
const DisplayGeometry* DesktopDisplayInfo::GetDisplayInfo(unsigned int id) { const DisplayGeometry* DesktopDisplayInfo::GetDisplayInfo(unsigned int id) {
if (id >= displays_.size()) if (id < 0 || id >= displays_.size())
return nullptr; return nullptr;
return &displays_[id]; return &displays_[id];
} }
......
...@@ -110,6 +110,9 @@ message VideoTrackLayout { ...@@ -110,6 +110,9 @@ message VideoTrackLayout {
message VideoLayout { message VideoLayout {
// Layout for each video track. // Layout for each video track.
repeated VideoTrackLayout video_track = 1; repeated VideoTrackLayout video_track = 1;
// True if this display configuration supports capturing the entire desktop.
optional bool supports_full_desktop_capture = 2;
} }
message SelectDesktopDisplayRequest { message SelectDesktopDisplayRequest {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment