| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "remoting/host/client_session.h" | 5 #include "remoting/host/client_session.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <string> | 10 #include <string> |
| 11 #include <utility> | 11 #include <utility> |
| 12 #include <vector> | 12 #include <vector> |
| 13 | 13 |
| 14 #include "base/memory/ptr_util.h" |
| 14 #include "base/message_loop/message_loop.h" | 15 #include "base/message_loop/message_loop.h" |
| 15 #include "base/run_loop.h" | 16 #include "base/run_loop.h" |
| 16 #include "base/strings/string_split.h" | 17 #include "base/strings/string_split.h" |
| 17 #include "base/strings/string_util.h" | 18 #include "base/strings/string_util.h" |
| 18 #include "build/build_config.h" | 19 #include "build/build_config.h" |
| 19 #include "remoting/base/auto_thread_task_runner.h" | 20 #include "remoting/base/auto_thread_task_runner.h" |
| 20 #include "remoting/base/constants.h" | 21 #include "remoting/base/constants.h" |
| 21 #include "remoting/codec/video_encoder_verbatim.h" | 22 #include "remoting/codec/video_encoder_verbatim.h" |
| 22 #include "remoting/host/desktop_environment.h" | 23 #include "remoting/host/desktop_environment.h" |
| 23 #include "remoting/host/fake_desktop_environment.h" | 24 #include "remoting/host/fake_desktop_environment.h" |
| 24 #include "remoting/host/fake_host_extension.h" | 25 #include "remoting/host/fake_host_extension.h" |
| 25 #include "remoting/host/fake_mouse_cursor_monitor.h" | 26 #include "remoting/host/fake_mouse_cursor_monitor.h" |
| 26 #include "remoting/host/host_extension.h" | 27 #include "remoting/host/host_extension.h" |
| 27 #include "remoting/host/host_extension_session.h" | 28 #include "remoting/host/host_extension_session.h" |
| 28 #include "remoting/host/host_mock_objects.h" | 29 #include "remoting/host/host_mock_objects.h" |
| 29 #include "remoting/protocol/fake_connection_to_client.h" | 30 #include "remoting/protocol/fake_connection_to_client.h" |
| 30 #include "remoting/protocol/fake_desktop_capturer.h" | 31 #include "remoting/protocol/fake_desktop_capturer.h" |
| 32 #include "remoting/protocol/fake_session.h" |
| 31 #include "remoting/protocol/protocol_mock_objects.h" | 33 #include "remoting/protocol/protocol_mock_objects.h" |
| 32 #include "remoting/protocol/test_event_matchers.h" | 34 #include "remoting/protocol/test_event_matchers.h" |
| 33 #include "testing/gmock/include/gmock/gmock-matchers.h" | 35 #include "testing/gmock/include/gmock/gmock-matchers.h" |
| 34 #include "testing/gtest/include/gtest/gtest.h" | 36 #include "testing/gtest/include/gtest/gtest.h" |
| 35 #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h" | 37 #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h" |
| 36 | 38 |
| 37 namespace remoting { | 39 namespace remoting { |
| 38 | 40 |
| 41 using protocol::FakeSession; |
| 39 using protocol::MockClientStub; | 42 using protocol::MockClientStub; |
| 40 using protocol::MockHostStub; | 43 using protocol::MockHostStub; |
| 41 using protocol::MockInputStub; | 44 using protocol::MockInputStub; |
| 42 using protocol::MockSession; | |
| 43 using protocol::MockVideoStub; | 45 using protocol::MockVideoStub; |
| 44 using protocol::SessionConfig; | 46 using protocol::SessionConfig; |
| 45 using protocol::test::EqualsClipboardEvent; | 47 using protocol::test::EqualsClipboardEvent; |
| 46 using protocol::test::EqualsMouseButtonEvent; | 48 using protocol::test::EqualsMouseButtonEvent; |
| 47 using protocol::test::EqualsMouseMoveEvent; | 49 using protocol::test::EqualsMouseMoveEvent; |
| 48 using protocol::test::EqualsKeyEvent; | 50 using protocol::test::EqualsKeyEvent; |
| 49 | 51 |
| 50 using testing::_; | 52 using testing::_; |
| 51 using testing::AtLeast; | 53 using testing::AtLeast; |
| 52 using testing::ReturnRef; | 54 using testing::ReturnRef; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 89 protocol::ClipboardEvent result; | 91 protocol::ClipboardEvent result; |
| 90 result.set_mime_type(kMimeTypeTextUtf8); | 92 result.set_mime_type(kMimeTypeTextUtf8); |
| 91 result.set_data(text); | 93 result.set_data(text); |
| 92 return result; | 94 return result; |
| 93 } | 95 } |
| 94 | 96 |
| 95 } // namespace | 97 } // namespace |
| 96 | 98 |
| 97 class ClientSessionTest : public testing::Test { | 99 class ClientSessionTest : public testing::Test { |
| 98 public: | 100 public: |
| 99 ClientSessionTest() : client_jid_("user@domain/rest-of-jid") {} | 101 ClientSessionTest() = default; |
| 100 | 102 |
| 101 void SetUp() override; | 103 void SetUp() override; |
| 102 void TearDown() override; | 104 void TearDown() override; |
| 103 | 105 |
| 106 protected: |
| 107 // Creates the client session from a FakeSession instance. |
| 108 void CreateClientSession(std::unique_ptr<protocol::FakeSession> session); |
| 109 |
| 104 // Creates the client session. | 110 // Creates the client session. |
| 105 void CreateClientSession(); | 111 void CreateClientSession(); |
| 106 | 112 |
| 107 protected: | |
| 108 // Notifies the client session that the client connection has been | 113 // Notifies the client session that the client connection has been |
| 109 // authenticated and channels have been connected. This effectively enables | 114 // authenticated and channels have been connected. This effectively enables |
| 110 // the input pipe line and starts video capturing. | 115 // the input pipe line and starts video capturing. |
| 111 void ConnectClientSession(); | 116 void ConnectClientSession(); |
| 112 | 117 |
| 113 // Fakes video size notification from the VideoStream. | 118 // Fakes video size notification from the VideoStream. |
| 114 void NotifyVideoSize(); | 119 void NotifyVideoSize(); |
| 115 | 120 |
| 116 // Creates expectations to send an extension message and to disconnect | |
| 117 // afterwards. | |
| 118 void SetSendMessageAndDisconnectExpectation(const std::string& message_type); | |
| 119 | |
| 120 // Message loop that will process all ClientSession tasks. | 121 // Message loop that will process all ClientSession tasks. |
| 121 base::MessageLoop message_loop_; | 122 base::MessageLoop message_loop_; |
| 122 | 123 |
| 123 // AutoThreadTaskRunner on which |client_session_| will be run. | 124 // AutoThreadTaskRunner on which |client_session_| will be run. |
| 124 scoped_refptr<AutoThreadTaskRunner> task_runner_; | 125 scoped_refptr<AutoThreadTaskRunner> task_runner_; |
| 125 | 126 |
| 126 // Used to run |message_loop_| after each test, until no objects remain that | 127 // Used to run |message_loop_| after each test, until no objects remain that |
| 127 // require it. | 128 // require it. |
| 128 base::RunLoop run_loop_; | 129 base::RunLoop run_loop_; |
| 129 | 130 |
| 130 // HostExtensions to pass when creating the ClientSession. Caller retains | 131 // HostExtensions to pass when creating the ClientSession. Caller retains |
| 131 // ownership of the HostExtensions themselves. | 132 // ownership of the HostExtensions themselves. |
| 132 std::vector<HostExtension*> extensions_; | 133 std::vector<HostExtension*> extensions_; |
| 133 | 134 |
| 134 // ClientSession instance under test. | 135 // ClientSession instance under test. |
| 135 std::unique_ptr<ClientSession> client_session_; | 136 std::unique_ptr<ClientSession> client_session_; |
| 136 | 137 |
| 137 // ClientSession::EventHandler mock for use in tests. | 138 // ClientSession::EventHandler mock for use in tests. |
| 138 MockClientSessionEventHandler session_event_handler_; | 139 MockClientSessionEventHandler session_event_handler_; |
| 139 | 140 |
| 140 // Storage for values to be returned by the protocol::Session mock. | |
| 141 std::unique_ptr<SessionConfig> session_config_; | |
| 142 const std::string client_jid_; | |
| 143 | |
| 144 // Stubs returned to |client_session_| components by |connection_|. | 141 // Stubs returned to |client_session_| components by |connection_|. |
| 145 MockClientStub client_stub_; | 142 MockClientStub client_stub_; |
| 146 | 143 |
| 147 // ClientSession owns |connection_| but tests need it to inject fake events. | 144 // ClientSession owns |connection_| but tests need it to inject fake events. |
| 148 protocol::FakeConnectionToClient* connection_; | 145 protocol::FakeConnectionToClient* connection_; |
| 149 | 146 |
| 150 std::unique_ptr<FakeDesktopEnvironmentFactory> desktop_environment_factory_; | 147 std::unique_ptr<FakeDesktopEnvironmentFactory> desktop_environment_factory_; |
| 151 }; | 148 }; |
| 152 | 149 |
| 153 void ClientSessionTest::SetUp() { | 150 void ClientSessionTest::SetUp() { |
| 154 // Arrange to run |message_loop_| until no components depend on it. | 151 // Arrange to run |message_loop_| until no components depend on it. |
| 155 task_runner_ = new AutoThreadTaskRunner( | 152 task_runner_ = new AutoThreadTaskRunner( |
| 156 message_loop_.task_runner(), run_loop_.QuitClosure()); | 153 message_loop_.task_runner(), run_loop_.QuitClosure()); |
| 157 | 154 |
| 158 desktop_environment_factory_.reset( | 155 desktop_environment_factory_.reset( |
| 159 new FakeDesktopEnvironmentFactory(message_loop_.task_runner())); | 156 new FakeDesktopEnvironmentFactory(message_loop_.task_runner())); |
| 160 session_config_ = SessionConfig::ForTest(); | |
| 161 } | 157 } |
| 162 | 158 |
| 163 void ClientSessionTest::TearDown() { | 159 void ClientSessionTest::TearDown() { |
| 164 if (client_session_) { | 160 if (client_session_) { |
| 165 client_session_->DisconnectSession(protocol::OK); | 161 client_session_->DisconnectSession(protocol::OK); |
| 166 client_session_.reset(); | 162 client_session_.reset(); |
| 167 desktop_environment_factory_.reset(); | 163 desktop_environment_factory_.reset(); |
| 168 } | 164 } |
| 169 | 165 |
| 170 // Clear out |task_runner_| reference so the loop can quit, and run it until | 166 // Clear out |task_runner_| reference so the loop can quit, and run it until |
| 171 // it does. | 167 // it does. |
| 172 task_runner_ = nullptr; | 168 task_runner_ = nullptr; |
| 173 run_loop_.Run(); | 169 run_loop_.Run(); |
| 174 } | 170 } |
| 175 | 171 |
| 176 void ClientSessionTest::CreateClientSession() { | 172 void ClientSessionTest::CreateClientSession( |
| 177 // Mock protocol::Session APIs called directly by ClientSession. | 173 std::unique_ptr<protocol::FakeSession> session) { |
| 178 std::unique_ptr<protocol::MockSession> session(new MockSession()); | 174 DCHECK(session); |
| 179 EXPECT_CALL(*session, config()).WillRepeatedly(ReturnRef(*session_config_)); | |
| 180 EXPECT_CALL(*session, jid()).WillRepeatedly(ReturnRef(client_jid_)); | |
| 181 | 175 |
| 182 // Mock protocol::ConnectionToClient APIs called directly by ClientSession. | 176 // Mock protocol::ConnectionToClient APIs called directly by ClientSession. |
| 183 // HostStub is not touched by ClientSession, so we can safely pass nullptr. | 177 // HostStub is not touched by ClientSession, so we can safely pass nullptr. |
| 184 std::unique_ptr<protocol::FakeConnectionToClient> connection( | 178 std::unique_ptr<protocol::FakeConnectionToClient> connection( |
| 185 new protocol::FakeConnectionToClient(std::move(session))); | 179 new protocol::FakeConnectionToClient(std::move(session))); |
| 186 connection->set_client_stub(&client_stub_); | 180 connection->set_client_stub(&client_stub_); |
| 187 connection_ = connection.get(); | 181 connection_ = connection.get(); |
| 188 | 182 |
| 189 client_session_.reset( | 183 client_session_.reset( |
| 190 new ClientSession(&session_event_handler_, std::move(connection), | 184 new ClientSession(&session_event_handler_, std::move(connection), |
| 191 desktop_environment_factory_.get(), | 185 desktop_environment_factory_.get(), |
| 192 DesktopEnvironmentOptions::CreateDefault(), | 186 DesktopEnvironmentOptions::CreateDefault(), |
| 193 base::TimeDelta(), nullptr, extensions_)); | 187 base::TimeDelta(), nullptr, extensions_)); |
| 194 } | 188 } |
| 195 | 189 |
| 190 void ClientSessionTest::CreateClientSession() { |
| 191 CreateClientSession(base::MakeUnique<protocol::FakeSession>()); |
| 192 } |
| 193 |
| 196 void ClientSessionTest::ConnectClientSession() { | 194 void ClientSessionTest::ConnectClientSession() { |
| 197 EXPECT_CALL(session_event_handler_, OnSessionAuthenticated(_)); | 195 EXPECT_CALL(session_event_handler_, OnSessionAuthenticated(_)); |
| 198 EXPECT_CALL(session_event_handler_, OnSessionChannelsConnected(_)); | 196 EXPECT_CALL(session_event_handler_, OnSessionChannelsConnected(_)); |
| 199 | 197 |
| 200 // Stubs should be set only after connection is authenticated. | 198 // Stubs should be set only after connection is authenticated. |
| 201 EXPECT_FALSE(connection_->clipboard_stub()); | 199 EXPECT_FALSE(connection_->clipboard_stub()); |
| 202 EXPECT_FALSE(connection_->input_stub()); | 200 EXPECT_FALSE(connection_->input_stub()); |
| 203 | 201 |
| 204 client_session_->OnConnectionAuthenticated(); | 202 client_session_->OnConnectionAuthenticated(); |
| 205 | 203 |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 424 EXPECT_TRUE(extension1.has_handled_message()); | 422 EXPECT_TRUE(extension1.has_handled_message()); |
| 425 | 423 |
| 426 // ext2 was instantiated but not sent a message, and wrapped video encoder. | 424 // ext2 was instantiated but not sent a message, and wrapped video encoder. |
| 427 EXPECT_TRUE(extension2.was_instantiated()); | 425 EXPECT_TRUE(extension2.was_instantiated()); |
| 428 EXPECT_FALSE(extension2.has_handled_message()); | 426 EXPECT_FALSE(extension2.has_handled_message()); |
| 429 | 427 |
| 430 // ext3 was sent a message but not instantiated. | 428 // ext3 was sent a message but not instantiated. |
| 431 EXPECT_FALSE(extension3.was_instantiated()); | 429 EXPECT_FALSE(extension3.was_instantiated()); |
| 432 } | 430 } |
| 433 | 431 |
| 432 TEST_F(ClientSessionTest, ForwardHostSessionOptions1) { |
| 433 auto session = base::MakeUnique<protocol::FakeSession>(); |
| 434 auto configuration = base::MakeUnique<buzz::XmlElement>( |
| 435 buzz::QName(kChromotingXmlNamespace, "host-configuration")); |
| 436 configuration->SetBodyText("Detect-Updated-Region:true"); |
| 437 session->SetAttachment(0, std::move(configuration)); |
| 438 CreateClientSession(std::move(session)); |
| 439 ConnectClientSession(); |
| 440 ASSERT_TRUE(desktop_environment_factory_->last_desktop_environment() |
| 441 ->options() |
| 442 .desktop_capture_options() |
| 443 ->detect_updated_region()); |
| 444 } |
| 445 |
| 446 TEST_F(ClientSessionTest, ForwardHostSessionOptions2) { |
| 447 auto session = base::MakeUnique<protocol::FakeSession>(); |
| 448 auto configuration = base::MakeUnique<buzz::XmlElement>( |
| 449 buzz::QName(kChromotingXmlNamespace, "host-configuration")); |
| 450 configuration->SetBodyText("Detect-Updated-Region:false"); |
| 451 session->SetAttachment(0, std::move(configuration)); |
| 452 CreateClientSession(std::move(session)); |
| 453 ConnectClientSession(); |
| 454 ASSERT_FALSE(desktop_environment_factory_->last_desktop_environment() |
| 455 ->options() |
| 456 .desktop_capture_options() |
| 457 ->detect_updated_region()); |
| 458 } |
| 459 |
| 460 #if defined(OS_WIN) |
| 461 TEST_F(ClientSessionTest, ForwardDirectXHostSessionOptions1) { |
| 462 auto session = base::MakeUnique<protocol::FakeSession>(); |
| 463 auto configuration = base::MakeUnique<buzz::XmlElement>( |
| 464 buzz::QName(kChromotingXmlNamespace, "host-configuration")); |
| 465 configuration->SetBodyText("DirectX-Capturer:true"); |
| 466 session->SetAttachment(0, std::move(configuration)); |
| 467 CreateClientSession(std::move(session)); |
| 468 ConnectClientSession(); |
| 469 ASSERT_TRUE(desktop_environment_factory_->last_desktop_environment() |
| 470 ->options() |
| 471 .desktop_capture_options() |
| 472 ->allow_directx_capturer()); |
| 473 } |
| 474 |
| 475 TEST_F(ClientSessionTest, ForwardDirectXHostSessionOptions2) { |
| 476 auto session = base::MakeUnique<protocol::FakeSession>(); |
| 477 auto configuration = base::MakeUnique<buzz::XmlElement>( |
| 478 buzz::QName(kChromotingXmlNamespace, "host-configuration")); |
| 479 configuration->SetBodyText("DirectX-Capturer:false"); |
| 480 session->SetAttachment(0, std::move(configuration)); |
| 481 CreateClientSession(std::move(session)); |
| 482 ConnectClientSession(); |
| 483 ASSERT_FALSE(desktop_environment_factory_->last_desktop_environment() |
| 484 ->options() |
| 485 .desktop_capture_options() |
| 486 ->allow_directx_capturer()); |
| 487 } |
| 488 #endif |
| 489 |
| 434 } // namespace remoting | 490 } // namespace remoting |
| OLD | NEW |