// Copyright 2018 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 "services/ws/window_tree.h"

#include <stddef.h>
#include <stdint.h>

#include <memory>
#include <queue>

#include "base/run_loop.h"
#include "base/unguessable_token.h"
#include "services/ws/event_test_utils.h"
#include "services/ws/public/cpp/property_type_converters.h"
#include "services/ws/public/mojom/window_manager.mojom.h"
#include "services/ws/server_window.h"
#include "services/ws/server_window_test_helper.h"
#include "services/ws/window_service.h"
#include "services/ws/window_service_test_setup.h"
#include "services/ws/window_tree_test_helper.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/layout_manager.h"
#include "ui/aura/test/aura_test_helper.h"
#include "ui/aura/test/test_screen.h"
#include "ui/aura/test/test_window_delegate.h"
#include "ui/aura/window.h"
#include "ui/aura/window_tracker.h"
#include "ui/events/test/event_generator.h"
#include "ui/wm/core/capture_controller.h"
#include "ui/wm/core/default_screen_position_client.h"
#include "ui/wm/core/focus_controller.h"
#include "ui/wm/core/window_util.h"

namespace ws {
namespace {

DEFINE_UI_CLASS_PROPERTY_KEY(aura::Window*, kTestPropertyKey, nullptr);
const char kTestPropertyServerKey[] = "test-property-server";

// Passed to Embed() to give the default behavior (see kEmbedFlag* in mojom for
// details).
constexpr uint32_t kDefaultEmbedFlags = 0;

class TestLayoutManager : public aura::LayoutManager {
 public:
  TestLayoutManager() = default;
  ~TestLayoutManager() override = default;

  void set_next_bounds(const gfx::Rect& bounds) { next_bounds_ = bounds; }

  // aura::LayoutManager:
  void OnWindowResized() override {}
  void OnWindowAddedToLayout(aura::Window* child) override {}
  void OnWillRemoveWindowFromLayout(aura::Window* child) override {}
  void OnWindowRemovedFromLayout(aura::Window* child) override {}
  void OnChildWindowVisibilityChanged(aura::Window* child,
                                      bool visible) override {}
  void SetChildBounds(aura::Window* child,
                      const gfx::Rect& requested_bounds) override {
    if (next_bounds_) {
      SetChildBoundsDirect(child, *next_bounds_);
      next_bounds_.reset();
    } else {
      SetChildBoundsDirect(child, requested_bounds);
    }
  }

 private:
  base::Optional<gfx::Rect> next_bounds_;

  DISALLOW_COPY_AND_ASSIGN(TestLayoutManager);
};

// Used as callback from ScheduleEmbed().
void ScheduleEmbedCallback(base::UnguessableToken* result_token,
                           const base::UnguessableToken& actual_token) {
  *result_token = actual_token;
}

// Used as callback to EmbedUsingToken().
void EmbedUsingTokenCallback(bool* was_called,
                             bool* result_value,
                             bool actual_result) {
  *was_called = true;
  *result_value = actual_result;
}

// A screen position client with a fixed screen offset applied via SetBounds.
class TestScreenPositionClient : public wm::DefaultScreenPositionClient {
 public:
  explicit TestScreenPositionClient(const gfx::Vector2d& offset)
      : offset_(offset) {}
  ~TestScreenPositionClient() override = default;

  // wm::DefaultScreenPositionClient:
  void ConvertPointToScreen(const aura::Window* window,
                            gfx::PointF* point) override {
    wm::DefaultScreenPositionClient::ConvertPointToScreen(window, point);
    *point += offset_;
  }
  void ConvertPointFromScreen(const aura::Window* window,
                              gfx::PointF* point) override {
    *point -= offset_;
    wm::DefaultScreenPositionClient::ConvertPointFromScreen(window, point);
  }
  void SetBounds(aura::Window* window,
                 const gfx::Rect& bounds,
                 const display::Display& display) override {
    EXPECT_EQ(display, display::Screen::GetScreen()->GetPrimaryDisplay());
    gfx::Rect offset_bounds = bounds;
    offset_bounds.Offset(-offset_);
    wm::DefaultScreenPositionClient::SetBounds(window, offset_bounds, display);
  }

