// 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/bind.h"
#include "base/run_loop.h"
#include "base/unguessable_token.h"
#include "components/viz/common/surfaces/child_local_surface_id_allocator.h"
#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
#include "components/viz/host/host_frame_sink_manager.h"
#include "components/viz/test/fake_host_frame_sink_client.h"
#include "services/ws/client_root_test_helper.h"
#include "services/ws/event_test_utils.h"
#include "services/ws/proxy_window.h"
#include "services/ws/proxy_window_test_helper.h"
#include "services/ws/public/cpp/property_type_converters.h"
#include "services/ws/public/mojom/window_manager.mojom.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/env.h"
#include "ui/aura/layout_manager.h"
#include "ui/aura/mus/client_surface_embedder.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/test/test_window_parenting_client.h"
#include "ui/aura/test/window_occlusion_tracker_test_api.h"
#include "ui/aura/window.h"
#include "ui/aura/window_tracker.h"
#include "ui/base/hit_test.h"
#include "ui/events/mojo/event_constants.mojom.h"
#include "ui/events/test/event_generator.h"
#include "ui/gfx/transform.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()));
  ASSERT_TRUE((*setup.changes())[0].local_surface_id_allocation);
  EXPECT_TRUE((*setup.changes())[0].local_surface_id_allocation->IsValid());
  EXPECT_EQ(ProxyWindow::GetMayBeNull(top_level)->local_surface_id_allocation(),
            (*setup.changes())[0].local_surface_id_allocation);
}

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();
  ProxyWindow* top_level_proxy = ProxyWindow::GetMayBeNull(top_level);

  const gfx::Rect bounds_from_client = gfx::Rect(100, 200, 300, 400);
  viz::ChildLocalSurfaceIdAllocator child_allocator;
  child_allocator.UpdateFromParent(
      *top_level_proxy->local_surface_id_allocation());
  child_allocator.GenerateId();
  setup.window_tree_test_helper()->SetWindowBoundsWithAck(
      top_level, bounds_from_client,
      child_allocator.GetCurrentLocalSurfaceIdAllocation(), 2);
  EXPECT_EQ(bounds_from_client, top_level->GetBoundsInScreen());
  EXPECT_EQ("ChangeCompleted id=2 success=true",
            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].bounds);
  ASSERT_TRUE((*setup.changes())[0].local_surface_id_allocation);
  EXPECT_NE((*setup.changes())[0].local_surface_id_allocation,
            child_allocator.GetCurrentLocalSurfaceIdAllocation());
  EXPECT_EQ(top_level_proxy->local_surface_id_allocation(),
            (*setup.changes())[0].local_surface_id_allocation);
  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);
  child_allocator.GenerateId();
  setup.window_tree_test_helper()->SetWindowBoundsWithAck(
      top_level, bounds_from_client,
      child_allocator.GetCurrentLocalSurfaceIdAllocation(), 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].bounds);

  // 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.
  child_allocator.GenerateId();
  setup.window_tree_test_helper()->SetWindowBoundsWithAck(
      top_level, bounds_from_client,
      child_allocator.GetCurrentLocalSurfaceIdAllocation(), 4);
  EXPECT_EQ(bounds_from_client, top_level->GetBoundsInScreen());
  EXPECT_EQ(bounds_from_client - screen_offset, top_level->bounds());
  EXPECT_EQ("ChangeCompleted id=4 success=true",
            SingleChangeToDescription(*setup.changes()));

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

TEST(WindowTreeTest, SetTopLevelWindowBoundsSameSize) {
  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();
  ProxyWindow* top_level_proxy = ProxyWindow::GetMayBeNull(top_level);
  ASSERT_TRUE(top_level_proxy);
  ASSERT_TRUE(top_level_proxy->local_surface_id_allocation().has_value());
  viz::ChildLocalSurfaceIdAllocator child_allocator;
  child_allocator.UpdateFromParent(
      *top_level_proxy->local_surface_id_allocation());
  child_allocator.GenerateId();
  // WindowTreeTestHelper::SetWindowBounds() with same bounds should succeed.
  EXPECT_TRUE(setup.window_tree_test_helper()->SetWindowBounds(
      top_level, bounds, child_allocator.GetCurrentLocalSurfaceIdAllocation()));
  EXPECT_TRUE(setup.changes()->empty());
  ASSERT_TRUE(top_level_proxy->local_surface_id_allocation().has_value());
  EXPECT_EQ(child_allocator.GetCurrentLocalSurfaceIdAllocation(),
            *top_level_proxy->local_surface_id_allocation());
}

