// Copyright (c) 2012 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/client_session.h"

#include <stdint.h>

#include <algorithm>
#include <string>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/memory/ptr_util.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "build/build_config.h"
#include "remoting/base/auto_thread_task_runner.h"
#include "remoting/base/constants.h"
#include "remoting/codec/video_encoder_verbatim.h"
#include "remoting/host/desktop_environment.h"
#include "remoting/host/fake_desktop_environment.h"
#include "remoting/host/fake_host_extension.h"
#include "remoting/host/fake_mouse_cursor_monitor.h"
#include "remoting/host/host_extension.h"
#include "remoting/host/host_extension_session.h"
#include "remoting/host/host_mock_objects.h"
#include "remoting/protocol/fake_connection_to_client.h"
#include "remoting/protocol/fake_desktop_capturer.h"
#include "remoting/protocol/fake_message_pipe.h"
#include "remoting/protocol/fake_session.h"
#include "remoting/protocol/protocol_mock_objects.h"
#include "remoting/protocol/test_event_matchers.h"
#include "testing/gmock/include/gmock/gmock-matchers.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
#include "ui/events/event.h"

namespace remoting {

using protocol::FakeSession;
using protocol::MockClientStub;
using protocol::MockHostStub;
using protocol::MockInputStub;
using protocol::MockVideoStub;
using protocol::SessionConfig;
using protocol::test::EqualsClipboardEvent;
using protocol::test::EqualsMouseButtonEvent;
using protocol::test::EqualsMouseMoveEvent;
using protocol::test::EqualsKeyEvent;

using testing::_;
using testing::AtLeast;
using testing::ReturnRef;
using testing::StrictMock;

namespace {

constexpr char kTestDataChannelCallbackName[] = "test_channel_name";

// Matches a |protocol::Capabilities| argument against a list of capabilities
// formatted as a space-separated string.
MATCHER_P(EqCapabilities, expected_capabilities, "") {
  if (!arg.has_capabilities())
    return false;

  std::vector<std::string> words_args = base::SplitString(
      arg.capabilities(), " ", base::KEEP_WHITESPACE,
      base::SPLIT_WANT_NONEMPTY);
  std::vector<std::string> words_expected = base::SplitString(
      expected_capabilities, " ", base::KEEP_WHITESPACE,
      base::SPLIT_WANT_NONEMPTY);
  std::sort(words_args.begin(), words_args.end());
  std::sort(words_expected.begin(), words_expected.end());
  return words_args == words_expected;
}

protocol::MouseEvent MakeMouseMoveEvent(int x, int y) {
  protocol::MouseEvent result;
  result.set_x(x);
  result.set_y(y);
  return result;
}

protocol::KeyEvent MakeKeyEvent(bool pressed, uint32_t keycode) {
  protocol::KeyEvent result;
  result.set_pressed(pressed);
  result.set_usb_keycode(keycode);
  return result;
}

protocol::ClipboardEvent MakeClipboardEvent(const std::string& text) {
  protocol::ClipboardEvent result;
  result.set_mime_type(kMimeTypeTextUtf8);
  result.set_data(text);
  return result;
}

}  // namespace

class ClientSessionTest : public testing::Test {
 public:
  ClientSessionTest() = default;

  void SetUp() override;
  void TearDown() override;

 protected:
  // Fake multi-monitor setup.
  static const int kDisplay1Width =
      protocol::FakeDesktopCapturer::kWidth;  // 800
  static const int kDisplay1Height =
      protocol::FakeDesktopCapturer::kHeight;  // 600
  static const int kDisplay2Width = 1024;
  static const int kDisplay2Height = 768;
  static const int kDisplay2YOffset = 35;

  // Creates the client session from a FakeSession instance.
  void CreateClientSession(std::unique_ptr<protocol::FakeSession> session);

  // Creates the client session.
  void CreateClientSession();

  // Notifies the client session that the client connection has been
  // authenticated and channels have been connected. This effectively enables
  // the input pipe line and starts video capturing.
  void ConnectClientSession();