 private:
  const gfx::Vector2d offset_;
  DISALLOW_COPY_AND_ASSIGN(TestScreenPositionClient);
};

TEST(WindowTreeTest, NewWindow) {
  WindowServiceTestSetup setup;
  EXPECT_TRUE(setup.changes()->empty());
  aura::Window* window = setup.window_tree_test_helper()->NewWindow();
  ASSERT_TRUE(window);
  EXPECT_EQ("ChangeCompleted id=1 success=true",
            SingleChangeToDescription(*setup.changes()));
}

TEST(WindowTreeTest, NewWindowWithProperties) {
  WindowServiceTestSetup setup;
  EXPECT_TRUE(setup.changes()->empty());
  aura::PropertyConverter::PrimitiveType value = true;
  std::vector<uint8_t> transport = mojo::ConvertTo<std::vector<uint8_t>>(value);
  aura::Window* window = setup.window_tree_test_helper()->NewWindow(
      1, {{mojom::WindowManager::kAlwaysOnTop_Property, transport}});
  ASSERT_TRUE(window);
  EXPECT_EQ("ChangeCompleted id=1 success=true",
            SingleChangeToDescription(*setup.changes()));
  EXPECT_TRUE(window->GetProperty(aura::client::kAlwaysOnTopKey));
}

TEST(WindowTreeTest, NewTopLevelWindow) {
  WindowServiceTestSetup setup;
  EXPECT_TRUE(setup.changes()->empty());
  aura::Window* top_level =
      setup.window_tree_test_helper()->NewTopLevelWindow();
  ASSERT_TRUE(top_level);
  EXPECT_EQ("TopLevelCreated id=1 window_id=0,1 drawn=false",
            SingleChangeToDescription(*setup.changes()));
}

TEST(WindowTreeTest, NewTopLevelWindowWithProperties) {
  WindowServiceTestSetup setup;
  EXPECT_TRUE(setup.changes()->empty());
  aura::PropertyConverter::PrimitiveType value = true;
  std::vector<uint8_t> transport = mojo::ConvertTo<std::vector<uint8_t>>(value);
  aura::Window* top_level = setup.window_tree_test_helper()->NewTopLevelWindow(
      1, {{mojom::WindowManager::kAlwaysOnTop_Property, transport}});
  ASSERT_TRUE(top_level);
  EXPECT_EQ("TopLevelCreated id=1 window_id=0,1 drawn=false",
            SingleChangeToDescription(*setup.changes()));
  EXPECT_TRUE(top_level->GetProperty(aura::client::kAlwaysOnTopKey));
}

TEST(WindowTreeTest, SetTopLevelWindowBounds) {
  WindowServiceTestSetup setup;
  aura::Window* top_level =
      setup.window_tree_test_helper()->NewTopLevelWindow();
  setup.changes()->clear();

  const gfx::Rect bounds_from_client = gfx::Rect(100, 200, 300, 400);
  setup.window_tree_test_helper()->SetWindowBoundsWithAck(
      top_level, bounds_from_client, 2);
  EXPECT_EQ(bounds_from_client, top_level->GetBoundsInScreen());
  ASSERT_EQ(2u, setup.changes()->size());
  {
    const Change& change = (*setup.changes())[0];
    EXPECT_EQ(CHANGE_TYPE_NODE_BOUNDS_CHANGED, change.type);
    EXPECT_EQ(top_level->GetBoundsInScreen(), change.bounds2);
    EXPECT_TRUE(change.local_surface_id);
    setup.changes()->erase(setup.changes()->begin());
  }
  // See comments in WindowTree::SetBoundsImpl() for why this returns false.
  EXPECT_EQ("ChangeCompleted id=2 success=false",
            SingleChangeToDescription(*setup.changes()));
  setup.changes()->clear();

  const gfx::Rect bounds_from_server = gfx::Rect(101, 102, 103, 104);
  top_level->SetBounds(bounds_from_server);
  ASSERT_EQ(1u, setup.changes()->size());
  EXPECT_EQ(CHANGE_TYPE_NODE_BOUNDS_CHANGED, (*setup.changes())[0].type);
  EXPECT_EQ(bounds_from_server, (*setup.changes())[0].bounds2);
  setup.changes()->clear();

  // Set a LayoutManager so that when the client requests a bounds change the
  // window is resized to a different bounds.
  // |layout_manager| is owned by top_level->parent();
  TestLayoutManager* layout_manager = new TestLayoutManager();
  const gfx::Rect restricted_bounds = gfx::Rect(401, 405, 406, 407);
  layout_manager->set_next_bounds(restricted_bounds);
  top_level->parent()->SetLayoutManager(layout_manager);
  setup.window_tree_test_helper()->SetWindowBoundsWithAck(
      top_level, bounds_from_client, 3);
  ASSERT_EQ(2u, setup.changes()->size());
  // The layout manager changes the bounds to a different value than the client
  // requested, so the client should get OnWindowBoundsChanged() with
  // |restricted_bounds|.
  EXPECT_EQ(CHANGE_TYPE_NODE_BOUNDS_CHANGED, (*setup.changes())[0].type);
  EXPECT_EQ(restricted_bounds, (*setup.changes())[0].bounds2);

  // And because the layout manager changed the bounds the result is false.
  EXPECT_EQ("ChangeCompleted id=3 success=false",
            ChangeToDescription((*setup.changes())[1]));
  setup.changes()->clear();

  // Install a screen position client with a non-zero screen bounds offset.
  gfx::Vector2d screen_offset(10, 20);
  TestScreenPositionClient screen_position_client(screen_offset);
  aura::client::SetScreenPositionClient(setup.aura_test_helper()->root_window(),
                                        &screen_position_client);

  // Tests that top-level window bounds are set in screen coordinates.
  setup.window_tree_test_helper()->SetWindowBoundsWithAck(
      top_level, bounds_from_client, 4);
  EXPECT_EQ(bounds_from_client, top_level->GetBoundsInScreen());
  EXPECT_EQ(bounds_from_client - screen_offset, top_level->bounds());
  ASSERT_EQ(2u, setup.changes()->size());
  {
    const Change& change = (*setup.changes())[0];
    EXPECT_EQ(CHANGE_TYPE_NODE_BOUNDS_CHANGED, change.type);
    EXPECT_EQ(top_level->GetBoundsInScreen(), change.bounds2);
    EXPECT_TRUE(change.local_surface_id);
    setup.changes()->erase(setup.changes()->begin());
  }
  // See comments in WindowTree::SetBoundsImpl() for why this returns false.
  EXPECT_EQ("ChangeCompleted id=4 success=false",
            SingleChangeToDescription(*setup.changes()));

  aura::client::SetScreenPositionClient(setup.aura_test_helper()->root_window(),
                                        nullptr);
}

TEST(WindowTreeTest, SetTopLevelWindowBoundsFailsForSameSize) {
  WindowServiceTestSetup setup;
  aura::Window* top_level =
      setup.window_tree_test_helper()->NewTopLevelWindow();
  setup.changes()->clear();
  const gfx::Rect bounds = gfx::Rect(1, 2, 300, 400);
  top_level->SetBounds(bounds);
  setup.changes()->clear();
  // WindowTreeTestHelper::SetWindowBounds() uses a null LocalSurfaceId, which
  // differs from the current LocalSurfaceId (assigned by ClientRoot). Because
  // of this, the LocalSurfaceIds differ and the call returns false.
  EXPECT_FALSE(
      setup.window_tree_test_helper()->SetWindowBounds(top_level, bounds));
  EXPECT_TRUE(setup.changes()->empty());
}

TEST(WindowTreeTest, SetChildWindowBounds) {
  WindowServiceTestSetup setup;
  aura::Window* window = setup.window_tree_test_helper()->NewWindow();
  ASSERT_TRUE(window);
  const gfx::Rect bounds = gfx::Rect(1, 2, 300, 400);
  EXPECT_TRUE(setup.window_tree_test_helper()->SetWindowBounds(window, bounds));
  EXPECT_EQ(bounds, window->bounds());

  // Setting to same bounds should return true.
  EXPECT_TRUE(setup.window_tree_test_helper()->SetWindowBounds(window, bounds));
  EXPECT_EQ(bounds, window->bounds());
}

TEST(WindowTreeTest, SetBoundsAtEmbedWindow) {
  WindowServiceTestSetup setup;
  aura::Window* window = setup.window_tree_test_helper()->NewWindow();
  ASSERT_TRUE(window);
  const gfx::Rect bounds1 = gfx::Rect(1, 2, 300, 400);
  EXPECT_TRUE(
      setup.window_tree_test_helper()->SetWindowBounds(window, bounds1));

  std::unique_ptr<EmbeddingHelper> embedding_helper =
      setup.CreateEmbedding(window);
  ASSERT_TRUE(embedding_helper);

  // Child client should not be able to change bounds of embed window.
  EXPECT_FALSE(embedding_helper->window_tree_test_helper->SetWindowBounds(
      window, gfx::Rect()));
  // Bounds should not have changed.
  EXPECT_EQ(bounds1, window->bounds());

  embedding_helper->window_tree_client.tracker()->changes()->clear();
  embedding_helper->window_tree_client.set_track_root_bounds_changes(true);

  // Set the bounds from the parent and ensure client is notified.
  const gfx::Rect bounds2 = gfx::Rect(1, 2, 300, 401);
  base::Optional<viz::LocalSurfaceId> local_surface_id(
      viz::LocalSurfaceId(1, 2, base::UnguessableToken::Create()));
  EXPECT_TRUE(setup.window_tree_test_helper()->SetWindowBounds(
      window, bounds2, local_surface_id));
  EXPECT_EQ(bounds2, window->bounds());
  ASSERT_EQ(1u,
            embedding_helper->window_tree_client.tracker()->changes()->size());
  const Change bounds_change =
      (*(embedding_helper->window_tree_client.tracker()->changes()))[0];
  EXPECT_EQ(CHANGE_TYPE_NODE_BOUNDS_CHANGED, bounds_change.type);
  EXPECT_EQ(bounds2, bounds_change.bounds2);
  EXPECT_EQ(local_surface_id, bounds_change.local_surface_id);
}

// Tests the ability of the client to change properties on the server.
TEST(WindowTreeTest, SetTopLevelWindowProperty) {
  WindowServiceTestSetup setup;
  aura::Window* top_level =
      setup.window_tree_test_helper()->NewTopLevelWindow();
  setup.changes()->clear();

  EXPECT_FALSE(top_level->GetProperty(aura::client::kAlwaysOnTopKey));
  aura::PropertyConverter::PrimitiveType client_value = true;
  std::vector<uint8_t> client_transport_value =
      mojo::ConvertTo<std::vector<uint8_t>>(client_value);
  setup.window_tree_test_helper()->SetWindowProperty(
      top_level, mojom::WindowManager::kAlwaysOnTop_Property,
      client_transport_value, 2);
  EXPECT_EQ("ChangeCompleted id=2 success=true",
            SingleChangeToDescription(*setup.changes()));
  EXPECT_TRUE(top_level->GetProperty(aura::client::kAlwaysOnTopKey));
  setup.changes()->clear();

  top_level->SetProperty(aura::client::kAlwaysOnTopKey, false);
  EXPECT_EQ(
      "PropertyChanged window=0,1 key=prop:always_on_top "
      "value=0000000000000000",
      SingleChangeToDescription(*setup.changes()));
}

TEST(WindowTreeTest, WindowToWindowData) {
  WindowServiceTestSetup setup;
  aura::Window* window = setup.window_tree_test_helper()->NewWindow();
  setup.changes()->clear();

  window->SetBounds(gfx::Rect(1, 2, 300, 400));
  window->SetProperty(aura::client::kAlwaysOnTopKey, true);
  window->Show();  // Called to make the window visible.
  mojom::WindowDataPtr data =
      setup.window_tree_test_helper()->WindowToWindowData(window);
  EXPECT_EQ(gfx::Rect(1, 2, 300, 400), data->bounds);
  EXPECT_TRUE(data->visible);
  EXPECT_EQ(
      1u, data->properties.count(mojom::WindowManager::kAlwaysOnTop_Property));
  EXPECT_EQ(aura::PropertyConverter::PrimitiveType(true),
            mojo::ConvertTo<aura::PropertyConverter::PrimitiveType>(
                data->properties[mojom::WindowManager::kAlwaysOnTop_Property]));
}

TEST(WindowTreeTest, SetWindowPointerProperty) {
  WindowServiceTestSetup setup;
  setup.service()->property_converter()->RegisterWindowPtrProperty(
      kTestPropertyKey, kTestPropertyServerKey);

  WindowTreeTestHelper* helper = setup.window_tree_test_helper();
  aura::Window* top_level1 = helper->NewTopLevelWindow();
  aura::Window* top_level2 = helper->NewTopLevelWindow();
  Id id1 = helper->TransportIdForWindow(top_level1);
  Id id2 = helper->TransportIdForWindow(top_level2);

  base::Optional<std::vector<uint8_t>> value =
      mojo::ConvertTo<std::vector<uint8_t>>(id2);
  setup.window_tree_test_helper()->window_tree()->SetWindowProperty(
      1, id1, kTestPropertyServerKey, value);
  EXPECT_EQ(top_level2, top_level1->GetProperty(kTestPropertyKey));

  value.reset();
  setup.window_tree_test_helper()->window_tree()->SetWindowProperty(
      1, id1, kTestPropertyServerKey, value);
  EXPECT_FALSE(top_level1->GetProperty(kTestPropertyKey));
}

TEST(WindowTreeTest, SetWindowPointerPropertyWithInvalidValues) {
  WindowServiceTestSetup setup;
  setup.service()->property_converter()->RegisterWindowPtrProperty(
      kTestPropertyKey, kTestPropertyServerKey);

  WindowTreeTestHelper* helper = setup.window_tree_test_helper();
  aura::Window* top_level = helper->NewTopLevelWindow();
  Id id = helper->TransportIdForWindow(top_level);
  base::Optional<std::vector<uint8_t>> value =
      mojo::ConvertTo<std::vector<uint8_t>>(kInvalidTransportId);
  setup.window_tree_test_helper()->window_tree()->SetWindowProperty(
      1, id, kTestPropertyServerKey, value);
  EXPECT_FALSE(top_level->GetProperty(kTestPropertyKey));

  value = mojo::ConvertTo<std::vector<uint8_t>>(10);
  setup.window_tree_test_helper()->window_tree()->SetWindowProperty(
      1, id, kTestPropertyServerKey, value);
  EXPECT_FALSE(top_level->GetProperty(kTestPropertyKey));

  value->clear();
  value->push_back(1);
  setup.window_tree_test_helper()->window_tree()->SetWindowProperty(
      1, id, kTestPropertyServerKey, value);
  EXPECT_FALSE(top_level->GetProperty(kTestPropertyKey));
}

TEST(WindowTreeTest, EventLocation) {
  WindowServiceTestSetup setup;
  TestWindowTreeClient* window_tree_client = setup.window_tree_client();
  WindowTreeTestHelper* helper = setup.window_tree_test_helper();
  aura::Window* top_level = helper->NewTopLevelWindow();
  ASSERT_TRUE(top_level);

  top_level->Show();
  top_level->SetBounds(gfx::Rect(10, 20, 100, 100));

  // Add a child Window that covers the bottom half of the top-level window.
  aura::Window* window = setup.window_tree_test_helper()->NewWindow();
  ASSERT_TRUE(window);
  window->Show();
  window->SetBounds(gfx::Rect(0, 50, 100, 50));
  top_level->AddChild(window);

  ui::test::EventGenerator event_generator(setup.root());
  event_generator.MoveMouseTo(33, 44);
  ASSERT_EQ(1u, window_tree_client->input_events().size());
  TestWindowTreeClient::InputEvent event1 = window_tree_client->PopInputEvent();
  EXPECT_EQ(helper->TransportIdForWindow(top_level), event1.window_id);
  ASSERT_TRUE(event1.event->IsLocatedEvent());
  ui::LocatedEvent* located_event1 = event1.event->AsLocatedEvent();
  // The location is in the target window's coordinate system.
  EXPECT_EQ(gfx::Point(23, 24), located_event1->location());
  // The root location is in the client-root coordinate system.
  EXPECT_EQ(gfx::Point(23, 24), located_event1->root_location());

  event_generator.MoveMouseTo(55, 86);
  // 2 input events should happen -- exit on |top_level| and enter on |window|.
  ASSERT_EQ(2u, window_tree_client->input_events().size());

  // Check the exit event on |top_level|.
  TestWindowTreeClient::InputEvent event2 = window_tree_client->PopInputEvent();
  EXPECT_EQ(helper->TransportIdForWindow(top_level), event2.window_id);
  ASSERT_TRUE(event2.event->IsLocatedEvent());
  ui::LocatedEvent* located_event2 = event2.event->AsLocatedEvent();
  // The location is in the target window's coordinate system.
  EXPECT_EQ(gfx::Point(45, 66), located_event2->location());
  // The root location is in the client-root coordinate system.
  EXPECT_EQ(gfx::Point(45, 66), located_event2->root_location());

  // Check the enter event on |window|.
  TestWindowTreeClient::InputEvent event3 = window_tree_client->PopInputEvent();
  EXPECT_EQ(helper->TransportIdForWindow(window), event3.window_id);
  ASSERT_TRUE(event3.event->IsLocatedEvent());
  ui::LocatedEvent* located_event3 = event3.event->AsLocatedEvent();
  // The location is in the target window's coordinate system.
  EXPECT_EQ(gfx::Point(45, 16), located_event3->location());
  // The root location is in the client-root coordinate system.
  EXPECT_EQ(gfx::Point(45, 66), located_event3->root_location());
}

TEST(WindowTreeTest, EventLocationForTransientChildWindow) {
  WindowServiceTestSetup setup;
  TestWindowTreeClient* window_tree_client = setup.window_tree_client();
  WindowTreeTestHelper* helper = setup.window_tree_test_helper();

  aura::Window* top_level = helper->NewTopLevelWindow();
  ASSERT_TRUE(top_level);
  top_level->Show();
  top_level->SetBounds(gfx::Rect(10, 20, 100, 100));

  aura::Window* transient = helper->NewTopLevelWindow();
  ASSERT_TRUE(transient);
  transient->Show();
  transient->SetBounds(gfx::Rect(50, 30, 60, 90));

  helper->window_tree()->AddTransientWindow(
      10, helper->TransportIdForWindow(top_level),
      helper->TransportIdForWindow(transient));

  ui::test::EventGenerator event_generator(setup.root());
  event_generator.MoveMouseTo(61, 44);
  ASSERT_EQ(1u, window_tree_client->input_events().size());
  TestWindowTreeClient::InputEvent event = window_tree_client->PopInputEvent();
  EXPECT_EQ(helper->TransportIdForWindow(transient), event.window_id);
  ASSERT_TRUE(event.event->IsLocatedEvent());
  ui::LocatedEvent* located_event = event.event->AsLocatedEvent();
  // The location is in the target window's coordinate system.
  EXPECT_EQ(gfx::Point(11, 14), located_event->location());
  // The root location is in the client-root coordinate system. Transient
  // parents won't affect the coordinate system.
  EXPECT_EQ(gfx::Point(11, 14), located_event->root_location());
}

TEST(WindowTreeTest, MovePressDragRelease) {
  WindowServiceTestSetup setup;
  TestWindowTreeClient* window_tree_client = setup.window_tree_client();
  aura::Window* top_level =
      setup.window_tree_test_helper()->NewTopLevelWindow();
  ASSERT_TRUE(top_level);

  top_level->Show();
  top_level->SetBounds(gfx::Rect(10, 10, 100, 100));

  ui::test::EventGenerator event_generator(setup.root());
  event_generator.MoveMouseTo(50, 50);
  EXPECT_EQ("POINTER_MOVED 40,40",
            LocatedEventToEventTypeAndLocation(
                window_tree_client->PopInputEvent().event.get()));

  event_generator.PressLeftButton();
  EXPECT_EQ("POINTER_DOWN 40,40",
            LocatedEventToEventTypeAndLocation(
                window_tree_client->PopInputEvent().event.get()));

  event_generator.MoveMouseTo(0, 0);
  EXPECT_EQ("POINTER_MOVED -10,-10",
            LocatedEventToEventTypeAndLocation(
                window_tree_client->PopInputEvent().event.get()));

  event_generator.ReleaseLeftButton();
  EXPECT_EQ("POINTER_UP -10,-10",
            LocatedEventToEventTypeAndLocation(
                window_tree_client->PopInputEvent().event.get()));
}

// Used to verify destruction with a touch pointer down doesn't crash.
TEST(WindowTreeTest, ShutdownWithTouchDown) {
  WindowServiceTestSetup setup;
  aura::Window* top_level =
      setup.window_tree_test_helper()->NewTopLevelWindow();
  ASSERT_TRUE(top_level);
  top_level->Show();
  top_level->SetBounds(gfx::Rect(10, 10, 100, 100));

  ui::test::EventGenerator event_generator(setup.root());
  event_generator.set_current_location(gfx::Point(50, 51));
  event_generator.PressTouch();
}

TEST(WindowTreeTest, TouchPressDragRelease) {
  WindowServiceTestSetup setup;
  TestWindowTreeClient* window_tree_client = setup.window_tree_client();
  aura::Window* top_level =
      setup.window_tree_test_helper()->NewTopLevelWindow();
  ASSERT_TRUE(top_level);
  top_level->Show();
  top_level->SetBounds(gfx::Rect(10, 11, 100, 100));

  ui::test::EventGenerator event_generator(setup.root());
  event_generator.set_current_location(gfx::Point(50, 51));
  event_generator.PressTouch();
  EXPECT_EQ("POINTER_DOWN 40,40",
            LocatedEventToEventTypeAndLocation(
                window_tree_client->PopInputEvent().event.get()));

  event_generator.MoveTouch(gfx::Point(5, 6));
  EXPECT_EQ("POINTER_MOVED -5,-5",
            LocatedEventToEventTypeAndLocation(
                window_tree_client->PopInputEvent().event.get()));

  event_generator.ReleaseTouch();
  EXPECT_EQ("POINTER_UP -5,-5",
            LocatedEventToEventTypeAndLocation(
                window_tree_client->PopInputEvent().event.get()));
}

class EventRecordingWindowDelegate : public aura::test::TestWindowDelegate {
 public:
  EventRecordingWindowDelegate() = default;
  ~EventRecordingWindowDelegate() override = default;