TEST(WindowTreeTest, SetTopLevelWindowBoundsBadEmbedToken) {
  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();
  ProxyWindow* top_level_proxy = ProxyWindow::GetMayBeNull(top_level);
  ASSERT_TRUE(top_level_proxy);
  ASSERT_TRUE(top_level_proxy->local_surface_id_allocation().has_value());
  const viz::LocalSurfaceId initial_lsia =
      top_level_proxy->local_surface_id_allocation()->local_surface_id();
  viz::LocalSurfaceIdAllocation lsia_with_different_embed_token(
      viz::LocalSurfaceId(initial_lsia.parent_sequence_number(),
                          initial_lsia.child_sequence_number(),
                          base::UnguessableToken::Create()),
      base::TimeTicks::Now());
  // Clients are not allowed to change the embed token.
  EXPECT_FALSE(setup.window_tree_test_helper()->SetWindowBounds(
      top_level, gfx::Rect(1, 2, 3, 4), lsia_with_different_embed_token));
  EXPECT_EQ(initial_lsia,
            top_level_proxy->local_surface_id_allocation()->local_surface_id());
  EXPECT_EQ(bounds, top_level->bounds());
  EXPECT_TRUE(setup.changes()->empty());
}

TEST(WindowTreeTest, UpdateLocalSurfaceIdFromChildBadEmbedToken) {
  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();
  ProxyWindow* top_level_proxy = ProxyWindow::GetMayBeNull(top_level);
  ASSERT_TRUE(top_level_proxy);
  ASSERT_TRUE(top_level_proxy->local_surface_id_allocation().has_value());
  const viz::LocalSurfaceId initial_lsia =
      top_level_proxy->local_surface_id_allocation()->local_surface_id();
  viz::LocalSurfaceIdAllocation lsia_with_different_embed_token(
      viz::LocalSurfaceId(initial_lsia.parent_sequence_number(),
                          initial_lsia.child_sequence_number(),
                          base::UnguessableToken::Create()),
      base::TimeTicks::Now());
  // Clients are not allowed to change the embed token.
  setup.window_tree_test_helper()->window_tree()->UpdateLocalSurfaceIdFromChild(
      setup.window_tree_test_helper()->TransportIdForWindow(top_level),
      lsia_with_different_embed_token);
  EXPECT_EQ(initial_lsia,
            top_level_proxy->local_surface_id_allocation()->local_surface_id());
  EXPECT_EQ(bounds, top_level->bounds());
  EXPECT_TRUE(setup.changes()->empty());
}

TEST(WindowTreeTest, UpdateLocalSurfaceIdFromScheduleEmbedWindow) {
  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 a window that will serve as the parent for the remote window and
  // complete the embedding.
  aura::Window local_window(nullptr);
  local_window.Init(ui::LAYER_NOT_DRAWN);
  local_window.SetBounds(gfx::Rect(1, 2, 3, 4));
  ASSERT_TRUE(setup.service()->CompleteScheduleEmbedForExistingClient(
      &local_window, token, /* embed_flags */ 0));
  EXPECT_TRUE(WindowService::IsProxyWindow(&local_window));

  // Call UpdateLocalSurfaceIdFromScheduleEmbedWindow() for the embedded window
  // and ensure the value is updated.
  ProxyWindow* local_window_proxy = ProxyWindow::GetMayBeNull(&local_window);
  ASSERT_TRUE(local_window_proxy);
  ASSERT_TRUE(local_window_proxy->local_surface_id_allocation().has_value());
  viz::ChildLocalSurfaceIdAllocator child_allocator;
  child_allocator.UpdateFromParent(
      *local_window_proxy->local_surface_id_allocation());
  child_allocator.GenerateId();
  setup.window_tree_test_helper()->window_tree()->UpdateLocalSurfaceIdFromChild(
      setup.window_tree_test_helper()->TransportIdForWindow(&local_window),
      child_allocator.GetCurrentLocalSurfaceIdAllocation());
  EXPECT_EQ(child_allocator.GetCurrentLocalSurfaceIdAllocation(),
            local_window_proxy->local_surface_id_allocation());
}

