diff options
author | alexeypa@chromium.org <alexeypa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-18 01:03:48 +0000 |
---|---|---|
committer | alexeypa@chromium.org <alexeypa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-18 01:03:48 +0000 |
commit | 739e2803109683fec6e24ecbca3ad16fde7b43c4 (patch) | |
tree | d9459f07d896e6095e91f0590c420ea36495cecc /remoting | |
parent | 9e359452151c9bbeaff2fee78a8fde678a42749b (diff) | |
download | chromium_src-739e2803109683fec6e24ecbca3ad16fde7b43c4.zip chromium_src-739e2803109683fec6e24ecbca3ad16fde7b43c4.tar.gz chromium_src-739e2803109683fec6e24ecbca3ad16fde7b43c4.tar.bz2 |
Reworked the plumbing required to pass the client resolution to the desktop resizer.
This is mostly a renaming CL:
- DesktopSessionParams -> ScreenResolution
- OnClientResolutionChanged() -> SetScreenResolution().
Also added validation of ScreenResolution before passing it to session controllers.
BUG=196316
Review URL: https://codereview.chromium.org/12678008
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@188661 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting')
27 files changed, 280 insertions, 149 deletions
diff --git a/remoting/host/chromoting_messages.h b/remoting/host/chromoting_messages.h index 4faed33..9cfc3e5 100644 --- a/remoting/host/chromoting_messages.h +++ b/remoting/host/chromoting_messages.h @@ -8,7 +8,7 @@ #include "ipc/ipc_platform_file.h" #include "media/video/capture/screen/mouse_cursor_shape.h" #include "net/base/ip_endpoint.h" -#include "remoting/host/desktop_session.h" +#include "remoting/host/screen_resolution.h" #include "remoting/protocol/transport.h" #include "third_party/skia/include/core/SkPoint.h" #include "third_party/skia/include/core/SkRect.h" @@ -64,16 +64,16 @@ IPC_MESSAGE_CONTROL3(ChromotingDaemonNetworkMsg_DesktopAttached, // console session. IPC_MESSAGE_CONTROL0(ChromotingNetworkDaemonMsg_SendSasToConsole) -IPC_STRUCT_TRAITS_BEGIN(remoting::DesktopSessionParams) - IPC_STRUCT_TRAITS_MEMBER(client_dpi_) - IPC_STRUCT_TRAITS_MEMBER(client_size_) +IPC_STRUCT_TRAITS_BEGIN(remoting::ScreenResolution) + IPC_STRUCT_TRAITS_MEMBER(dimensions_) + IPC_STRUCT_TRAITS_MEMBER(dpi_) IPC_STRUCT_TRAITS_END() // Connects the terminal |terminal_id| (i.e. a remote client) to a desktop // session. IPC_MESSAGE_CONTROL3(ChromotingNetworkHostMsg_ConnectTerminal, int /* terminal_id */, - remoting::DesktopSessionParams /* params */, + remoting::ScreenResolution /* resolution */, bool /* virtual_terminal */) // Disconnects the terminal |terminal_id| from the desktop session it was @@ -179,7 +179,7 @@ IPC_STRUCT_BEGIN(SerializedCapturedData) // Captured region. IPC_STRUCT_MEMBER(std::vector<SkIRect>, dirty_region) - // Dimentions of the buffer in pixels. + // Dimensions of the buffer in pixels. IPC_STRUCT_MEMBER(SkISize, dimensions) // Time spent in capture. Unit is in milliseconds. diff --git a/remoting/host/client_session.cc b/remoting/host/client_session.cc index e3cfaf7..1a6c973 100644 --- a/remoting/host/client_session.cc +++ b/remoting/host/client_session.cc @@ -19,6 +19,7 @@ #include "remoting/host/audio_scheduler.h" #include "remoting/host/desktop_environment.h" #include "remoting/host/event_executor.h" +#include "remoting/host/screen_resolution.h" #include "remoting/host/session_controller.h" #include "remoting/host/video_scheduler.h" #include "remoting/proto/control.pb.h" @@ -26,12 +27,10 @@ #include "remoting/protocol/client_stub.h" #include "remoting/protocol/clipboard_thread_proxy.h" -namespace remoting { - -namespace { // Default DPI to assume for old clients that use notifyClientDimensions. const int kDefaultDPI = 96; -} // namespace + +namespace remoting { ClientSession::ClientSession( EventHandler* event_handler, @@ -96,16 +95,23 @@ ClientSession::~ClientSession() { void ClientSession::NotifyClientResolution( const protocol::ClientResolution& resolution) { - if (resolution.has_dips_width() && resolution.has_dips_height()) { - VLOG(1) << "Received ClientResolution (dips_width=" - << resolution.dips_width() << ", dips_height=" - << resolution.dips_height() << ")"; - if (session_controller_) { - session_controller_->OnClientResolutionChanged( - SkIPoint::Make(kDefaultDPI, kDefaultDPI), - SkISize::Make(resolution.dips_width(), resolution.dips_height())); - } - } + if (!resolution.has_dips_width() || !resolution.has_dips_height()) + return; + + VLOG(1) << "Received ClientResolution (dips_width=" + << resolution.dips_width() << ", dips_height=" + << resolution.dips_height() << ")"; + + if (!session_controller_) + return; + + ScreenResolution client_resolution( + SkISize::Make(resolution.dips_width(), resolution.dips_height()), + SkIPoint::Make(kDefaultDPI, kDefaultDPI)); + + // Try to match the client's resolution. + if (client_resolution.IsValid()) + session_controller_->SetScreenResolution(client_resolution); } void ClientSession::ControlVideo(const protocol::VideoControl& video_control) { diff --git a/remoting/host/daemon_process.cc b/remoting/host/daemon_process.cc index 2fcf3d8..9d2cdbc 100644 --- a/remoting/host/daemon_process.cc +++ b/remoting/host/daemon_process.cc @@ -18,25 +18,24 @@ #include "remoting/host/desktop_session.h" #include "remoting/host/host_event_logger.h" #include "remoting/host/host_status_observer.h" +#include "remoting/host/screen_resolution.h" #include "remoting/protocol/transport.h" +namespace remoting { + namespace { -std::ostream& operator<<(std::ostream& os, const SkIPoint& point) { - return os << "(" << point.x() << ", " << point.y() << ")"; -} +// This is used for tagging system event logs. +const char kApplicationName[] = "chromoting"; -std::ostream& operator<<(std::ostream& os, const SkISize& size) { - return os << size.width() << "x" << size.height(); +std::ostream& operator<<(std::ostream& os, const ScreenResolution& resolution) { + return os << resolution.dimensions_.width() << "x" + << resolution.dimensions_.height() << " at " + << resolution.dpi_.x() << "x" << resolution.dpi_.y() << " DPI"; } } // namespace -namespace remoting { - -// This is used for tagging system event logs. -const char kApplicationName[] = "chromoting"; - DaemonProcess::~DaemonProcess() { DCHECK(!config_watcher_.get()); DCHECK(desktop_sessions_.empty()); @@ -171,7 +170,7 @@ DaemonProcess::DaemonProcess( } void DaemonProcess::CreateDesktopSession(int terminal_id, - const DesktopSessionParams& params, + const ScreenResolution& resolution, bool virtual_terminal) { DCHECK(caller_task_runner()->BelongsToCurrentThread()); @@ -187,17 +186,9 @@ void DaemonProcess::CreateDesktopSession(int terminal_id, // Terminal IDs cannot be reused. Update the expected next terminal ID. next_terminal_id_ = std::max(next_terminal_id_, terminal_id + 1); - // Validate |params|. - if (params.client_dpi_.x() < 0 || params.client_dpi_.y() < 0) { - LOG(ERROR) << "Invalid DPI of the remote screen specified: " - << params.client_dpi_; - SendToNetwork( - new ChromotingDaemonNetworkMsg_TerminalDisconnected(terminal_id)); - return; - } - if (params.client_size_.width() < 0 || params.client_size_.height() < 0) { - LOG(ERROR) << "Invalid resolution of the remote screen specified: " - << params.client_size_; + // Validate |resolution|. + if (!resolution.IsValid()) { + LOG(ERROR) << "Invalid resolution specified: " << resolution; SendToNetwork( new ChromotingDaemonNetworkMsg_TerminalDisconnected(terminal_id)); return; @@ -205,7 +196,7 @@ void DaemonProcess::CreateDesktopSession(int terminal_id, // Create the desktop session. scoped_ptr<DesktopSession> session = DoCreateDesktopSession( - terminal_id, params, virtual_terminal); + terminal_id, resolution, virtual_terminal); if (!session) { LOG(ERROR) << "Failed to create a desktop session."; SendToNetwork( diff --git a/remoting/host/daemon_process.h b/remoting/host/daemon_process.h index aed640c..3276315 100644 --- a/remoting/host/daemon_process.h +++ b/remoting/host/daemon_process.h @@ -32,9 +32,9 @@ namespace remoting { class AutoThreadTaskRunner; class DesktopSession; -struct DesktopSessionParams; class HostEventLogger; class HostStatusObserver; +class ScreenResolution; // This class implements core of the daemon process. It manages the networking // process running at lower privileges and maintains the list of desktop @@ -94,7 +94,7 @@ class DaemonProcess // Creates a desktop session and assigns a unique ID to it. void CreateDesktopSession(int terminal_id, - const DesktopSessionParams& params, + const ScreenResolution& resolution, bool virtual_terminal); // Requests the network process to crash. @@ -126,7 +126,7 @@ class DaemonProcess // An implementation should validate |params| as they are received via IPC. virtual scoped_ptr<DesktopSession> DoCreateDesktopSession( int terminal_id, - const DesktopSessionParams& params, + const ScreenResolution& resolution, bool virtual_terminal) = 0; // Requests the network process to crash. diff --git a/remoting/host/daemon_process_unittest.cc b/remoting/host/daemon_process_unittest.cc index 033a49f..6856a0a 100644 --- a/remoting/host/daemon_process_unittest.cc +++ b/remoting/host/daemon_process_unittest.cc @@ -56,7 +56,7 @@ class MockDaemonProcess : public DaemonProcess { virtual scoped_ptr<DesktopSession> DoCreateDesktopSession( int terminal_id, - const DesktopSessionParams& params, + const ScreenResolution& resolution, bool virtual_terminal) OVERRIDE; virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; @@ -95,7 +95,7 @@ MockDaemonProcess::~MockDaemonProcess() { scoped_ptr<DesktopSession> MockDaemonProcess::DoCreateDesktopSession( int terminal_id, - const DesktopSessionParams& params, + const ScreenResolution& resolution, bool virtual_terminal) { return scoped_ptr<DesktopSession>(DoCreateDesktopSessionPtr(terminal_id)); } @@ -229,10 +229,10 @@ TEST_F(DaemonProcessTest, OpenClose) { StartDaemonProcess(); int id = terminal_id_++; - DesktopSessionParams params; + ScreenResolution resolution; EXPECT_TRUE(daemon_process_->OnMessageReceived( - ChromotingNetworkHostMsg_ConnectTerminal(id, params, false))); + ChromotingNetworkHostMsg_ConnectTerminal(id, resolution, false))); EXPECT_EQ(1u, desktop_sessions().size()); EXPECT_EQ(id, desktop_sessions().front()->id()); @@ -250,10 +250,10 @@ TEST_F(DaemonProcessTest, CallCloseDesktopSession) { StartDaemonProcess(); int id = terminal_id_++; - DesktopSessionParams params; + ScreenResolution resolution; EXPECT_TRUE(daemon_process_->OnMessageReceived( - ChromotingNetworkHostMsg_ConnectTerminal(id, params, false))); + ChromotingNetworkHostMsg_ConnectTerminal(id, resolution, false))); EXPECT_EQ(1u, desktop_sessions().size()); EXPECT_EQ(id, desktop_sessions().front()->id()); @@ -274,10 +274,10 @@ TEST_F(DaemonProcessTest, DoubleDisconnectTerminal) { StartDaemonProcess(); int id = terminal_id_++; - DesktopSessionParams params; + ScreenResolution resolution; EXPECT_TRUE(daemon_process_->OnMessageReceived( - ChromotingNetworkHostMsg_ConnectTerminal(id, params, false))); + ChromotingNetworkHostMsg_ConnectTerminal(id, resolution, false))); EXPECT_EQ(1u, desktop_sessions().size()); EXPECT_EQ(id, desktop_sessions().front()->id()); @@ -326,15 +326,15 @@ TEST_F(DaemonProcessTest, InvalidConnectTerminal) { StartDaemonProcess(); int id = terminal_id_++; - DesktopSessionParams params; + ScreenResolution resolution; EXPECT_TRUE(daemon_process_->OnMessageReceived( - ChromotingNetworkHostMsg_ConnectTerminal(id, params, false))); + ChromotingNetworkHostMsg_ConnectTerminal(id, resolution, false))); EXPECT_EQ(1u, desktop_sessions().size()); EXPECT_EQ(id, desktop_sessions().front()->id()); EXPECT_TRUE(daemon_process_->OnMessageReceived( - ChromotingNetworkHostMsg_ConnectTerminal(id, params, false))); + ChromotingNetworkHostMsg_ConnectTerminal(id, resolution, false))); EXPECT_TRUE(desktop_sessions().empty()); EXPECT_EQ(0, terminal_id_); } diff --git a/remoting/host/daemon_process_win.cc b/remoting/host/daemon_process_win.cc index 75537dd..d847838 100644 --- a/remoting/host/daemon_process_win.cc +++ b/remoting/host/daemon_process_win.cc @@ -25,6 +25,7 @@ #include "remoting/host/host_exit_codes.h" #include "remoting/host/host_main.h" #include "remoting/host/ipc_constants.h" +#include "remoting/host/screen_resolution.h" #include "remoting/host/win/launch_process_with_token.h" #include "remoting/host/win/unprivileged_process_delegate.h" #include "remoting/host/win/worker_process_launcher.h" @@ -65,7 +66,7 @@ class DaemonProcessWin : public DaemonProcess { // DaemonProcess implementation. virtual scoped_ptr<DesktopSession> DoCreateDesktopSession( int terminal_id, - const DesktopSessionParams& params, + const ScreenResolution& resolution, bool virtual_terminal) OVERRIDE; virtual void DoCrashNetworkProcess( const tracked_objects::Location& location) OVERRIDE; @@ -146,16 +147,16 @@ void DaemonProcessWin::DoStop() { scoped_ptr<DesktopSession> DaemonProcessWin::DoCreateDesktopSession( int terminal_id, - const DesktopSessionParams& params, + const ScreenResolution& resolution, bool virtual_terminal) { DCHECK(caller_task_runner()->BelongsToCurrentThread()); if (virtual_terminal) { return DesktopSessionWin::CreateForVirtualTerminal( - caller_task_runner(), io_task_runner(), this, terminal_id, params); + caller_task_runner(), io_task_runner(), this, terminal_id, resolution); } else { return DesktopSessionWin::CreateForConsole( - caller_task_runner(), io_task_runner(), this, terminal_id, params); + caller_task_runner(), io_task_runner(), this, terminal_id, resolution); } } diff --git a/remoting/host/desktop_session.cc b/remoting/host/desktop_session.cc index e347cbe..c445387 100644 --- a/remoting/host/desktop_session.cc +++ b/remoting/host/desktop_session.cc @@ -9,11 +9,6 @@ namespace remoting { -DesktopSessionParams::DesktopSessionParams() - : client_dpi_(SkIPoint::Make(0, 0)), - client_size_(SkISize::Make(0, 0)) { -} - DesktopSession::~DesktopSession() { } diff --git a/remoting/host/desktop_session.h b/remoting/host/desktop_session.h index 4dd8a3b..8d98e92 100644 --- a/remoting/host/desktop_session.h +++ b/remoting/host/desktop_session.h @@ -7,27 +7,11 @@ #include "base/basictypes.h" #include "base/compiler_specific.h" -#include "third_party/skia/include/core/SkPoint.h" -#include "third_party/skia/include/core/SkSize.h" namespace remoting { class DaemonProcess; -// This structure describes parameters required to create a desktop session. -struct DesktopSessionParams { - DesktopSessionParams(); - - // Vertical and horizontal DPI of the remote screen. The caller should pass - // (0, 0) if DPI of the remote screen is not known. The default 96 DPI will be - // assumed in that case. - SkIPoint client_dpi_; - - // Resolution of the remote screen in pixels. The caller should pass (0, 0) if - // resolution of the remote screen size in not known. - SkISize client_size_; -}; - // Represents the desktop session for a connected terminal. Each desktop session // has a unique identifier used by cross-platform code to refer to it. class DesktopSession { diff --git a/remoting/host/desktop_session_connector.h b/remoting/host/desktop_session_connector.h index 1d8b716..65887817 100644 --- a/remoting/host/desktop_session_connector.h +++ b/remoting/host/desktop_session_connector.h @@ -12,7 +12,7 @@ namespace remoting { class DesktopSessionProxy; -struct DesktopSessionParams; +class ScreenResolution; // Provides a way to connect a terminal (i.e. a remote client) with a desktop // session (i.e. the screen, keyboard and the rest). @@ -27,7 +27,7 @@ class DesktopSessionConnector { // can be deleted. virtual void ConnectTerminal( DesktopSessionProxy* desktop_session_proxy, - const DesktopSessionParams& params, + const ScreenResolution& resolution, bool virtual_terminal) = 0; // Requests the daemon process disconnect |desktop_session_proxy| from diff --git a/remoting/host/desktop_session_proxy.cc b/remoting/host/desktop_session_proxy.cc index 1e3ec99..5baa69d 100644 --- a/remoting/host/desktop_session_proxy.cc +++ b/remoting/host/desktop_session_proxy.cc @@ -19,6 +19,7 @@ #include "remoting/host/ipc_event_executor.h" #include "remoting/host/ipc_session_controller.h" #include "remoting/host/ipc_video_frame_capturer.h" +#include "remoting/host/screen_resolution.h" #include "remoting/host/session_controller.h" #include "remoting/proto/audio.pb.h" #include "remoting/proto/control.pb.h" @@ -288,7 +289,7 @@ void DesktopSessionProxy::ConnectToDesktopSession( desktop_session_connector_ = desktop_session_connector; desktop_session_connector_->ConnectTerminal( - this, DesktopSessionParams(), virtual_terminal); + this, ScreenResolution(), virtual_terminal); } DesktopSessionProxy::~DesktopSessionProxy() { diff --git a/remoting/host/desktop_session_proxy.h b/remoting/host/desktop_session_proxy.h index e484e44..7b15e41 100644 --- a/remoting/host/desktop_session_proxy.h +++ b/remoting/host/desktop_session_proxy.h @@ -39,7 +39,6 @@ namespace remoting { class AudioPacket; class ClientSession; class DesktopSessionConnector; -struct DesktopSessionParams; struct DesktopSessionProxyTraits; class IpcAudioCapturer; class IpcVideoFrameCapturer; diff --git a/remoting/host/desktop_session_win.cc b/remoting/host/desktop_session_win.cc index ff863a4..3ef448e 100644 --- a/remoting/host/desktop_session_win.cc +++ b/remoting/host/desktop_session_win.cc @@ -31,6 +31,7 @@ #include "remoting/host/host_main.h" #include "remoting/host/ipc_constants.h" #include "remoting/host/sas_injector.h" +#include "remoting/host/screen_resolution.h" #include "remoting/host/win/host_service.h" #include "remoting/host/win/worker_process_launcher.h" #include "remoting/host/win/wts_session_process_delegate.h" @@ -65,9 +66,8 @@ const int kMaxRdpScreenHeight = 2048; const int kMinRdpScreenWidth = 800; const int kMinRdpScreenHeight = 600; -// Default dots per inch is 96 DPI. -const int kDefaultDpiX = 96; -const int kDefaultDpiY = 96; +// Default dots per inch used by RDP is 96 DPI. +const int kDefaultRdpDpi = 96; // The session attach notification should arrive within 30 seconds. const int kSessionAttachTimeoutSeconds = 30; @@ -113,7 +113,7 @@ class RdpSession : public DesktopSessionWin { virtual ~RdpSession(); // Performs the part of initialization that can fail. - bool Initialize(const DesktopSessionParams& params); + bool Initialize(const ScreenResolution& resolution); // Mirrors IRdpDesktopSessionEventHandler. void OnRdpConnected(const net::IPEndPoint& client_endpoint); @@ -195,7 +195,7 @@ RdpSession::RdpSession( RdpSession::~RdpSession() { } -bool RdpSession::Initialize(const DesktopSessionParams& params) { +bool RdpSession::Initialize(const ScreenResolution& resolution) { DCHECK(caller_task_runner()->BelongsToCurrentThread()); // Create the RDP wrapper object. @@ -207,30 +207,13 @@ bool RdpSession::Initialize(const DesktopSessionParams& params) { return false; } - // DaemonProcess::CreateDesktopSession() varifies that |client_dpi_| and - // |client_size_| are positive. - DCHECK(params.client_dpi_.x() >= 0 && params.client_dpi_.y() >= 0); - DCHECK(params.client_size_.width() >= 0 && params.client_size_.height() >= 0); - - // Handle the default DPI. - SkIPoint client_dpi = params.client_dpi_; - if (!client_dpi.x()) - client_dpi.setX(kDefaultDpiX); - if (!client_dpi.y()) - client_dpi.setY(kDefaultDpiY); - - // Make sure there will be no integer overflow while scaling the client - // resolution. - SkISize client_size = SkISize::Make( - std::min(params.client_size_.width(), - std::numeric_limits<int32_t>::max() / kDefaultDpiX), - std::min(params.client_size_.height(), - std::numeric_limits<int32_t>::max() / kDefaultDpiY)); - - // Scale the client resolution assiming RDP gives us the default 96 DPI. - SkISize host_size = SkISize::Make( - client_size.width() * kDefaultDpiX / client_dpi.x(), - client_size.height() * kDefaultDpiY / client_dpi.y()); + // DaemonProcess::CreateDesktopSession() verifies that the resolution is + // valid. + DCHECK(resolution.IsValid()); + + // Get the screen dimensions assuming the default DPI. + SkISize host_size = resolution.ScaleDimensionsToDpi( + SkIPoint::Make(kDefaultRdpDpi, kDefaultRdpDpi)); // Make sure that the host resolution is within the limits supported by RDP. host_size = SkISize::Make( @@ -357,7 +340,7 @@ scoped_ptr<DesktopSession> DesktopSessionWin::CreateForConsole( scoped_refptr<AutoThreadTaskRunner> io_task_runner, DaemonProcess* daemon_process, int id, - const DesktopSessionParams& params) { + const ScreenResolution& resolution) { scoped_ptr<ConsoleSession> session(new ConsoleSession( caller_task_runner, io_task_runner, daemon_process, id, HostService::GetInstance())); @@ -371,11 +354,11 @@ scoped_ptr<DesktopSession> DesktopSessionWin::CreateForVirtualTerminal( scoped_refptr<AutoThreadTaskRunner> io_task_runner, DaemonProcess* daemon_process, int id, - const DesktopSessionParams& params) { + const ScreenResolution& resolution) { scoped_ptr<RdpSession> session(new RdpSession( caller_task_runner, io_task_runner, daemon_process, id, HostService::GetInstance())); - if (!session->Initialize(params)) + if (!session->Initialize(resolution)) return scoped_ptr<DesktopSession>(); return session.PassAs<DesktopSession>(); diff --git a/remoting/host/desktop_session_win.h b/remoting/host/desktop_session_win.h index 51d229b..d4c6d71 100644 --- a/remoting/host/desktop_session_win.h +++ b/remoting/host/desktop_session_win.h @@ -27,7 +27,7 @@ namespace remoting { class AutoThreadTaskRunner; class DaemonProcess; class DesktopSession; -struct DesktopSessionParams; +class ScreenResolution; class WorkerProcessLauncher; class WtsTerminalMonitor; @@ -46,7 +46,7 @@ class DesktopSessionWin scoped_refptr<AutoThreadTaskRunner> io_task_runner, DaemonProcess* daemon_process, int id, - const DesktopSessionParams& params); + const ScreenResolution& resolution); // Creates a desktop session instance that attaches to a virtual console. static scoped_ptr<DesktopSession> CreateForVirtualTerminal( @@ -54,7 +54,7 @@ class DesktopSessionWin scoped_refptr<AutoThreadTaskRunner> io_task_runner, DaemonProcess* daemon_process, int id, - const DesktopSessionParams& params); + const ScreenResolution& resolution); protected: // Passes the owning |daemon_process|, a unique identifier of the desktop diff --git a/remoting/host/host_mock_objects.h b/remoting/host/host_mock_objects.h index d9d57a9..610f90e 100644 --- a/remoting/host/host_mock_objects.h +++ b/remoting/host/host_mock_objects.h @@ -14,6 +14,7 @@ #include "remoting/host/event_executor.h" #include "remoting/host/host_status_observer.h" #include "remoting/host/local_input_monitor.h" +#include "remoting/host/screen_resolution.h" #include "remoting/host/session_controller.h" #include "remoting/proto/control.pb.h" #include "testing/gmock/include/gmock/gmock.h" @@ -158,8 +159,7 @@ class MockSessionController : public SessionController { MockSessionController(); virtual ~MockSessionController(); - MOCK_METHOD2(OnClientResolutionChanged, - void(const SkIPoint&, const SkISize&)); + MOCK_METHOD1(SetScreenResolution, void(const ScreenResolution&)); private: DISALLOW_COPY_AND_ASSIGN(MockSessionController); diff --git a/remoting/host/ipc_desktop_environment.cc b/remoting/host/ipc_desktop_environment.cc index 53f90e1..bbe93e3 100644 --- a/remoting/host/ipc_desktop_environment.cc +++ b/remoting/host/ipc_desktop_environment.cc @@ -114,7 +114,7 @@ bool IpcDesktopEnvironmentFactory::SupportsAudioCapture() const { void IpcDesktopEnvironmentFactory::ConnectTerminal( DesktopSessionProxy* desktop_session_proxy, - const DesktopSessionParams& params, + const ScreenResolution& resolution, bool virtual_terminal) { DCHECK(caller_task_runner_->BelongsToCurrentThread()); @@ -126,7 +126,7 @@ void IpcDesktopEnvironmentFactory::ConnectTerminal( VLOG(1) << "Network: registered desktop environment " << id; daemon_channel_->Send(new ChromotingNetworkHostMsg_ConnectTerminal( - id, params, virtual_terminal)); + id, resolution, virtual_terminal)); } void IpcDesktopEnvironmentFactory::DisconnectTerminal( diff --git a/remoting/host/ipc_desktop_environment.h b/remoting/host/ipc_desktop_environment.h index 99a0a28..a07efd7 100644 --- a/remoting/host/ipc_desktop_environment.h +++ b/remoting/host/ipc_desktop_environment.h @@ -28,7 +28,7 @@ class Sender; namespace remoting { class DesktopSessionProxy; -struct DesktopSessionParams; +class ScreenResolution; // A variant of desktop environment integrating with the desktop by means of // a helper process and talking to that process via IPC. @@ -93,7 +93,7 @@ class IpcDesktopEnvironmentFactory // DesktopSessionConnector implementation. virtual void ConnectTerminal( DesktopSessionProxy* desktop_session_proxy, - const DesktopSessionParams& params, + const ScreenResolution& resolution, bool virtual_terminal) OVERRIDE; virtual void DisconnectTerminal( DesktopSessionProxy* desktop_session_proxy) OVERRIDE; diff --git a/remoting/host/ipc_desktop_environment_unittest.cc b/remoting/host/ipc_desktop_environment_unittest.cc index f93e164..2ed434c 100644 --- a/remoting/host/ipc_desktop_environment_unittest.cc +++ b/remoting/host/ipc_desktop_environment_unittest.cc @@ -51,7 +51,7 @@ class FakeDaemonSender : public IPC::Sender { // IPC::Sender implementation. virtual bool Send(IPC::Message* message) OVERRIDE; - MOCK_METHOD3(ConnectTerminal, void(int, const DesktopSessionParams&, bool)); + MOCK_METHOD3(ConnectTerminal, void(int, const ScreenResolution&, bool)); MOCK_METHOD1(DisconnectTerminal, void(int)); private: @@ -117,7 +117,7 @@ class IpcDesktopEnvironmentTest : public testing::Test { virtual void SetUp() OVERRIDE; void ConnectTerminal(int terminal_id, - const DesktopSessionParams& params, + const ScreenResolution& resolution, bool virtual_terminal); void DisconnectTerminal(int terminal_id); @@ -264,7 +264,7 @@ void IpcDesktopEnvironmentTest::SetUp() { void IpcDesktopEnvironmentTest::ConnectTerminal( int terminal_id, - const DesktopSessionParams& params, + const ScreenResolution& resolution, bool virtual_terminal) { EXPECT_NE(terminal_id_, terminal_id); diff --git a/remoting/host/ipc_session_controller.cc b/remoting/host/ipc_session_controller.cc index e925038..30f51e7 100644 --- a/remoting/host/ipc_session_controller.cc +++ b/remoting/host/ipc_session_controller.cc @@ -17,9 +17,8 @@ IpcSessionController::IpcSessionController( IpcSessionController::~IpcSessionController() { } -void IpcSessionController::OnClientResolutionChanged( - const SkIPoint& client_dpi, - const SkISize& client_size) { +void IpcSessionController::SetScreenResolution( + const ScreenResolution& resolution) { NOTIMPLEMENTED(); } diff --git a/remoting/host/ipc_session_controller.h b/remoting/host/ipc_session_controller.h index fc39299..63d677e 100644 --- a/remoting/host/ipc_session_controller.h +++ b/remoting/host/ipc_session_controller.h @@ -12,6 +12,7 @@ namespace remoting { class DesktopSessionProxy; +class ScreenResolution; class IpcSessionController : public SessionController { public: @@ -20,8 +21,7 @@ class IpcSessionController : public SessionController { virtual ~IpcSessionController(); // SessionController interface. - virtual void OnClientResolutionChanged(const SkIPoint& client_dpi, - const SkISize& client_size) OVERRIDE; + virtual void SetScreenResolution(const ScreenResolution& resolution) OVERRIDE; private: // Wraps the IPC channel to the desktop session agent. diff --git a/remoting/host/resizing_host_observer.cc b/remoting/host/resizing_host_observer.cc index 7491eea..658a39b 100644 --- a/remoting/host/resizing_host_observer.cc +++ b/remoting/host/resizing_host_observer.cc @@ -8,6 +8,7 @@ #include "base/logging.h" #include "remoting/host/desktop_resizer.h" +#include "remoting/host/screen_resolution.h" namespace { @@ -108,24 +109,22 @@ ResizingHostObserver::~ResizingHostObserver() { desktop_resizer_->RestoreSize(original_size_); } -void ResizingHostObserver::OnClientResolutionChanged( - const SkIPoint& client_dpi, - const SkISize& client_size) { - if (client_size.isEmpty()) { +void ResizingHostObserver::SetScreenResolution( + const ScreenResolution& resolution) { + if (resolution.IsEmpty()) return; - } // If the implementation returns any sizes, pick the best one according to // the algorithm described in CandidateSize::IsBetterThen. std::list<SkISize> sizes = - desktop_resizer_->GetSupportedSizes(client_size); + desktop_resizer_->GetSupportedSizes(resolution.dimensions_); if (sizes.empty()) { return; } - CandidateSize best_size(sizes.front(), client_size); + CandidateSize best_size(sizes.front(), resolution.dimensions_); for (std::list<SkISize>::const_iterator i = ++sizes.begin(); i != sizes.end(); ++i) { - CandidateSize candidate_size(*i, client_size); + CandidateSize candidate_size(*i, resolution.dimensions_); if (candidate_size.IsBetterThan(best_size)) { best_size = candidate_size; } diff --git a/remoting/host/resizing_host_observer.h b/remoting/host/resizing_host_observer.h index ded8fc8..d6f4390 100644 --- a/remoting/host/resizing_host_observer.h +++ b/remoting/host/resizing_host_observer.h @@ -14,6 +14,7 @@ namespace remoting { class DesktopResizer; +class ScreenResolution; // TODO(alexeypa): Rename this class to reflect that it is not // HostStatusObserver any more. @@ -27,8 +28,7 @@ class ResizingHostObserver : public SessionController { virtual ~ResizingHostObserver(); // SessionController interface. - virtual void OnClientResolutionChanged(const SkIPoint& client_dpi, - const SkISize& client_size) OVERRIDE; + virtual void SetScreenResolution(const ScreenResolution& resolution) OVERRIDE; private: scoped_ptr<DesktopResizer> desktop_resizer_; diff --git a/remoting/host/resizing_host_observer_unittest.cc b/remoting/host/resizing_host_observer_unittest.cc index f318bc5..cc4019a 100644 --- a/remoting/host/resizing_host_observer_unittest.cc +++ b/remoting/host/resizing_host_observer_unittest.cc @@ -8,6 +8,7 @@ #include "base/logging.h" #include "remoting/host/desktop_resizer.h" #include "remoting/host/resizing_host_observer.h" +#include "remoting/host/screen_resolution.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/skia/include/core/SkSize.h" @@ -15,6 +16,8 @@ std::ostream& operator<<(std::ostream& os, const SkISize& size) { return os << size.width() << "x" << size.height(); } +const int kDefaultDPI = 96; + namespace remoting { class FakeDesktopResizer : public DesktopResizer { @@ -79,7 +82,8 @@ class ResizingHostObserverTest : public testing::Test { } SkISize GetBestSize(const SkISize& client_size) { - resizing_host_observer_->OnClientResolutionChanged(SkIPoint(), client_size); + resizing_host_observer_->SetScreenResolution(ScreenResolution( + client_size, SkIPoint::Make(kDefaultDPI, kDefaultDPI))); return desktop_resizer_->GetCurrentSize(); } diff --git a/remoting/host/screen_resolution.cc b/remoting/host/screen_resolution.cc new file mode 100644 index 0000000..a8a7e68 --- /dev/null +++ b/remoting/host/screen_resolution.cc @@ -0,0 +1,43 @@ +// Copyright (c) 2013 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/screen_resolution.h" + +#include <algorithm> +#include <limits> + +namespace remoting { + +ScreenResolution::ScreenResolution() + : dimensions_(SkISize::Make(0, 0)), + dpi_(SkIPoint::Make(0, 0)) { +} + +ScreenResolution::ScreenResolution(const SkISize& dimensions, + const SkIPoint& dpi) + : dimensions_(dimensions), + dpi_(dpi) { +} + +SkISize ScreenResolution::ScaleDimensionsToDpi(const SkIPoint& new_dpi) const { + int64 width = dimensions_.width(); + int64 height = dimensions_.height(); + + // Scale the screen dimensions to new DPI. + width = std::min(width * new_dpi.x() / dpi_.x(), + static_cast<int64>(std::numeric_limits<int32>::max())); + height = std::min(height * new_dpi.y() / dpi_.y(), + static_cast<int64>(std::numeric_limits<int32>::max())); + return SkISize::Make(static_cast<int32>(width), static_cast<int32>(height)); +} + +bool ScreenResolution::IsEmpty() const { + return dimensions_.isEmpty() || dpi_.x() <= 0 || dpi_.y() <= 0; +} + +bool ScreenResolution::IsValid() const { + return !IsEmpty() || dimensions_.isZero(); +} + +} // namespace remoting diff --git a/remoting/host/screen_resolution.h b/remoting/host/screen_resolution.h new file mode 100644 index 0000000..d09eb64 --- /dev/null +++ b/remoting/host/screen_resolution.h @@ -0,0 +1,42 @@ +// Copyright (c) 2013 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_SCREEN_RESOLUTION_H_ +#define REMOTING_HOST_SCREEN_RESOLUTION_H_ + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "third_party/skia/include/core/SkPoint.h" +#include "third_party/skia/include/core/SkSize.h" + +namespace remoting { + +// Describes a screen's dimensions and DPI. +class ScreenResolution { + public: + ScreenResolution(); + + ScreenResolution(const SkISize& dimensions, const SkIPoint& dpi); + + // Returns the screen dimensions scaled according to the passed |new_dpi|. + SkISize ScaleDimensionsToDpi(const SkIPoint& new_dpi) const; + + // Returns true if |dimensions_| specifies an empty rectangle or when + // IsValid() returns false. + bool IsEmpty() const; + + // Returns true if both |dimensions_| and |dpi_| are valid. |dimensions_| + // specifying an empty rectangle is considered to be valid. + bool IsValid() const; + + // Dimensions of the screen in pixels. + SkISize dimensions_; + + // The vertical and horizontal DPI of the screen. + SkIPoint dpi_; +}; + +} // namespace remoting + +#endif // REMOTING_HOST_SCREEN_RESOLUTION_H_ diff --git a/remoting/host/screen_resolution_unittest.cc b/remoting/host/screen_resolution_unittest.cc new file mode 100644 index 0000000..dce7bc0 --- /dev/null +++ b/remoting/host/screen_resolution_unittest.cc @@ -0,0 +1,80 @@ +// Copyright (c) 2013 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/screen_resolution.h" + +#include <limits> + +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace remoting { + +TEST(ScreenResolutionTest, Empty) { + ScreenResolution resolution; + EXPECT_TRUE(resolution.IsEmpty()); + + resolution.dimensions_.set(-1, 0); + EXPECT_TRUE(resolution.IsEmpty()); + + resolution.dimensions_.set(0, -1); + EXPECT_TRUE(resolution.IsEmpty()); + + resolution.dimensions_.set(-1, -1); + EXPECT_TRUE(resolution.IsEmpty()); + + resolution.dpi_.set(-1, 0); + EXPECT_TRUE(resolution.IsEmpty()); + + resolution.dpi_.set(0, -1); + EXPECT_TRUE(resolution.IsEmpty()); + + resolution.dpi_.set(-1, -1); + EXPECT_TRUE(resolution.IsEmpty()); +} + +TEST(ScreenResolutionTest, Invalid) { + ScreenResolution resolution; + EXPECT_TRUE(resolution.IsValid()); + + resolution.dimensions_.set(-1, 0); + EXPECT_FALSE(resolution.IsValid()); + + resolution.dimensions_.set(0, -1); + EXPECT_FALSE(resolution.IsValid()); + + resolution.dimensions_.set(-1, -1); + EXPECT_FALSE(resolution.IsValid()); + + resolution.dpi_.set(-1, 0); + EXPECT_FALSE(resolution.IsValid()); + + resolution.dpi_.set(0, -1); + EXPECT_FALSE(resolution.IsValid()); + + resolution.dpi_.set(-1, -1); + EXPECT_FALSE(resolution.IsValid()); +} + +TEST(ScreenResolutionTest, Scaling) { + ScreenResolution resolution( + SkISize::Make(100, 100), SkIPoint::Make(10, 10)); + + EXPECT_EQ(resolution.ScaleDimensionsToDpi(SkIPoint::Make(5, 5)), + SkISize::Make(50, 50)); + + EXPECT_EQ(resolution.ScaleDimensionsToDpi(SkIPoint::Make(20, 20)), + SkISize::Make(200, 200)); +} + +TEST(ScreenResolutionTest, ScalingSaturation) { + ScreenResolution resolution( + SkISize::Make(10000000, 1000000), SkIPoint::Make(1, 1)); + + EXPECT_EQ(resolution.ScaleDimensionsToDpi(SkIPoint::Make(1000000, 1000000)), + SkISize::Make(std::numeric_limits<int32>::max(), + std::numeric_limits<int32>::max())); +} + +} // namespace remoting diff --git a/remoting/host/session_controller.h b/remoting/host/session_controller.h index 46fff8d..8587a44 100644 --- a/remoting/host/session_controller.h +++ b/remoting/host/session_controller.h @@ -11,13 +11,14 @@ namespace remoting { +class ScreenResolution; + class SessionController { public: virtual ~SessionController() {} - // Called when the client view size or pixel density change. - virtual void OnClientResolutionChanged(const SkIPoint& client_dpi, - const SkISize& client_size) = 0; + // Attempts to set new screen resolution in the session. + virtual void SetScreenResolution(const ScreenResolution& resolution) = 0; }; } // namespace remoting diff --git a/remoting/remoting.gyp b/remoting/remoting.gyp index 33b185c..3089f51 100644 --- a/remoting/remoting.gyp +++ b/remoting/remoting.gyp @@ -423,6 +423,8 @@ 'host/resizing_host_observer.h', 'host/sas_injector.h', 'host/sas_injector_win.cc', + 'host/screen_resolution.cc', + 'host/screen_resolution.h', 'host/server_log_entry.cc', 'host/server_log_entry.h', 'host/service_client.cc', @@ -2547,6 +2549,7 @@ 'host/register_support_host_request_unittest.cc', 'host/remote_input_filter_unittest.cc', 'host/resizing_host_observer_unittest.cc', + 'host/screen_resolution_unittest.cc', 'host/server_log_entry_unittest.cc', 'host/setup/oauth_helper_unittest.cc', 'host/setup/pin_validator_unittest.cc', |