// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/exo/seat.h"

#include <optional>

#include "ash/public/mojom/input_device_settings.mojom.h"
#include "base/containers/flat_map.h"
#include "base/files/file_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/pickle.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/thread_pool/thread_pool_instance.h"
#include "base/test/bind.h"
#include "components/exo/data_device.h"
#include "components/exo/data_device_delegate.h"
#include "components/exo/data_source.h"
#include "components/exo/data_source_delegate.h"
#include "components/exo/seat_observer.h"
#include "components/exo/surface.h"
#include "components/exo/test/exo_test_base.h"
#include "components/exo/test/exo_test_data_exchange_delegate.h"
#include "components/exo/test/test_data_device_delegate.h"
#include "components/exo/test/test_data_source_delegate.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/clipboard/clipboard.h"
#include "ui/base/clipboard/clipboard_format_type.h"
#include "ui/base/clipboard/custom_data_helper.h"
#include "ui/base/clipboard/scoped_clipboard_writer.h"
#include "ui/base/dragdrop/mojom/drag_drop_types.mojom-shared.h"
#include "ui/events/event.h"
#include "ui/events/event_constants.h"
#include "ui/events/event_utils.h"
#include "ui/events/types/event_type.h"

namespace exo {
namespace {

using SeatTest = test::ExoTestBase;
using test::TestDataSourceDelegate;

class TestSeatObserver : public SeatObserver {
 public:
  explicit TestSeatObserver(const base::RepeatingClosure& callback)
      : callback_(callback) {}

  // Overridden from SeatObserver:
  void OnSurfaceFocused(Surface* gained_focus,
                        Surface* lost_focus,
                        bool has_focused_surface) override {
    callback_.Run();
  }

 private:
  base::RepeatingClosure callback_;
};

void RunReadingTask() {
  base::ThreadPoolInstance::Get()->FlushForTesting();
  base::RunLoop().RunUntilIdle();
}

class TestSeat : public Seat {
 public:
  TestSeat() : Seat(std::make_unique<TestDataExchangeDelegate>()) {}
  explicit TestSeat(
      std::unique_ptr<TestDataExchangeDelegate> data_exchange_delegate)
      : Seat(std::move(data_exchange_delegate)) {}

  TestSeat(const TestSeat&) = delete;
  void operator=(const TestSeat&) = delete;

  void set_focused_surface(Surface* surface) { surface_ = surface; }

  // Seat:
  Surface* GetFocusedSurface() override { return surface_; }