TEST(WindowTreeTest, SetTopLevelWindowBoundsNullSurfaceId) {
  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();
  // Server allows null LocalSurfaceIds, which is used on the initial resize
  // from the client.
  EXPECT_TRUE(
      setup.window_tree_test_helper()->SetWindowBounds(top_level, bounds));
  // The server always responds with a bounds change when the client changes the
  // bounds and does not supply a LocalSurfaceId.
  ASSERT_FALSE(setup.changes()->empty());
  const auto& change = (*setup.changes())[0];
  EXPECT_EQ(CHANGE_TYPE_NODE_BOUNDS_CHANGED, change.type);
  EXPECT_EQ(setup.window_tree_test_helper()->TransportIdForWindow(top_level),
            change.window_id);
  EXPECT_TRUE(change.local_surface_id_allocation);
  EXPECT_EQ(bounds, change.bounds);
}

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::LocalSurfaceIdAllocation> local_surface_id_allocation(
      viz::LocalSurfaceIdAllocation(
          viz::LocalSurfaceId(1, 2, base::UnguessableToken::Create()),
          base::TimeTicks::Now()));
  EXPECT_TRUE(setup.window_tree_test_helper()->SetWindowBounds(
      window, bounds2, local_surface_id_allocation));
  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.bounds);
  EXPECT_EQ(local_surface_id_allocation,
            bounds_change.local_surface_id_allocation);
  embedding_helper->window_tree_client.tracker()->changes()->clear();

  // Set the bounds from the parent, only updating the LocalSurfaceId (bounds
  // remains the same). The client should be notified.
  base::Optional<viz::LocalSurfaceIdAllocation> local_surface_id_allocation2(
      viz::LocalSurfaceIdAllocation(
          viz::LocalSurfaceId(1, 3, base::UnguessableToken::Create()),
          base::TimeTicks::Now()));
  EXPECT_TRUE(setup.window_tree_test_helper()->SetWindowBounds(
      window, bounds2, local_surface_id_allocation2));
  EXPECT_EQ(bounds2, window->bounds());
  ASSERT_EQ(1u,
            embedding_helper->window_tree_client.tracker()->changes()->size());
  const Change bounds_change2 =
      (*(embedding_helper->window_tree_client.tracker()->changes()))[0];
  EXPECT_EQ(CHANGE_TYPE_NODE_BOUNDS_CHANGED, bounds_change2.type);
  EXPECT_EQ(bounds2, bounds_change2.bounds);
  EXPECT_EQ(local_surface_id_allocation2,
            bounds_change2.local_surface_id_allocation);
  embedding_helper->window_tree_client.tracker()->changes()->clear();

  // Try again with the same values. This should succeed, but not notify the
  // client.
  EXPECT_TRUE(setup.window_tree_test_helper()->SetWindowBounds(
      window, bounds2, local_surface_id_allocation2));
  EXPECT_TRUE(
      embedding_helper->window_tree_client.tracker()->changes()->empty());
}