  // Fakes video size notification from the VideoStream.
  void NotifyVideoSize(int width, int height, int dpi_x, int dpi_y);

  // Add a fake display to the layout list. Used in conjunction with
  // NotifyDesktopDisplaySize.
  void AddDisplayToLayout(protocol::VideoLayout* displays,
                          int x,
                          int y,
                          int width,
                          int height,
                          int dpi_x,
                          int dpi_y);

  // Fakes desktop display size notification from Webrtc.
  void NotifyDesktopDisplaySize(
      std::unique_ptr<protocol::VideoLayout> displays);

  // Fakes display select request from user.
  void NotifySelectDesktopDisplay(std::string id);

  // Convenience methods to setup a single- or double-monitor setup.
  void SetupSingleDisplay();
  void SetupMultiDisplay();

  // When using a multi-mon setup, this fakes the user selecting which displays
  // to show.
  void MultiMon_SelectFirstDisplay();
  void MultiMon_SelectSecondDisplay();
  void MultiMon_SelectAllDisplays();

  // Message loop that will process all ClientSession tasks.
  base::MessageLoop message_loop_;

  // AutoThreadTaskRunner on which |client_session_| will be run.
  scoped_refptr<AutoThreadTaskRunner> task_runner_;

  // Used to run |message_loop_| after each test, until no objects remain that
  // require it.
  base::RunLoop run_loop_;

  // HostExtensions to pass when creating the ClientSession. Caller retains
  // ownership of the HostExtensions themselves.
  std::vector<HostExtension*> extensions_;

  // ClientSession instance under test.
  std::unique_ptr<ClientSession> client_session_;

  // ClientSession::EventHandler mock for use in tests.
  MockClientSessionEventHandler session_event_handler_;

  // Stubs returned to |client_session_| components by |connection_|.
  MockClientStub client_stub_;

  // ClientSession owns |connection_| but tests need it to inject fake events.
  protocol::FakeConnectionToClient* connection_;

  std::unique_ptr<FakeDesktopEnvironmentFactory> desktop_environment_factory_;