 private:
  raw_ptr<Surface> surface_ = nullptr;
};

TEST_F(SeatTest, OnSurfaceFocused) {
  TestSeat seat;
  int callback_counter = 0;
  std::optional<int> observer1_counter;
  TestSeatObserver observer1(base::BindLambdaForTesting(
      [&]() { observer1_counter = callback_counter++; }));
  std::optional<int> observer2_counter;
  TestSeatObserver observer2(base::BindLambdaForTesting(
      [&]() { observer2_counter = callback_counter++; }));

  // Register observers in the reversed order.
  seat.AddObserver(&observer2, 1);
  seat.AddObserver(&observer1, 0);
  seat.OnWindowFocused(nullptr, nullptr);
  EXPECT_EQ(observer1_counter, 0);
  EXPECT_EQ(observer2_counter, 1);

  observer1_counter.reset();
  observer2_counter.reset();
  seat.RemoveObserver(&observer1);
  seat.RemoveObserver(&observer2);

  seat.OnWindowFocused(nullptr, nullptr);
  EXPECT_FALSE(observer1_counter.has_value());
  EXPECT_FALSE(observer2_counter.has_value());
}

TEST_F(SeatTest, SetSelection) {
  TestSeat seat;
  Surface focused_surface;
  seat.set_focused_surface(&focused_surface);

  TestDataSourceDelegate delegate;
  DataSource source(&delegate);
  source.Offer("text/plain;charset=utf-8");
  seat.SetSelection(&source);

  RunReadingTask();

  std::string clipboard;
  ui::Clipboard::GetForCurrentThread()->ReadAsciiText(
      ui::ClipboardBuffer::kCopyPaste, /*data_dst=*/nullptr, &clipboard);

  EXPECT_EQ(clipboard, std::string("TestData"));
}

TEST_F(SeatTest, SetSelectionReadDteFromLacros) {
  std::unique_ptr<TestDataExchangeDelegate> data_exchange_delegate(
      std::make_unique<TestDataExchangeDelegate>());
  data_exchange_delegate->set_endpoint_type(ui::EndpointType::kLacros);
  TestSeat seat(std::move(data_exchange_delegate));
  Surface focused_surface;
  seat.set_focused_surface(&focused_surface);

  const std::string kTestText = "TestData";
  const std::string kEncodedTestDte =
      R"({"endpoint_type":"url","url":"https://www.google.com"})";

  const std::string kTextMimeType = "text/plain;charset=utf-8";
  const std::string kDteMimeType = "chromium/x-data-transfer-endpoint";

  TestDataSourceDelegate delegate;
  DataSource source(&delegate);

  source.Offer(kTextMimeType);
  delegate.SetData(kTextMimeType, kTestText);
  source.Offer(kDteMimeType);
  delegate.SetData(kDteMimeType, kEncodedTestDte);
  seat.SetSelection(&source);

  RunReadingTask();

  std::string clipboard;
  ui::Clipboard::GetForCurrentThread()->ReadAsciiText(
      ui::ClipboardBuffer::kCopyPaste, /*data_dst=*/nullptr, &clipboard);

  EXPECT_EQ(clipboard, kTestText);

  std::optional<ui::DataTransferEndpoint> source_dte =
      ui::Clipboard::GetForCurrentThread()->GetSource(
          ui::ClipboardBuffer::kCopyPaste);

  ASSERT_TRUE(source_dte);
  EXPECT_EQ(ui::EndpointType::kUrl, source_dte->type());

  const ui::DataTransferEndpoint expected_dte =
      ui::DataTransferEndpoint((GURL("https://www.google.com")));
  EXPECT_EQ(*expected_dte.GetURL(), *source_dte->GetURL());
}

TEST_F(SeatTest, SetSelectionIgnoreDteFromNonLacros) {
  std::unique_ptr<TestDataExchangeDelegate> data_exchange_delegate(
      std::make_unique<TestDataExchangeDelegate>());
  data_exchange_delegate->set_endpoint_type(ui::EndpointType::kCrostini);
  TestSeat seat(std::move(data_exchange_delegate));
  Surface focused_surface;
  seat.set_focused_surface(&focused_surface);

  const std::string kTestText = "TestData";
  const std::string kEncodedTestDte =
      R"({"endpoint_type":"url","url":"https://www.google.com"})";

  const std::string kTextMimeType = "text/plain;charset=utf-8";
  const std::string kDteMimeType = "chromium/x-data-transfer-endpoint";

  TestDataSourceDelegate delegate;
  DataSource source(&delegate);

  source.Offer(kTextMimeType);
  delegate.SetData(kTextMimeType, kTestText);
  source.Offer(kDteMimeType);
  delegate.SetData(kDteMimeType, kEncodedTestDte);
  seat.SetSelection(&source);

  RunReadingTask();

  std::string clipboard;
  ui::Clipboard::GetForCurrentThread()->ReadAsciiText(
      ui::ClipboardBuffer::kCopyPaste, /*data_dst=*/nullptr, &clipboard);

  EXPECT_EQ(clipboard, kTestText);

  std::optional<ui::DataTransferEndpoint> source_dte =
      ui::Clipboard::GetForCurrentThread()->GetSource(
          ui::ClipboardBuffer::kCopyPaste);

  ASSERT_TRUE(source_dte);
  EXPECT_EQ(ui::EndpointType::kCrostini, source_dte->type());
}

TEST_F(SeatTest, SetSelectionTextUTF8) {
  TestSeat seat;
  Surface focused_surface;
  seat.set_focused_surface(&focused_surface);

  // UTF8 encoded data
  std::string data(
      "\xe2\x9d\x84"        // SNOWFLAKE
      "\xf0\x9f\x94\xa5");  // FIRE
  std::u16string converted_data = base::UTF8ToUTF16(data);

  TestDataSourceDelegate delegate;
  DataSource source(&delegate);

  const std::string kTextPlainType = "text/plain;charset=utf-8";
  const std::string kTextHtmlType = "text/html;charset=utf-8";
  source.Offer(kTextPlainType);
  source.Offer(kTextHtmlType);
  delegate.SetData(kTextPlainType, data);
  delegate.SetData(kTextHtmlType, data);
  seat.SetSelection(&source);

  RunReadingTask();

  std::u16string clipboard;
  ui::Clipboard::GetForCurrentThread()->ReadText(
      ui::ClipboardBuffer::kCopyPaste, /*data_dst=*/nullptr, &clipboard);
  EXPECT_EQ(clipboard, converted_data);

  std::string url;
  uint32_t start, end;
  ui::Clipboard::GetForCurrentThread()->ReadHTML(
      ui::ClipboardBuffer::kCopyPaste, /*data_dst=*/nullptr, &clipboard, &url,
      &start, &end);
  EXPECT_EQ(clipboard, converted_data);
}

TEST_F(SeatTest, SetSelectionTextUTF8Legacy) {
  TestSeat seat;
  Surface focused_surface;
  seat.set_focused_surface(&focused_surface);

  // UTF8 encoded data
  std::string data(
      "\xe2\x9d\x84"        // SNOWFLAKE
      "\xf0\x9f\x94\xa5");  // FIRE
  std::u16string converted_data = base::UTF8ToUTF16(data);

  TestDataSourceDelegate delegate;
  DataSource source(&delegate);
  const std::string kMimeType = "UTF8_STRING";
  source.Offer(kMimeType);
  delegate.SetData(kMimeType, data);
  seat.SetSelection(&source);

  RunReadingTask();

  std::u16string clipboard;
  ui::Clipboard::GetForCurrentThread()->ReadText(
      ui::ClipboardBuffer::kCopyPaste, /*data_dst=*/nullptr, &clipboard);
  EXPECT_EQ(clipboard, converted_data);
}

TEST_F(SeatTest, SetSelectionTextUTF16LE) {
  TestSeat seat;
  Surface focused_surface;
  seat.set_focused_surface(&focused_surface);

  // UTF16 little endian encoded data
  std::string data(
      "\xff\xfe"            // Byte order mark
      "\x44\x27"            // SNOWFLAKE
      "\x3d\xd8\x25\xdd");  // FIRE
  std::u16string converted_data;
  converted_data.push_back(0x2744);
  converted_data.push_back(0xd83d);
  converted_data.push_back(0xdd25);

  TestDataSourceDelegate delegate;
  DataSource source(&delegate);
  const std::string kTextPlainType = "text/plain;charset=utf-16";
  const std::string kTextHtmlType = "text/html;charset=utf-16";
  source.Offer(kTextPlainType);
  source.Offer(kTextHtmlType);
  delegate.SetData(kTextPlainType, data);
  delegate.SetData(kTextHtmlType, data);
  seat.SetSelection(&source);

  RunReadingTask();

  std::u16string clipboard;
  ui::Clipboard::GetForCurrentThread()->ReadText(
      ui::ClipboardBuffer::kCopyPaste, /*data_dst=*/nullptr, &clipboard);
  EXPECT_EQ(clipboard, converted_data);

  std::string url;
  uint32_t start, end;
  ui::Clipboard::GetForCurrentThread()->ReadHTML(
      ui::ClipboardBuffer::kCopyPaste, /*data_dst=*/nullptr, &clipboard, &url,
      &start, &end);
  EXPECT_EQ(clipboard, converted_data);
}

TEST_F(SeatTest, SetSelectionTextUTF16BE) {
  TestSeat seat;
  Surface focused_surface;
  seat.set_focused_surface(&focused_surface);

  // UTF16 big endian encoded data
  std::string data(
      "\xfe\xff"            // Byte order mark
      "\x27\x44"            // SNOWFLAKE
      "\xd8\x3d\xdd\x25");  // FIRE
  std::u16string converted_data;
  converted_data.push_back(0x2744);
  converted_data.push_back(0xd83d);
  converted_data.push_back(0xdd25);

  TestDataSourceDelegate delegate;
  DataSource source(&delegate);
  const std::string kTextPlainType = "text/plain;charset=utf-16";
  const std::string kTextHtmlType = "text/html;charset=utf-16";
  source.Offer(kTextPlainType);
  source.Offer(kTextHtmlType);
  delegate.SetData(kTextPlainType, data);
  delegate.SetData(kTextHtmlType, data);
  seat.SetSelection(&source);

  RunReadingTask();

  std::u16string clipboard;
  ui::Clipboard::GetForCurrentThread()->ReadText(
      ui::ClipboardBuffer::kCopyPaste, /*data_dst=*/nullptr, &clipboard);
  EXPECT_EQ(clipboard, converted_data);

  std::string url;
  uint32_t start, end;
  ui::Clipboard::GetForCurrentThread()->ReadHTML(
      ui::ClipboardBuffer::kCopyPaste, /*data_dst=*/nullptr, &clipboard, &url,
      &start, &end);
  EXPECT_EQ(clipboard, converted_data);
}

TEST_F(SeatTest, SetSelectionTextEmptyString) {
  TestSeat seat;
  Surface focused_surface;
  seat.set_focused_surface(&focused_surface);

  TestDataSourceDelegate delegate;
  DataSource source(&delegate);
  const std::string kTextPlainType = "text/plain;charset=utf-8";
  const std::string kTextHtmlType = "text/html;charset=utf-16";
  source.Offer(kTextPlainType);
  source.Offer(kTextHtmlType);
  delegate.SetData(kTextPlainType, std::string());
  delegate.SetData(kTextHtmlType, std::string());
  seat.SetSelection(&source);

  RunReadingTask();

  std::u16string clipboard;
  ui::Clipboard::GetForCurrentThread()->ReadText(
      ui::ClipboardBuffer::kCopyPaste, /*data_dst=*/nullptr, &clipboard);
  EXPECT_EQ(clipboard.size(), 0u);

  std::string url;
  uint32_t start, end;
  ui::Clipboard::GetForCurrentThread()->ReadHTML(
      ui::ClipboardBuffer::kCopyPaste, /*data_dst=*/nullptr, &clipboard, &url,
      &start, &end);
  EXPECT_EQ(clipboard.size(), 0u);
}

TEST_F(SeatTest, SetSelectionRTF) {
  TestSeat seat;
  Surface focused_surface;
  seat.set_focused_surface(&focused_surface);

  TestDataSourceDelegate delegate;
  DataSource source(&delegate);
  source.Offer("text/rtf");
  seat.SetSelection(&source);

  RunReadingTask();

  std::string clipboard;
  ui::Clipboard::GetForCurrentThread()->ReadRTF(
      ui::ClipboardBuffer::kCopyPaste, /*data_dst=*/nullptr, &clipboard);

  EXPECT_EQ(clipboard, std::string("TestData"));
}

TEST_F(SeatTest, SetSelectionFilenames) {
  TestSeat seat;
  Surface focused_surface;
  seat.set_focused_surface(&focused_surface);

  const std::string data("file:///path1\r\nfile:///path2");

  TestDataSourceDelegate delegate;
  const std::string kMimeType = "text/uri-list";
  delegate.SetData(kMimeType, data);
  DataSource source(&delegate);
  source.Offer(kMimeType);
  seat.SetSelection(&source);

  RunReadingTask();

  std::vector<ui::FileInfo> filenames;
  ui::Clipboard::GetForCurrentThread()->ReadFilenames(
      ui::ClipboardBuffer::kCopyPaste,
      /*data_dst=*/nullptr, &filenames);

  EXPECT_EQ(ui::FileInfosToURIList(filenames), data);
}

TEST_F(SeatTest, SetSelectionWebCustomData) {
  TestSeat seat;
  Surface focused_surface;
  seat.set_focused_surface(&focused_surface);

  base::flat_map<std::u16string, std::u16string> custom_data;
  custom_data[u"text/uri-list"] = u"data";
  base::Pickle pickle;
  ui::WriteCustomDataToPickle(custom_data, &pickle);
  auto custom_data_str =
      std::string(reinterpret_cast<const char*>(pickle.data()), pickle.size());

  TestDataSourceDelegate delegate;
  const std::string kMimeType = "chromium/x-web-custom-data";
  delegate.SetData(kMimeType, std::move(custom_data_str));
  DataSource source(&delegate);
  source.Offer(kMimeType);
  seat.SetSelection(&source);

  RunReadingTask();

  std::u16string result;
  ui::Clipboard::GetForCurrentThread()->ReadCustomData(
      ui::ClipboardBuffer::kCopyPaste, u"text/uri-list", /*data_dst=*/nullptr,
      &result);
  EXPECT_EQ(result, u"data");
}

TEST_F(SeatTest, SetSelection_TwiceSame) {
  TestSeat seat;
  Surface focused_surface;
  seat.set_focused_surface(&focused_surface);

  TestDataSourceDelegate delegate;
  DataSource source(&delegate);
  seat.SetSelection(&source);
  RunReadingTask();
  seat.SetSelection(&source);
  RunReadingTask();

  EXPECT_FALSE(delegate.cancelled());
}

TEST_F(SeatTest, SetSelection_TwiceDifferent) {
  TestSeat seat;
  Surface focused_surface;
  seat.set_focused_surface(&focused_surface);

  TestDataSourceDelegate delegate1;
  DataSource source1(&delegate1);
  seat.SetSelection(&source1);
  RunReadingTask();

  EXPECT_FALSE(delegate1.cancelled());

  TestDataSourceDelegate delegate2;
  DataSource source2(&delegate2);
  seat.SetSelection(&source2);
  RunReadingTask();

  EXPECT_TRUE(delegate1.cancelled());
}

TEST_F(SeatTest, SetSelection_ClipboardChangedDuringSetSelection) {
  TestSeat seat;
  Surface focused_surface;
  seat.set_focused_surface(&focused_surface);

  TestDataSourceDelegate delegate;
  DataSource source(&delegate);
  seat.SetSelection(&source);

  {
    ui::ScopedClipboardWriter writer(ui::ClipboardBuffer::kCopyPaste);
    writer.WriteText(u"New data");
  }

  RunReadingTask();

  // The previous source should be cancelled.
  EXPECT_TRUE(delegate.cancelled());

  std::string clipboard;
  ui::Clipboard::GetForCurrentThread()->ReadAsciiText(
      ui::ClipboardBuffer::kCopyPaste, /*data_dst=*/nullptr, &clipboard);
  EXPECT_EQ(clipboard, "New data");
}

TEST_F(SeatTest, SetSelection_ClipboardChangedAfterSetSelection) {
  TestSeat seat;
  Surface focused_surface;
  seat.set_focused_surface(&focused_surface);

  TestDataSourceDelegate delegate;
  DataSource source(&delegate);
  seat.SetSelection(&source);
  RunReadingTask();

  {
    ui::ScopedClipboardWriter writer(ui::ClipboardBuffer::kCopyPaste);
    writer.WriteText(u"New data");
  }

  // The previous source should be cancelled.
  EXPECT_TRUE(delegate.cancelled());

  std::string clipboard;
  ui::Clipboard::GetForCurrentThread()->ReadAsciiText(
      ui::ClipboardBuffer::kCopyPaste, /*data_dst=*/nullptr, &clipboard);
  EXPECT_EQ(clipboard, "New data");
}

TEST_F(SeatTest, SetSelection_SourceDestroyedDuringSetSelection) {
  TestSeat seat;
  Surface focused_surface;
  seat.set_focused_surface(&focused_surface);

  {
    ui::ScopedClipboardWriter writer(ui::ClipboardBuffer::kCopyPaste);
    writer.WriteText(u"Original data");
  }

  {
    TestDataSourceDelegate delegate;
    DataSource source(&delegate);
    seat.SetSelection(&source);
    // source destroyed here.
  }

  RunReadingTask();

  std::string clipboard;
  ui::Clipboard::GetForCurrentThread()->ReadAsciiText(
      ui::ClipboardBuffer::kCopyPaste, /*data_dst=*/nullptr, &clipboard);
  EXPECT_EQ(clipboard, "Original data");
}

TEST_F(SeatTest, SetSelection_SourceDestroyedAfterSetSelection) {
  TestSeat seat;
  Surface focused_surface;
  seat.set_focused_surface(&focused_surface);

  TestDataSourceDelegate delegate1;
  {
    DataSource source(&delegate1);
    seat.SetSelection(&source);
    RunReadingTask();
    // source destroyed here.
  }

  RunReadingTask();

  {
    TestDataSourceDelegate delegate2;
    DataSource source(&delegate2);
    seat.SetSelection(&source);
    RunReadingTask();
    // source destroyed here.
  }

  RunReadingTask();

  // delegate1 should not receive cancel request because the first data source
  // has already been destroyed.
  EXPECT_FALSE(delegate1.cancelled());
}

TEST_F(SeatTest, SetSelection_NullSource) {
  TestSeat seat;
  Surface focused_surface;
  seat.set_focused_surface(&focused_surface);

  TestDataSourceDelegate delegate;
  DataSource source(&delegate);
  source.Offer("text/plain;charset=utf-8");
  seat.SetSelection(&source);

  RunReadingTask();

  {
    ui::ScopedClipboardWriter writer(ui::ClipboardBuffer::kCopyPaste);
    writer.WriteText(u"Golden data");
  }

  // Should not affect the current state of the clipboard.
  seat.SetSelection(nullptr);

  ASSERT_TRUE(delegate.cancelled());

  std::string clipboard;
  ui::Clipboard::GetForCurrentThread()->ReadAsciiText(
      ui::ClipboardBuffer::kCopyPaste, /*data_dst=*/nullptr, &clipboard);
  EXPECT_EQ(clipboard, "Golden data");
}

TEST_F(SeatTest, SetSelection_NoFocusedSurface) {
  TestSeat seat;
  seat.set_focused_surface(nullptr);

  TestDataSourceDelegate delegate;
  DataSource source(&delegate);
  source.Offer("text/plain;charset=utf-8");
  seat.SetSelection(&source);

  EXPECT_TRUE(delegate.cancelled());
}

TEST_F(SeatTest, SetSelection_ClientOutOfFocus) {
  TestSeat seat;
  Surface focused_surface;
  seat.set_focused_surface(&focused_surface);

  TestDataSourceDelegate delegate;
  delegate.set_can_accept(false);
  DataSource source(&delegate);
  source.Offer("text/plain;charset=utf-8");
  seat.SetSelection(&source);

  EXPECT_TRUE(delegate.cancelled());
}

TEST_F(SeatTest, PressedKeys) {
  TestSeat seat;
  ui::KeyEvent press_a(ui::ET_KEY_PRESSED, ui::VKEY_A, ui::DomCode::US_A, 0);
  ui::KeyEvent release_a(ui::ET_KEY_RELEASED, ui::VKEY_A, ui::DomCode::US_A, 0);
  ui::KeyEvent press_b(ui::ET_KEY_PRESSED, ui::VKEY_B, ui::DomCode::US_B, 0);
  ui::KeyEvent release_b(ui::ET_KEY_RELEASED, ui::VKEY_B, ui::DomCode::US_B, 0);

  // Press A, it should be in the map.
  seat.WillProcessEvent(&press_a);
  seat.OnKeyEvent(press_a.AsKeyEvent());
  seat.DidProcessEvent(&press_a);
  base::flat_map<PhysicalCode, base::flat_set<KeyState>> pressed_keys;
  pressed_keys[ui::CodeFromNative(&press_a)].emplace(press_a.code(), false);
  EXPECT_EQ(pressed_keys, seat.pressed_keys());

  // Press B, then A & B should be in the map.
  seat.WillProcessEvent(&press_b);
  seat.OnKeyEvent(press_b.AsKeyEvent());
  seat.DidProcessEvent(&press_b);
  pressed_keys[ui::CodeFromNative(&press_b)].emplace(press_b.code(), false);
  EXPECT_EQ(pressed_keys, seat.pressed_keys());

  // Release A, with the normal order where DidProcessEvent is after OnKeyEvent,
  // only B should be in the map.
  seat.WillProcessEvent(&release_a);
  seat.OnKeyEvent(release_a.AsKeyEvent());
  seat.DidProcessEvent(&release_a);
  pressed_keys.erase(PhysicalCode(ui::CodeFromNative(&press_a)));
  EXPECT_EQ(pressed_keys, seat.pressed_keys());

  // Release B, do it out of order so DidProcessEvent is before OnKeyEvent, the
  // map should then be empty.
  seat.WillProcessEvent(&release_b);
  seat.DidProcessEvent(&release_b);
  seat.OnKeyEvent(release_b.AsKeyEvent());
  EXPECT_TRUE(seat.pressed_keys().empty());
}

TEST_F(SeatTest, DragDropAbort) {
  TestSeat seat;
  test::TestDataDeviceDelegate data_device_delegate;

  DataDevice data_device(&data_device_delegate, &seat);
  TestDataSourceDelegate delegate;
  DataSource source(&delegate);
  Surface origin, icon;

  // Give origin a root window for DragDropOperation.
  GetContext()->AddChild(origin.window());

  data_device.StartDrag(&source, &origin, &icon,
                        ui::mojom::DragEventSource::kMouse);
  EXPECT_TRUE(seat.get_drag_drop_operation_for_testing());
  seat.AbortPendingDragOperation();
  EXPECT_FALSE(seat.get_drag_drop_operation_for_testing());
}

TEST_F(SeatTest, MultiRewriteEventsFromInvalidSource) {
  TestSeat seat;

  ui::KeyEvent press_a(ui::ET_KEY_PRESSED, ui::VKEY_A, ui::DomCode::US_A, 0);
  ui::KeyEvent release_a(ui::ET_KEY_RELEASED, ui::VKEY_A, ui::DomCode::US_A, 0);
  ui::KeyEvent press_b(ui::ET_KEY_PRESSED, ui::VKEY_B, ui::DomCode::US_B, 0);
  ui::KeyEvent release_b(ui::ET_KEY_RELEASED, ui::VKEY_B, ui::DomCode::US_B, 0);

  // Press A, it should be in the map.
  seat.WillProcessEvent(&press_a);
  seat.OnKeyEvent(press_a.AsKeyEvent());
  base::flat_map<PhysicalCode, base::flat_set<KeyState>> pressed_keys;
  pressed_keys[ui::CodeFromNative(&press_a)].emplace(press_a.code(), false);
  EXPECT_EQ(pressed_keys, seat.pressed_keys());

  // Press A, but it was remapped to B. Should not be added to pressed_keys map.
  seat.OnKeyEvent(press_b.AsKeyEvent());
  seat.DidProcessEvent(&press_a);
  EXPECT_EQ(pressed_keys, seat.pressed_keys());

  // Release B -> A from the same physical "A" event. Entry should be removed
  // after first event.
  seat.WillProcessEvent(&release_a);
  seat.OnKeyEvent(release_b.AsKeyEvent());
  pressed_keys.erase(PhysicalCode(ui::CodeFromNative(&press_a)));
  EXPECT_EQ(pressed_keys, seat.pressed_keys());

  seat.OnKeyEvent(release_a.AsKeyEvent());
  seat.DidProcessEvent(&release_a);
  EXPECT_EQ(pressed_keys, seat.pressed_keys());
}

TEST_F(SeatTest, MultiRewriteEventsFromValidSource) {
  TestSeat seat;

  ui::KeyEvent press_a(ui::ET_KEY_PRESSED, ui::VKEY_A, ui::DomCode::US_A,
                       ui::EF_IS_CUSTOMIZED_FROM_BUTTON);
  ui::KeyEvent release_a(ui::ET_KEY_RELEASED, ui::VKEY_A, ui::DomCode::US_A,
                         ui::EF_IS_CUSTOMIZED_FROM_BUTTON);
  ui::KeyEvent press_b(ui::ET_KEY_PRESSED, ui::VKEY_B, ui::DomCode::US_B,
                       ui::EF_IS_CUSTOMIZED_FROM_BUTTON);
  ui::KeyEvent release_b(ui::ET_KEY_RELEASED, ui::VKEY_B, ui::DomCode::US_B,
                         ui::EF_IS_CUSTOMIZED_FROM_BUTTON);

  // Press A, it should be in the map.
  seat.WillProcessEvent(&press_a);
  seat.OnKeyEvent(press_a.AsKeyEvent());
  base::flat_map<PhysicalCode, base::flat_set<KeyState>> pressed_keys;
  auto& key_state_set = pressed_keys[ui::CodeFromNative(&press_a)];
  key_state_set.emplace(press_a.code(), false);
  EXPECT_EQ(pressed_keys, seat.pressed_keys());

  // Press A, but it was remapped to B. Should be added to pressed_keys map
  // since it is explicitly allowlisted.
  seat.OnKeyEvent(press_b.AsKeyEvent());
  seat.DidProcessEvent(&press_a);
  key_state_set.emplace(press_b.code(), false);
  EXPECT_EQ(pressed_keys, seat.pressed_keys());

  // Release B -> A from the same physical "A" event. Entry should be removed
  // after first event.
  seat.WillProcessEvent(&release_a);
  seat.OnKeyEvent(release_b.AsKeyEvent());
  pressed_keys.erase(PhysicalCode(ui::CodeFromNative(&press_a)));
  EXPECT_EQ(pressed_keys, seat.pressed_keys());

  seat.OnKeyEvent(release_a.AsKeyEvent());
  seat.DidProcessEvent(&release_a);
  EXPECT_EQ(pressed_keys, seat.pressed_keys());
}

TEST_F(SeatTest, MouseMultiRewriteEventsFromValidSource) {
  TestSeat seat;

  ui::MouseEvent press_back(ui::ET_MOUSE_PRESSED, gfx::PointF{}, gfx::PointF{},
                            base::TimeTicks(), ui::EF_BACK_MOUSE_BUTTON,
                            ui::EF_BACK_MOUSE_BUTTON);
  ui::MouseEvent release_back(
      ui::ET_MOUSE_RELEASED, gfx::PointF{}, gfx::PointF{}, base::TimeTicks(),
      ui::EF_BACK_MOUSE_BUTTON, ui::EF_BACK_MOUSE_BUTTON);

  ui::KeyEvent press_a(ui::ET_KEY_PRESSED, ui::VKEY_A, ui::DomCode::US_A,
                       ui::EF_IS_CUSTOMIZED_FROM_BUTTON);
  ui::KeyEvent release_a(ui::ET_KEY_RELEASED, ui::VKEY_A, ui::DomCode::US_A,
                         ui::EF_IS_CUSTOMIZED_FROM_BUTTON);
  ui::KeyEvent press_b(ui::ET_KEY_PRESSED, ui::VKEY_B, ui::DomCode::US_B,
                       ui::EF_IS_CUSTOMIZED_FROM_BUTTON);
  ui::KeyEvent release_b(ui::ET_KEY_RELEASED, ui::VKEY_B, ui::DomCode::US_B,
                         ui::EF_IS_CUSTOMIZED_FROM_BUTTON);

  // Press Back remapped to "A", it should be in the map.
  seat.WillProcessEvent(&press_back);
  seat.OnKeyEvent(press_a.AsKeyEvent());
  base::flat_map<PhysicalCode, base::flat_set<KeyState>> pressed_keys;
  auto& key_state_set = pressed_keys[ash::mojom::CustomizableButton::kBack];
  key_state_set.emplace(press_a.code(), false);
  EXPECT_EQ(pressed_keys, seat.pressed_keys());

  // Press B remapped within the same Back mouse button. Should also be added to
  // the map.
  seat.OnKeyEvent(press_b.AsKeyEvent());
  seat.DidProcessEvent(&press_back);
  key_state_set.emplace(press_b.code(), false);
  EXPECT_EQ(pressed_keys, seat.pressed_keys());

  // Release B then A from the same physical mouse button release. Both should
  // be instantly removed from the map.
  seat.WillProcessEvent(&press_back);
  seat.OnKeyEvent(release_b.AsKeyEvent());
  pressed_keys.erase(PhysicalCode(ash::mojom::CustomizableButton::kBack));
  EXPECT_EQ(pressed_keys, seat.pressed_keys());

  seat.OnKeyEvent(release_a.AsKeyEvent());
  seat.DidProcessEvent(&press_back);
  EXPECT_EQ(pressed_keys, seat.pressed_keys());
}

}  // namespace
}  // namespace exo