  std::queue<std::unique_ptr<ui::Event>>& events() { return events_; }

  std::unique_ptr<ui::Event> PopEvent() {
    if (events_.empty())
      return nullptr;
    auto event = std::move(events_.front());
    events_.pop();
    return event;
  }

  void ClearEvents() {
    std::queue<std::unique_ptr<ui::Event>> events;
    std::swap(events_, events);
  }

  // aura::test::TestWindowDelegate:
  void OnEvent(ui::Event* event) override {
    events_.push(ui::Event::Clone(*event));
  }

 private:
  std::queue<std::unique_ptr<ui::Event>> events_;

  DISALLOW_COPY_AND_ASSIGN(EventRecordingWindowDelegate);
};

TEST(WindowTreeTest, MoveFromClientToNonClient) {
  EventRecordingWindowDelegate window_delegate;
  WindowServiceTestSetup setup;
  TestWindowTreeClient* window_tree_client = setup.window_tree_client();
  setup.delegate()->set_delegate_for_next_top_level(&window_delegate);
  aura::Window* top_level =
      setup.window_tree_test_helper()->NewTopLevelWindow();
  ASSERT_TRUE(top_level);

  top_level->Show();
  top_level->SetBounds(gfx::Rect(10, 10, 100, 100));
  setup.window_tree_test_helper()->SetClientArea(top_level,
                                                 gfx::Insets(10, 0, 0, 0));

  window_delegate.ClearEvents();

  ui::test::EventGenerator event_generator(setup.root());
  event_generator.MoveMouseTo(50, 50);
  EXPECT_EQ("POINTER_MOVED 40,40",
            LocatedEventToEventTypeAndLocation(
                window_tree_client->PopInputEvent().event.get()));

  // The delegate should see the same events (but as mouse events).
  EXPECT_EQ("MOUSE_ENTERED 40,40", LocatedEventToEventTypeAndLocation(
                                       window_delegate.PopEvent().get()));
  EXPECT_EQ("MOUSE_MOVED 40,40", LocatedEventToEventTypeAndLocation(
                                     window_delegate.PopEvent().get()));

  // Move the mouse over the non-client area.
  // The event is still sent to the client, and the delegate.
  event_generator.MoveMouseTo(15, 16);
  EXPECT_EQ("POINTER_MOVED 5,6",
            LocatedEventToEventTypeAndLocation(
                window_tree_client->PopInputEvent().event.get()));

  // Delegate should also get the events.
  EXPECT_EQ("MOUSE_MOVED 5,6", LocatedEventToEventTypeAndLocation(
                                   window_delegate.PopEvent().get()));

  // Only the delegate should get the press in this case.
  event_generator.PressLeftButton();
  ASSERT_FALSE(window_tree_client->PopInputEvent().event.get());

  EXPECT_EQ("MOUSE_PRESSED 5,6", LocatedEventToEventTypeAndLocation(
                                     window_delegate.PopEvent().get()));

  // Move mouse into client area, only the delegate should get the move (drag).
  event_generator.MoveMouseTo(35, 51);
  ASSERT_FALSE(window_tree_client->PopInputEvent().event.get());

  EXPECT_EQ("MOUSE_DRAGGED 25,41", LocatedEventToEventTypeAndLocation(
                                       window_delegate.PopEvent().get()));

  // Release over client area, again only delegate should get it.
  event_generator.ReleaseLeftButton();
  ASSERT_FALSE(window_tree_client->PopInputEvent().event.get());

  EXPECT_EQ("MOUSE_RELEASED",
            EventToEventType(window_delegate.PopEvent().get()));

  event_generator.MoveMouseTo(26, 50);
  EXPECT_EQ("POINTER_MOVED 16,40",
            LocatedEventToEventTypeAndLocation(
                window_tree_client->PopInputEvent().event.get()));

  // Delegate should also get the events.
  EXPECT_EQ("MOUSE_MOVED 16,40", LocatedEventToEventTypeAndLocation(
                                     window_delegate.PopEvent().get()));

  // Press in client area. Only the client should get the event.
  event_generator.PressLeftButton();
  EXPECT_EQ("POINTER_DOWN 16,40",
            LocatedEventToEventTypeAndLocation(
                window_tree_client->PopInputEvent().event.get()));

  ASSERT_FALSE(window_delegate.PopEvent().get());
}

TEST(WindowTreeTest, MouseDownInNonClientWithChildWindow) {
  EventRecordingWindowDelegate window_delegate;
  WindowServiceTestSetup setup;
  TestWindowTreeClient* window_tree_client = setup.window_tree_client();
  setup.delegate()->set_delegate_for_next_top_level(&window_delegate);
  aura::Window* top_level =
      setup.window_tree_test_helper()->NewTopLevelWindow();
  ASSERT_TRUE(top_level);
  top_level->Show();
  top_level->SetBounds(gfx::Rect(10, 10, 100, 100));
  setup.window_tree_test_helper()->SetClientArea(top_level,
                                                 gfx::Insets(10, 0, 0, 0));

  // Add a child Window that is sized to fill the top-level.
  aura::Window* window = setup.window_tree_test_helper()->NewWindow();
  ASSERT_TRUE(window);
  window->Show();
  window->SetBounds(gfx::Rect(top_level->bounds().size()));
  top_level->AddChild(window);

  window_delegate.ClearEvents();

  // Move the mouse over the non-client area. Both the client and the delegate
  // should get the event.
  ui::test::EventGenerator event_generator(setup.root());
  event_generator.MoveMouseTo(15, 16);
  EXPECT_EQ("POINTER_MOVED 5,6",
            LocatedEventToEventTypeAndLocation(
                window_tree_client->PopInputEvent().event.get()));
  EXPECT_TRUE(window_tree_client->input_events().empty());
  EXPECT_EQ("MOUSE_ENTERED",
            EventToEventType(window_delegate.PopEvent().get()));
  EXPECT_EQ("MOUSE_MOVED", EventToEventType(window_delegate.PopEvent().get()));
  EXPECT_TRUE(window_delegate.events().empty());

  // Press over the non-client. The client should not be notified as the event
  // should be handled locally.
  event_generator.PressLeftButton();
  ASSERT_FALSE(window_tree_client->PopInputEvent().event.get());
  EXPECT_EQ("MOUSE_PRESSED 5,6", LocatedEventToEventTypeAndLocation(
                                     window_delegate.PopEvent().get()));
}

TEST(WindowTreeTest, MouseDownInNonClientDragToClientWithChildWindow) {
  EventRecordingWindowDelegate window_delegate;
  WindowServiceTestSetup setup;
  setup.delegate()->set_delegate_for_next_top_level(&window_delegate);
  aura::Window* top_level =
      setup.window_tree_test_helper()->NewTopLevelWindow();
  ASSERT_TRUE(top_level);
  top_level->Show();
  top_level->SetBounds(gfx::Rect(10, 10, 100, 100));
  setup.window_tree_test_helper()->SetClientArea(top_level,
                                                 gfx::Insets(10, 0, 0, 0));

  // Add a child Window that is sized to fill the top-level.
  aura::Window* window = setup.window_tree_test_helper()->NewWindow();
  ASSERT_TRUE(window);
  window->Show();
  window->SetBounds(gfx::Rect(top_level->bounds().size()));
  top_level->AddChild(window);

  // Press in non-client area.
  ui::test::EventGenerator event_generator(setup.root());
  event_generator.MoveMouseTo(15, 16);
  event_generator.PressLeftButton();

  TestWindowTreeClient* window_tree_client = setup.window_tree_client();
  window_tree_client->ClearInputEvents();
  window_delegate.ClearEvents();
  // Drag over client area, only the delegate should get it (because the press
  // was in the non-client area).
  event_generator.MoveMouseTo(15, 26);
  EXPECT_EQ("MOUSE_DRAGGED",
            EventToEventType(window_delegate.PopEvent().get()));
  EXPECT_TRUE(window_tree_client->input_events().empty());
}

TEST(WindowTreeTest, SetHitTestMask) {
  EventRecordingWindowDelegate window_delegate;
  WindowServiceTestSetup setup;
  setup.delegate()->set_delegate_for_next_top_level(&window_delegate);
  aura::Window* top_level =
      setup.window_tree_test_helper()->NewTopLevelWindow();
  ASSERT_TRUE(top_level);
  top_level->Show();
  top_level->SetBounds(gfx::Rect(10, 10, 100, 100));

  TestWindowTreeClient* window_tree_client = setup.window_tree_client();
  window_tree_client->ClearInputEvents();
  window_delegate.ClearEvents();

  // Set a hit test mask in the window's bounds that excludes the top half.
  setup.window_tree_test_helper()->SetHitTestMask(top_level,
                                                  gfx::Rect(0, 50, 100, 50));

  // Events outside the hit test mask are not seen by the delegate or client.
  ui::test::EventGenerator event_generator(setup.root());
  event_generator.MoveMouseTo(50, 30);
  EXPECT_TRUE(window_tree_client->input_events().empty());
  EXPECT_TRUE(window_delegate.events().empty());

  // Events in the hit test mask are seen by the delegate and client.
  event_generator.MoveMouseTo(50, 80);
  EXPECT_EQ("POINTER_MOVED 40,70",
            LocatedEventToEventTypeAndLocation(
                window_tree_client->PopInputEvent().event.get()));
  EXPECT_EQ("MOUSE_ENTERED 40,70", LocatedEventToEventTypeAndLocation(
                                       window_delegate.PopEvent().get()));
  EXPECT_EQ("MOUSE_MOVED 40,70", LocatedEventToEventTypeAndLocation(
                                     window_delegate.PopEvent().get()));
}

TEST(WindowTreeTest, PointerWatcher) {
  WindowServiceTestSetup setup;
  TestWindowTreeClient* window_tree_client = setup.window_tree_client();
  aura::Window* top_level =
      setup.window_tree_test_helper()->NewTopLevelWindow();
  ASSERT_TRUE(top_level);
  setup.window_tree_test_helper()->SetEventTargetingPolicy(
      top_level, mojom::EventTargetingPolicy::NONE);
  EXPECT_EQ(mojom::EventTargetingPolicy::NONE,
            top_level->event_targeting_policy());
  // Start the pointer watcher only for pointer down/up.
  setup.window_tree_test_helper()->window_tree()->StartPointerWatcher(false);

  top_level->Show();
  top_level->SetBounds(gfx::Rect(10, 10, 100, 100));

  ui::test::EventGenerator event_generator(setup.root());
  event_generator.MoveMouseTo(50, 50);
  ASSERT_TRUE(window_tree_client->observed_pointer_events().empty());

  event_generator.MoveMouseTo(5, 6);
  ASSERT_TRUE(window_tree_client->observed_pointer_events().empty());

  event_generator.PressLeftButton();
  EXPECT_EQ("POINTER_DOWN 5,6",
            LocatedEventToEventTypeAndLocation(
                window_tree_client->PopObservedPointerEvent().event.get()));

  event_generator.ReleaseLeftButton();
  EXPECT_EQ("POINTER_UP 5,6",
            LocatedEventToEventTypeAndLocation(
                window_tree_client->PopObservedPointerEvent().event.get()));

  // Enable observing move events.
  setup.window_tree_test_helper()->window_tree()->StartPointerWatcher(true);
  event_generator.MoveMouseTo(8, 9);
  EXPECT_EQ("POINTER_MOVED 8,9",
            LocatedEventToEventTypeAndLocation(
                window_tree_client->PopObservedPointerEvent().event.get()));

  const int kTouchId = 11;
  event_generator.MoveTouchId(gfx::Point(2, 3), kTouchId);
  EXPECT_EQ("POINTER_MOVED 2,3",
            LocatedEventToEventTypeAndLocation(
                window_tree_client->PopObservedPointerEvent().event.get()));
}

TEST(WindowTreeTest, MatchesPointerWatcherSet) {
  WindowServiceTestSetup setup;
  TestWindowTreeClient* window_tree_client = setup.window_tree_client();
  aura::Window* top_level =
      setup.window_tree_test_helper()->NewTopLevelWindow(1);
  ASSERT_TRUE(top_level);
  top_level->Show();
  top_level->SetBounds(gfx::Rect(10, 10, 100, 100));
  // Start the pointer watcher only for pointer down/up.
  setup.window_tree_test_helper()->window_tree()->StartPointerWatcher(false);

  ui::test::EventGenerator event_generator(setup.root());
  event_generator.MoveMouseTo(50, 50);
  EXPECT_TRUE(window_tree_client->observed_pointer_events().empty());
  window_tree_client->ClearInputEvents();

  event_generator.PressLeftButton();
  // The client should get the event, and |matches_pointer_watcher| should be
  // true (because it matched the pointer watcher).
  TestWindowTreeClient::InputEvent press_input =
      window_tree_client->PopInputEvent();
  ASSERT_TRUE(press_input.event);
  EXPECT_EQ("POINTER_DOWN 40,40",
            LocatedEventToEventTypeAndLocation(press_input.event.get()));
  EXPECT_TRUE(press_input.matches_pointer_watcher);
  // Because the event matches a pointer event there should be no observed
  // pointer events.
  EXPECT_TRUE(window_tree_client->observed_pointer_events().empty());
}

TEST(WindowTreeTest, Capture) {
  WindowServiceTestSetup setup;
  aura::Window* window = setup.window_tree_test_helper()->NewWindow();

  // Setting capture on |window| should fail as it's not visible.
  EXPECT_FALSE(setup.window_tree_test_helper()->SetCapture(window));

  aura::Window* top_level =
      setup.window_tree_test_helper()->NewTopLevelWindow();
  ASSERT_TRUE(top_level);
  EXPECT_FALSE(setup.window_tree_test_helper()->SetCapture(top_level));
  top_level->Show();
  EXPECT_TRUE(setup.window_tree_test_helper()->SetCapture(top_level));

  EXPECT_FALSE(setup.window_tree_test_helper()->ReleaseCapture(window));
  EXPECT_TRUE(setup.window_tree_test_helper()->ReleaseCapture(top_level));

  top_level->AddChild(window);
  window->Show();
  EXPECT_TRUE(setup.window_tree_test_helper()->SetCapture(window));
  EXPECT_TRUE(setup.window_tree_test_helper()->ReleaseCapture(window));
}

TEST(WindowTreeTest, TransferCaptureToClient) {
  EventRecordingWindowDelegate window_delegate;
  WindowServiceTestSetup setup;
  setup.delegate()->set_delegate_for_next_top_level(&window_delegate);
  aura::Window* top_level =
      setup.window_tree_test_helper()->NewTopLevelWindow();
  ASSERT_TRUE(top_level);
  top_level->Show();
  top_level->SetBounds(gfx::Rect(0, 0, 100, 100));
  setup.window_tree_test_helper()->SetClientArea(top_level,
                                                 gfx::Insets(10, 0, 0, 0));

  wm::CaptureController::Get()->SetCapture(top_level);
  ui::test::EventGenerator event_generator(setup.root());
  event_generator.MoveMouseTo(6, 6);
  setup.window_tree_client()->ClearInputEvents();
  window_delegate.ClearEvents();
  event_generator.MoveMouseTo(7, 7);

  // Because capture was initiated locally event should go to |window_delegate|
  // only (not the client).
  EXPECT_TRUE(setup.window_tree_client()->input_events().empty());
  EXPECT_EQ("MOUSE_MOVED", EventToEventType(window_delegate.PopEvent().get()));
  EXPECT_TRUE(window_delegate.events().empty());

  // Request capture from the client.
  EXPECT_TRUE(setup.window_tree_test_helper()->SetCapture(top_level));
  event_generator.MoveMouseTo(8, 8);
  // Now the event should go to the client and not local.
  EXPECT_TRUE(window_delegate.events().empty());
  EXPECT_EQ("POINTER_MOVED",
            EventToEventType(
                setup.window_tree_client()->PopInputEvent().event.get()));
  EXPECT_TRUE(setup.window_tree_client()->input_events().empty());
}

TEST(WindowTreeTest, TransferCaptureBetweenParentAndChild) {
  EventRecordingWindowDelegate window_delegate;
  WindowServiceTestSetup setup;
  setup.delegate()->set_delegate_for_next_top_level(&window_delegate);
  aura::Window* top_level =
      setup.window_tree_test_helper()->NewTopLevelWindow();
  ASSERT_TRUE(top_level);
  top_level->Show();
  top_level->SetBounds(gfx::Rect(0, 0, 100, 100));
  aura::Window* window = setup.window_tree_test_helper()->NewWindow();
  ASSERT_TRUE(window);
  top_level->AddChild(window);
  window->Show();
  std::unique_ptr<EmbeddingHelper> embedding_helper =
      setup.CreateEmbedding(window);
  ASSERT_TRUE(embedding_helper);

  // Move the mouse and set capture from the child.
  ui::test::EventGenerator event_generator(setup.root());
  event_generator.MoveMouseTo(6, 6);
  setup.window_tree_client()->ClearInputEvents();
  window_delegate.ClearEvents();
  embedding_helper->window_tree_client.ClearInputEvents();
  EXPECT_TRUE(embedding_helper->window_tree_test_helper->SetCapture(window));
  event_generator.MoveMouseTo(7, 7);

  // As capture was set from the child, only the child should get the event.
  EXPECT_TRUE(setup.window_tree_client()->input_events().empty());
  EXPECT_TRUE(window_delegate.events().empty());
  EXPECT_EQ(
      "POINTER_MOVED",
      EventToEventType(
          embedding_helper->window_tree_client.PopInputEvent().event.get()));
  EXPECT_TRUE(embedding_helper->window_tree_client.input_events().empty());

  // Set capture from the parent, only the parent should get the event now.
  EXPECT_TRUE(setup.window_tree_test_helper()->SetCapture(top_level));
  event_generator.MoveMouseTo(8, 8);
  EXPECT_EQ("POINTER_MOVED",
            EventToEventType(
                setup.window_tree_client()->PopInputEvent().event.get()));
  EXPECT_TRUE(setup.window_tree_client()->input_events().empty());
  EXPECT_TRUE(window_delegate.events().empty());
  EXPECT_TRUE(embedding_helper->window_tree_client.input_events().empty());
}

TEST(WindowTreeTest, CaptureNotification) {
  WindowServiceTestSetup setup;
  aura::Window* window = setup.window_tree_test_helper()->NewWindow();
  aura::Window* top_level =
      setup.window_tree_test_helper()->NewTopLevelWindow();
  top_level->AddChild(window);
  ASSERT_TRUE(top_level);
  top_level->Show();
  window->Show();
  setup.changes()->clear();
  EXPECT_TRUE(setup.window_tree_test_helper()->SetCapture(window));
  EXPECT_TRUE(setup.changes()->empty());

  wm::CaptureController::Get()->ReleaseCapture(window);
  EXPECT_EQ("OnCaptureChanged new_window=null old_window=0,1",
            SingleChangeToDescription(*(setup.changes())));
}

TEST(WindowTreeTest, CaptureNotificationForEmbedRoot) {
  WindowServiceTestSetup setup;
  aura::Window* window = setup.window_tree_test_helper()->NewWindow();
  aura::Window* top_level =
      setup.window_tree_test_helper()->NewTopLevelWindow();
  top_level->AddChild(window);
  ASSERT_TRUE(top_level);
  top_level->Show();
  window->Show();
  setup.changes()->clear();
  EXPECT_TRUE(setup.window_tree_test_helper()->SetCapture(window));
  EXPECT_TRUE(setup.changes()->empty());

  // Set capture on the embed-root from the embedded client. The embedder
  // should be notified.
  std::unique_ptr<EmbeddingHelper> embedding_helper =
      setup.CreateEmbedding(window);
  ASSERT_TRUE(embedding_helper);
  setup.changes()->clear();
  embedding_helper->changes()->clear();
  EXPECT_TRUE(embedding_helper->window_tree_test_helper->SetCapture(window));
  EXPECT_EQ("OnCaptureChanged new_window=null old_window=0,1",
            SingleChangeToDescription(*(setup.changes())));
  setup.changes()->clear();
  EXPECT_TRUE(embedding_helper->changes()->empty());

  // Set capture from the embedder. This triggers the embedded client to lose
  // capture.
  EXPECT_TRUE(setup.window_tree_test_helper()->SetCapture(window));
  EXPECT_TRUE(setup.changes()->empty());
  // NOTE: the '2' is because the embedded client sees the high order bits of
  // the root.
  EXPECT_EQ("OnCaptureChanged new_window=null old_window=2,1",
            SingleChangeToDescription(*(embedding_helper->changes())));
  embedding_helper->changes()->clear();

  // And release capture locally.
  wm::CaptureController::Get()->ReleaseCapture(window);
  EXPECT_EQ("OnCaptureChanged new_window=null old_window=0,1",
            SingleChangeToDescription(*(setup.changes())));
  EXPECT_TRUE(embedding_helper->changes()->empty());
}

TEST(WindowTreeTest, CaptureNotificationForTopLevel) {
  WindowServiceTestSetup setup;
  aura::Window* top_level =
      setup.window_tree_test_helper()->NewTopLevelWindow(11);
  ASSERT_TRUE(top_level);
  top_level->Show();
  setup.changes()->clear();
  EXPECT_TRUE(setup.window_tree_test_helper()->SetCapture(top_level));
  EXPECT_TRUE(setup.changes()->empty());

  // Release capture locally.
  wm::CaptureController* capture_controller = wm::CaptureController::Get();
  capture_controller->ReleaseCapture(top_level);
  EXPECT_EQ("OnCaptureChanged new_window=null old_window=0,11",
            SingleChangeToDescription(*(setup.changes())));
  setup.changes()->clear();

  // Set capture locally.
  capture_controller->SetCapture(top_level);
  EXPECT_TRUE(setup.changes()->empty());

  // Set capture from client.
  EXPECT_TRUE(setup.window_tree_test_helper()->SetCapture(top_level));
  EXPECT_TRUE(setup.changes()->empty());

  // Release locally.
  capture_controller->ReleaseCapture(top_level);
  EXPECT_EQ("OnCaptureChanged new_window=null old_window=0,11",
            SingleChangeToDescription(*(setup.changes())));
}

TEST(WindowTreeTest, EventsGoToCaptureWindow) {
  WindowServiceTestSetup setup;
  aura::Window* window = setup.window_tree_test_helper()->NewWindow();
  aura::Window* top_level =
      setup.window_tree_test_helper()->NewTopLevelWindow();
  top_level->AddChild(window);
  ASSERT_TRUE(top_level);
  top_level->Show();
  window->Show();
  top_level->SetBounds(gfx::Rect(0, 0, 100, 100));
  window->SetBounds(gfx::Rect(10, 10, 90, 90));
  // Left press on the top-level, leaving mouse down.
  ui::test::EventGenerator event_generator(setup.root());
  event_generator.MoveMouseTo(5, 5);
  event_generator.PressLeftButton();
  setup.window_tree_client()->ClearInputEvents();

  // Set capture on |window|.
  EXPECT_TRUE(setup.window_tree_test_helper()->SetCapture(window));
  EXPECT_TRUE(setup.window_tree_client()->input_events().empty());

  // Move mouse, should go to |window|.
  event_generator.MoveMouseTo(6, 6);
  auto drag_event = setup.window_tree_client()->PopInputEvent();
  EXPECT_EQ(setup.window_tree_test_helper()->TransportIdForWindow(window),
            drag_event.window_id);
  EXPECT_EQ("POINTER_MOVED -4,-4",
            LocatedEventToEventTypeAndLocation(drag_event.event.get()));
}

TEST(WindowTreeTest, InterceptEventsOnEmbeddedWindowWithCapture) {
  EventRecordingWindowDelegate window_delegate;
  WindowServiceTestSetup setup;
  aura::Window* window = setup.window_tree_test_helper()->NewWindow();
  ASSERT_TRUE(window);
  setup.delegate()->set_delegate_for_next_top_level(&window_delegate);
  aura::Window* top_level =
      setup.window_tree_test_helper()->NewTopLevelWindow();
  ASSERT_TRUE(top_level);
  top_level->AddChild(window);
  top_level->Show();
  window->Show();

  // Create an embedding, and a new window in the embedding.
  std::unique_ptr<EmbeddingHelper> embedding_helper =
      setup.CreateEmbedding(window, mojom::kEmbedFlagEmbedderInterceptsEvents);
  ASSERT_TRUE(embedding_helper);
  aura::Window* window_in_child =
      embedding_helper->window_tree_test_helper->NewWindow();
  ASSERT_TRUE(window_in_child);
  window_in_child->Show();
  window->AddChild(window_in_child);
  EXPECT_TRUE(
      embedding_helper->window_tree_test_helper->SetCapture(window_in_child));

  // Do an initial move (which generates some additional events) and clear
  // everything out.
  ui::test::EventGenerator event_generator(setup.root());
  event_generator.MoveMouseTo(5, 5);
  setup.window_tree_client()->ClearInputEvents();
  window_delegate.ClearEvents();
  embedding_helper->window_tree_client.ClearInputEvents();

  // Move the mouse. Even though the window in the embedding has capture, the
  // event should go to the parent client (setup.window_tree_client()), because
  // the embedding was created such that the embedder (parent) intercepts the
  // events.
  event_generator.MoveMouseTo(6, 6);
  EXPECT_TRUE(window_delegate.events().empty());
  EXPECT_EQ("POINTER_MOVED",
            EventToEventType(
                setup.window_tree_client()->PopInputEvent().event.get()));
  EXPECT_TRUE(setup.window_tree_client()->input_events().empty());
  EXPECT_TRUE(embedding_helper->window_tree_client.input_events().empty());
}

TEST(WindowTreeTest, PointerDownResetOnCaptureChange) {
  WindowServiceTestSetup setup;
  aura::Window* window = setup.window_tree_test_helper()->NewWindow();
  ASSERT_TRUE(window);
  aura::Window* top_level =
      setup.window_tree_test_helper()->NewTopLevelWindow();
  ASSERT_TRUE(top_level);
  top_level->AddChild(window);
  setup.window_tree_test_helper()->SetClientArea(top_level,
                                                 gfx::Insets(10, 0, 0, 0));
  top_level->Show();
  window->Show();
  top_level->SetBounds(gfx::Rect(0, 0, 100, 100));
  window->SetBounds(gfx::Rect(10, 10, 90, 90));
  // Left press on the top-level, leaving mouse down.
  ui::test::EventGenerator event_generator(setup.root());
  event_generator.MoveMouseTo(5, 5);
  event_generator.PressLeftButton();
  ServerWindow* top_level_server_window = ServerWindow::GetMayBeNull(top_level);
  ASSERT_TRUE(top_level_server_window);
  ServerWindowTestHelper top_level_server_window_helper(
      top_level_server_window);
  EXPECT_TRUE(top_level_server_window_helper.IsHandlingPointerPress(
      ui::MouseEvent::kMousePointerId));

  // Set capture on |window|, top_level should no longer be in pointer-down
  // (because capture changed).
  EXPECT_TRUE(setup.window_tree_test_helper()->SetCapture(window));
  EXPECT_FALSE(top_level_server_window_helper.IsHandlingPointerPress(
      ui::MouseEvent::kMousePointerId));
}

TEST(WindowTreeTest, PointerDownResetOnHide) {
  WindowServiceTestSetup setup;
  aura::Window* top_level =
      setup.window_tree_test_helper()->NewTopLevelWindow();
  ASSERT_TRUE(top_level);
  setup.window_tree_test_helper()->SetClientArea(top_level,
                                                 gfx::Insets(10, 0, 0, 0));
  top_level->Show();
  top_level->SetBounds(gfx::Rect(0, 0, 100, 100));
  // Left press on the top-level, leaving mouse down.
  ui::test::EventGenerator event_generator(setup.root());
  event_generator.MoveMouseTo(5, 5);
  event_generator.PressLeftButton();
  ServerWindow* top_level_server_window = ServerWindow::GetMayBeNull(top_level);
  ASSERT_TRUE(top_level_server_window);
  ServerWindowTestHelper top_level_server_window_helper(
      top_level_server_window);
  EXPECT_TRUE(top_level_server_window_helper.IsHandlingPointerPress(
      ui::MouseEvent::kMousePointerId));

  // Hiding should implicitly cancel capture.
  top_level->Hide();
  EXPECT_FALSE(top_level_server_window_helper.IsHandlingPointerPress(
      ui::MouseEvent::kMousePointerId));
}

TEST(WindowTreeTest, DeleteWindow) {
  WindowServiceTestSetup setup;
  aura::Window* window = setup.window_tree_test_helper()->NewWindow();
  ASSERT_TRUE(window);
  aura::WindowTracker tracker;
  tracker.Add(window);
  setup.changes()->clear();
  setup.window_tree_test_helper()->DeleteWindow(window);
  EXPECT_TRUE(tracker.windows().empty());
  EXPECT_EQ("ChangeCompleted id=1 success=true",
            SingleChangeToDescription(*setup.changes()));
}

TEST(WindowTreeTest, DeleteTopLevel) {
  WindowServiceTestSetup setup;
  aura::Window* top_level =
      setup.window_tree_test_helper()->NewTopLevelWindow();
  const ClientWindowId top_level_id =
      setup.window_tree_test_helper()->ClientWindowIdForWindow(top_level);
  ASSERT_TRUE(top_level);
  aura::WindowTracker tracker;
  tracker.Add(top_level);
  setup.changes()->clear();

  // Ask the tree to delete the window, which should result in deleting the
  // Window as well responding with success.
  setup.window_tree_test_helper()->DeleteWindow(top_level);
  EXPECT_TRUE(tracker.windows().empty());
  EXPECT_EQ("ChangeCompleted id=1 success=true",
            SingleChangeToDescription(*setup.changes()));

  // Make sure the WindowTree doesn't have a mapping for the id anymore.
  EXPECT_FALSE(
      setup.window_tree_test_helper()->GetWindowByClientId(top_level_id));
}

TEST(WindowTreeTest, ExternalDeleteTopLevel) {
  WindowServiceTestSetup setup;
  aura::Window* top_level =
      setup.window_tree_test_helper()->NewTopLevelWindow();
  setup.changes()->clear();
  ASSERT_TRUE(top_level);
  delete top_level;
  EXPECT_EQ("WindowDeleted window=0,1",
            SingleChangeToDescription(*setup.changes()));
}

TEST(WindowTreeTest, ExternalDeleteWindow) {
  WindowServiceTestSetup setup;
  aura::Window* window = setup.window_tree_test_helper()->NewWindow();
  ASSERT_TRUE(window);
  setup.changes()->clear();
  delete window;
  EXPECT_EQ("WindowDeleted window=0,1",
            SingleChangeToDescription(*setup.changes()));
}

TEST(WindowTreeTest, Embed) {
  WindowServiceTestSetup setup;
  aura::Window* window = setup.window_tree_test_helper()->NewWindow();
  aura::Window* embed_window = setup.window_tree_test_helper()->NewWindow();
  ASSERT_TRUE(window);
  ASSERT_TRUE(embed_window);
  window->AddChild(embed_window);
  embed_window->SetBounds(gfx::Rect(1, 2, 3, 4));
  setup.changes()->clear();

  std::unique_ptr<EmbeddingHelper> embedding_helper =
      setup.CreateEmbedding(embed_window);
  ASSERT_TRUE(embedding_helper);
  ASSERT_EQ("OnEmbed", SingleChangeToDescription(*embedding_helper->changes()));
  const Change& test_change = (*embedding_helper->changes())[0];
  ASSERT_EQ(1u, test_change.windows.size());
  EXPECT_EQ(embed_window->bounds(), test_change.windows[0].bounds);
  EXPECT_EQ(kInvalidTransportId, test_change.windows[0].parent_id);
  EXPECT_EQ(embed_window->TargetVisibility(), test_change.windows[0].visible);
  EXPECT_NE(kInvalidTransportId, test_change.windows[0].window_id);

  // OnFrameSinkIdAllocated() should called on the parent tree.
  ASSERT_EQ(1u, setup.changes()->size());
  EXPECT_EQ(CHANGE_TYPE_FRAME_SINK_ID_ALLOCATED, (*setup.changes())[0].type);
  const Id embed_window_transport_id =
      setup.window_tree_test_helper()->TransportIdForWindow(embed_window);
  EXPECT_EQ(embed_window_transport_id, (*setup.changes())[0].window_id);
  EXPECT_EQ(ServerWindow::GetMayBeNull(embed_window)->frame_sink_id(),
            (*setup.changes())[0].frame_sink_id);
}

// Base class for ScheduleEmbed() related tests. This creates a Window and
// prepares a secondary client (|embed_client_|) that is intended to be embedded
// at some point.
class WindowTreeScheduleEmbedTest : public testing::Test {
 public:
  WindowTreeScheduleEmbedTest() = default;
  ~WindowTreeScheduleEmbedTest() override = default;