  DesktopEnvironmentOptions desktop_environment_options_;
};

void ClientSessionTest::SetUp() {
  // Arrange to run |message_loop_| until no components depend on it.
  task_runner_ = new AutoThreadTaskRunner(
      message_loop_.task_runner(), run_loop_.QuitClosure());

  desktop_environment_factory_.reset(
      new FakeDesktopEnvironmentFactory(message_loop_.task_runner()));
  desktop_environment_options_ = DesktopEnvironmentOptions::CreateDefault();
}

void ClientSessionTest::TearDown() {
  if (client_session_) {
    if (connection_->is_connected())
      client_session_->DisconnectSession(protocol::OK);
    client_session_.reset();
    desktop_environment_factory_.reset();
  }

  // Clear out |task_runner_| reference so the loop can quit, and run it until
  // it does.
  task_runner_ = nullptr;
  run_loop_.Run();
}

void ClientSessionTest::CreateClientSession(
    std::unique_ptr<protocol::FakeSession> session) {
  DCHECK(session);

  // Mock protocol::ConnectionToClient APIs called directly by ClientSession.
  // HostStub is not touched by ClientSession, so we can safely pass nullptr.
  std::unique_ptr<protocol::FakeConnectionToClient> connection(
      new protocol::FakeConnectionToClient(std::move(session)));
  connection->set_client_stub(&client_stub_);
  connection_ = connection.get();

  client_session_.reset(new ClientSession(
      &session_event_handler_, std::move(connection),
      desktop_environment_factory_.get(), desktop_environment_options_,
      base::TimeDelta(), nullptr, extensions_));
}

void ClientSessionTest::CreateClientSession() {
  CreateClientSession(std::make_unique<protocol::FakeSession>());
}

void ClientSessionTest::ConnectClientSession() {
  EXPECT_CALL(session_event_handler_, OnSessionAuthenticated(_));
  EXPECT_CALL(session_event_handler_, OnSessionChannelsConnected(_));

  // Stubs should be set only after connection is authenticated.
  EXPECT_FALSE(connection_->clipboard_stub());
  EXPECT_FALSE(connection_->input_stub());

  client_session_->OnConnectionAuthenticated();

  EXPECT_TRUE(connection_->clipboard_stub());
  EXPECT_TRUE(connection_->input_stub());

  client_session_->CreateMediaStreams();
  client_session_->OnConnectionChannelsConnected();
}

void ClientSessionTest::NotifyVideoSize(int width,
                                        int height,
                                        int dpi_x,
                                        int dpi_y) {
  connection_->last_video_stream()->observer()->OnVideoSizeChanged(
      connection_->last_video_stream().get(),
      webrtc::DesktopSize(width, height), webrtc::DesktopVector(dpi_x, dpi_y));
}

void ClientSessionTest::AddDisplayToLayout(protocol::VideoLayout* displays,
                                           int x,
                                           int y,
                                           int width,
                                           int height,
                                           int dpi_x,
                                           int dpi_y) {
  protocol::VideoTrackLayout* video_track = displays->add_video_track();
  video_track->set_position_x(x);
  video_track->set_position_y(y);
  video_track->set_width(width);
  video_track->set_height(height);
  video_track->set_x_dpi(dpi_x);
  video_track->set_y_dpi(dpi_y);
}

void ClientSessionTest::NotifyDesktopDisplaySize(
    std::unique_ptr<protocol::VideoLayout> displays) {
  client_session_->OnDesktopDisplayChanged(std::move(displays));
}

void ClientSessionTest::NotifySelectDesktopDisplay(std::string id) {
  protocol::SelectDesktopDisplayRequest req;
  req.set_id(id);
  client_session_->SelectDesktopDisplay(req);
}

// Set up a single display (default size).
void ClientSessionTest::SetupSingleDisplay() {
  NotifyVideoSize(kDisplay1Width, kDisplay1Height, kDefaultDpi, kDefaultDpi);
  auto displays = std::make_unique<protocol::VideoLayout>();
  AddDisplayToLayout(displays.get(), 0, 0, kDisplay1Width, kDisplay1Height,
                     kDefaultDpi, kDefaultDpi);
  NotifyDesktopDisplaySize(std::move(displays));
}

// Set up multiple displays:
// +-----------+
// |  800x600  |---------------+
// |     0     |   1024x768    |
// +-----------+       1       |
//             |               |
//             +---------------+
void ClientSessionTest::SetupMultiDisplay() {
  NotifyVideoSize(kDisplay1Width + kDisplay2Width, kDisplay2Height, kDefaultDpi,
                  kDefaultDpi);
  auto displays = std::make_unique<protocol::VideoLayout>();
  AddDisplayToLayout(displays.get(), 0, 0, kDisplay1Width, kDisplay1Height,
                     kDefaultDpi, kDefaultDpi);
  AddDisplayToLayout(displays.get(), kDisplay1Width, kDisplay2YOffset,
                     kDisplay2Width, kDisplay2Height, kDefaultDpi, kDefaultDpi);
  NotifyDesktopDisplaySize(std::move(displays));
}

void ClientSessionTest::MultiMon_SelectFirstDisplay() {
  NotifySelectDesktopDisplay("0");
  NotifyVideoSize(kDisplay1Width, kDisplay1Height, kDefaultDpi, kDefaultDpi);
}

void ClientSessionTest::MultiMon_SelectSecondDisplay() {
  NotifySelectDesktopDisplay("1");
  NotifyVideoSize(kDisplay2Width, kDisplay2Height, kDefaultDpi, kDefaultDpi);
}

void ClientSessionTest::MultiMon_SelectAllDisplays() {
  NotifySelectDesktopDisplay("all");
  NotifyVideoSize(kDisplay1Width + kDisplay2Width, kDisplay2Height, kDefaultDpi,
                  kDefaultDpi);
}

TEST_F(ClientSessionTest, MultiMonMouseMove) {
  CreateClientSession();
  ConnectClientSession();
  SetupMultiDisplay();

  FakeInputInjector* input_injector =
      desktop_environment_factory_->last_desktop_environment()
          ->last_input_injector()
          .get();
  std::vector<protocol::MouseEvent> mouse_events;
  input_injector->set_mouse_events(&mouse_events);

  // These mouse events are in global (full desktop) coordinates.
  connection_->input_stub()->InjectMouseEvent(MakeMouseMoveEvent(70, 50));
  connection_->input_stub()->InjectMouseEvent(MakeMouseMoveEvent(1000, 650));

  // Select second display: origin: 800,35 ; size: 1024x768
  MultiMon_SelectSecondDisplay();
  // This mouse event is injected relative to the second display.
  connection_->input_stub()->InjectMouseEvent(MakeMouseMoveEvent(1005, 625));
  // Events should clamp to the selected display.
  connection_->input_stub()->InjectMouseEvent(MakeMouseMoveEvent(2000, 700));

  // Select first display: origin: 0,0 ; size: 800x600
  MultiMon_SelectFirstDisplay();
  connection_->input_stub()->InjectMouseEvent(MakeMouseMoveEvent(80, 60));
  // Events should clamp to the selected display (800,600).
  connection_->input_stub()->InjectMouseEvent(MakeMouseMoveEvent(1000, 640));

  // Select entire desktop again: origin: 0,0 ; size: 1824x768
  MultiMon_SelectAllDisplays();
  // Events should clamp to the entire desktop (800+1024, 768).
  connection_->input_stub()->InjectMouseEvent(MakeMouseMoveEvent(2000, 1000));

  client_session_->DisconnectSession(protocol::OK);
  client_session_.reset();

  EXPECT_EQ(7U, mouse_events.size());
  EXPECT_THAT(mouse_events[0], EqualsMouseMoveEvent(70, 50));
  EXPECT_THAT(mouse_events[1], EqualsMouseMoveEvent(1000, 650));
  EXPECT_THAT(mouse_events[2], EqualsMouseMoveEvent(1005 + kDisplay1Width,
                                                    625 + kDisplay2YOffset));
  EXPECT_THAT(mouse_events[3],
              EqualsMouseMoveEvent(kDisplay1Width + kDisplay2Width - 1,
                                   700 + kDisplay2YOffset));
  EXPECT_THAT(mouse_events[4], EqualsMouseMoveEvent(80, 60));
  EXPECT_THAT(mouse_events[5],
              EqualsMouseMoveEvent(kDisplay1Width - 1, kDisplay1Height - 1));
  EXPECT_THAT(mouse_events[6],
              EqualsMouseMoveEvent(kDisplay1Width + kDisplay2Width - 1,
                                   kDisplay2Height - 1));
}

TEST_F(ClientSessionTest, DisableInputs) {
  CreateClientSession();
  ConnectClientSession();
  SetupSingleDisplay();

  FakeInputInjector* input_injector =
      desktop_environment_factory_->last_desktop_environment()
          ->last_input_injector()
          .get();
  std::vector<protocol::KeyEvent> key_events;
  input_injector->set_key_events(&key_events);
  std::vector<protocol::MouseEvent> mouse_events;
  input_injector->set_mouse_events(&mouse_events);
  std::vector<protocol::ClipboardEvent> clipboard_events;
  input_injector->set_clipboard_events(&clipboard_events);

  // Inject test events that are expected to be injected.
  connection_->clipboard_stub()->InjectClipboardEvent(MakeClipboardEvent("a"));
  connection_->input_stub()->InjectKeyEvent(MakeKeyEvent(true, 1));
  connection_->input_stub()->InjectMouseEvent(MakeMouseMoveEvent(100, 101));

  // Disable input.
  client_session_->SetDisableInputs(true);

  // These event shouldn't get though to the input injector.
  connection_->clipboard_stub()->InjectClipboardEvent(MakeClipboardEvent("b"));
  connection_->input_stub()->InjectKeyEvent(MakeKeyEvent(true, 2));
  connection_->input_stub()->InjectKeyEvent(MakeKeyEvent(false, 2));
  connection_->input_stub()->InjectMouseEvent(MakeMouseMoveEvent(200, 201));

  // Enable input again.
  client_session_->SetDisableInputs(false);
  connection_->clipboard_stub()->InjectClipboardEvent(MakeClipboardEvent("c"));
  connection_->input_stub()->InjectKeyEvent(MakeKeyEvent(true, 3));
  connection_->input_stub()->InjectMouseEvent(MakeMouseMoveEvent(300, 301));

  client_session_->DisconnectSession(protocol::OK);
  client_session_.reset();

  EXPECT_EQ(2U, mouse_events.size());
  EXPECT_THAT(mouse_events[0], EqualsMouseMoveEvent(100, 101));
  EXPECT_THAT(mouse_events[1], EqualsMouseMoveEvent(300, 301));

  EXPECT_EQ(4U, key_events.size());
  EXPECT_THAT(key_events[0], EqualsKeyEvent(1, true));
  EXPECT_THAT(key_events[1], EqualsKeyEvent(1, false));
  EXPECT_THAT(key_events[2], EqualsKeyEvent(3, true));
  EXPECT_THAT(key_events[3], EqualsKeyEvent(3, false));

  EXPECT_EQ(2U, clipboard_events.size());
  EXPECT_THAT(clipboard_events[0],
              EqualsClipboardEvent(kMimeTypeTextUtf8, "a"));
  EXPECT_THAT(clipboard_events[1],
              EqualsClipboardEvent(kMimeTypeTextUtf8, "c"));
}

TEST_F(ClientSessionTest, LocalInputTest) {
  CreateClientSession();
  ConnectClientSession();
  SetupSingleDisplay();

  std::vector<protocol::MouseEvent> mouse_events;
  desktop_environment_factory_->last_desktop_environment()
      ->last_input_injector()
      ->set_mouse_events(&mouse_events);

  connection_->input_stub()->InjectMouseEvent(MakeMouseMoveEvent(100, 101));

#if !defined(OS_WIN)
  // The OS echoes the injected event back.
  client_session_->OnLocalPointerMoved(webrtc::DesktopVector(100, 101),
                                       ui::ET_MOUSE_MOVED);
#endif  // !defined(OS_WIN)

  // This one should get throught as well.
  connection_->input_stub()->InjectMouseEvent(MakeMouseMoveEvent(200, 201));

  // Now this is a genuine local event.
  client_session_->OnLocalPointerMoved(webrtc::DesktopVector(100, 101),
                                       ui::ET_MOUSE_MOVED);

  // This one should be blocked because of the previous local input event.
  connection_->input_stub()->InjectMouseEvent(MakeMouseMoveEvent(300, 301));

  // Verify that we've received correct set of mouse events.
  EXPECT_EQ(2U, mouse_events.size());
  EXPECT_THAT(mouse_events[0], EqualsMouseMoveEvent(100, 101));
  EXPECT_THAT(mouse_events[1], EqualsMouseMoveEvent(200, 201));

  // Verify that we're still connected.
  EXPECT_TRUE(connection_->is_connected());

  // TODO(jamiewalch): Verify that remote inputs are re-enabled
  // eventually (via dependency injection, not sleep!)
}

TEST_F(ClientSessionTest, DisconnectOnLocalInputTest) {
  desktop_environment_options_.set_terminate_upon_input(true);
  CreateClientSession();
  ConnectClientSession();
  SetupSingleDisplay();

  client_session_->OnLocalPointerMoved(webrtc::DesktopVector(100, 101),
                                       ui::ET_MOUSE_MOVED);
  EXPECT_FALSE(connection_->is_connected());
}

TEST_F(ClientSessionTest, RestoreEventState) {
  CreateClientSession();
  ConnectClientSession();
  SetupSingleDisplay();

  FakeInputInjector* input_injector =
      desktop_environment_factory_->last_desktop_environment()
          ->last_input_injector()
          .get();
  std::vector<protocol::KeyEvent> key_events;
  input_injector->set_key_events(&key_events);
  std::vector<protocol::MouseEvent> mouse_events;
  input_injector->set_mouse_events(&mouse_events);

  connection_->input_stub()->InjectKeyEvent(MakeKeyEvent(true, 1));
  connection_->input_stub()->InjectKeyEvent(MakeKeyEvent(true, 2));

  protocol::MouseEvent mousedown;
  mousedown.set_button(protocol::MouseEvent::BUTTON_LEFT);
  mousedown.set_button_down(true);
  connection_->input_stub()->InjectMouseEvent(mousedown);

  client_session_->DisconnectSession(protocol::OK);
  client_session_.reset();

  EXPECT_EQ(2U, mouse_events.size());
  EXPECT_THAT(mouse_events[0],
              EqualsMouseButtonEvent(protocol::MouseEvent::BUTTON_LEFT, true));
  EXPECT_THAT(mouse_events[1],
              EqualsMouseButtonEvent(protocol::MouseEvent::BUTTON_LEFT, false));

  EXPECT_EQ(4U, key_events.size());
  EXPECT_THAT(key_events[0], EqualsKeyEvent(1, true));
  EXPECT_THAT(key_events[1], EqualsKeyEvent(2, true));
  EXPECT_THAT(key_events[2], EqualsKeyEvent(1, false));
  EXPECT_THAT(key_events[3], EqualsKeyEvent(2, false));
}

TEST_F(ClientSessionTest, ClampMouseEvents) {
  CreateClientSession();
  ConnectClientSession();
  SetupSingleDisplay();

  std::vector<protocol::MouseEvent> mouse_events;
  desktop_environment_factory_->last_desktop_environment()
      ->last_input_injector()
      ->set_mouse_events(&mouse_events);

  int input_x[3] = {-999, 100, 999};
  int expected_x[3] = {0, 100, protocol::FakeDesktopCapturer::kWidth - 1};
  int input_y[3] = {-999, 50, 999};
  int expected_y[3] = {0, 50, protocol::FakeDesktopCapturer::kHeight - 1};

  protocol::MouseEvent expected_event;
  for (int j = 0; j < 3; j++) {
    for (int i = 0; i < 3; i++) {
      mouse_events.clear();
      connection_->input_stub()->InjectMouseEvent(
          MakeMouseMoveEvent(input_x[i], input_y[j]));

      EXPECT_EQ(1U, mouse_events.size());
      EXPECT_THAT(mouse_events[0],
                  EqualsMouseMoveEvent(expected_x[i], expected_y[j]));
    }
  }
}

// Verifies that clients can have extensions registered, resulting in the
// correct capabilities being reported, and messages delivered correctly.
// The extension system is tested more extensively in the
// HostExtensionSessionManager unit-tests.
TEST_F(ClientSessionTest, Extensions) {
  // Configure fake extensions for testing.
  FakeExtension extension1("ext1", "cap1");
  extensions_.push_back(&extension1);
  FakeExtension extension2("ext2", "");
  extensions_.push_back(&extension2);
  FakeExtension extension3("ext3", "cap3");
  extensions_.push_back(&extension3);

  // Verify that the ClientSession reports the correct capabilities.
  EXPECT_CALL(client_stub_, SetCapabilities(EqCapabilities("cap1 cap3")));

  CreateClientSession();
  ConnectClientSession();

  testing::Mock::VerifyAndClearExpectations(&client_stub_);

  // Mimic the client reporting an overlapping set of capabilities.
  protocol::Capabilities capabilities_message;
  capabilities_message.set_capabilities("cap1 cap4 default");
  client_session_->SetCapabilities(capabilities_message);

  // Verify that the correct extension messages are delivered, and dropped.
  protocol::ExtensionMessage message1;
  message1.set_type("ext1");
  message1.set_data("data");
  client_session_->DeliverClientMessage(message1);
  protocol::ExtensionMessage message3;
  message3.set_type("ext3");
  message3.set_data("data");
  client_session_->DeliverClientMessage(message3);
  protocol::ExtensionMessage message4;
  message4.set_type("ext4");
  message4.set_data("data");
  client_session_->DeliverClientMessage(message4);

  base::RunLoop().RunUntilIdle();

  // ext1 was instantiated and sent a message, and did not wrap anything.
  EXPECT_TRUE(extension1.was_instantiated());
  EXPECT_TRUE(extension1.has_handled_message());

  // ext2 was instantiated but not sent a message, and wrapped video encoder.
  EXPECT_TRUE(extension2.was_instantiated());
  EXPECT_FALSE(extension2.has_handled_message());

  // ext3 was sent a message but not instantiated.
  EXPECT_FALSE(extension3.was_instantiated());
}

TEST_F(ClientSessionTest, DataChannelCallbackIsCalled) {
  bool callback_called = false;

  CreateClientSession();
  client_session_->RegisterCreateHandlerCallbackForTesting(
      kTestDataChannelCallbackName,
      base::Bind([](bool* callback_was_called, const std::string& name,
                    std::unique_ptr<protocol::MessagePipe> pipe)
                     -> void { *callback_was_called = true; },
                 &callback_called));
  ConnectClientSession();

  std::unique_ptr<protocol::MessagePipe> pipe =
      base::WrapUnique(new protocol::FakeMessagePipe(false));

  client_session_->OnIncomingDataChannel(kTestDataChannelCallbackName,
                                         std::move(pipe));

  ASSERT_TRUE(callback_called);
}

TEST_F(ClientSessionTest, ForwardHostSessionOptions1) {
  auto session = std::make_unique<protocol::FakeSession>();
  auto configuration = std::make_unique<jingle_xmpp::XmlElement>(
      jingle_xmpp::QName(kChromotingXmlNamespace, "host-configuration"));
  configuration->SetBodyText("Detect-Updated-Region:true");
  session->SetAttachment(0, std::move(configuration));
  CreateClientSession(std::move(session));
  ConnectClientSession();
  ASSERT_TRUE(desktop_environment_factory_->last_desktop_environment()
                  ->options()
                  .desktop_capture_options()
                  ->detect_updated_region());
}

TEST_F(ClientSessionTest, ForwardHostSessionOptions2) {
  auto session = std::make_unique<protocol::FakeSession>();
  auto configuration = std::make_unique<jingle_xmpp::XmlElement>(
      jingle_xmpp::QName(kChromotingXmlNamespace, "host-configuration"));
  configuration->SetBodyText("Detect-Updated-Region:false");
  session->SetAttachment(0, std::move(configuration));
  CreateClientSession(std::move(session));
  ConnectClientSession();
  ASSERT_FALSE(desktop_environment_factory_->last_desktop_environment()
                   ->options()
                   .desktop_capture_options()
                   ->detect_updated_region());
}

#if defined(OS_WIN)
TEST_F(ClientSessionTest, ForwardDirectXHostSessionOptions1) {
  auto session = std::make_unique<protocol::FakeSession>();
  auto configuration = std::make_unique<jingle_xmpp::XmlElement>(
      jingle_xmpp::QName(kChromotingXmlNamespace, "host-configuration"));
  configuration->SetBodyText("DirectX-Capturer:true");
  session->SetAttachment(0, std::move(configuration));
  CreateClientSession(std::move(session));
  ConnectClientSession();
  ASSERT_TRUE(desktop_environment_factory_->last_desktop_environment()
                  ->options()
                  .desktop_capture_options()
                  ->allow_directx_capturer());
}

TEST_F(ClientSessionTest, ForwardDirectXHostSessionOptions2) {
  auto session = std::make_unique<protocol::FakeSession>();
  auto configuration = std::make_unique<jingle_xmpp::XmlElement>(
      jingle_xmpp::QName(kChromotingXmlNamespace, "host-configuration"));
  configuration->SetBodyText("DirectX-Capturer:false");
  session->SetAttachment(0, std::move(configuration));
  CreateClientSession(std::move(session));
  ConnectClientSession();
  ASSERT_FALSE(desktop_environment_factory_->last_desktop_environment()
                   ->options()
                   .desktop_capture_options()
                   ->allow_directx_capturer());
}
#endif

}  // namespace remoting