// 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, OnWindowInputEventAck) {
  WindowServiceTestSetup setup;
  setup.set_ack_events_immediately(false);
  TestWindowTreeClient* window_tree_client = setup.window_tree_client();
  WindowTreeTestHelper* tree = setup.window_tree_test_helper();
  aura::Window* top_level = tree->NewTopLevelWindow();
  ASSERT_TRUE(top_level);

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

  // Send a key event and a mouse event to the client.
  ui::test::EventGenerator event_generator(setup.root());
  event_generator.PressKey(ui::VKEY_A, ui::EF_NONE);
  event_generator.MoveMouseTo(10, 10);
  ASSERT_EQ(2u, window_tree_client->input_events().size());
  TestWindowTreeClient::InputEvent event1 = window_tree_client->PopInputEvent();
  ASSERT_TRUE(event1.event->IsKeyEvent());
  TestWindowTreeClient::InputEvent event2 = window_tree_client->PopInputEvent();
  ASSERT_TRUE(event2.event->IsLocatedEvent());

  // Acking the events in the order they were received works fine.
  EXPECT_EQ(1u, tree->in_flight_key_events().size());
  tree->OnWindowInputEventAck(event1.event_id, ws::mojom::EventResult::HANDLED);
  EXPECT_EQ(0u, tree->in_flight_key_events().size());
  EXPECT_EQ(1u, tree->in_flight_other_events().size());
  tree->OnWindowInputEventAck(event2.event_id, ws::mojom::EventResult::HANDLED);
  EXPECT_EQ(0u, tree->in_flight_other_events().size());

  // Send another key event and a mouse event.
  event_generator.ReleaseKey(ui::VKEY_A, ui::EF_NONE);
  event_generator.MoveMouseTo(11, 11);
  ASSERT_EQ(2u, window_tree_client->input_events().size());
  TestWindowTreeClient::InputEvent event3 = window_tree_client->PopInputEvent();
  ASSERT_TRUE(event3.event->IsKeyEvent());
  TestWindowTreeClient::InputEvent event4 = window_tree_client->PopInputEvent();
  ASSERT_TRUE(event4.event->IsLocatedEvent());

  // Acking the mouse and key events out of order from one another is okay.
  EXPECT_EQ(1u, tree->in_flight_other_events().size());
  tree->OnWindowInputEventAck(event4.event_id, ws::mojom::EventResult::HANDLED);
  EXPECT_EQ(0u, tree->in_flight_other_events().size());
  EXPECT_EQ(1u, tree->in_flight_key_events().size());
  tree->OnWindowInputEventAck(event3.event_id, ws::mojom::EventResult::HANDLED);
  EXPECT_EQ(0u, tree->in_flight_key_events().size());

  // Send two more mouse events.
  event_generator.MoveMouseTo(12, 12);
  event_generator.MoveMouseTo(13, 13);
  ASSERT_EQ(2u, window_tree_client->input_events().size());
  TestWindowTreeClient::InputEvent event5 = window_tree_client->PopInputEvent();
  ASSERT_TRUE(event5.event->IsLocatedEvent());
  TestWindowTreeClient::InputEvent event6 = window_tree_client->PopInputEvent();
  ASSERT_TRUE(event6.event->IsLocatedEvent());

  // The client cannot ack the second mouse event before the first.
  EXPECT_EQ(2u, tree->in_flight_other_events().size());
  tree->OnWindowInputEventAck(event6.event_id, ws::mojom::EventResult::HANDLED);
  EXPECT_EQ(2u, tree->in_flight_other_events().size());

  // Send a key-press.
  event_generator.PressKey(ui::VKEY_A, ui::EF_NONE);
  ASSERT_EQ(1u, window_tree_client->input_events().size());
  TestWindowTreeClient::InputEvent event7 = window_tree_client->PopInputEvent();
  ASSERT_TRUE(event7.event->IsKeyEvent());
  // Acking the wrong event should be ignored.
  tree->OnWindowInputEventAck(event7.event_id + 11,
                              ws::mojom::EventResult::HANDLED);
  EXPECT_EQ(1u, tree->in_flight_key_events().size());
}

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("MOUSE_MOVED 40,40",
            LocatedEventToEventTypeAndLocation(
                window_tree_client->PopInputEvent().event.get()));

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

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

  event_generator.ReleaseLeftButton();
  EXPECT_EQ("MOUSE_RELEASED -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_screen_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_screen_location(gfx::Point(50, 51));
  event_generator.PressTouch();
  EXPECT_EQ("ET_TOUCH_PRESSED 40,40",
            LocatedEventToEventTypeAndLocation(
                window_tree_client->PopInputEvent().event.get()));

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

  event_generator.ReleaseTouch();
  EXPECT_EQ("ET_TOUCH_RELEASED -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("MOUSE_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("MOUSE_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("MOUSE_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("MOUSE_PRESSED 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("MOUSE_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, SetHitTestInsets) {
  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 the hit test insets in the window's bounds that excludes the top half.
  setup.window_tree_test_helper()->SetHitTestInsets(
      top_level, gfx::Insets(50, 0, 0, 0), gfx::Insets(50, 0, 0, 0));

  // Events outside the hit test insets 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 insets are seen by the delegate and client.
  event_generator.MoveMouseTo(50, 80);
  EXPECT_EQ("MOUSE_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, EventObserver) {
  WindowServiceTestSetup setup;
  TestWindowTreeClient* window_tree_client = setup.window_tree_client();
  aura::Window* top_level =
      setup.window_tree_test_helper()->NewTopLevelWindow();
  ASSERT_TRUE(top_level);
  // Start observing mouse press and release.
  setup.window_tree_test_helper()->window_tree()->ObserveEventTypes(
      {ui::mojom::EventType::MOUSE_PRESSED_EVENT,
       ui::mojom::EventType::MOUSE_RELEASED_EVENT});

  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_events().empty());

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

  event_generator.PressLeftButton();
  EXPECT_EQ("MOUSE_PRESSED 5,6",
            LocatedEventToEventTypeAndLocation(
                window_tree_client->PopObservedEvent().get()));

  event_generator.ReleaseLeftButton();
  EXPECT_EQ("MOUSE_RELEASED 5,6",
            LocatedEventToEventTypeAndLocation(
                window_tree_client->PopObservedEvent().get()));

  // Start also observing mouse move events.
  setup.window_tree_test_helper()->window_tree()->ObserveEventTypes(
      {ui::mojom::EventType::MOUSE_PRESSED_EVENT,
       ui::mojom::EventType::MOUSE_RELEASED_EVENT,
       ui::mojom::EventType::MOUSE_MOVED_EVENT});
  event_generator.MoveMouseTo(8, 9);
  EXPECT_EQ("MOUSE_MOVED 8,9",
            LocatedEventToEventTypeAndLocation(
                window_tree_client->PopObservedEvent().get()));
}

TEST(WindowTreeTest, MatchesEventObserverSet) {
  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 observing touch press and release.
  setup.window_tree_test_helper()->window_tree()->ObserveEventTypes(
      {ui::mojom::EventType::TOUCH_PRESSED,
       ui::mojom::EventType::TOUCH_RELEASED});

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

  // The client should get the input event, and |matches_event_observer| should
  // be true (because it also matched the event observer).
  TestWindowTreeClient::InputEvent press_input =
      window_tree_client->PopInputEvent();
  ASSERT_TRUE(press_input.event);
  EXPECT_EQ("ET_TOUCH_PRESSED 40,40",
            LocatedEventToEventTypeAndLocation(press_input.event.get()));
  EXPECT_TRUE(press_input.matches_event_observer);
  // The event targeted the client, so there are no separately observed events.
  EXPECT_TRUE(window_tree_client->observed_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, CaptureDisallowedWhenEmbedderInterceptsEvents) {
  WindowServiceTestSetup setup;
  aura::Window* top_level =
      setup.window_tree_test_helper()->NewTopLevelWindow();
  ASSERT_TRUE(top_level);
  top_level->Show();
  aura::Window* window = setup.window_tree_test_helper()->NewWindow();
  top_level->AddChild(window);
  window->Show();
  std::unique_ptr<EmbeddingHelper> embedding_helper =
      setup.CreateEmbedding(window, mojom::kEmbedFlagEmbedderInterceptsEvents);
  ASSERT_TRUE(embedding_helper);
  EXPECT_FALSE(embedding_helper->window_tree_test_helper->SetCapture(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("MOUSE_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(
      "MOUSE_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("MOUSE_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("MOUSE_DRAGGED -4,-4",
            LocatedEventToEventTypeAndLocation(drag_event.event.get()));
}

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();
  ProxyWindow* top_level_proxy_window = ProxyWindow::GetMayBeNull(top_level);
  ASSERT_TRUE(top_level_proxy_window);
  ProxyWindowTestHelper top_level_proxy_window_helper(top_level_proxy_window);
  EXPECT_TRUE(top_level_proxy_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_proxy_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();
  ProxyWindow* top_level_proxy_window = ProxyWindow::GetMayBeNull(top_level);
  ASSERT_TRUE(top_level_proxy_window);
  ProxyWindowTestHelper top_level_proxy_window_helper(top_level_proxy_window);
  EXPECT_TRUE(top_level_proxy_window_helper.IsHandlingPointerPress(
      ui::MouseEvent::kMousePointerId));

  // Hiding should implicitly cancel capture.
  top_level->Hide();
  EXPECT_FALSE(top_level_proxy_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(ProxyWindow::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(ProxyWindow::GetMayBeNull(window_in_parent)->HasEmbedding());

  tree2.reset();
  EXPECT_FALSE(ProxyWindow::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;
  // This test acks its own events.
  setup.set_ack_events_immediately(false);
  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, VisibilityChanged) {
  WindowServiceTestSetup setup;
  aura::Window* window = setup.window_tree_test_helper()->NewTopLevelWindow();
  setup.changes()->clear();
  EXPECT_FALSE(window->IsVisible());

  window->Show();
  EXPECT_TRUE(window->IsVisible());
  EXPECT_EQ("VisibilityChanged window=0,1 visible=true",
            SingleChangeToDescription(*setup.changes()));
}

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(), HTCAPTION);
  // |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.changes()->clear();
  setup.window_tree_test_helper()->window_tree()->PerformWindowMove(
      13, top_level_id, mojom::MoveLoopSource::TOUCH, gfx::Point(), HTCAPTION);
  // 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(), HTCAPTION);
  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(), HTCAPTION);
  // 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(), HTCAPTION);
  // 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(), HTCAPTION);

  // 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();
  ProxyWindow* top_level_proxy_window = ProxyWindow::GetMayBeNull(top_level);
  const base::Optional<viz::LocalSurfaceIdAllocation>
      initial_surface_id_allocation =
          top_level_proxy_window->local_surface_id_allocation();
  EXPECT_TRUE(initial_surface_id_allocation);

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

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("ET_TOUCH_PRESSED",
            EventToEventType(
                setup.window_tree_client()->PopInputEvent().event.get()));
  EXPECT_EQ("ET_TOUCH_RELEASED",
            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));
}

TEST(WindowTreeTest, AttachFrameSinkId) {
  // Create two top-levels and focuses (activates) the second.
  WindowServiceTestSetup setup;
  aura::Window* top_level =
      setup.window_tree_test_helper()->NewTopLevelWindow();
  ASSERT_TRUE(top_level);
  top_level->Show();

  aura::Window* child_window = setup.window_tree_test_helper()->NewWindow();
  ASSERT_TRUE(child_window);
  viz::FrameSinkId test_frame_sink_id(101, 102);
  viz::HostFrameSinkManager* host_frame_sink_manager =
      child_window->env()->context_factory_private()->GetHostFrameSinkManager();

  // Attach a frame sink to |child_window|. This shouldn't immediately register.
  setup.window_tree_test_helper()->window_tree()->AttachFrameSinkId(
      setup.window_tree_test_helper()->TransportIdForWindow(child_window),
      test_frame_sink_id);
  EXPECT_FALSE(
      host_frame_sink_manager->IsFrameSinkIdRegistered(test_frame_sink_id));

  // Add the window to a parent, which should trigger registering the hierarchy.
  viz::FakeHostFrameSinkClient test_host_frame_sink_client;
  host_frame_sink_manager->RegisterFrameSinkId(
      test_frame_sink_id, &test_host_frame_sink_client,
      viz::ReportFirstSurfaceActivation::kYes);
  EXPECT_EQ(test_frame_sink_id,
            ProxyWindow::GetMayBeNull(child_window)->attached_frame_sink_id());
  top_level->AddChild(child_window);
  EXPECT_TRUE(host_frame_sink_manager->IsFrameSinkHierarchyRegistered(
      ProxyWindow::GetMayBeNull(top_level)->frame_sink_id(),
      test_frame_sink_id));

  // Removing the window should remove the association.
  top_level->RemoveChild(child_window);
  EXPECT_FALSE(host_frame_sink_manager->IsFrameSinkHierarchyRegistered(
      ProxyWindow::GetMayBeNull(top_level)->frame_sink_id(),
      test_frame_sink_id));

  setup.window_tree_test_helper()->DeleteWindow(child_window);

  host_frame_sink_manager->InvalidateFrameSinkId(test_frame_sink_id);
}

TEST(WindowTreeTest, OcclusionStateChange) {
  WindowServiceTestSetup setup;

  // Create |tracked| and tracks its occlusion state.
  aura::Window* tracked = setup.window_tree_test_helper()->NewTopLevelWindow();
  ASSERT_TRUE(tracked);
  tracked->SetBounds(gfx::Rect(0, 0, 10, 10));

  tracked->TrackOcclusionState();

  // Gets HIDDEN state since |tracked| is created hidden.
  EXPECT_TRUE(ContainsChange(
      *setup.changes(),
      "OnOcclusionStatesChanged {{window_id=0,1, state=HIDDEN}}"));

  // Gets VISIBLE state when |tracked| is shown.
  tracked->Show();
  EXPECT_TRUE(ContainsChange(
      *setup.changes(),
      "OnOcclusionStatesChanged {{window_id=0,1, state=VISIBLE}}"));

  // Creates |blocking_window| and make it occlude |tracked|.
  aura::Window* blocking_window =
      setup.window_tree_test_helper()->NewTopLevelWindow();
  ASSERT_TRUE(blocking_window);
  blocking_window->SetProperty(aura::client::kWindowLayerDrawn, true);
  blocking_window->SetBounds(gfx::Rect(0, 0, 15, 15));
  blocking_window->Show();

  // Gets OCCLUDED state since |blocking_window| covers |tracked|.
  EXPECT_TRUE(ContainsChange(
      *setup.changes(),
      "OnOcclusionStatesChanged {{window_id=0,1, state=OCCLUDED}}"));
}

TEST(WindowTreeTest, OcclusionStateChangeBatchSameTree) {
  WindowServiceTestSetup setup;

  // Create two tracked windows and tracks their occlusion state.
  aura::Window* tracked_1 =
      setup.window_tree_test_helper()->NewTopLevelWindow();
  ASSERT_TRUE(tracked_1);
  tracked_1->SetBounds(gfx::Rect(0, 0, 10, 10));
  tracked_1->TrackOcclusionState();
  tracked_1->Show();

  aura::Window* tracked_2 =
      setup.window_tree_test_helper()->NewTopLevelWindow();
  ASSERT_TRUE(tracked_2);
  tracked_2->SetBounds(gfx::Rect(10, 0, 10, 10));
  tracked_2->TrackOcclusionState();
  tracked_2->Show();

  // Creates |blocking_window| and make it occlude both tracked windows.
  aura::Window* blocking_window =
      setup.window_tree_test_helper()->NewTopLevelWindow();
  ASSERT_TRUE(blocking_window);
  blocking_window->SetProperty(aura::client::kWindowLayerDrawn, true);
  blocking_window->SetBounds(gfx::Rect(0, 0, 20, 15));
  blocking_window->Show();

  // Occlusion changes of windows for the same tree are sent together.
  EXPECT_TRUE(
      ContainsChange(*setup.changes(),
                     "OnOcclusionStatesChanged {{window_id=0,1, "
                     "state=OCCLUDED}, {window_id=0,2, state=OCCLUDED}}"));
}

TEST(WindowTreeTest, OcclusionStateChangeBatchDifferentTree) {
  WindowServiceTestSetup setup;

  // Create |tracked_1| from default tree.
  aura::Window* tracked_1 =
      setup.window_tree_test_helper()->NewTopLevelWindow(100);
  ASSERT_TRUE(tracked_1);
  tracked_1->SetBounds(gfx::Rect(0, 0, 10, 10));
  tracked_1->TrackOcclusionState();
  tracked_1->Show();

  // Create |tracked_2| from a second tree.
  TestWindowTreeClient client2;
  std::unique_ptr<WindowTree> tree2 =
      setup.service()->CreateWindowTree(&client2);
  tree2->InitFromFactory();
  WindowTreeTestHelper tree2_test_helper(tree2.get());

  aura::Window* tracked_2 = tree2_test_helper.NewTopLevelWindow(200);
  ASSERT_TRUE(tracked_2);
  tracked_2->SetBounds(gfx::Rect(10, 0, 10, 10));
  tracked_2->TrackOcclusionState();
  tracked_2->Show();

  // Creates |blocking_window| and make it occlude both tracked windows.
  aura::Window* blocking_window =
      setup.window_tree_test_helper()->NewTopLevelWindow();
  ASSERT_TRUE(blocking_window);
  blocking_window->SetProperty(aura::client::kWindowLayerDrawn, true);
  blocking_window->SetBounds(gfx::Rect(0, 0, 20, 15));
  blocking_window->Show();

  // Occlusion changes are sent separately for different trees.
  EXPECT_TRUE(ContainsChange(*setup.changes(),
                             "OnOcclusionStatesChanged {{window_id=0,100, "
                             "state=OCCLUDED}}"));
  EXPECT_TRUE(ContainsChange(*client2.tracker()->changes(),
                             "OnOcclusionStatesChanged {{window_id=0,200, "
                             "state=OCCLUDED}}"));
}

TEST(WindowTreeTest, OcclusionTrackingPause) {
  WindowServiceTestSetup setup;
  aura::test::WindowOcclusionTrackerTestApi tracker_api(
      setup.service()->env()->GetWindowOcclusionTracker());
  ASSERT_FALSE(tracker_api.IsPaused());

  // Simple case of one pause.
  setup.window_tree_test_helper()
      ->window_tree()
      ->PauseWindowOcclusionTracking();
  EXPECT_TRUE(tracker_api.IsPaused());
  setup.window_tree_test_helper()
      ->window_tree()
      ->UnpauseWindowOcclusionTracking();
  EXPECT_FALSE(tracker_api.IsPaused());

  // Multiple pauses.
  constexpr int kPauses = 3;
  for (int i = 0; i < kPauses; ++i) {
    setup.window_tree_test_helper()
        ->window_tree()
        ->PauseWindowOcclusionTracking();
    EXPECT_TRUE(tracker_api.IsPaused());
  }
  for (int i = 0; i < kPauses - 1; ++i) {
    setup.window_tree_test_helper()
        ->window_tree()
        ->UnpauseWindowOcclusionTracking();
    EXPECT_TRUE(tracker_api.IsPaused());
  }
  setup.window_tree_test_helper()
      ->window_tree()
      ->UnpauseWindowOcclusionTracking();
  EXPECT_FALSE(tracker_api.IsPaused());
}

TEST(WindowTreeTest, OcclusionTrackingPauseInterleaved) {
  WindowServiceTestSetup setup;
  aura::test::WindowOcclusionTrackerTestApi tracker_api(
      setup.service()->env()->GetWindowOcclusionTracker());
  ASSERT_FALSE(tracker_api.IsPaused());

  // Creates a second WindowTree.
  TestWindowTreeClient tree_client;
  std::unique_ptr<WindowTree> tree2 =
      setup.service()->CreateWindowTree(&tree_client);
  tree2->InitFromFactory();
  auto helper2 = std::make_unique<WindowTreeTestHelper>(tree2.get());

  // Tree1 pauses.
  setup.window_tree_test_helper()
      ->window_tree()
      ->PauseWindowOcclusionTracking();
  EXPECT_TRUE(tracker_api.IsPaused());

  // Tree2 pauses.
  helper2->window_tree()->PauseWindowOcclusionTracking();
  EXPECT_TRUE(tracker_api.IsPaused());

  // Tree1 unpauses.
  setup.window_tree_test_helper()
      ->window_tree()
      ->UnpauseWindowOcclusionTracking();
  EXPECT_TRUE(tracker_api.IsPaused());

  // Tree2 unpauses
  helper2->window_tree()->UnpauseWindowOcclusionTracking();
  EXPECT_FALSE(tracker_api.IsPaused());
}

TEST(WindowTreeTest, OcclusionTrackingPauseGoingAwayTree) {
  WindowServiceTestSetup setup;
  aura::test::WindowOcclusionTrackerTestApi tracker_api(
      setup.service()->env()->GetWindowOcclusionTracker());
  ASSERT_FALSE(tracker_api.IsPaused());

  // Tree1 pauses.
  setup.window_tree_test_helper()
      ->window_tree()
      ->PauseWindowOcclusionTracking();
  EXPECT_TRUE(tracker_api.IsPaused());

  // Creates a second WindowTree.
  TestWindowTreeClient tree_client;
  std::unique_ptr<WindowTree> tree2 =
      setup.service()->CreateWindowTree(&tree_client);
  tree2->InitFromFactory();
  auto helper2 = std::make_unique<WindowTreeTestHelper>(tree2.get());

  // Tree2 creates an outstanding pause.
  helper2->window_tree()->PauseWindowOcclusionTracking();
  EXPECT_TRUE(tracker_api.IsPaused());

  // Tree2 goes away with the outstanding pause.
  helper2.reset();
  tree2.reset();

  // Still paused because tree1 still holds a pause.
  EXPECT_TRUE(tracker_api.IsPaused());

  // Tree1 releases the pause and tracker is unpaused.
  setup.window_tree_test_helper()
      ->window_tree()
      ->UnpauseWindowOcclusionTracking();
  EXPECT_FALSE(tracker_api.IsPaused());
}

// Forces window visibility to a target value in OnWindowVisibilityChanged().
// This mimics MultiUserWindowManager in ash.
class WindowVisibilityEnforcer : public aura::WindowObserver {
 public:
  WindowVisibilityEnforcer(aura::Window* window, bool target_visibility)
      : window_(window), target_visibility_(target_visibility) {
    window_->AddObserver(this);
  }
  ~WindowVisibilityEnforcer() override { StopObservering(); }

  // aura::WindowObserver:
  void OnWindowVisibilityChanged(aura::Window* window, bool visible) override {
    if (visible == target_visibility_)
      return;

    if (target_visibility_)
      window->Show();
    else
      window->Hide();
  }
  void OnWindowDestroying(aura::Window* window) override { StopObservering(); }

 private:
  void StopObservering() {
    if (!window_)
      return;
    window_->RemoveObserver(this);
    window_ = nullptr;
  }

  aura::Window* window_;
  const bool target_visibility_;

  DISALLOW_COPY_AND_ASSIGN(WindowVisibilityEnforcer);
};

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

  // WindowVisibilityEnforcer ensures the window remains hidden.
  std::unique_ptr<WindowVisibilityEnforcer> enforcer =
      std::make_unique<WindowVisibilityEnforcer>(top_level, false);
  // Attempting to show the window should fail because WindowVisibilityEnforcer
  // forces the window to remain hidden.
  EXPECT_FALSE(
      setup.window_tree_test_helper()->SetWindowVisibility(top_level, true));
  EXPECT_FALSE(top_level->IsVisible());
  // The client should not be notified of anything (returning false is enough).
  EXPECT_TRUE(setup.changes()->empty());

  // Destroy the enforcer and make the window visible.
  enforcer.reset();
  EXPECT_TRUE(
      setup.window_tree_test_helper()->SetWindowVisibility(top_level, true));
  EXPECT_TRUE(top_level->IsVisible());
  EXPECT_TRUE(setup.changes()->empty());

  // Create another enforcer that forces the window to remain visible.
  enforcer = std::make_unique<WindowVisibilityEnforcer>(top_level, true);
  // Attempting to hide the window should fail because WindowVisibilityEnforcer
  // forces the window to remain visible.
  EXPECT_FALSE(
      setup.window_tree_test_helper()->SetWindowVisibility(top_level, false));
  EXPECT_TRUE(top_level->IsVisible());
  EXPECT_TRUE(setup.changes()->empty());
}

TEST(WindowTreeTest, SetWindowTransform) {
  WindowServiceTestSetup setup;
  aura::Window* top_level =
      setup.window_tree_test_helper()->NewTopLevelWindow();
  setup.changes()->clear();
  gfx::Transform scaled;
  scaled.Scale(2, 2);
  EXPECT_FALSE(
      setup.window_tree_test_helper()->SetTransform(top_level, scaled));
  EXPECT_EQ(gfx::Transform(), top_level->transform());

  aura::Window* child_window = setup.window_tree_test_helper()->NewWindow();
  EXPECT_TRUE(
      setup.window_tree_test_helper()->SetTransform(child_window, scaled));
  EXPECT_EQ(scaled, child_window->transform());
}

TEST(WindowTreeTest, AddingTransientGoesThroughParentingClient) {
  WindowServiceTestSetup setup;
  aura::test::TestWindowParentingClient test_window_parenting_client(
      setup.aura_test_helper()->root_window());
  WindowTreeTestHelper* helper = setup.window_tree_test_helper();
  aura::Window* top_level = helper->NewTopLevelWindow();
  ASSERT_TRUE(top_level);
  aura::Window* transient = helper->NewTopLevelWindow();
  ASSERT_TRUE(transient);

  // Put |top_level| in |container|.
  aura::Window container(nullptr);
  container.Init(ui::LAYER_NOT_DRAWN);
  top_level->parent()->AddChild(&container);
  container.AddChild(top_level);
  test_window_parenting_client.set_default_parent(&container);
  EXPECT_NE(&container, transient->parent());

  // AddTransientWindow() should trigger calling into the WindowParentingClient,
  // which will result in adding |transient| as a child of |container|.
  helper->window_tree()->AddTransientWindow(
      10, helper->TransportIdForWindow(top_level),
      helper->TransportIdForWindow(transient));
  EXPECT_EQ(&container, transient->parent());
}

}  // namespace
}  // namespace ws