  // testing::Test:
  void SetUp() override {
    testing::Test::SetUp();
    setup_ = std::make_unique<WindowServiceTestSetup>();
    embed_binding_.Bind(mojo::MakeRequest(&embed_client_ptr_));
    window_ = setup_->window_tree_test_helper()->NewWindow();
    ASSERT_TRUE(window_);
  }
  void TearDown() override {
    window_ = nullptr;
    embed_binding_.Close();
    setup_.reset();
    testing::Test::TearDown();
  }

 protected:
  std::unique_ptr<WindowServiceTestSetup> setup_;
  TestWindowTreeClient embed_client_;
  mojom::WindowTreeClientPtr embed_client_ptr_;
  aura::Window* window_ = nullptr;

 private:
  mojo::Binding<mojom::WindowTreeClient> embed_binding_{&embed_client_};

  DISALLOW_COPY_AND_ASSIGN(WindowTreeScheduleEmbedTest);
};

TEST_F(WindowTreeScheduleEmbedTest, ScheduleEmbedWithUnregisteredToken) {
  bool embed_result = false;
  bool embed_callback_called = false;
  setup_->window_tree_test_helper()->window_tree()->EmbedUsingToken(
      setup_->window_tree_test_helper()->TransportIdForWindow(window_),
      base::UnguessableToken::Create(), kDefaultEmbedFlags,
      base::BindOnce(&EmbedUsingTokenCallback, &embed_callback_called,
                     &embed_result));
  EXPECT_TRUE(embed_callback_called);
  // ScheduleEmbed() with an invalid token should fail.
  EXPECT_FALSE(embed_result);
}

TEST_F(WindowTreeScheduleEmbedTest, ScheduleEmbedRegisteredTokenInvalidWindow) {
  // Register a token for embedding.
  base::UnguessableToken token;
  setup_->window_tree_test_helper()->window_tree()->ScheduleEmbed(
      std::move(embed_client_ptr_),
      base::BindOnce(&ScheduleEmbedCallback, &token));
  EXPECT_FALSE(token.is_empty());

  bool embed_result = false;
  bool embed_callback_called = false;
  setup_->window_tree_test_helper()->window_tree()->EmbedUsingToken(
      kInvalidTransportId, token, kDefaultEmbedFlags,
      base::BindOnce(&EmbedUsingTokenCallback, &embed_callback_called,
                     &embed_result));
  EXPECT_TRUE(embed_callback_called);
  // ScheduleEmbed() with a valid token, but invalid window should fail.
  EXPECT_FALSE(embed_result);
}

TEST_F(WindowTreeScheduleEmbedTest, ScheduleEmbed) {
  base::UnguessableToken token;
  // ScheduleEmbed() with a valid token and valid window.
  setup_->window_tree_test_helper()->window_tree()->ScheduleEmbed(
      std::move(embed_client_ptr_),
      base::BindOnce(&ScheduleEmbedCallback, &token));
  EXPECT_FALSE(token.is_empty());

  bool embed_result = false;
  bool embed_callback_called = false;
  setup_->window_tree_test_helper()->window_tree()->EmbedUsingToken(
      setup_->window_tree_test_helper()->TransportIdForWindow(window_), token,
      kDefaultEmbedFlags,
      base::BindOnce(&EmbedUsingTokenCallback, &embed_callback_called,
                     &embed_result));
  EXPECT_TRUE(embed_callback_called);
  EXPECT_TRUE(embed_result);
  base::RunLoop().RunUntilIdle();

  // The embedded client should get OnEmbed().
  EXPECT_EQ("OnEmbed",
            SingleChangeToDescription(*embed_client_.tracker()->changes()));
}

TEST(WindowTreeTest, ScheduleEmbedForExistingClient) {
  WindowServiceTestSetup setup;
  // Schedule an embed in the tree created by |setup|.
  base::UnguessableToken token;
  const uint32_t window_id_in_child = 149;
  setup.window_tree_test_helper()
      ->window_tree()
      ->ScheduleEmbedForExistingClient(
          window_id_in_child, base::BindOnce(&ScheduleEmbedCallback, &token));
  EXPECT_FALSE(token.is_empty());

  // Create another client and a window.
  TestWindowTreeClient client2;
  std::unique_ptr<WindowTree> tree2 =
      setup.service()->CreateWindowTree(&client2);
  ASSERT_TRUE(tree2);
  WindowTreeTestHelper tree2_test_helper(tree2.get());
  aura::Window* window_in_parent = tree2_test_helper.NewWindow();
  ASSERT_TRUE(window_in_parent);

  // Call EmbedUsingToken() from tree2, which should result in the tree from
  // |setup| getting OnEmbedFromToken().
  bool embed_result = false;
  bool embed_callback_called = false;
  WindowTreeTestHelper(tree2.get())
      .window_tree()
      ->EmbedUsingToken(
          tree2_test_helper.TransportIdForWindow(window_in_parent), token,
          kDefaultEmbedFlags,
          base::BindOnce(&EmbedUsingTokenCallback, &embed_callback_called,
                         &embed_result));
  EXPECT_TRUE(embed_callback_called);
  EXPECT_TRUE(embed_result);

  EXPECT_EQ("OnEmbedFromToken", SingleChangeToDescription(*setup.changes()));
  EXPECT_EQ(
      static_cast<Id>(window_id_in_child),
      setup.window_tree_test_helper()->TransportIdForWindow(window_in_parent));
}

TEST(WindowTreeTest, DeleteRootOfEmbeddingFromScheduleEmbedForExistingClient) {
  WindowServiceTestSetup setup;
  aura::Window* window_in_parent = setup.window_tree_test_helper()->NewWindow();
  ASSERT_TRUE(window_in_parent);

  // Create another client.
  TestWindowTreeClient client2;
  std::unique_ptr<WindowTree> tree2 =
      setup.service()->CreateWindowTree(&client2);
  WindowTreeTestHelper tree2_test_helper(tree2.get());
  base::UnguessableToken token;
  tree2_test_helper.window_tree()->ScheduleEmbedForExistingClient(
      11, base::BindOnce(&ScheduleEmbedCallback, &token));
  EXPECT_FALSE(token.is_empty());

  // Call EmbedUsingToken() from setup.window_tree(), which should result in
  // |tree2| getting OnEmbedFromToken().
  bool embed_result = false;
  bool embed_callback_called = false;
  setup.window_tree_test_helper()->window_tree()->EmbedUsingToken(
      setup.window_tree_test_helper()->TransportIdForWindow(window_in_parent),
      token, kDefaultEmbedFlags,
      base::BindOnce(&EmbedUsingTokenCallback, &embed_callback_called,
                     &embed_result));
  EXPECT_TRUE(embed_callback_called);
  EXPECT_TRUE(embed_result);

  EXPECT_EQ("OnEmbedFromToken",
            SingleChangeToDescription(*client2.tracker()->changes()));
  client2.tracker()->changes()->clear();

  // Delete |window_in_parent|, which should trigger notifying tree2.
  setup.window_tree_test_helper()->DeleteWindow(window_in_parent);
  window_in_parent = nullptr;

  // 11 is the same value supplied to ScheduleEmbedForExistingClient().
  EXPECT_EQ("WindowDeleted window=0,11",
            SingleChangeToDescription(*client2.tracker()->changes()));
}

TEST(WindowTreeTest, DeleteEmbededTreeFromScheduleEmbedForExistingClient) {
  WindowServiceTestSetup setup;
  aura::Window* window_in_parent = setup.window_tree_test_helper()->NewWindow();
  ASSERT_TRUE(window_in_parent);

  // Create another client and call ScheduleEmbedForExistingClient() from it.
  TestWindowTreeClient client2;
  std::unique_ptr<WindowTree> tree2 =
      setup.service()->CreateWindowTree(&client2);
  WindowTreeTestHelper tree2_test_helper(tree2.get());
  base::UnguessableToken token;
  tree2_test_helper.window_tree()->ScheduleEmbedForExistingClient(
      11, base::BindOnce(&ScheduleEmbedCallback, &token));
  EXPECT_FALSE(token.is_empty());

  // Call EmbedUsingToken() from setup.window_tree(), which should result in
  // |tree2| getting OnEmbedFromToken().
  bool embed_result = false;
  bool embed_callback_called = false;
  setup.window_tree_test_helper()->window_tree()->EmbedUsingToken(
      setup.window_tree_test_helper()->TransportIdForWindow(window_in_parent),
      token, kDefaultEmbedFlags,
      base::BindOnce(&EmbedUsingTokenCallback, &embed_callback_called,
                     &embed_result));
  EXPECT_TRUE(embed_callback_called);
  EXPECT_TRUE(embed_result);
  EXPECT_TRUE(ServerWindow::GetMayBeNull(window_in_parent)->HasEmbedding());

  tree2.reset();
  EXPECT_FALSE(ServerWindow::GetMayBeNull(window_in_parent)->HasEmbedding());
}

TEST(WindowTreeTest, StackAtTop) {
  WindowServiceTestSetup setup;
  aura::Window* top_level1 =
      setup.window_tree_test_helper()->NewTopLevelWindow();
  ASSERT_TRUE(top_level1);
  setup.changes()->clear();
  setup.window_tree_test_helper()->window_tree()->StackAtTop(
      10, setup.window_tree_test_helper()->TransportIdForWindow(top_level1));
  // This succeeds because |top_level1| is already at top. |10| is the value
  // supplied to StackAtTop().
  EXPECT_EQ("ChangeCompleted id=10 success=true",
            SingleChangeToDescription(*setup.changes()));

  // Create another top-level. |top_level2| should initially be above 1.
  aura::Window* top_level2 =
      setup.window_tree_test_helper()->NewTopLevelWindow();
  ASSERT_TRUE(top_level2);
  ASSERT_EQ(2u, top_level1->parent()->children().size());
  EXPECT_EQ(top_level2, top_level1->parent()->children()[1]);

  // Stack 1 at the top.
  EXPECT_TRUE(setup.window_tree_test_helper()->StackAtTop(top_level1));
  EXPECT_EQ(top_level1, top_level1->parent()->children()[1]);

  // Stacking a non-toplevel window at top should fail.
  aura::Window* non_top_level_window =
      setup.window_tree_test_helper()->NewWindow();
  EXPECT_FALSE(
      setup.window_tree_test_helper()->StackAtTop(non_top_level_window));
}

TEST(WindowTreeTest, OnUnhandledKeyEvent) {
  // Create a top-level, show it and give it focus.
  WindowServiceTestSetup setup;
  aura::Window* top_level =
      setup.window_tree_test_helper()->NewTopLevelWindow();
  ASSERT_TRUE(top_level);
  top_level->Show();
  top_level->Focus();
  ASSERT_TRUE(top_level->HasFocus());
  ui::test::EventGenerator event_generator(setup.root());

  // Generate a key-press. The client should get the event, but not the
  // delegate.
  event_generator.PressKey(ui::VKEY_A, ui::EF_CONTROL_DOWN);
  EXPECT_TRUE(setup.delegate()->unhandled_key_events()->empty());

  // Respond that the event was not handled. Should result in notifying the
  // delegate.
  EXPECT_TRUE(setup.window_tree_client()->AckFirstEvent(
      setup.window_tree(), mojom::EventResult::UNHANDLED));
  ASSERT_EQ(1u, setup.delegate()->unhandled_key_events()->size());
  EXPECT_EQ(ui::VKEY_A,
            (*setup.delegate()->unhandled_key_events())[0].key_code());
  EXPECT_EQ(ui::EF_CONTROL_DOWN,
            (*setup.delegate()->unhandled_key_events())[0].flags());
  setup.delegate()->unhandled_key_events()->clear();

  // Repeat, but respond with handled. This should not result in the delegate
  // being notified.
  event_generator.PressKey(ui::VKEY_B, ui::EF_SHIFT_DOWN);
  EXPECT_TRUE(setup.window_tree_client()->AckFirstEvent(
      setup.window_tree(), mojom::EventResult::HANDLED));
  EXPECT_TRUE(setup.delegate()->unhandled_key_events()->empty());
}

TEST(WindowTreeTest, ReorderWindow) {
  // Create a top-level and two child windows.
  WindowServiceTestSetup setup;
  aura::Window* top_level =
      setup.window_tree_test_helper()->NewTopLevelWindow();
  ASSERT_TRUE(top_level);
  aura::Window* window1 = setup.window_tree_test_helper()->NewWindow();
  ASSERT_TRUE(window1);
  top_level->AddChild(window1);
  aura::Window* window2 = setup.window_tree_test_helper()->NewWindow();
  ASSERT_TRUE(window2);
  top_level->AddChild(window2);

  // Reorder |window1| on top of |window2|.
  EXPECT_TRUE(setup.window_tree_test_helper()->ReorderWindow(
      window1, window2, mojom::OrderDirection::ABOVE));
  EXPECT_EQ(window2, top_level->children()[0]);
  EXPECT_EQ(window1, top_level->children()[1]);

  // Reorder |window2| on top of |window1|.
  EXPECT_TRUE(setup.window_tree_test_helper()->ReorderWindow(
      window2, window1, mojom::OrderDirection::ABOVE));
  EXPECT_EQ(window1, top_level->children()[0]);
  EXPECT_EQ(window2, top_level->children()[1]);

  // Repeat, but use the WindowTree interface, which should result in an ack.
  setup.changes()->clear();
  uint32_t change_id = 101;
  setup.window_tree_test_helper()->window_tree()->ReorderWindow(
      change_id, setup.window_tree_test_helper()->TransportIdForWindow(window1),
      setup.window_tree_test_helper()->TransportIdForWindow(window2),
      mojom::OrderDirection::ABOVE);
  EXPECT_EQ("ChangeCompleted id=101 success=true",
            SingleChangeToDescription(*setup.changes()));
  setup.changes()->clear();

  // Supply invalid window ids, which should fail.
  setup.window_tree_test_helper()->window_tree()->ReorderWindow(
      change_id, 0, 1, mojom::OrderDirection::ABOVE);
  EXPECT_EQ("ChangeCompleted id=101 success=false",
            SingleChangeToDescription(*setup.changes()));

  // These calls should fail as the windows are not siblings.
  EXPECT_FALSE(setup.window_tree_test_helper()->ReorderWindow(
      window1, top_level, mojom::OrderDirection::ABOVE));
  EXPECT_FALSE(setup.window_tree_test_helper()->ReorderWindow(
      top_level, window2, mojom::OrderDirection::ABOVE));
}

TEST(WindowTreeTest, StackAbove) {
  // Create two top-levels.
  WindowServiceTestSetup setup;
  aura::Window* top_level1 =
      setup.window_tree_test_helper()->NewTopLevelWindow();
  ASSERT_TRUE(top_level1);
  aura::Window* top_level2 =
      setup.window_tree_test_helper()->NewTopLevelWindow();
  ASSERT_TRUE(top_level2);
  ASSERT_TRUE(top_level1->parent());
  ASSERT_EQ(top_level1->parent(), top_level2->parent());
  ASSERT_EQ(2u, top_level2->parent()->children().size());

  // 1 on top of 2.
  EXPECT_TRUE(
      setup.window_tree_test_helper()->StackAbove(top_level1, top_level2));
  EXPECT_EQ(top_level2, top_level2->parent()->children()[0]);
  EXPECT_EQ(top_level1, top_level2->parent()->children()[1]);

  // Repeat, should still succeed and nothing should change.
  EXPECT_TRUE(
      setup.window_tree_test_helper()->StackAbove(top_level1, top_level2));
  EXPECT_EQ(top_level2, top_level2->parent()->children()[0]);
  EXPECT_EQ(top_level1, top_level2->parent()->children()[1]);

  // 2 on top of 1.
  EXPECT_TRUE(
      setup.window_tree_test_helper()->StackAbove(top_level2, top_level1));
  EXPECT_EQ(top_level1, top_level2->parent()->children()[0]);
  EXPECT_EQ(top_level2, top_level2->parent()->children()[1]);

  // 1 on top of 2, using WindowTree interface, which should result in an ack.
  setup.changes()->clear();
  uint32_t change_id = 102;
  setup.window_tree_test_helper()->window_tree()->StackAbove(
      change_id,
      setup.window_tree_test_helper()->TransportIdForWindow(top_level1),
      setup.window_tree_test_helper()->TransportIdForWindow(top_level2));
  EXPECT_EQ("ChangeCompleted id=102 success=true",
            SingleChangeToDescription(*setup.changes()));
  setup.changes()->clear();
  EXPECT_EQ(top_level2, top_level2->parent()->children()[0]);
  EXPECT_EQ(top_level1, top_level2->parent()->children()[1]);

  // Using invalid id should fail.
  setup.window_tree_test_helper()->window_tree()->StackAbove(
      change_id,
      setup.window_tree_test_helper()->TransportIdForWindow(top_level1),
      kInvalidTransportId);
  EXPECT_EQ("ChangeCompleted id=102 success=false",
            SingleChangeToDescription(*setup.changes()));

  // Using non-top-level should fail.
  aura::Window* non_top_level_window =
      setup.window_tree_test_helper()->NewWindow();
  EXPECT_FALSE(setup.window_tree_test_helper()->StackAbove(
      top_level1, non_top_level_window));
}

TEST(WindowTreeTest, RunMoveLoopTouch) {
  WindowServiceTestSetup setup;
  aura::Window* top_level =
      setup.window_tree_test_helper()->NewTopLevelWindow();
  ASSERT_TRUE(top_level);
  const Id top_level_id =
      setup.window_tree_test_helper()->TransportIdForWindow(top_level);
  setup.changes()->clear();
  setup.window_tree_test_helper()->window_tree()->PerformWindowMove(
      12, top_level_id, mojom::MoveLoopSource::TOUCH, gfx::Point());
  // |top_level| isn't visible, so should fail immediately.
  EXPECT_EQ("ChangeCompleted id=12 success=false",
            SingleChangeToDescription(*setup.changes()));
  setup.changes()->clear();

  // Make the window visible and repeat.
  top_level->Show();
  setup.window_tree_test_helper()->window_tree()->PerformWindowMove(
      13, top_level_id, mojom::MoveLoopSource::TOUCH, gfx::Point());
  // WindowServiceDelegate should be asked to do the move.
  WindowServiceDelegate::DoneCallback move_loop_callback =
      setup.delegate()->TakeMoveLoopCallback();
  ASSERT_TRUE(move_loop_callback);
  // As the move is in progress, changes should be empty.
  EXPECT_TRUE(setup.changes()->empty());

  // Respond to the callback with success, which should notify client.
  std::move(move_loop_callback).Run(true);
  EXPECT_EQ("ChangeCompleted id=13 success=true",
            SingleChangeToDescription(*setup.changes()));

  // Trying to move non-top-level should fail.
  aura::Window* non_top_level_window =
      setup.window_tree_test_helper()->NewWindow();
  non_top_level_window->Show();
  setup.changes()->clear();
  setup.window_tree_test_helper()->window_tree()->PerformWindowMove(
      14,
      setup.window_tree_test_helper()->TransportIdForWindow(
          non_top_level_window),
      mojom::MoveLoopSource::TOUCH, gfx::Point());
  EXPECT_EQ("ChangeCompleted id=14 success=false",
            SingleChangeToDescription(*setup.changes()));
}

TEST(WindowTreeTest, RunMoveLoopMouse) {
  WindowServiceTestSetup setup;
  aura::Window* top_level =
      setup.window_tree_test_helper()->NewTopLevelWindow();
  ASSERT_TRUE(top_level);
  top_level->Show();
  const Id top_level_id =
      setup.window_tree_test_helper()->TransportIdForWindow(top_level);
  setup.changes()->clear();
  setup.window_tree_test_helper()->window_tree()->PerformWindowMove(
      12, top_level_id, mojom::MoveLoopSource::MOUSE, gfx::Point());
  // The mouse isn't down, so this should fail.
  EXPECT_EQ("ChangeCompleted id=12 success=false",
            SingleChangeToDescription(*setup.changes()));
  setup.changes()->clear();

  // Press the left button and repeat.
  ui::test::EventGenerator event_generator(setup.root());
  event_generator.PressLeftButton();
  setup.window_tree_test_helper()->window_tree()->PerformWindowMove(
      13, top_level_id, mojom::MoveLoopSource::MOUSE, gfx::Point());
  // WindowServiceDelegate should be asked to do the move.
  WindowServiceDelegate::DoneCallback move_loop_callback =
      setup.delegate()->TakeMoveLoopCallback();
  ASSERT_TRUE(move_loop_callback);
  // As the move is in progress, changes should be empty.
  EXPECT_TRUE(setup.changes()->empty());

  // Respond to the callback, which should notify client.
  std::move(move_loop_callback).Run(true);
  EXPECT_EQ("ChangeCompleted id=13 success=true",
            SingleChangeToDescription(*setup.changes()));
  setup.changes()->clear();
}

TEST(WindowTreeTest, CancelMoveLoop) {
  WindowServiceTestSetup setup;
  aura::Window* top_level =
      setup.window_tree_test_helper()->NewTopLevelWindow();
  ASSERT_TRUE(top_level);
  top_level->Show();
  const Id top_level_id =
      setup.window_tree_test_helper()->TransportIdForWindow(top_level);
  setup.changes()->clear();
  setup.window_tree_test_helper()->window_tree()->PerformWindowMove(
      12, top_level_id, mojom::MoveLoopSource::TOUCH, gfx::Point());

  // WindowServiceDelegate should be asked to do the move.
  WindowServiceDelegate::DoneCallback move_loop_callback =
      setup.delegate()->TakeMoveLoopCallback();
  ASSERT_TRUE(move_loop_callback);
  // As the move is in progress, changes should be empty.
  EXPECT_TRUE(setup.changes()->empty());

  // Cancelling with an invalid id should do nothing.
  EXPECT_FALSE(setup.delegate()->cancel_window_move_loop_called());
  setup.window_tree_test_helper()->window_tree()->CancelWindowMove(
      kInvalidTransportId);
  EXPECT_TRUE(setup.changes()->empty());
  EXPECT_FALSE(setup.delegate()->cancel_window_move_loop_called());

  // Cancel with the real id should notify the delegate.
  EXPECT_FALSE(setup.delegate()->cancel_window_move_loop_called());
  setup.window_tree_test_helper()->window_tree()->CancelWindowMove(
      top_level_id);
  EXPECT_TRUE(setup.delegate()->cancel_window_move_loop_called());
  // No changes yet, because |move_loop_callback| was not run yet.
  EXPECT_TRUE(setup.changes()->empty());
  // Run the closure, which triggers notifying the client.
  std::move(move_loop_callback).Run(false);
  EXPECT_EQ("ChangeCompleted id=12 success=false",
            SingleChangeToDescription(*setup.changes()));
}

TEST(WindowTreeTest, CancelMode) {
  WindowServiceTestSetup setup;
  aura::Window* top_level =
      setup.window_tree_test_helper()->NewTopLevelWindow();
  ASSERT_TRUE(top_level);
  top_level->Show();
  EXPECT_TRUE(setup.window_tree_test_helper()->SetFocus(top_level));
  // Dispatch a CancelEvent. This should go to the |top_level| as it has focus.
  setup.root()->GetHost()->dispatcher()->DispatchCancelModeEvent();
  EXPECT_EQ("CANCEL_MODE",
            EventToEventType(
                setup.window_tree_client()->PopInputEvent().event.get()));
}

TEST(WindowTreeTest, PerformDragDrop) {
  WindowServiceTestSetup setup;
  aura::Window* top_level =
      setup.window_tree_test_helper()->NewTopLevelWindow();
  ASSERT_TRUE(top_level);
  top_level->Show();
  const Id top_level_id =
      setup.window_tree_test_helper()->TransportIdForWindow(top_level);
  setup.changes()->clear();
  setup.window_tree_test_helper()->window_tree()->PerformDragDrop(
      12, top_level_id, gfx::Point(),
      base::flat_map<std::string, std::vector<uint8_t>>(), gfx::ImageSkia(),
      gfx::Vector2d(), 0, ::ui::mojom::PointerKind::MOUSE);

  // Let the posted drag loop task run.
  base::RunLoop().RunUntilIdle();

  // WindowServiceDelegate should be asked to run the drag loop.
  WindowServiceDelegate::DragDropCompletedCallback drag_loop_callback =
      setup.delegate()->TakeDragLoopCallback();
  ASSERT_TRUE(drag_loop_callback);

  // As the drag is in progress, changes should be empty.
  EXPECT_TRUE(setup.changes()->empty());

  // Respond with a drop operation, client should be notified with success.
  std::move(drag_loop_callback).Run(ui::DragDropTypes::DRAG_MOVE);
  EXPECT_EQ("OnPerformDragDropCompleted id=12 success=true action=1",
            SingleChangeToDescription(*setup.changes()));

  // Starts another drag and but the drag is canceled this time.
  setup.changes()->clear();
  setup.window_tree_test_helper()->window_tree()->PerformDragDrop(
      13, top_level_id, gfx::Point(),
      base::flat_map<std::string, std::vector<uint8_t>>(), gfx::ImageSkia(),
      gfx::Vector2d(), 0, ::ui::mojom::PointerKind::MOUSE);
  base::RunLoop().RunUntilIdle();
  drag_loop_callback = setup.delegate()->TakeDragLoopCallback();
  ASSERT_TRUE(drag_loop_callback);

  std::move(drag_loop_callback).Run(ui::DragDropTypes::DRAG_NONE);
  EXPECT_EQ("OnPerformDragDropCompleted id=13 success=false action=0",
            SingleChangeToDescription(*setup.changes()));
}

TEST(WindowTreeTest, PerformDragDropBeforePreviousOneFinish) {
  WindowServiceTestSetup setup;
  aura::Window* top_level =
      setup.window_tree_test_helper()->NewTopLevelWindow();
  ASSERT_TRUE(top_level);
  top_level->Show();
  const Id top_level_id =
      setup.window_tree_test_helper()->TransportIdForWindow(top_level);
  setup.changes()->clear();
  setup.window_tree_test_helper()->window_tree()->PerformDragDrop(
      12, top_level_id, gfx::Point(),
      base::flat_map<std::string, std::vector<uint8_t>>(), gfx::ImageSkia(),
      gfx::Vector2d(), 0, ::ui::mojom::PointerKind::MOUSE);

  // PerformDragDrop before the drag loop task runs should fail.
  setup.window_tree_test_helper()->window_tree()->PerformDragDrop(
      13, top_level_id, gfx::Point(),
      base::flat_map<std::string, std::vector<uint8_t>>(), gfx::ImageSkia(),
      gfx::Vector2d(), 0, ::ui::mojom::PointerKind::MOUSE);
  EXPECT_EQ("OnPerformDragDropCompleted id=13 success=false action=0",
            SingleChangeToDescription(*setup.changes()));

  // Let the posted drag loop task run.
  base::RunLoop().RunUntilIdle();

  // WindowServiceDelegate should be asked to run the drag loop.
  WindowServiceDelegate::DragDropCompletedCallback drag_loop_callback =
      setup.delegate()->TakeDragLoopCallback();
  ASSERT_TRUE(drag_loop_callback);

  // PerformDragDrop after the drop loop task runs should fail too because
  // the drag is not finished.
  setup.changes()->clear();
  setup.window_tree_test_helper()->window_tree()->PerformDragDrop(
      14, top_level_id, gfx::Point(),
      base::flat_map<std::string, std::vector<uint8_t>>(), gfx::ImageSkia(),
      gfx::Vector2d(), 0, ::ui::mojom::PointerKind::MOUSE);
  EXPECT_EQ("OnPerformDragDropCompleted id=14 success=false action=0",
            SingleChangeToDescription(*setup.changes()));

  // Finish the drop operation, client should be notified with success.
  setup.changes()->clear();
  std::move(drag_loop_callback).Run(ui::DragDropTypes::DRAG_MOVE);
  EXPECT_EQ("OnPerformDragDropCompleted id=12 success=true action=1",
            SingleChangeToDescription(*setup.changes()));
}

TEST(WindowTreeTest, CancelDragDrop) {
  WindowServiceTestSetup setup;
  aura::Window* top_level =
      setup.window_tree_test_helper()->NewTopLevelWindow();
  ASSERT_TRUE(top_level);
  top_level->Show();
  const Id top_level_id =
      setup.window_tree_test_helper()->TransportIdForWindow(top_level);
  setup.changes()->clear();
  setup.window_tree_test_helper()->window_tree()->PerformDragDrop(
      12, top_level_id, gfx::Point(),
      base::flat_map<std::string, std::vector<uint8_t>>(), gfx::ImageSkia(),
      gfx::Vector2d(), 0, ::ui::mojom::PointerKind::MOUSE);

  // Let the posted drag loop task run.
  base::RunLoop().RunUntilIdle();

  // WindowServiceDelegate should be asked to run the drag loop.
  WindowServiceDelegate::DragDropCompletedCallback drag_loop_callback =
      setup.delegate()->TakeDragLoopCallback();
  ASSERT_TRUE(drag_loop_callback);

  // Cancelling with an invalid id should do nothing.
  EXPECT_FALSE(setup.delegate()->cancel_drag_loop_called());
  setup.window_tree_test_helper()->window_tree()->CancelDragDrop(
      kInvalidTransportId);
  EXPECT_TRUE(setup.changes()->empty());
  EXPECT_FALSE(setup.delegate()->cancel_drag_loop_called());

  // Cancel with the real id should notify the delegate.
  EXPECT_FALSE(setup.delegate()->cancel_drag_loop_called());
  setup.window_tree_test_helper()->window_tree()->CancelDragDrop(top_level_id);
  EXPECT_TRUE(setup.delegate()->cancel_drag_loop_called());

  // No changes yet because the |drag_loop_callback| has not run.
  EXPECT_TRUE(setup.changes()->empty());

  // Run the closure to simulate drag cancel.
  std::move(drag_loop_callback).Run(ui::DragDropTypes::DRAG_NONE);
  EXPECT_EQ("OnPerformDragDropCompleted id=12 success=false action=0",
            SingleChangeToDescription(*setup.changes()));
}

TEST(WindowTreeTest, CancelDragDropBeforeDragLoopRun) {
  WindowServiceTestSetup setup;
  aura::Window* top_level =
      setup.window_tree_test_helper()->NewTopLevelWindow();
  ASSERT_TRUE(top_level);
  top_level->Show();
  const Id top_level_id =
      setup.window_tree_test_helper()->TransportIdForWindow(top_level);
  setup.changes()->clear();
  setup.window_tree_test_helper()->window_tree()->PerformDragDrop(
      12, top_level_id, gfx::Point(),
      base::flat_map<std::string, std::vector<uint8_t>>(), gfx::ImageSkia(),
      gfx::Vector2d(), 0, ::ui::mojom::PointerKind::MOUSE);

  // Cancel the drag before the drag loop task runs.
  EXPECT_FALSE(setup.delegate()->cancel_drag_loop_called());
  setup.window_tree_test_helper()->window_tree()->CancelDragDrop(top_level_id);
  EXPECT_TRUE(setup.delegate()->cancel_drag_loop_called());

  // Let the posted drag loop task run.
  base::RunLoop().RunUntilIdle();

  // WindowServiceDelegate should not be notified.
  WindowServiceDelegate::DragDropCompletedCallback drag_loop_callback =
      setup.delegate()->TakeDragLoopCallback();
  EXPECT_FALSE(drag_loop_callback);

  // The request should fail.
  EXPECT_EQ("OnPerformDragDropCompleted id=12 success=false action=0",
            SingleChangeToDescription(*setup.changes()));
}

TEST(WindowTreeTest, DsfChanges) {
  WindowServiceTestSetup setup;
  aura::Window* top_level =
      setup.window_tree_test_helper()->NewTopLevelWindow();
  ASSERT_TRUE(top_level);
  top_level->Show();
  ServerWindow* top_level_server_window = ServerWindow::GetMayBeNull(top_level);
  const base::Optional<viz::LocalSurfaceId> initial_surface_id =
      top_level_server_window->local_surface_id();
  EXPECT_TRUE(initial_surface_id);

  // Changing the scale factor should change the LocalSurfaceId.
  setup.aura_test_helper()->test_screen()->SetDeviceScaleFactor(2.0f);
  EXPECT_TRUE(top_level_server_window->local_surface_id());
  EXPECT_NE(*top_level_server_window->local_surface_id(), *initial_surface_id);
}

TEST(WindowTreeTest, DontSendGestures) {
  // Create a top-level and a child window.
  WindowServiceTestSetup setup;
  aura::Window* top_level =
      setup.window_tree_test_helper()->NewTopLevelWindow();
  ASSERT_TRUE(top_level);
  top_level->SetBounds(gfx::Rect(0, 0, 100, 100));
  top_level->Show();
  aura::Window* child_window = setup.window_tree_test_helper()->NewWindow();
  ASSERT_TRUE(child_window);
  top_level->AddChild(child_window);
  child_window->SetBounds(gfx::Rect(0, 0, 100, 100));
  child_window->Show();

  ui::test::EventGenerator event_generator(setup.root());
  // GestureTapAt() generates a touch down/up, and should not generate a gesture
  // because the Window Service consumes touch events (consuming touch events
  // results in no GestureEvents being generated). Additionally, gestures should
  // never be forwarded to the client, as it's assumed the client runs its own
  // gesture recognizer.
  event_generator.GestureTapAt(gfx::Point(10, 10));
  EXPECT_EQ("POINTER_DOWN",
            EventToEventType(
                setup.window_tree_client()->PopInputEvent().event.get()));
  EXPECT_EQ("POINTER_UP",
            EventToEventType(
                setup.window_tree_client()->PopInputEvent().event.get()));
  EXPECT_TRUE(setup.window_tree_client()->input_events().empty());
}

TEST(WindowTreeTest, DeactivateWindow) {
  // Create two top-levels and focuses (activates) the second.
  WindowServiceTestSetup setup;
  aura::Window* top_level1 =
      setup.window_tree_test_helper()->NewTopLevelWindow();
  ASSERT_TRUE(top_level1);
  top_level1->Show();
  aura::Window* top_level2 =
      setup.window_tree_test_helper()->NewTopLevelWindow();
  ASSERT_TRUE(top_level2);
  top_level2->Show();
  EXPECT_TRUE(setup.window_tree_test_helper()->SetFocus(top_level2));
  EXPECT_TRUE(wm::IsActiveWindow(top_level2));

  // Attempting to deactivate |top_level1| should do nothing.
  setup.window_tree_test_helper()->window_tree()->DeactivateWindow(
      setup.window_tree_test_helper()->TransportIdForWindow(top_level1));
  EXPECT_TRUE(wm::IsActiveWindow(top_level2));

  // Similarly, calling Deactivate() with an invalid id should do nothing.
  setup.window_tree_test_helper()->window_tree()->DeactivateWindow(
      kInvalidTransportId);
  EXPECT_TRUE(wm::IsActiveWindow(top_level2));

  // Deactivate() with |top_level2| should activate |top_level1|.
  setup.window_tree_test_helper()->window_tree()->DeactivateWindow(
      setup.window_tree_test_helper()->TransportIdForWindow(top_level2));
  EXPECT_TRUE(wm::IsActiveWindow(top_level1));
}

}  // namespace
}  // namespace ws
