// Copyright 2015 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 "ui/aura/mus/window_tree_client.h"

#include <stdint.h>

#include <utility>

#include "base/bind.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/stl_util.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "cc/base/switches.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/common/surfaces/surface_info.h"
#include "mojo/public/cpp/bindings/map.h"
#include "services/ws/public/cpp/property_type_converters.h"
#include "services/ws/public/mojom/window_manager.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/client/capture_client.h"
#include "ui/aura/client/capture_client_observer.h"
#include "ui/aura/client/default_capture_client.h"
#include "ui/aura/client/focus_client.h"
#include "ui/aura/client/transient_window_client.h"
#include "ui/aura/mus/capture_synchronizer.h"
#include "ui/aura/mus/client_surface_embedder.h"
#include "ui/aura/mus/embed_root.h"
#include "ui/aura/mus/embed_root_delegate.h"
#include "ui/aura/mus/focus_synchronizer.h"
#include "ui/aura/mus/mus_lsi_allocator.h"
#include "ui/aura/mus/property_converter.h"
#include "ui/aura/mus/window_mus.h"
#include "ui/aura/mus/window_port_mus.h"
#include "ui/aura/mus/window_tree_client_delegate.h"
#include "ui/aura/mus/window_tree_client_observer.h"
#include "ui/aura/mus/window_tree_host_mus.h"
#include "ui/aura/mus/window_tree_host_mus_init_params.h"
#include "ui/aura/test/aura_mus_test_base.h"
#include "ui/aura/test/mus/test_window_tree.h"
#include "ui/aura/test/mus/window_port_mus_test_helper.h"
#include "ui/aura/test/mus/window_tree_client_test_api.h"
#include "ui/aura/test/test_screen.h"
#include "ui/aura/test/test_window_delegate.h"
#include "ui/aura/test/test_window_targeter.h"
#include "ui/aura/window.h"
#include "ui/aura/window_targeter.h"
#include "ui/aura/window_tracker.h"
#include "ui/aura/window_tree_host_observer.h"
#include "ui/base/class_property.h"
#include "ui/base/ui_base_features.h"
#include "ui/base/ui_base_switches.h"
#include "ui/compositor/compositor.h"
#include "ui/display/display.h"
#include "ui/display/display_switches.h"
#include "ui/display/screen.h"
#include "ui/events/event.h"
#include "ui/events/event_observer.h"
#include "ui/events/event_utils.h"
#include "ui/events/test/test_event_handler.h"
#include "ui/gfx/geometry/dip_util.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/transform.h"

namespace aura {

namespace {

DEFINE_UI_CLASS_PROPERTY_KEY(uint8_t, kTestPropertyKey1, 0)
DEFINE_UI_CLASS_PROPERTY_KEY(uint16_t, kTestPropertyKey2, 0)
DEFINE_UI_CLASS_PROPERTY_KEY(bool, kTestPropertyKey3, false)
DEFINE_UI_CLASS_PROPERTY_KEY(Window*, kTestPropertyKey4, nullptr)

const char kTestPropertyServerKey1[] = "test-property-server1";
const char kTestPropertyServerKey2[] = "test-property-server2";
const char kTestPropertyServerKey3[] = "test-property-server3";
const char kTestPropertyServerKey4[] = "test-property-server4";

ws::Id server_id(Window* window) {
  return window ? WindowMus::Get(window)->server_id() : 0;
}

std::unique_ptr<Window> CreateWindowUsingId(
    WindowTreeClient* window_tree_client,
    ws::Id server_id,
    Window* parent = nullptr) {
  ws::mojom::WindowData window_data;
  window_data.window_id = server_id;
  WindowMus* window_mus =
      WindowTreeClientTestApi(window_tree_client)
          .NewWindowFromWindowData(WindowMus::Get(parent), window_data);
  // WindowTreeClient implicitly creates the Window but doesn't own it.
  // Pass ownership to the caller.
  return base::WrapUnique<Window>(window_mus->GetWindow());
}

void SetWindowVisibility(Window* window, bool visible) {
  if (visible)
    window->Show();
  else
    window->Hide();
}

bool IsWindowHostVisible(Window* window) {
  return window->GetRootWindow()->GetHost()->compositor()->IsVisible();
}

// Register some test window properties for aura/mus conversion.
void RegisterTestProperties(PropertyConverter* converter) {
  converter->RegisterPrimitiveProperty(
      kTestPropertyKey1, kTestPropertyServerKey1,
      PropertyConverter::CreateAcceptAnyValueCallback());
  converter->RegisterPrimitiveProperty(
      kTestPropertyKey2, kTestPropertyServerKey2,
      PropertyConverter::CreateAcceptAnyValueCallback());
  converter->RegisterPrimitiveProperty(
      kTestPropertyKey3, kTestPropertyServerKey3,
      PropertyConverter::CreateAcceptAnyValueCallback());
  converter->RegisterWindowPtrProperty(kTestPropertyKey4,
                                       kTestPropertyServerKey4);
}

// Convert a primitive aura property value to a mus transport value.
// Note that this implicitly casts arguments to the aura storage type, int64_t.
std::vector<uint8_t> ConvertToPropertyTransportValue(int64_t value) {
  return mojo::ConvertTo<std::vector<uint8_t>>(value);
}

void OnWindowMoveDone(int* call_count, bool* last_result, bool result) {
  (*call_count)++;
  *last_result = result;
}

// A simple event observer that records the last observed event.
class TestEventObserver : public ui::EventObserver {
 public:
  TestEventObserver() = default;
  ~TestEventObserver() override = default;

  const ui::Event* last_event() const { return last_event_.get(); }
  void ResetLastEvent() { last_event_.reset(); }

 private:
  // ui::EventObserver:
  void OnEvent(const ui::Event& event) override {
    last_event_ = ui::Event::Clone(event);
  }

  std::unique_ptr<ui::Event> last_event_;

  DISALLOW_COPY_AND_ASSIGN(TestEventObserver);
};

}  // namespace

class WindowTreeClientTest : public test::AuraMusClientTestBase {
 public:
  WindowTreeClientTest() = default;
  ~WindowTreeClientTest() override = default;

  struct TopLevel {
    std::unique_ptr<client::DefaultCaptureClient> capture_client;
    std::unique_ptr<WindowTreeHostMus> host;
  };

  void CreateCaptureClientForTopLevel(TopLevel* top_level) {
    top_level->capture_client =
        std::make_unique<client::DefaultCaptureClient>();
    client::SetCaptureClient(top_level->host->window(),
                             top_level->capture_client.get());
    window_tree_client_impl()->capture_synchronizer()->AttachToCaptureClient(
        top_level->capture_client.get());
  }

  viz::LocalSurfaceIdAllocation GenerateLocalSurfaceIdForNewTopLevel() {
    parent_local_surface_id_allocator_.GenerateId();
    return parent_local_surface_id_allocator_
        .GetCurrentLocalSurfaceIdAllocation();
  }

  viz::LocalSurfaceIdAllocation GenerateChildLocalIdFromParentAllocator() {
    viz::LocalSurfaceId current_id =
        parent_local_surface_id_allocator_.GetCurrentLocalSurfaceIdAllocation()
            .local_surface_id();
    return viz::LocalSurfaceIdAllocation(
        viz::LocalSurfaceId(current_id.parent_sequence_number(),
                            current_id.child_sequence_number() + 1,
                            current_id.embed_token()),
        base::TimeTicks::Now());
  }

  void AckNewTopLevelWindow(TopLevel* top_level, uint32_t change_id) {
    Window* top_level_window = top_level->host->window();
    ws::mojom::WindowDataPtr data = ws::mojom::WindowData::New();
    data->window_id = server_id(top_level_window);
    data->visible = true;
    window_tree_client()->OnTopLevelCreated(
        change_id, std::move(data), next_display_id_++, true,
        GenerateLocalSurfaceIdForNewTopLevel());
    EXPECT_EQ(0u, window_tree()->GetChangeCountForType(
                      WindowTreeChangeType::VISIBLE));
    EXPECT_TRUE(top_level_window->TargetVisibility());
  }

  void AckNewTopLevelWindow(TopLevel* top_level) {
    // Ack the request to the windowtree to create the new window.
    uint32_t change_id = 0;
    EXPECT_TRUE(window_tree()->GetAndRemoveFirstChangeOfType(
        WindowTreeChangeType::NEW_TOP_LEVEL, &change_id));
    EXPECT_EQ(window_tree()->window_id(), server_id(top_level->host->window()));

    AckNewTopLevelWindow(top_level, change_id);
  }

  // Returns a TopLevel with the |host| and |capture_client|.
  std::unique_ptr<TopLevel> CreateTopLevel() {
    std::unique_ptr<TopLevel> top_level = std::make_unique<TopLevel>();
    top_level->host = std::make_unique<WindowTreeHostMus>(
        CreateInitParamsForTopLevel(window_tree_client_impl()));
    top_level->host->InitHost();
    CreateCaptureClientForTopLevel(top_level.get());

    // Ack the request to the windowtree to create the new window.
    AckNewTopLevelWindow(top_level.get());
    return top_level;
  }

 protected:
  viz::ParentLocalSurfaceIdAllocator parent_local_surface_id_allocator_;

 private:
  int64_t next_display_id_ = 1;

  DISALLOW_COPY_AND_ASSIGN(WindowTreeClientTest);
};

class WindowTreeClientTestSurfaceSync
    : public WindowTreeClientTest,
      public ::testing::WithParamInterface<bool> {
 public:
  WindowTreeClientTestSurfaceSync() {}
  ~WindowTreeClientTestSurfaceSync() override {}

  // WindowTreeClientTest:
  void SetUp() override {
    if (GetParam()) {
      base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
          switches::kForceDeviceScaleFactor, "2");
    }
    WindowTreeClientTest::SetUp();
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(WindowTreeClientTestSurfaceSync);
};

// WindowTreeClientTest with --force-device-scale-factor=2.
class WindowTreeClientTestHighDPI : public WindowTreeClientTest {
 public:
  WindowTreeClientTestHighDPI() = default;
  ~WindowTreeClientTestHighDPI() override = default;

  // WindowTreeClientTest:
  void SetUp() override {
    base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
        switches::kForceDeviceScaleFactor, "2");
    WindowTreeClientTest::SetUp();
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(WindowTreeClientTestHighDPI);
};

// Verifies bounds are reverted if the server replied that the change failed.
TEST_F(WindowTreeClientTest, SetBoundsFailed) {
  Window window(nullptr);
  window.Init(ui::LAYER_NOT_DRAWN);
  const gfx::Rect original_bounds(window.bounds());
  const gfx::Rect new_bounds(gfx::Rect(0, 0, 100, 100));
  ASSERT_NE(new_bounds, window.bounds());
  window.SetBounds(new_bounds);
  EXPECT_EQ(new_bounds, window.bounds());
  ASSERT_TRUE(window_tree()->AckSingleChangeOfType(WindowTreeChangeType::BOUNDS,
                                                   false));
  EXPECT_EQ(original_bounds, window.bounds());
}

TEST_F(WindowTreeClientTest, SetBoundsFailedLocalSurfaceId) {
  Window window(nullptr);
  window.Init(ui::LAYER_NOT_DRAWN);
  WindowPortMusTestHelper(&window).SimulateEmbedding();
  // SimulateEmbedding() triggers a bounds change.
  ASSERT_TRUE(
      window_tree()->AckSingleChangeOfType(WindowTreeChangeType::BOUNDS, true));

  // Create a new LocalSurfaceIdAllocation and change the bounds.
  const gfx::Rect original_bounds(window.bounds());
  const viz::LocalSurfaceId original_local_surface_id(
      window.GetLocalSurfaceIdAllocation().local_surface_id());
  const gfx::Rect new_bounds(gfx::Rect(0, 0, 100, 100));
  ASSERT_NE(new_bounds, window.bounds());
  window.SetBounds(new_bounds);
  EXPECT_EQ(new_bounds, window.bounds());
  WindowMus* window_mus = WindowMus::Get(&window);
  ASSERT_NE(nullptr, window_mus);
  ASSERT_TRUE(window_mus->GetLocalSurfaceIdAllocation().IsValid());
  const viz::LocalSurfaceId new_surface_id =
      window_mus->GetLocalSurfaceIdAllocation().local_surface_id();

  // Return the bounds.
  ASSERT_TRUE(window_tree()->AckSingleChangeOfType(WindowTreeChangeType::BOUNDS,
                                                   false));
  EXPECT_EQ(original_bounds, window.bounds());
  // Whenever the bounds changes a new LocalSurfaceId needs to be allocated.
  EXPECT_EQ(1u,
            window_tree()->GetChangeCountForType(WindowTreeChangeType::BOUNDS));
}

INSTANTIATE_TEST_SUITE_P(/* no prefix */,
                         WindowTreeClientTestSurfaceSync,
                         ::testing::Bool());

// Verifies that windows with an embedding create a ClientSurfaceEmbedder.
TEST_P(WindowTreeClientTestSurfaceSync, ClientSurfaceEmbedderCreated) {
  Window window(nullptr);
  window.Init(ui::LAYER_NOT_DRAWN);

  WindowPortMusTestHelper window_test_helper(&window);

  // A ClientSurfaceEmbedder is only created once there is an embedding.
  ClientSurfaceEmbedder* client_surface_embedder =
      window_test_helper.GetClientSurfaceEmbedder();
  EXPECT_EQ(nullptr, client_surface_embedder);
  window_test_helper.SimulateEmbedding();

  gfx::Rect new_bounds(gfx::Rect(0, 0, 100, 100));
  ASSERT_NE(new_bounds, window.bounds());
  window.SetBounds(new_bounds);
  EXPECT_EQ(new_bounds, window.bounds());
  EXPECT_TRUE(WindowMus::Get(&window)->GetLocalSurfaceIdAllocation().IsValid());

  // Once the bounds have been set, the ClientSurfaceEmbedder should be created.
  client_surface_embedder = window_test_helper.GetClientSurfaceEmbedder();
  EXPECT_TRUE(client_surface_embedder);
}

// Verifies that the viz::LocalSurfaceId generated by an embedder changes when
// the size changes, but not when the position changes.
TEST_P(WindowTreeClientTestSurfaceSync, SetBoundsLocalSurfaceIdChanges) {
  ASSERT_EQ(base::nullopt, window_tree()->last_local_surface_id());
  Window window(nullptr);
  window.Init(ui::LAYER_NOT_DRAWN);
  WindowPortMusTestHelper(&window).SimulateEmbedding();

  // Resize the window and verify that we've allocated a viz::LocalSurfaceId.
  const gfx::Rect new_bounds(0, 0, 100, 100);
  ASSERT_NE(new_bounds, window.bounds());
  window.SetBounds(new_bounds);
  EXPECT_EQ(new_bounds, window.bounds());
  base::Optional<viz::LocalSurfaceId> last_local_surface_id =
      window_tree()->last_local_surface_id();
  ASSERT_NE(base::nullopt, last_local_surface_id);

  // Resize the window again and verify that the viz::LocalSurfaceId has
  // changed.
  const gfx::Rect new_bounds2(0, 0, 100, 102);
  ASSERT_NE(new_bounds2, window.bounds());
  window.SetBounds(new_bounds2);
  EXPECT_EQ(new_bounds2, window.bounds());
  base::Optional<viz::LocalSurfaceId> last_local_surface_id2 =
      window_tree()->last_local_surface_id();
  ASSERT_NE(base::nullopt, last_local_surface_id2);
  EXPECT_NE(last_local_surface_id2, last_local_surface_id);

  // Moving the window but not changing the size should not allocate a new
  // viz::LocalSurfaceId.
  const gfx::Rect new_bounds3(1337, 7331, 100, 102);
  ASSERT_NE(new_bounds3, window.bounds());
  window.SetBounds(new_bounds3);
  EXPECT_EQ(new_bounds3, window.bounds());
  base::Optional<viz::LocalSurfaceId> last_local_surface_id3 =
      window_tree()->last_local_surface_id();
  ASSERT_NE(base::nullopt, last_local_surface_id3);
  EXPECT_EQ(last_local_surface_id2, last_local_surface_id3);
}

// Verifies a new window from the server doesn't result in attempting to add
// the window back to the server.
TEST_F(WindowTreeClientTest, AddFromServerDoesntAddAgain) {
  const ws::Id child_window_id = server_id(root_window()) + 11;
  ws::mojom::WindowDataPtr data = ws::mojom::WindowData::New();
  data->parent_id = server_id(root_window());
  data->window_id = child_window_id;
  data->bounds = gfx::Rect(1, 2, 3, 4);
  data->visible = false;
  std::vector<ws::mojom::WindowDataPtr> data_array(1);
  data_array[0] = std::move(data);
  ASSERT_TRUE(root_window()->children().empty());
  window_tree_client()->OnWindowHierarchyChanged(
      child_window_id, 0, server_id(root_window()), std::move(data_array));
  ASSERT_FALSE(window_tree()->has_change());
  ASSERT_EQ(1u, root_window()->children().size());
  Window* child = root_window()->children()[0];
  EXPECT_FALSE(child->TargetVisibility());
}

// Verifies a reparent from the server doesn't attempt signal the server.
TEST_F(WindowTreeClientTest, ReparentFromServerDoesntAddAgain) {
  Window window1(nullptr);
  window1.Init(ui::LAYER_NOT_DRAWN);
  Window window2(nullptr);
  window2.Init(ui::LAYER_NOT_DRAWN);
  root_window()->AddChild(&window1);
  root_window()->AddChild(&window2);

  window_tree()->AckAllChanges();
  // Simulate moving |window1| to be a child of |window2| from the server.
  window_tree_client()->OnWindowHierarchyChanged(
      server_id(&window1), server_id(root_window()), server_id(&window2),
      std::vector<ws::mojom::WindowDataPtr>());
  ASSERT_FALSE(window_tree()->has_change());
  EXPECT_EQ(&window2, window1.parent());
  EXPECT_EQ(root_window(), window2.parent());
  window1.parent()->RemoveChild(&window1);
}

// Verifies properties passed in OnWindowHierarchyChanged() make there way to
// the new window.
TEST_F(WindowTreeClientTest, OnWindowHierarchyChangedWithProperties) {
  RegisterTestProperties(GetPropertyConverter());
  window_tree()->AckAllChanges();
  const ws::Id child_window_id = server_id(root_window()) + 11;
  ws::mojom::WindowDataPtr data = ws::mojom::WindowData::New();
  const uint8_t server_test_property1_value = 91;
  data->properties[kTestPropertyServerKey1] =
      ConvertToPropertyTransportValue(server_test_property1_value);
  data->properties[ws::mojom::WindowManager::kWindowType_InitProperty] =
      mojo::ConvertTo<std::vector<uint8_t>>(
          static_cast<int32_t>(ws::mojom::WindowType::BUBBLE));
  constexpr int kWindowCornerRadiusValue = 6;
  data->properties[ws::mojom::WindowManager::kWindowCornerRadius_Property] =
      ConvertToPropertyTransportValue(kWindowCornerRadiusValue);
  data->parent_id = server_id(root_window());
  data->window_id = child_window_id;
  data->bounds = gfx::Rect(1, 2, 3, 4);
  data->visible = false;
  std::vector<ws::mojom::WindowDataPtr> data_array(1);
  data_array[0] = std::move(data);
  ASSERT_TRUE(root_window()->children().empty());
  window_tree_client()->OnWindowHierarchyChanged(
      child_window_id, 0, server_id(root_window()), std::move(data_array));
  ASSERT_FALSE(window_tree()->has_change());
  ASSERT_EQ(1u, root_window()->children().size());
  Window* child = root_window()->children()[0];
  EXPECT_FALSE(child->TargetVisibility());
  EXPECT_EQ(server_test_property1_value, child->GetProperty(kTestPropertyKey1));
  EXPECT_EQ(kWindowCornerRadiusValue,
            child->GetProperty(client::kWindowCornerRadiusKey));
  EXPECT_EQ(child->type(), client::WINDOW_TYPE_POPUP);
  EXPECT_EQ(ws::mojom::WindowType::BUBBLE,
            child->GetProperty(client::kWindowTypeKey));
}

// Verifies a move from the server doesn't attempt signal the server.
TEST_F(WindowTreeClientTest, MoveFromServerDoesntAddAgain) {
  Window window1(nullptr);
  window1.Init(ui::LAYER_NOT_DRAWN);
  Window window2(nullptr);
  window2.Init(ui::LAYER_NOT_DRAWN);
  root_window()->AddChild(&window1);
  root_window()->AddChild(&window2);

  window_tree()->AckAllChanges();
  // Simulate moving |window1| to be a child of |window2| from the server.
  window_tree_client()->OnWindowReordered(server_id(&window2),
                                          server_id(&window1),
                                          ws::mojom::OrderDirection::BELOW);
  ASSERT_FALSE(window_tree()->has_change());
  ASSERT_EQ(2u, root_window()->children().size());
  EXPECT_EQ(&window2, root_window()->children()[0]);
  EXPECT_EQ(&window1, root_window()->children()[1]);
}

TEST_F(WindowTreeClientTest, FocusFromServer) {
  Window window1(nullptr);
  window1.Init(ui::LAYER_NOT_DRAWN);
  Window window2(nullptr);
  window2.Init(ui::LAYER_NOT_DRAWN);
  root_window()->AddChild(&window1);
  root_window()->AddChild(&window2);

  ASSERT_TRUE(window1.CanFocus());
  window_tree()->AckAllChanges();
  EXPECT_FALSE(window1.HasFocus());
  // Simulate moving |window1| to be a child of |window2| from the server.
  window_tree_client()->OnWindowFocused(server_id(&window1));
  ASSERT_FALSE(window_tree()->has_change());
  EXPECT_TRUE(window1.HasFocus());
}

// Simulates a bounds change, and while the bounds change is in flight the
// server replies with a new bounds and the original bounds change fails.
// The server bounds change takes hold.
TEST_F(WindowTreeClientTest, SetBoundsFailedWithPendingChange) {
  aura::Window root_window(nullptr);
  root_window.Init(ui::LAYER_NOT_DRAWN);
  const gfx::Rect original_bounds(root_window.bounds());
  const gfx::Rect new_bounds(gfx::Rect(0, 0, 100, 100));
  ASSERT_NE(new_bounds, root_window.bounds());
  root_window.SetBounds(new_bounds);
  EXPECT_EQ(new_bounds, root_window.bounds());
  const viz::LocalSurfaceIdAllocation initial_local_surface_id_allocation =
      root_window.GetLocalSurfaceIdAllocation();

  // Simulate the server responding with a bounds change.
  const gfx::Rect server_changed_bounds(gfx::Rect(0, 0, 101, 102));
  const viz::LocalSurfaceIdAllocation
      server_changed_local_surface_id_allocation(
          viz::LocalSurfaceId(1, base::UnguessableToken::Create()),
          base::TimeTicks::Now());
  window_tree_client()->OnWindowBoundsChanged(
      server_id(&root_window), server_changed_bounds,
      server_changed_local_surface_id_allocation);

  WindowMus* root_window_mus = WindowMus::Get(&root_window);
  ASSERT_NE(nullptr, root_window_mus);

  // This shouldn't trigger the bounds changing yet.
  EXPECT_EQ(new_bounds, root_window.bounds());

  // Tell the client the change failed, which should trigger failing to the
  // most recent bounds from server.
  ASSERT_TRUE(window_tree()->AckSingleChangeOfType(WindowTreeChangeType::BOUNDS,
                                                   false));
  EXPECT_EQ(server_changed_bounds, root_window.bounds());
  // LocalSurfaceIdAllocation, for non-embed/top-levels is entirely controlled
  // by the client.
  EXPECT_EQ(initial_local_surface_id_allocation,
            root_window_mus->GetLocalSurfaceIdAllocation());

  // Simulate server changing back to original bounds. Should take immediately.
  window_tree_client()->OnWindowBoundsChanged(server_id(&root_window),
                                              original_bounds, base::nullopt);
  EXPECT_EQ(original_bounds, root_window.bounds());
}

TEST_F(WindowTreeClientTest, TwoInFlightBoundsChangesBothCanceled) {
  aura::Window root_window(nullptr);
  root_window.Init(ui::LAYER_NOT_DRAWN);
  const gfx::Rect original_bounds(root_window.bounds());
  const gfx::Rect bounds1(gfx::Rect(0, 0, 100, 100));
  const gfx::Rect bounds2(gfx::Rect(0, 0, 100, 102));
  root_window.SetBounds(bounds1);
  EXPECT_EQ(bounds1, root_window.bounds());

  root_window.SetBounds(bounds2);
  EXPECT_EQ(bounds2, root_window.bounds());

  // Tell the client the first bounds failed. As there is a still a change in
  // flight nothing should happen.
  ASSERT_TRUE(
      window_tree()->AckFirstChangeOfType(WindowTreeChangeType::BOUNDS, false));
  EXPECT_EQ(bounds2, root_window.bounds());

  // Tell the client the seconds bounds failed. Should now fallback to original
  // value.
  ASSERT_TRUE(window_tree()->AckSingleChangeOfType(WindowTreeChangeType::BOUNDS,
                                                   false));
  EXPECT_EQ(original_bounds, root_window.bounds());
}

TEST_F(WindowTreeClientTest, TwoInFlightTransformsChangesBothCanceled) {
  const gfx::Transform original_transform(root_window()->layer()->transform());
  gfx::Transform transform1;
  transform1.Scale(SkIntToMScalar(2), SkIntToMScalar(2));
  gfx::Transform transform2;
  transform2.Scale(SkIntToMScalar(3), SkIntToMScalar(3));
  root_window()->SetTransform(transform1);
  EXPECT_EQ(transform1, root_window()->layer()->transform());

  root_window()->SetTransform(transform2);
  EXPECT_EQ(transform2, root_window()->layer()->transform());

  // Tell the client the first transform failed. As there is a still a change in
  // flight nothing should happen.
  ASSERT_TRUE(window_tree()->AckFirstChangeOfType(
      WindowTreeChangeType::TRANSFORM, false));
  EXPECT_EQ(transform2, root_window()->layer()->transform());

  // Tell the client the seconds transform failed. Should now fallback to
  // original value.
  ASSERT_TRUE(window_tree()->AckSingleChangeOfType(
      WindowTreeChangeType::TRANSFORM, false));
  EXPECT_EQ(original_transform, root_window()->layer()->transform());
}

// Verifies properties are set if the server replied that the change succeeded.
TEST_F(WindowTreeClientTest, SetPropertySucceeded) {
  ASSERT_FALSE(root_window()->GetProperty(client::kAlwaysOnTopKey));
  root_window()->SetProperty(client::kAlwaysOnTopKey, true);
  EXPECT_TRUE(root_window()->GetProperty(client::kAlwaysOnTopKey));
  base::Optional<std::vector<uint8_t>> value =
      window_tree()->GetLastPropertyValue();
  ASSERT_TRUE(value.has_value());
  // PropertyConverter uses int64_t values, even for smaller types, like bool.
  ASSERT_EQ(8u, value->size());
  EXPECT_EQ(1, mojo::ConvertTo<int64_t>(*value));
  ASSERT_TRUE(window_tree()->AckSingleChangeOfType(
      WindowTreeChangeType::PROPERTY, true));
  EXPECT_TRUE(root_window()->GetProperty(client::kAlwaysOnTopKey));
}

// Verifies properties are reverted if the server replied that the change
// failed.
TEST_F(WindowTreeClientTest, SetPropertyFailed) {
  ASSERT_FALSE(root_window()->GetProperty(client::kAlwaysOnTopKey));
  root_window()->SetProperty(client::kAlwaysOnTopKey, true);
  EXPECT_TRUE(root_window()->GetProperty(client::kAlwaysOnTopKey));
  base::Optional<std::vector<uint8_t>> value =
      window_tree()->GetLastPropertyValue();
  ASSERT_TRUE(value.has_value());
  // PropertyConverter uses int64_t values, even for smaller types, like bool.
  ASSERT_EQ(8u, value->size());
  EXPECT_EQ(1, mojo::ConvertTo<int64_t>(*value));
  ASSERT_TRUE(window_tree()->AckSingleChangeOfType(
      WindowTreeChangeType::PROPERTY, false));
  EXPECT_FALSE(root_window()->GetProperty(client::kAlwaysOnTopKey));
}

// Simulates a property change, and while the property change is in flight the
// server replies with a new property and the original property change fails.
TEST_F(WindowTreeClientTest, SetPropertyFailedWithPendingChange) {
  RegisterTestProperties(GetPropertyConverter());
  const uint8_t value1 = 11;
  root_window()->SetProperty(kTestPropertyKey1, value1);
  EXPECT_EQ(value1, root_window()->GetProperty(kTestPropertyKey1));

  // Simulate the server responding with a different value.
  const uint8_t server_value = 12;
  window_tree_client()->OnWindowSharedPropertyChanged(
      server_id(root_window()), kTestPropertyServerKey1,
      ConvertToPropertyTransportValue(server_value));

  // This shouldn't trigger the property changing yet.
  EXPECT_EQ(value1, root_window()->GetProperty(kTestPropertyKey1));

  // Tell the client the change failed, which should trigger failing to the
  // most recent value from server.
  ASSERT_TRUE(window_tree()->AckSingleChangeOfType(
      WindowTreeChangeType::PROPERTY, false));
  EXPECT_EQ(server_value, root_window()->GetProperty(kTestPropertyKey1));

  // Simulate server changing back to value1. Should take immediately.
  window_tree_client()->OnWindowSharedPropertyChanged(
      server_id(root_window()), kTestPropertyServerKey1,
      ConvertToPropertyTransportValue(value1));
  EXPECT_EQ(value1, root_window()->GetProperty(kTestPropertyKey1));
}

// Verifies property setting behavior with failures for primitive properties.
TEST_F(WindowTreeClientTest, SetPrimitiveProperties) {
  PropertyConverter* property_converter = GetPropertyConverter();
  RegisterTestProperties(property_converter);

  const uint8_t value1_local = UINT8_MAX / 2;
  const uint8_t value1_server = UINT8_MAX / 3;
  root_window()->SetProperty(kTestPropertyKey1, value1_local);
  EXPECT_EQ(value1_local, root_window()->GetProperty(kTestPropertyKey1));
  window_tree_client()->OnWindowSharedPropertyChanged(
      server_id(root_window()), kTestPropertyServerKey1,
      ConvertToPropertyTransportValue(value1_server));
  ASSERT_TRUE(window_tree()->AckSingleChangeOfType(
      WindowTreeChangeType::PROPERTY, false));
  EXPECT_EQ(value1_server, root_window()->GetProperty(kTestPropertyKey1));

  const uint16_t value2_local = UINT16_MAX / 3;
  const uint16_t value2_server = UINT16_MAX / 4;
  root_window()->SetProperty(kTestPropertyKey2, value2_local);
  EXPECT_EQ(value2_local, root_window()->GetProperty(kTestPropertyKey2));
  window_tree_client()->OnWindowSharedPropertyChanged(
      server_id(root_window()), kTestPropertyServerKey2,
      ConvertToPropertyTransportValue(value2_server));
  ASSERT_TRUE(window_tree()->AckSingleChangeOfType(
      WindowTreeChangeType::PROPERTY, false));
  EXPECT_EQ(value2_server, root_window()->GetProperty(kTestPropertyKey2));

  EXPECT_FALSE(root_window()->GetProperty(kTestPropertyKey3));
  root_window()->SetProperty(kTestPropertyKey3, true);
  EXPECT_TRUE(root_window()->GetProperty(kTestPropertyKey3));
  window_tree_client()->OnWindowSharedPropertyChanged(
      server_id(root_window()), kTestPropertyServerKey3,
      ConvertToPropertyTransportValue(false));
  ASSERT_TRUE(window_tree()->AckSingleChangeOfType(
      WindowTreeChangeType::PROPERTY, false));
  EXPECT_FALSE(root_window()->GetProperty(kTestPropertyKey3));
}

// Verifies property setting behavior for a gfx::Rect* property.
TEST_F(WindowTreeClientTest, SetRectProperty) {
  gfx::Rect example(1, 2, 3, 4);
  ASSERT_EQ(nullptr, root_window()->GetProperty(client::kRestoreBoundsKey));
  root_window()->SetProperty(client::kRestoreBoundsKey, new gfx::Rect(example));
  EXPECT_TRUE(root_window()->GetProperty(client::kRestoreBoundsKey));
  base::Optional<std::vector<uint8_t>> value =
      window_tree()->GetLastPropertyValue();
  ASSERT_TRUE(value.has_value());
  EXPECT_EQ(example, mojo::ConvertTo<gfx::Rect>(*value));
  ASSERT_TRUE(window_tree()->AckSingleChangeOfType(
      WindowTreeChangeType::PROPERTY, true));
  EXPECT_EQ(example, *root_window()->GetProperty(client::kRestoreBoundsKey));

  root_window()->SetProperty(client::kRestoreBoundsKey, new gfx::Rect());
  EXPECT_EQ(gfx::Rect(),
            *root_window()->GetProperty(client::kRestoreBoundsKey));
  ASSERT_TRUE(window_tree()->AckSingleChangeOfType(
      WindowTreeChangeType::PROPERTY, false));
  EXPECT_EQ(example, *root_window()->GetProperty(client::kRestoreBoundsKey));
}

// Verifies property setting behavior for a std::string* property.
TEST_F(WindowTreeClientTest, SetStringProperty) {
  std::string example = "123";
  ASSERT_NE(nullptr, root_window()->GetProperty(client::kNameKey));
  root_window()->SetProperty(client::kNameKey, new std::string(example));
  EXPECT_TRUE(root_window()->GetProperty(client::kNameKey));
  base::Optional<std::vector<uint8_t>> value =
      window_tree()->GetLastPropertyValue();
  ASSERT_TRUE(value.has_value());
  EXPECT_EQ(example, mojo::ConvertTo<std::string>(*value));
  ASSERT_TRUE(window_tree()->AckSingleChangeOfType(
      WindowTreeChangeType::PROPERTY, true));
  EXPECT_EQ(example, *root_window()->GetProperty(client::kNameKey));

  root_window()->SetProperty(client::kNameKey, new std::string());
  EXPECT_EQ(std::string(), *root_window()->GetProperty(client::kNameKey));
  ASSERT_TRUE(window_tree()->AckSingleChangeOfType(
      WindowTreeChangeType::PROPERTY, false));
  EXPECT_EQ(example, *root_window()->GetProperty(client::kNameKey));
}

TEST_F(WindowTreeClientTest, SetWindowPointerProperty) {
  PropertyConverter* property_converter = GetPropertyConverter();
  RegisterTestProperties(property_converter);

  Window window(nullptr);
  window.Init(ui::LAYER_NOT_DRAWN);
  window.Show();
  root_window()->SetProperty(kTestPropertyKey4, &window);
  base::Optional<std::vector<uint8_t>> value =
      window_tree()->GetLastPropertyValue();
  ASSERT_TRUE(value.has_value());
  EXPECT_EQ(WindowMus::Get(&window)->server_id(),
            mojo::ConvertTo<ws::Id>(*value));
  window_tree()->AckAllChanges();

  root_window()->ClearProperty(kTestPropertyKey4);
  value = window_tree()->GetLastPropertyValue();
  EXPECT_FALSE(value.has_value());
}

// Verifies visible is reverted if the server replied that the change failed.
TEST_F(WindowTreeClientTest, SetVisibleFailed) {
  const bool original_visible = root_window()->TargetVisibility();
  const bool new_visible = !original_visible;
  SetWindowVisibility(root_window(), new_visible);
  ASSERT_TRUE(window_tree()->AckSingleChangeOfType(
      WindowTreeChangeType::VISIBLE, false));
  EXPECT_EQ(original_visible, root_window()->TargetVisibility());
}

// Simulates a visible change, and while the visible change is in flight the
// server replies with a new visible and the original visible change fails.
TEST_F(WindowTreeClientTest, SetVisibleFailedWithPendingChange) {
  const bool original_visible = root_window()->TargetVisibility();
  const bool new_visible = !original_visible;
  SetWindowVisibility(root_window(), new_visible);
  EXPECT_EQ(new_visible, root_window()->TargetVisibility());

  // Simulate the server responding with a visible change.
  const bool server_changed_visible = !new_visible;
  window_tree_client()->OnWindowVisibilityChanged(server_id(root_window()),
                                                  server_changed_visible);

  // This shouldn't trigger visible changing yet.
  EXPECT_EQ(new_visible, root_window()->TargetVisibility());

  // Tell the client the change failed, which should trigger failing to the
  // most recent visible from server.
  ASSERT_TRUE(window_tree()->AckSingleChangeOfType(
      WindowTreeChangeType::VISIBLE, false));
  EXPECT_EQ(server_changed_visible, root_window()->TargetVisibility());

  // Simulate server changing back to original visible. Should take immediately.
  window_tree_client()->OnWindowVisibilityChanged(server_id(root_window()),
                                                  original_visible);
  EXPECT_EQ(original_visible, root_window()->TargetVisibility());
}

namespace {

class InputEventBasicTestWindowDelegate : public test::TestWindowDelegate {
 public:
  explicit InputEventBasicTestWindowDelegate(TestWindowTree* test_window_tree)
      : test_window_tree_(test_window_tree) {}
  ~InputEventBasicTestWindowDelegate() override {}

  int move_count() const { return move_count_; }
  int press_count() const { return press_count_; }
  int release_count() const { return release_count_; }
  bool was_acked() const { return was_acked_; }
  const gfx::Point& last_event_location() const { return last_event_location_; }
  void set_event_id(uint32_t event_id) { event_id_ = event_id; }
  bool last_mouse_event_had_native_event() const {
    return last_mouse_event_had_native_event_;
  }
  const gfx::Point& last_native_event_location() const {
    return last_native_event_location_;
  }
  ui::EventPointerType last_pointer_type() const { return last_pointer_type_; }

  // TestWindowDelegate::
  void OnMouseEvent(ui::MouseEvent* event) override {
    was_acked_ = test_window_tree_->WasEventAcked(event_id_);
    if (event->type() == ui::ET_MOUSE_MOVED)
      ++move_count_;
    else if (event->type() == ui::ET_MOUSE_PRESSED)
      ++press_count_;
    else if (event->type() == ui::ET_MOUSE_RELEASED)
      ++release_count_;
    last_event_location_ = event->location();
    last_mouse_event_had_native_event_ = event->HasNativeEvent();
    if (event->HasNativeEvent()) {
      last_native_event_location_ =
          ui::EventSystemLocationFromNative(event->native_event());
    }
    last_pointer_type_ = event->pointer_details().pointer_type;
    event->SetHandled();
  }

  void OnTouchEvent(ui::TouchEvent* event) override {
    was_acked_ = test_window_tree_->WasEventAcked(event_id_);
    if (event->type() == ui::ET_TOUCH_PRESSED)
      ++press_count_;
    else if (event->type() == ui::ET_TOUCH_RELEASED)
      ++release_count_;
    last_event_location_ = event->location();
    last_pointer_type_ = event->pointer_details().pointer_type;
    event->SetHandled();
  }

  void reset() {
    was_acked_ = false;
    move_count_ = 0;
    press_count_ = 0;
    release_count_ = 0;
    last_event_location_ = gfx::Point();
    event_id_ = 0;
    last_mouse_event_had_native_event_ = false;
    last_native_event_location_ = gfx::Point();
    last_pointer_type_ = ui::EventPointerType::POINTER_TYPE_UNKNOWN;
  }

 private:
  TestWindowTree* test_window_tree_;
  bool was_acked_ = false;
  int move_count_ = 0;
  int press_count_ = 0;
  int release_count_ = false;
  gfx::Point last_event_location_;
  uint32_t event_id_ = 0;
  bool last_mouse_event_had_native_event_ = false;
  gfx::Point last_native_event_location_;
  ui::EventPointerType last_pointer_type_ =
      ui::EventPointerType::POINTER_TYPE_UNKNOWN;

  DISALLOW_COPY_AND_ASSIGN(InputEventBasicTestWindowDelegate);
};

class InputEventBasicTestEventHandler : public ui::test::TestEventHandler {
 public:
  explicit InputEventBasicTestEventHandler(Window* target_window)
      : target_window_(target_window) {}
  ~InputEventBasicTestEventHandler() override {}

  int move_count() const { return move_count_; }
  const gfx::Point& last_event_location() const { return last_event_location_; }
  void set_event_id(uint32_t event_id) { event_id_ = event_id; }

  // ui::test::TestEventHandler overrides.
  void OnMouseEvent(ui::MouseEvent* event) override {
    if (event->target() == target_window_) {
      if (event->type() == ui::ET_MOUSE_MOVED)
        ++move_count_;
      last_event_location_ = event->location();
      event->SetHandled();
    }
  }

  void reset() {
    move_count_ = 0;
    last_event_location_ = gfx::Point();
    event_id_ = 0;
  }

 private:
  Window* target_window_ = nullptr;
  int move_count_ = 0;
  gfx::Point last_event_location_;
  uint32_t event_id_ = 0;

  DISALLOW_COPY_AND_ASSIGN(InputEventBasicTestEventHandler);
};

}  // namespace

TEST_F(WindowTreeClientTest, InputEventBasic) {
  InputEventBasicTestWindowDelegate window_delegate(window_tree());
  WindowTreeHostMus window_tree_host(
      CreateInitParamsForTopLevel(window_tree_client_impl()));
  Window* top_level = window_tree_host.window();
  const gfx::Rect bounds(0, 0, 100, 100);
  static_cast<WindowTreeHost*>(&window_tree_host)->SetBoundsInPixels(bounds);
  window_tree_host.InitHost();
  window_tree_host.Show();
  EXPECT_EQ(bounds, top_level->bounds());
  EXPECT_EQ(bounds, window_tree_host.GetBoundsInPixels());
  Window child(&window_delegate);
  child.Init(ui::LAYER_NOT_DRAWN);
  top_level->AddChild(&child);
  child.SetBounds(gfx::Rect(10, 10, 100, 100));
  child.Show();
  EXPECT_EQ(0, window_delegate.move_count());
  EXPECT_FALSE(window_delegate.was_acked());
  const gfx::Point event_location_in_child(2, 3);
  const uint32_t event_id = 1;
  window_delegate.set_event_id(event_id);
  std::unique_ptr<ui::Event> ui_event(
      new ui::MouseEvent(ui::ET_MOUSE_MOVED, event_location_in_child,
                         gfx::Point(), ui::EventTimeForNow(), ui::EF_NONE, 0));
  window_tree_client()->OnWindowInputEvent(
      event_id, server_id(&child), window_tree_host.display_id(),
      ui::Event::Clone(*ui_event.get()), 0);
  EXPECT_TRUE(window_tree()->WasEventAcked(event_id));
  EXPECT_EQ(ws::mojom::EventResult::HANDLED,
            window_tree()->GetEventResult(event_id));
  EXPECT_EQ(1, window_delegate.move_count());
  EXPECT_FALSE(window_delegate.was_acked());
  EXPECT_EQ(event_location_in_child, window_delegate.last_event_location());
}

TEST_F(WindowTreeClientTest, InputEventMouse) {
  InputEventBasicTestWindowDelegate window_delegate(window_tree());
  WindowTreeHostMus window_tree_host(
      CreateInitParamsForTopLevel(window_tree_client_impl()));
  Window* top_level = window_tree_host.window();
  const gfx::Rect bounds(0, 0, 100, 100);
  static_cast<WindowTreeHost*>(&window_tree_host)->SetBoundsInPixels(bounds);
  window_tree_host.InitHost();
  window_tree_host.Show();
  EXPECT_EQ(bounds, top_level->bounds());
  EXPECT_EQ(bounds, window_tree_host.GetBoundsInPixels());
  Window child(&window_delegate);
  child.Init(ui::LAYER_NOT_DRAWN);
  top_level->AddChild(&child);
  child.SetBounds(gfx::Rect(10, 10, 100, 100));
  child.Show();
  EXPECT_EQ(0, window_delegate.move_count());
  const gfx::Point event_location(2, 3);
  const uint32_t event_id = 1;
  window_delegate.set_event_id(event_id);
  ui::MouseEvent mouse_event(
      ui::ET_MOUSE_MOVED, event_location, event_location, ui::EventTimeForNow(),
      ui::EF_NONE, ui::EF_NONE,
      ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_MOUSE, 0));
  window_tree_client()->OnWindowInputEvent(event_id, server_id(&child),
                                           window_tree_host.display_id(),
                                           ui::Event::Clone(mouse_event), 0);
  EXPECT_TRUE(window_tree()->WasEventAcked(event_id));
  EXPECT_EQ(ws::mojom::EventResult::HANDLED,
            window_tree()->GetEventResult(event_id));
  EXPECT_EQ(1, window_delegate.move_count());
  EXPECT_EQ(event_location, window_delegate.last_event_location());
}

TEST_F(WindowTreeClientTest, InputEventPen) {
  // Create a root window.
  WindowTreeHostMus window_tree_host(
      CreateInitParamsForTopLevel(window_tree_client_impl()));
  Window* top_level = window_tree_host.window();
  const gfx::Rect bounds(0, 0, 100, 100);
  static_cast<WindowTreeHost*>(&window_tree_host)->SetBoundsInPixels(bounds);
  window_tree_host.InitHost();
  window_tree_host.Show();

  // Create a child window with a test delegate to sense events.
  InputEventBasicTestWindowDelegate window_delegate(window_tree());
  Window child(&window_delegate);
  child.Init(ui::LAYER_NOT_DRAWN);
  top_level->AddChild(&child);
  child.SetBounds(gfx::Rect(10, 10, 100, 100));
  child.Show();

  // Dispatch a pen event to the child window.
  const gfx::Point event_location(2, 3);
  const uint32_t event_id = 1;
  window_delegate.set_event_id(event_id);
  ui::MouseEvent mouse_event(
      ui::ET_MOUSE_PRESSED, event_location, event_location,
      ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE,
      ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_PEN, 0));
  window_tree_client()->OnWindowInputEvent(event_id, server_id(&child),
                                           window_tree_host.display_id(),
                                           ui::Event::Clone(mouse_event), 0);

  // Pen event was handled.
  EXPECT_TRUE(window_tree()->WasEventAcked(event_id));
  EXPECT_EQ(ws::mojom::EventResult::HANDLED,
            window_tree()->GetEventResult(event_id));
  EXPECT_EQ(ui::EventPointerType::POINTER_TYPE_PEN,
            window_delegate.last_pointer_type());
}

TEST_F(WindowTreeClientTest, InputEventFindTargetAndConversion) {
  WindowTreeHostMus window_tree_host(
      CreateInitParamsForTopLevel(window_tree_client_impl()));
  Window* top_level = window_tree_host.window();
  const gfx::Rect bounds(0, 0, 100, 100);
  static_cast<WindowTreeHost*>(&window_tree_host)->SetBoundsInPixels(bounds);
  window_tree_host.InitHost();
  window_tree_host.Show();
  EXPECT_EQ(bounds, top_level->bounds());
  EXPECT_EQ(bounds, window_tree_host.GetBoundsInPixels());
  InputEventBasicTestWindowDelegate window_delegate1(window_tree());
  Window child1(&window_delegate1);
  child1.Init(ui::LAYER_NOT_DRAWN);
  child1.SetEventTargeter(std::make_unique<WindowTargeter>());
  top_level->AddChild(&child1);
  child1.SetBounds(gfx::Rect(10, 10, 100, 100));
  child1.Show();
  InputEventBasicTestWindowDelegate window_delegate2(window_tree());
  Window child2(&window_delegate2);
  child2.Init(ui::LAYER_NOT_DRAWN);
  child1.AddChild(&child2);
  child2.SetBounds(gfx::Rect(20, 30, 100, 100));
  child2.Show();

  EXPECT_EQ(0, window_delegate1.move_count());
  EXPECT_EQ(0, window_delegate2.move_count());

  // child1 has a targeter set and event_location is (50, 60), child2
  // should get the event even though mus-ws wants to send to child1.
  const gfx::Point event_location(50, 60);
  uint32_t event_id = 1;
  window_delegate1.set_event_id(event_id);
  window_delegate2.set_event_id(event_id);
  std::unique_ptr<ui::Event> ui_event(
      new ui::MouseEvent(ui::ET_MOUSE_MOVED, event_location, gfx::Point(),
                         ui::EventTimeForNow(), ui::EF_NONE, 0));
  window_tree_client()->OnWindowInputEvent(
      event_id, server_id(&child1), window_tree_host.display_id(),
      ui::Event::Clone(*ui_event.get()), 0);
  EXPECT_TRUE(window_tree()->WasEventAcked(event_id));
  EXPECT_EQ(ws::mojom::EventResult::HANDLED,
            window_tree()->GetEventResult(event_id));
  EXPECT_EQ(0, window_delegate1.move_count());
  EXPECT_EQ(1, window_delegate2.move_count());
  EXPECT_EQ(gfx::Point(30, 30), window_delegate2.last_event_location());
  window_delegate1.reset();
  window_delegate2.reset();

  // Remove the targeter for child1 and specify the event to go to child1. This
  // time child1 should receive the event not child2.
  child1.SetEventTargeter(nullptr);
  event_id = 2;
  window_delegate1.set_event_id(event_id);
  window_delegate2.set_event_id(event_id);
  std::unique_ptr<ui::Event> ui_event1(
      new ui::MouseEvent(ui::ET_MOUSE_MOVED, event_location, gfx::Point(),
                         ui::EventTimeForNow(), ui::EF_NONE, 0));
  window_tree_client()->OnWindowInputEvent(
      event_id, server_id(&child1), window_tree_host.display_id(),
      ui::Event::Clone(*ui_event1.get()), 0);
  EXPECT_TRUE(window_tree()->WasEventAcked(event_id));
  EXPECT_EQ(ws::mojom::EventResult::HANDLED,
            window_tree()->GetEventResult(event_id));
  EXPECT_EQ(1, window_delegate1.move_count());
  EXPECT_EQ(0, window_delegate2.move_count());
  EXPECT_EQ(gfx::Point(50, 60), window_delegate1.last_event_location());
}

TEST_F(WindowTreeClientTest, InputEventCustomWindowTargeter) {
  WindowTreeHostMus window_tree_host(
      CreateInitParamsForTopLevel(window_tree_client_impl()));
  Window* top_level = window_tree_host.window();
  const gfx::Rect bounds(0, 0, 100, 100);
  static_cast<WindowTreeHost*>(&window_tree_host)->SetBoundsInPixels(bounds);
  window_tree_host.InitHost();
  window_tree_host.Show();
  EXPECT_EQ(bounds, top_level->bounds());
  EXPECT_EQ(bounds, window_tree_host.GetBoundsInPixels());
  InputEventBasicTestWindowDelegate window_delegate1(window_tree());
  Window child1(&window_delegate1);
  child1.Init(ui::LAYER_NOT_DRAWN);
  child1.SetEventTargeter(std::make_unique<test::TestWindowTargeter>());
  top_level->AddChild(&child1);
  child1.SetBounds(gfx::Rect(10, 10, 100, 100));
  child1.Show();
  InputEventBasicTestWindowDelegate window_delegate2(window_tree());
  Window child2(&window_delegate2);
  child2.Init(ui::LAYER_NOT_DRAWN);
  child1.AddChild(&child2);
  child2.SetBounds(gfx::Rect(20, 30, 100, 100));
  child2.Show();

  EXPECT_EQ(0, window_delegate1.move_count());
  EXPECT_EQ(0, window_delegate2.move_count());

  // child1 has a custom targeter set which would always return itself as the
  // target window therefore event should go to child1 unlike
  // WindowTreeClientTest.InputEventFindTargetAndConversion.
  const gfx::Point event_location(50, 60);
  uint32_t event_id = 1;
  window_delegate1.set_event_id(event_id);
  window_delegate2.set_event_id(event_id);
  std::unique_ptr<ui::Event> ui_event(
      new ui::MouseEvent(ui::ET_MOUSE_MOVED, event_location, gfx::Point(),
                         ui::EventTimeForNow(), ui::EF_NONE, 0));
  window_tree_client()->OnWindowInputEvent(
      event_id, server_id(&child1), window_tree_host.display_id(),
      ui::Event::Clone(*ui_event.get()), 0);
  EXPECT_TRUE(window_tree()->WasEventAcked(event_id));
  EXPECT_EQ(ws::mojom::EventResult::HANDLED,
            window_tree()->GetEventResult(event_id));
  EXPECT_EQ(1, window_delegate1.move_count());
  EXPECT_EQ(0, window_delegate2.move_count());
  EXPECT_EQ(gfx::Point(50, 60), window_delegate1.last_event_location());
  window_delegate1.reset();
  window_delegate2.reset();

  // child1 should get the event even though mus-ws specifies child2 and it's
  // actually in child2's space. Event location will be transformed.
  event_id = 2;
  window_delegate1.set_event_id(event_id);
  window_delegate2.set_event_id(event_id);
  window_tree_client()->OnWindowInputEvent(
      event_id, server_id(&child2), window_tree_host.display_id(),
      ui::Event::Clone(*ui_event.get()), 0);
  EXPECT_TRUE(window_tree()->WasEventAcked(event_id));
  EXPECT_EQ(ws::mojom::EventResult::HANDLED,
            window_tree()->GetEventResult(event_id));
  EXPECT_EQ(1, window_delegate1.move_count());
  EXPECT_EQ(0, window_delegate2.move_count());
  EXPECT_EQ(gfx::Point(70, 90), window_delegate1.last_event_location());
}

TEST_F(WindowTreeClientTest, InputEventCaptureWindow) {
  std::unique_ptr<WindowTreeHostMus> window_tree_host =
      std::make_unique<WindowTreeHostMus>(
          CreateInitParamsForTopLevel(window_tree_client_impl()));
  Window* top_level = window_tree_host->window();
  const gfx::Rect bounds(0, 0, 100, 100);
  static_cast<WindowTreeHost*>(window_tree_host.get())
      ->SetBoundsInPixels(bounds);
  window_tree_host->InitHost();
  window_tree_host->Show();
  EXPECT_EQ(bounds, top_level->bounds());
  EXPECT_EQ(bounds, window_tree_host->GetBoundsInPixels());
  std::unique_ptr<InputEventBasicTestWindowDelegate> window_delegate1(
      std::make_unique<InputEventBasicTestWindowDelegate>(window_tree()));
  std::unique_ptr<Window> child1(
      std::make_unique<Window>(window_delegate1.get()));
  child1->Init(ui::LAYER_NOT_DRAWN);
  child1->SetEventTargeter(std::make_unique<test::TestWindowTargeter>());
  top_level->AddChild(child1.get());
  child1->SetBounds(gfx::Rect(10, 10, 100, 100));
  child1->Show();
  std::unique_ptr<InputEventBasicTestWindowDelegate> window_delegate2(
      std::make_unique<InputEventBasicTestWindowDelegate>(window_tree()));
  std::unique_ptr<Window> child2(
      std::make_unique<Window>(window_delegate2.get()));
  child2->Init(ui::LAYER_NOT_DRAWN);
  child1->AddChild(child2.get());
  child2->SetBounds(gfx::Rect(20, 30, 100, 100));
  child2->Show();

  EXPECT_EQ(0, window_delegate1->move_count());
  EXPECT_EQ(0, window_delegate2->move_count());

  // child1 has a custom targeter set which would always return itself as the
  // target window therefore event should go to child1.
  const gfx::Point event_location(50, 60);
  const gfx::Point root_location;
  uint32_t event_id = 1;
  window_delegate1->set_event_id(event_id);
  window_delegate2->set_event_id(event_id);
  std::unique_ptr<ui::Event> ui_event(
      new ui::MouseEvent(ui::ET_MOUSE_MOVED, event_location, root_location,
                         ui::EventTimeForNow(), ui::EF_NONE, 0));
  window_tree_client()->OnWindowInputEvent(
      event_id, server_id(child1.get()), window_tree_host->display_id(),
      ui::Event::Clone(*ui_event.get()), 0);
  EXPECT_TRUE(window_tree()->WasEventAcked(event_id));
  EXPECT_EQ(ws::mojom::EventResult::HANDLED,
            window_tree()->GetEventResult(event_id));
  EXPECT_EQ(1, window_delegate1->move_count());
  EXPECT_EQ(0, window_delegate2->move_count());
  EXPECT_EQ(gfx::Point(50, 60), window_delegate1->last_event_location());
  window_delegate1->reset();
  window_delegate2->reset();

  // Set capture to |child2|. Capture takes precedence, and because the event is
  // converted local coordinates are converted from the original target to root
  // and then to capture target.
  std::unique_ptr<client::DefaultCaptureClient> capture_client(
      std::make_unique<client::DefaultCaptureClient>());
  client::SetCaptureClient(top_level, capture_client.get());
  child2->SetCapture();
  EXPECT_EQ(child2.get(), client::GetCaptureWindow(child2->GetRootWindow()));
  event_id = 2;
  window_delegate1->set_event_id(event_id);
  window_delegate2->set_event_id(event_id);
  window_tree_client()->OnWindowInputEvent(
      event_id, server_id(child1.get()), window_tree_host->display_id(),
      ui::Event::Clone(*ui_event.get()), 0);
  EXPECT_TRUE(window_tree()->WasEventAcked(event_id));
  EXPECT_EQ(ws::mojom::EventResult::HANDLED,
            window_tree()->GetEventResult(event_id));
  EXPECT_EQ(0, window_delegate1->move_count());
  EXPECT_EQ(1, window_delegate2->move_count());
  gfx::Point location_in_child2(event_location);
  Window::ConvertPointToTarget(child1.get(), top_level, &location_in_child2);
  Window::ConvertPointToTarget(top_level, child2.get(), &location_in_child2);
  EXPECT_EQ(location_in_child2, window_delegate2->last_event_location());
  child2.reset();
  child1.reset();
  window_tree_host.reset();
  capture_client.reset();
}

TEST_F(WindowTreeClientTest, InputEventRootWindow) {
  WindowTreeHostMus window_tree_host(
      CreateInitParamsForTopLevel(window_tree_client_impl()));
  Window* top_level = window_tree_host.window();
  InputEventBasicTestEventHandler root_handler(top_level);
  top_level->AddPreTargetHandler(&root_handler);
  const gfx::Rect bounds(0, 0, 100, 100);
  static_cast<WindowTreeHost*>(&window_tree_host)->SetBoundsInPixels(bounds);
  window_tree_host.InitHost();
  window_tree_host.Show();
  EXPECT_EQ(bounds, top_level->bounds());
  EXPECT_EQ(bounds, window_tree_host.GetBoundsInPixels());
  InputEventBasicTestWindowDelegate child_delegate(window_tree());
  Window child(&child_delegate);
  child.Init(ui::LAYER_NOT_DRAWN);
  top_level->AddChild(&child);
  child.SetBounds(gfx::Rect(10, 10, 100, 100));
  child.Show();

  EXPECT_EQ(0, root_handler.move_count());
  EXPECT_EQ(0, child_delegate.move_count());

  const gfx::Point event_location_in_child(20, 30);
  const uint32_t event_id = 1;
  root_handler.set_event_id(event_id);
  child_delegate.set_event_id(event_id);
  std::unique_ptr<ui::Event> ui_event(
      new ui::MouseEvent(ui::ET_MOUSE_MOVED, event_location_in_child,
                         gfx::Point(), ui::EventTimeForNow(), ui::EF_NONE, 0));
  window_tree_client()->OnWindowInputEvent(
      event_id, server_id(top_level), window_tree_host.display_id(),
      ui::Event::Clone(*ui_event.get()), 0);

  EXPECT_TRUE(window_tree()->WasEventAcked(event_id));
  EXPECT_EQ(ws::mojom::EventResult::HANDLED,
            window_tree()->GetEventResult(event_id));
  EXPECT_EQ(1, root_handler.move_count());
  EXPECT_EQ(gfx::Point(20, 30), root_handler.last_event_location());
  EXPECT_EQ(0, child_delegate.move_count());
  EXPECT_EQ(gfx::Point(), child_delegate.last_event_location());
  top_level->RemovePreTargetHandler(&root_handler);
}

TEST_F(WindowTreeClientTest, InputMouseEventNoWindow) {
  Env* env = Env::GetInstance();
  InputEventBasicTestWindowDelegate window_delegate(window_tree());
  WindowTreeHostMus window_tree_host(
      CreateInitParamsForTopLevel(window_tree_client_impl()));
  Window* top_level = window_tree_host.window();
  const gfx::Rect bounds(0, 0, 100, 100);
  static_cast<WindowTreeHost*>(&window_tree_host)->SetBoundsInPixels(bounds);
  window_tree_host.InitHost();
  window_tree_host.Show();
  EXPECT_EQ(bounds, top_level->bounds());
  EXPECT_EQ(bounds, window_tree_host.GetBoundsInPixels());
  Window child(&window_delegate);
  child.Init(ui::LAYER_NOT_DRAWN);
  top_level->AddChild(&child);
  child.SetBounds(gfx::Rect(10, 10, 100, 100));
  child.Show();

  EXPECT_EQ(0, window_delegate.press_count());
  EXPECT_FALSE(env->IsMouseButtonDown());
  EXPECT_FALSE(env->mouse_button_flags());
  EXPECT_EQ(gfx::Point(), env->last_mouse_location());

  const gfx::Point event_location(2, 3);
  uint32_t event_id = 1;
  window_delegate.set_event_id(event_id);
  ui::MouseEvent mouse_event_down(
      ui::ET_MOUSE_PRESSED, event_location, event_location,
      ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON, 0,
      ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_MOUSE, 0));
  window_tree_client()->OnWindowInputEvent(
      event_id, server_id(&child), window_tree_host.display_id(),
      ui::Event::Clone(mouse_event_down), 0);
  EXPECT_TRUE(window_tree()->WasEventAcked(event_id));
  EXPECT_EQ(ws::mojom::EventResult::HANDLED,
            window_tree()->GetEventResult(event_id));
  EXPECT_EQ(1, window_delegate.press_count());
  EXPECT_TRUE(env->IsMouseButtonDown());
  EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON, env->mouse_button_flags());
  EXPECT_EQ(event_location, env->last_mouse_location());
  window_delegate.reset();

  const gfx::Point event_location1(4, 5);
  event_id = 2;
  window_delegate.set_event_id(event_id);
  ui::MouseEvent mouse_event_up(
      ui::ET_MOUSE_RELEASED, event_location1, event_location,
      ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON,
      ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_MOUSE, 0));
  window_tree_client()->OnWindowInputEvent(event_id, kInvalidServerId,
                                           window_tree_host.display_id(),
                                           ui::Event::Clone(mouse_event_up), 0);
  EXPECT_TRUE(window_tree()->WasEventAcked(event_id));
  // WindowTreeClient::OnWindowInputEvent cannot find a target window with
  // kInvalidServerId but should use the event to update event states kept in
  // aura::Env, location shouldn't be updated.
  EXPECT_EQ(ws::mojom::EventResult::UNHANDLED,
            window_tree()->GetEventResult(event_id));
  EXPECT_EQ(0, window_delegate.release_count());
  EXPECT_FALSE(env->IsMouseButtonDown());
  EXPECT_FALSE(env->mouse_button_flags());
  EXPECT_EQ(event_location, env->last_mouse_location());
}

TEST_F(WindowTreeClientTest, InputTouchEventNoWindow) {
  Env* env = Env::GetInstance();
  InputEventBasicTestWindowDelegate window_delegate(window_tree());
  WindowTreeHostMus window_tree_host(
      CreateInitParamsForTopLevel(window_tree_client_impl()));
  Window* top_level = window_tree_host.window();
  const gfx::Rect bounds(0, 0, 100, 100);
  static_cast<WindowTreeHost*>(&window_tree_host)->SetBoundsInPixels(bounds);
  window_tree_host.InitHost();
  window_tree_host.Show();
  EXPECT_EQ(bounds, top_level->bounds());
  EXPECT_EQ(bounds, window_tree_host.GetBoundsInPixels());
  Window child(&window_delegate);
  child.Init(ui::LAYER_NOT_DRAWN);
  top_level->AddChild(&child);
  child.SetBounds(gfx::Rect(10, 10, 100, 100));
  child.Show();

  EXPECT_EQ(0, window_delegate.press_count());
  EXPECT_FALSE(env->is_touch_down());

  const gfx::Point event_location(2, 3);
  uint32_t event_id = 1;
  window_delegate.set_event_id(event_id);
  ui::TouchEvent touch_event_down(
      ui::ET_TOUCH_PRESSED, event_location, ui::EventTimeForNow(),
      ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0));
  window_tree_client()->OnWindowInputEvent(
      event_id, server_id(&child), window_tree_host.display_id(),
      ui::Event::Clone(touch_event_down), 0);
  EXPECT_TRUE(window_tree()->WasEventAcked(event_id));
  EXPECT_EQ(ws::mojom::EventResult::HANDLED,
            window_tree()->GetEventResult(event_id));
  EXPECT_EQ(1, window_delegate.press_count());
  EXPECT_TRUE(env->is_touch_down());
  window_delegate.reset();

  event_id = 2;
  window_delegate.set_event_id(event_id);
  ui::TouchEvent touch_event_up(
      ui::ET_TOUCH_RELEASED, event_location, ui::EventTimeForNow(),
      ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0));
  window_tree_client()->OnWindowInputEvent(event_id, kInvalidServerId,
                                           window_tree_host.display_id(),
                                           ui::Event::Clone(touch_event_up), 0);
  EXPECT_TRUE(window_tree()->WasEventAcked(event_id));
  // WindowTreeClient::OnWindowInputEvent cannot find a target window with
  // kInvalidServerId but should use the event to update event states kept in
  // aura::Env.
  EXPECT_EQ(ws::mojom::EventResult::UNHANDLED,
            window_tree()->GetEventResult(event_id));
  EXPECT_EQ(0, window_delegate.release_count());
  EXPECT_FALSE(env->is_touch_down());
}

// Tests observation of events that did not hit a target in this window tree.
TEST_F(WindowTreeClientTest, OnObservedInputEvent) {
  std::unique_ptr<Window> top_level(std::make_unique<Window>(nullptr));
  top_level->SetType(client::WINDOW_TYPE_NORMAL);
  top_level->Init(ui::LAYER_NOT_DRAWN);
  top_level->SetBounds(gfx::Rect(0, 0, 100, 100));
  top_level->Show();

  // Start observing touch press events.
  TestEventObserver test_event_observer;
  top_level->env()->AddEventObserver(&test_event_observer, top_level->env(),
                                     {ui::ET_TOUCH_PRESSED});

  // Simulate the server sending an observed event.
  ui::TouchEvent touch_press(
      ui::ET_TOUCH_PRESSED, gfx::Point(), ui::EventTimeForNow(),
      ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 1));
  window_tree_client()->OnObservedInputEvent(ui::Event::Clone(touch_press));

  // The observer should have been notified of the event.
  ASSERT_TRUE(test_event_observer.last_event());
  EXPECT_EQ(ui::ET_TOUCH_PRESSED, test_event_observer.last_event()->type());
  test_event_observer.ResetLastEvent();

  // Remove the event observer.
  top_level->env()->RemoveEventObserver(&test_event_observer);

  // Simulate another event from the server.
  window_tree_client()->OnObservedInputEvent(ui::Event::Clone(touch_press));

  // The observer should not have been notified of the event.
  EXPECT_FALSE(test_event_observer.last_event());
}

// Tests observation of events that did hit a target in this window tree.
TEST_F(WindowTreeClientTest, OnWindowInputEventWithObserver) {
  WindowTreeHostMus window_tree_host(
      CreateInitParamsForTopLevel(window_tree_client_impl()));
  Window* top_level = window_tree_host.window();
  const gfx::Rect bounds(50, 50, 100, 100);
  static_cast<WindowTreeHost*>(&window_tree_host)->SetBoundsInPixels(bounds);
  window_tree_host.InitHost();
  window_tree_host.Show();
  EXPECT_EQ(bounds.size(), top_level->bounds().size());

  // Start observing touch press events.
  TestEventObserver test_event_observer;
  top_level->env()->AddEventObserver(&test_event_observer, top_level->env(),
                                     {ui::ET_TOUCH_PRESSED});

  // Simulate the server dispatching an event that also matched the observer.
  ui::TouchEvent touch_press(
      ui::ET_TOUCH_PRESSED, gfx::Point(), ui::EventTimeForNow(),
      ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 1));
  window_tree_client()->OnWindowInputEvent(1, server_id(top_level), 0,
                                           ui::Event::Clone(touch_press), true);

  // The observer should have been notified of the event.
  ASSERT_TRUE(test_event_observer.last_event());
  EXPECT_EQ(ui::ET_TOUCH_PRESSED, test_event_observer.last_event()->type());
  top_level->env()->RemoveEventObserver(&test_event_observer);
}

// Verifies focus is reverted if the server replied that the change failed.
TEST_F(WindowTreeClientTest, SetFocusFailed) {
  Window child(nullptr);
  child.Init(ui::LAYER_NOT_DRAWN);
  root_window()->AddChild(&child);
  // AuraTestHelper::SetUp sets the active focus client and focus client root,
  // root_window is assumed to have focus until we actually focus on a
  // certain window.
  EXPECT_EQ(WindowMus::Get(root_window()),
            window_tree_client_impl()->focus_synchronizer()->focused_window());
  child.Focus();
  ASSERT_TRUE(child.HasFocus());
  EXPECT_EQ(&child, client::GetFocusClient(&child)->GetFocusedWindow());
  ASSERT_TRUE(
      window_tree()->AckSingleChangeOfType(WindowTreeChangeType::FOCUS, false));
  // If the change failed, we fall back to the revert_value which is the
  // current focused_window.
  EXPECT_EQ(root_window(), client::GetFocusClient(&child)->GetFocusedWindow());
}

// Simulates a focus change, and while the focus change is in flight the server
// replies with a new focus and the original focus change fails.
TEST_F(WindowTreeClientTest, SetFocusFailedWithPendingChange) {
  Window child1(nullptr);
  child1.Init(ui::LAYER_NOT_DRAWN);
  root_window()->AddChild(&child1);
  Window child2(nullptr);
  child2.Init(ui::LAYER_NOT_DRAWN);
  root_window()->AddChild(&child2);
  Window* original_focus = client::GetFocusClient(&child1)->GetFocusedWindow();
  Window* new_focus = &child1;
  ASSERT_NE(new_focus, original_focus);
  new_focus->Focus();
  ASSERT_TRUE(new_focus->HasFocus());

  // Simulate the server responding with a focus change.
  window_tree_client()->OnWindowFocused(server_id(&child2));

  // This shouldn't trigger focus changing yet.
  EXPECT_TRUE(child1.HasFocus());

  // Tell the client the change failed, which should trigger failing to the
  // most recent focus from server.
  ASSERT_TRUE(
      window_tree()->AckSingleChangeOfType(WindowTreeChangeType::FOCUS, false));
  EXPECT_FALSE(child1.HasFocus());
  EXPECT_TRUE(child2.HasFocus());
  EXPECT_EQ(&child2, client::GetFocusClient(&child1)->GetFocusedWindow());

  // Simulate server changing focus to child1. Should take immediately.
  window_tree_client()->OnWindowFocused(server_id(&child1));
  EXPECT_TRUE(child1.HasFocus());
}

TEST_F(WindowTreeClientTest, FocusOnRemovedWindowWithoutInFlightFocusChange) {
  std::unique_ptr<Window> child1(std::make_unique<Window>(nullptr));
  child1->Init(ui::LAYER_NOT_DRAWN);
  root_window()->AddChild(child1.get());
  Window child2(nullptr);
  child2.Init(ui::LAYER_NOT_DRAWN);
  root_window()->AddChild(&child2);

  child1->Focus();
  // Acked for the focus change.
  EXPECT_TRUE(
      window_tree()->AckSingleChangeOfType(WindowTreeChangeType::FOCUS, true));

  // Destroy child1, which should set focus to null.
  child1.reset(nullptr);
  EXPECT_EQ(nullptr, client::GetFocusClient(root_window())->GetFocusedWindow());
  // The reset of the focus shouldn't be sent to the server.
  EXPECT_EQ(0u,
            window_tree()->GetChangeCountForType(WindowTreeChangeType::FOCUS));

  // Server changes focus to 2.
  window_tree_client()->OnWindowFocused(server_id(&child2));
  // Should take effect immediately.
  EXPECT_TRUE(child2.HasFocus());
}

class ToggleVisibilityFromDestroyedObserver : public WindowObserver {
 public:
  explicit ToggleVisibilityFromDestroyedObserver(Window* window)
      : window_(window) {
    window_->AddObserver(this);
  }

  ToggleVisibilityFromDestroyedObserver() { EXPECT_FALSE(window_); }

  // WindowObserver:
  void OnWindowDestroyed(Window* window) override {
    SetWindowVisibility(window, !window->TargetVisibility());
    window_->RemoveObserver(this);
    window_ = nullptr;
  }

 private:
  Window* window_;

  DISALLOW_COPY_AND_ASSIGN(ToggleVisibilityFromDestroyedObserver);
};

TEST_F(WindowTreeClientTest, ToggleVisibilityFromWindowDestroyed) {
  std::unique_ptr<Window> child(std::make_unique<Window>(nullptr));
  child->Init(ui::LAYER_NOT_DRAWN);
  root_window()->AddChild(child.get());
  ToggleVisibilityFromDestroyedObserver toggler(child.get());
  // Destroying the window triggers
  // ToggleVisibilityFromDestroyedObserver::OnWindowDestroyed(), which toggles
  // the visibility of the window. Ack the change, which should not crash or
  // trigger DCHECKs.
  child.reset();
  ASSERT_TRUE(window_tree()->AckSingleChangeOfType(
      WindowTreeChangeType::VISIBLE, true));
}

TEST_F(WindowTreeClientTest, NewTopLevelWindow) {
  const size_t initial_root_count =
      window_tree_client_impl()->GetRoots().size();
  std::unique_ptr<WindowTreeHostMus> window_tree_host =
      std::make_unique<WindowTreeHostMus>(
          CreateInitParamsForTopLevel(window_tree_client_impl()));
  window_tree_host->InitHost();
  EXPECT_FALSE(window_tree_host->window()->TargetVisibility());
  aura::Window* top_level = window_tree_host->window();
  EXPECT_EQ(initial_root_count + 1,
            window_tree_client_impl()->GetRoots().size());
  EXPECT_TRUE(window_tree_client_impl()->GetRoots().count(top_level) > 0u);

  // Ack the request to the windowtree to create the new window.
  uint32_t change_id;
  ASSERT_TRUE(window_tree()->GetAndRemoveFirstChangeOfType(
      WindowTreeChangeType::NEW_TOP_LEVEL, &change_id));
  EXPECT_EQ(window_tree()->window_id(), server_id(top_level));

  ws::mojom::WindowDataPtr data = ws::mojom::WindowData::New();
  data->window_id = server_id(top_level);
  const int64_t display_id = 1;
  window_tree_client()->OnTopLevelCreated(
      change_id, std::move(data), display_id, false,
      GenerateLocalSurfaceIdForNewTopLevel());

  EXPECT_FALSE(window_tree_host->window()->TargetVisibility());

  // Should not be able to add a top level as a child of another window.
  // TODO(sky): decide how to handle this.
  // root_window()->AddChild(top_level);
  // ASSERT_EQ(nullptr, top_level->parent());

  // Destroy the first root, shouldn't initiate tear down.
  window_tree_host.reset();
  EXPECT_EQ(initial_root_count, window_tree_client_impl()->GetRoots().size());
}

TEST_F(WindowTreeClientTest, NewTopLevelWindowGetsPropertiesFromData) {
  const size_t initial_root_count =
      window_tree_client_impl()->GetRoots().size();
  WindowTreeHostMus window_tree_host(
      CreateInitParamsForTopLevel(window_tree_client_impl()));
  Window* top_level = window_tree_host.window();
  EXPECT_EQ(initial_root_count + 1,
            window_tree_client_impl()->GetRoots().size());

  EXPECT_FALSE(IsWindowHostVisible(top_level));
  EXPECT_FALSE(top_level->TargetVisibility());

  window_tree_host.InitHost();
  EXPECT_FALSE(window_tree_host.window()->TargetVisibility());

  // Ack the request to the windowtree to create the new window.
  EXPECT_EQ(window_tree()->window_id(), server_id(top_level));

  ws::mojom::WindowDataPtr data = ws::mojom::WindowData::New();
  data->window_id = server_id(top_level);
  data->bounds.SetRect(1, 2, 3, 4);
  data->visible = true;
  const int64_t display_id = 10;
  uint32_t change_id;
  ASSERT_TRUE(window_tree()->GetAndRemoveFirstChangeOfType(
      WindowTreeChangeType::NEW_TOP_LEVEL, &change_id));
  window_tree_client()->OnTopLevelCreated(
      change_id, std::move(data), display_id, true,
      GenerateLocalSurfaceIdForNewTopLevel());
  EXPECT_EQ(
      0u, window_tree()->GetChangeCountForType(WindowTreeChangeType::VISIBLE));

  // Make sure all the properties took.
  EXPECT_TRUE(IsWindowHostVisible(top_level));
  EXPECT_TRUE(top_level->TargetVisibility());
  EXPECT_EQ(display_id, window_tree_host.display_id());
  EXPECT_EQ(gfx::Rect(0, 0, 3, 4), top_level->bounds());
  EXPECT_EQ(gfx::Rect(1, 2, 3, 4), top_level->GetHost()->GetBoundsInPixels());
}

TEST_F(WindowTreeClientTest, NewWindowGetsAllChangesInFlight) {
  RegisterTestProperties(GetPropertyConverter());

  WindowTreeHostMus window_tree_host(
      CreateInitParamsForTopLevel(window_tree_client_impl()));
  Window* top_level = window_tree_host.window();
  EXPECT_FALSE(top_level->TargetVisibility());

  window_tree_host.InitHost();

  // Make visibility go from false->true->false. Don't ack immediately.
  top_level->Show();
  top_level->Hide();

  // Change bounds to 5, 6, 7, 8.
  static_cast<WindowTreeHost*>(&window_tree_host)
      ->SetBoundsInPixels(gfx::Rect(5, 6, 7, 8));
  EXPECT_EQ(gfx::Rect(0, 0, 7, 8), window_tree_host.window()->bounds());

  const uint8_t explicitly_set_test_property1_value = 2;
  top_level->SetProperty(kTestPropertyKey1,
                         explicitly_set_test_property1_value);

  // Ack the new window top level top_level Vis and bounds shouldn't change.
  ws::mojom::WindowDataPtr data = ws::mojom::WindowData::New();
  data->window_id = server_id(top_level);
  const gfx::Rect bounds_from_server(1, 2, 3, 4);
  data->bounds = bounds_from_server;
  data->visible = true;
  const uint8_t server_test_property1_value = 3;
  data->properties[kTestPropertyServerKey1] =
      ConvertToPropertyTransportValue(server_test_property1_value);
  const uint8_t server_test_property2_value = 4;
  data->properties[kTestPropertyServerKey2] =
      ConvertToPropertyTransportValue(server_test_property2_value);
  const int64_t display_id = 1;
  // Get the id of the in flight change for creating the new top_level.
  uint32_t new_window_in_flight_change_id;
  ASSERT_TRUE(window_tree()->GetAndRemoveFirstChangeOfType(
      WindowTreeChangeType::NEW_TOP_LEVEL, &new_window_in_flight_change_id));
  window_tree_client()->OnTopLevelCreated(
      new_window_in_flight_change_id, std::move(data), display_id, true,
      GenerateLocalSurfaceIdForNewTopLevel());

  // The only value that should take effect is the property for 'yy' as it was
  // not in flight.
  EXPECT_FALSE(top_level->TargetVisibility());
  EXPECT_EQ(gfx::Rect(5, 6, 7, 8), window_tree_host.GetBoundsInPixels());
  EXPECT_EQ(gfx::Rect(0, 0, 7, 8), top_level->bounds());
  EXPECT_EQ(explicitly_set_test_property1_value,
            top_level->GetProperty(kTestPropertyKey1));
  EXPECT_EQ(server_test_property2_value,
            top_level->GetProperty(kTestPropertyKey2));

  // Tell the client the changes failed. This should cause the values to change
  // to that of the server.
  ASSERT_TRUE(window_tree()->AckFirstChangeOfType(WindowTreeChangeType::VISIBLE,
                                                  false));
  EXPECT_FALSE(top_level->TargetVisibility());
  ASSERT_TRUE(window_tree()->AckSingleChangeOfType(
      WindowTreeChangeType::VISIBLE, false));
  EXPECT_TRUE(top_level->TargetVisibility());
  window_tree()->AckAllChangesOfType(WindowTreeChangeType::PROPERTY, false);
  EXPECT_EQ(server_test_property1_value,
            top_level->GetProperty(kTestPropertyKey1));
  EXPECT_EQ(server_test_property2_value,
            top_level->GetProperty(kTestPropertyKey2));
}

TEST_F(WindowTreeClientTest, NewWindowGetsProperties) {
  RegisterTestProperties(GetPropertyConverter());
  Window window(nullptr);
  const uint8_t explicitly_set_test_property1_value = 29;
  window.SetProperty(kTestPropertyKey1, explicitly_set_test_property1_value);
  window.Init(ui::LAYER_NOT_DRAWN);
  base::Optional<base::flat_map<std::string, std::vector<uint8_t>>>
      transport_properties = window_tree()->GetLastNewWindowProperties();
  ASSERT_TRUE(transport_properties.has_value());
  std::map<std::string, std::vector<uint8_t>> properties =
      mojo::FlatMapToMap(*transport_properties);
  ASSERT_EQ(1u, properties.count(kTestPropertyServerKey1));
  // PropertyConverter uses int64_t values, even for smaller types like uint8_t.
  ASSERT_EQ(8u, properties[kTestPropertyServerKey1].size());
  EXPECT_EQ(static_cast<int64_t>(explicitly_set_test_property1_value),
            mojo::ConvertTo<int64_t>(properties[kTestPropertyServerKey1]));
  ASSERT_EQ(0u, properties.count(kTestPropertyServerKey2));
}

// Assertions around transient windows.
TEST_F(WindowTreeClientTest, Transients) {
  aura::Window root_window(nullptr);
  root_window.Init(ui::LAYER_NOT_DRAWN);
  client::TransientWindowClient* transient_client =
      client::GetTransientWindowClient();
  Window parent(nullptr);
  parent.Init(ui::LAYER_NOT_DRAWN);
  root_window.AddChild(&parent);
  Window transient(nullptr);
  transient.Init(ui::LAYER_NOT_DRAWN);
  root_window.AddChild(&transient);
  window_tree()->AckAllChanges();
  transient_client->AddTransientChild(&parent, &transient);
  ASSERT_EQ(1u, window_tree()->GetChangeCountForType(
                    WindowTreeChangeType::ADD_TRANSIENT));
  EXPECT_EQ(server_id(&parent), window_tree()->transient_data().parent_id);
  EXPECT_EQ(server_id(&transient), window_tree()->transient_data().child_id);

  // Remove from the server side.
  window_tree_client()->OnTransientWindowRemoved(server_id(&parent),
                                                 server_id(&transient));
  EXPECT_EQ(nullptr, transient_client->GetTransientParent(&transient));
  window_tree()->AckAllChanges();

  // Add from the server.
  window_tree_client()->OnTransientWindowAdded(server_id(&parent),
                                               server_id(&transient));
  EXPECT_EQ(&parent, transient_client->GetTransientParent(&transient));

  // Remove locally.
  transient_client->RemoveTransientChild(&parent, &transient);
  ASSERT_EQ(1u, window_tree()->GetChangeCountForType(
                    WindowTreeChangeType::REMOVE_TRANSIENT));
  EXPECT_EQ(server_id(&transient), window_tree()->transient_data().child_id);
}

TEST_F(WindowTreeClientTest, DontRestackTransientsFromOtherClients) {
  // Create a window from another client with 3 children.
  const int32_t other_client_id = 11 << 16;
  int32_t other_client_window_id = 1;
  std::unique_ptr<Window> other_client_window = CreateWindowUsingId(
      window_tree_client_impl(), other_client_id | other_client_window_id++,
      root_window());
  std::unique_ptr<Window> other_client_child_window1 = CreateWindowUsingId(
      window_tree_client_impl(), other_client_id | other_client_window_id++,
      other_client_window.get());
  std::unique_ptr<Window> other_client_child_window2 = CreateWindowUsingId(
      window_tree_client_impl(), other_client_id | other_client_window_id++,
      other_client_window.get());
  std::unique_ptr<Window> other_client_child_window3 = CreateWindowUsingId(
      window_tree_client_impl(), other_client_id | other_client_window_id++,
      other_client_window.get());
  window_tree()->AckAllChanges();

  // Make |other_client_child_window3| a transient child of
  // |other_client_child_window1|. This should *not* reorder locally as the
  // windows are parented to a window owned by another client.
  window_tree_client()->OnTransientWindowAdded(
      server_id(other_client_child_window1.get()),
      server_id(other_client_child_window3.get()));
  // There should be no changes sent to the server, and the children should
  // not have been reordered.
  EXPECT_EQ(0u, window_tree()->number_of_changes());
  ASSERT_EQ(3u, other_client_window->children().size());
  EXPECT_EQ(other_client_child_window2.get(),
            other_client_window->children()[1]);

  // Make sure transient was wired correctly though.
  client::TransientWindowClient* transient_client =
      client::GetTransientWindowClient();
  EXPECT_EQ(
      other_client_child_window1.get(),
      transient_client->GetTransientParent(other_client_child_window3.get()));
}

// Verifies adding/removing a transient child notifies the server of the restack
// when the change originates from the server.
TEST_F(WindowTreeClientTest, TransientChildServerMutateNotifiesOfRestack) {
  aura::Window root_window(nullptr);
  root_window.Init(ui::LAYER_NOT_DRAWN);
  Window* w1 = new Window(nullptr);
  w1->Init(ui::LAYER_NOT_DRAWN);
  root_window.AddChild(w1);
  Window* w2 = new Window(nullptr);
  w2->Init(ui::LAYER_NOT_DRAWN);
  root_window.AddChild(w2);
  Window* w3 = new Window(nullptr);
  w3->Init(ui::LAYER_NOT_DRAWN);
  root_window.AddChild(w3);
  // Three children of root: |w1|, |w2| and |w3| (in that order). Make |w1| a
  // transient child of |w2|. Should trigger moving |w1| on top of |w2|, but not
  // notify the server of the reorder.
  window_tree()->AckAllChanges();
  window_tree_client()->OnTransientWindowAdded(server_id(w2), server_id(w1));
  EXPECT_EQ(w2, root_window.children()[0]);
  EXPECT_EQ(w1, root_window.children()[1]);
  EXPECT_EQ(w3, root_window.children()[2]);
  // Only reorders should be generated.
  EXPECT_NE(0u, window_tree()->number_of_changes());
  window_tree()->AckAllChangesOfType(WindowTreeChangeType::REORDER, true);
  EXPECT_EQ(0u, window_tree()->number_of_changes());

  // Make |w3| also a transient child of |w2|.
  window_tree_client()->OnTransientWindowAdded(server_id(w2), server_id(w3));
  EXPECT_EQ(w2, root_window.children()[0]);
  EXPECT_EQ(w1, root_window.children()[1]);
  EXPECT_EQ(w3, root_window.children()[2]);
  // Only reorders should be generated.
  EXPECT_NE(0u, window_tree()->number_of_changes());
  window_tree()->AckAllChangesOfType(WindowTreeChangeType::REORDER, true);
  EXPECT_EQ(0u, window_tree()->number_of_changes());

  // Remove |w1| as a transient child, this should move |w3| on top of |w2|.
  window_tree_client()->OnTransientWindowRemoved(server_id(w2), server_id(w1));
  EXPECT_EQ(w2, root_window.children()[0]);
  EXPECT_EQ(w3, root_window.children()[1]);
  EXPECT_EQ(w1, root_window.children()[2]);
  // Only reorders should be generated.
  EXPECT_NE(0u, window_tree()->number_of_changes());
  window_tree()->AckAllChangesOfType(WindowTreeChangeType::REORDER, true);
  EXPECT_EQ(0u, window_tree()->number_of_changes());
}

// Verifies adding/removing a transient child notifies the server of the
// restacks;
TEST_F(WindowTreeClientTest, TransientChildClientMutateNotifiesOfRestack) {
  aura::Window root_window(nullptr);
  root_window.Init(ui::LAYER_NOT_DRAWN);

  client::TransientWindowClient* transient_client =
      client::GetTransientWindowClient();
  Window* w1 = new Window(nullptr);
  w1->Init(ui::LAYER_NOT_DRAWN);
  root_window.AddChild(w1);
  Window* w2 = new Window(nullptr);
  w2->Init(ui::LAYER_NOT_DRAWN);
  root_window.AddChild(w2);
  Window* w3 = new Window(nullptr);
  w3->Init(ui::LAYER_NOT_DRAWN);
  root_window.AddChild(w3);
  // Three children of root: |w1|, |w2| and |w3| (in that order). Make |w1| a
  // transient child of |w2|. Should trigger moving |w1| on top of |w2|, and
  // notify notify the server of the reorder.
  window_tree()->AckAllChanges();
  transient_client->AddTransientChild(w2, w1);
  EXPECT_EQ(w2, root_window.children()[0]);
  EXPECT_EQ(w1, root_window.children()[1]);
  EXPECT_EQ(w3, root_window.children()[2]);
  EXPECT_TRUE(window_tree()->AckSingleChangeOfType(
      WindowTreeChangeType::ADD_TRANSIENT, true));
  EXPECT_TRUE(window_tree()->AckSingleChangeOfType(
      WindowTreeChangeType::REORDER, true));
  EXPECT_EQ(0u, window_tree()->number_of_changes());

  // Make |w3| also a transient child of |w2|. Order shouldn't change.
  transient_client->AddTransientChild(w2, w3);
  EXPECT_EQ(w2, root_window.children()[0]);
  EXPECT_EQ(w1, root_window.children()[1]);
  EXPECT_EQ(w3, root_window.children()[2]);
  EXPECT_TRUE(window_tree()->AckSingleChangeOfType(
      WindowTreeChangeType::ADD_TRANSIENT, true));
  // While the order doesn't change, internally aura shuffles things around,
  // hence the REORDERs.
  EXPECT_NE(0u, window_tree()->number_of_changes());
  window_tree()->AckAllChangesOfType(WindowTreeChangeType::REORDER, true);
  EXPECT_EQ(0u, window_tree()->number_of_changes());

  // Remove |w1| as a transient child, this should move |w3| on top of |w2|.
  transient_client->RemoveTransientChild(w2, w1);
  EXPECT_EQ(w2, root_window.children()[0]);
  EXPECT_EQ(w3, root_window.children()[1]);
  EXPECT_EQ(w1, root_window.children()[2]);
  EXPECT_TRUE(window_tree()->AckSingleChangeOfType(
      WindowTreeChangeType::REMOVE_TRANSIENT, true));
  EXPECT_TRUE(window_tree()->AckSingleChangeOfType(
      WindowTreeChangeType::REORDER, true));
  EXPECT_EQ(0u, window_tree()->number_of_changes());

  // Make |w1| the first child and ensure a REORDER was scheduled.
  root_window.StackChildAtBottom(w1);
  EXPECT_EQ(w1, root_window.children()[0]);
  EXPECT_EQ(w2, root_window.children()[1]);
  EXPECT_EQ(w3, root_window.children()[2]);
  EXPECT_TRUE(window_tree()->AckSingleChangeOfType(
      WindowTreeChangeType::REORDER, true));
  EXPECT_EQ(0u, window_tree()->number_of_changes());

  // Try stacking |w2| above |w3|. This should be disallowed as that would
  // result in placing |w2| above its transient child.
  root_window.StackChildAbove(w2, w3);
  EXPECT_EQ(w1, root_window.children()[0]);
  EXPECT_EQ(w2, root_window.children()[1]);
  EXPECT_EQ(w3, root_window.children()[2]);
  // The stack above is followed by a reorder from TransientWindowManager,
  // hence multiple changes.
  EXPECT_NE(0u, window_tree()->number_of_changes());
  window_tree()->AckAllChangesOfType(WindowTreeChangeType::REORDER, true);
  EXPECT_EQ(0u, window_tree()->number_of_changes());
}

TEST_F(WindowTreeClientTest, TopLevelWindowDestroyedBeforeCreateComplete) {
  const size_t initial_root_count =
      window_tree_client_impl()->GetRoots().size();
  std::unique_ptr<WindowTreeHostMus> window_tree_host =
      std::make_unique<WindowTreeHostMus>(
          CreateInitParamsForTopLevel(window_tree_client_impl()));
  window_tree_host->InitHost();
  EXPECT_EQ(initial_root_count + 1,
            window_tree_client_impl()->GetRoots().size());

  ws::mojom::WindowDataPtr data = ws::mojom::WindowData::New();
  data->window_id = server_id(window_tree_host->window());

  // Destroy the window before the server has a chance to ack the window
  // creation.
  window_tree_host.reset();
  EXPECT_EQ(initial_root_count, window_tree_client_impl()->GetRoots().size());

  // Get the id of the in flight change for creating the new window.
  uint32_t change_id;
  ASSERT_TRUE(window_tree()->GetAndRemoveFirstChangeOfType(
      WindowTreeChangeType::NEW_TOP_LEVEL, &change_id));

  const int64_t display_id = 1;
  window_tree_client()->OnTopLevelCreated(
      change_id, std::move(data), display_id, true,
      GenerateLocalSurfaceIdForNewTopLevel());
  EXPECT_EQ(initial_root_count, window_tree_client_impl()->GetRoots().size());
}

TEST_F(WindowTreeClientTest, NewTopLevelWindowGetsProperties) {
  RegisterTestProperties(GetPropertyConverter());
  const uint8_t property_value = 11;
  std::map<std::string, std::vector<uint8_t>> properties;
  properties[kTestPropertyServerKey1] =
      ConvertToPropertyTransportValue(property_value);
  const char kUnknownPropertyKey[] = "unknown-property";
  using UnknownPropertyType = int32_t;
  const UnknownPropertyType kUnknownPropertyValue = 101;
  properties[kUnknownPropertyKey] =
      mojo::ConvertTo<std::vector<uint8_t>>(kUnknownPropertyValue);
  WindowTreeHostMus window_tree_host(CreateInitParamsForTopLevel(
      window_tree_client_impl(), std::move(properties)));
  window_tree_host.InitHost();
  window_tree_host.window()->Show();
  // Verify the property made it to the window.
  EXPECT_EQ(property_value,
            window_tree_host.window()->GetProperty(kTestPropertyKey1));

  // Get the id of the in flight change for creating the new top level window.
  uint32_t change_id;
  ASSERT_TRUE(window_tree()->GetAndRemoveFirstChangeOfType(
      WindowTreeChangeType::NEW_TOP_LEVEL, &change_id));

  // Verify the properties were sent to the server.
  base::Optional<base::flat_map<std::string, std::vector<uint8_t>>>
      transport_properties = window_tree()->GetLastNewWindowProperties();
  ASSERT_TRUE(transport_properties.has_value());
  std::map<std::string, std::vector<uint8_t>> properties2 =
      mojo::FlatMapToMap(*transport_properties);
  ASSERT_EQ(1u, properties2.count(kTestPropertyServerKey1));
  // PropertyConverter uses int64_t values, even for smaller types like uint8_t.
  ASSERT_EQ(8u, properties2[kTestPropertyServerKey1].size());
  EXPECT_EQ(static_cast<int64_t>(property_value),
            mojo::ConvertTo<int64_t>(properties2[kTestPropertyServerKey1]));

  ASSERT_EQ(1u, properties2.count(kUnknownPropertyKey));
  ASSERT_EQ(sizeof(UnknownPropertyType),
            properties2[kUnknownPropertyKey].size());
  EXPECT_EQ(kUnknownPropertyValue, mojo::ConvertTo<UnknownPropertyType>(
                                       properties2[kUnknownPropertyKey]));
}

namespace {

class CloseWindowWindowTreeHostObserver : public aura::WindowTreeHostObserver {
 public:
  CloseWindowWindowTreeHostObserver() {}
  ~CloseWindowWindowTreeHostObserver() override {}

  bool root_destroyed() const { return root_destroyed_; }

  // aura::WindowTreeHostObserver::
  void OnHostCloseRequested(aura::WindowTreeHost* host) override {
    root_destroyed_ = true;
  }

 private:
  bool root_destroyed_ = false;

  DISALLOW_COPY_AND_ASSIGN(CloseWindowWindowTreeHostObserver);
};

}  // namespace

TEST_F(WindowTreeClientTest, CloseWindow) {
  WindowTreeHostMus window_tree_host(
      CreateInitParamsForTopLevel(window_tree_client_impl()));
  window_tree_host.InitHost();
  CloseWindowWindowTreeHostObserver observer;
  window_tree_host.AddObserver(&observer);
  Window* top_level = window_tree_host.window();

  // Close a root window should send close request to the observer of its
  // WindowTreeHost.
  EXPECT_FALSE(observer.root_destroyed());
  window_tree_client()->RequestClose(server_id(top_level));
  EXPECT_TRUE(observer.root_destroyed());
}

// Tests both SetCapture and ReleaseCapture, to ensure that Window is properly
// updated on failures.
TEST_F(WindowTreeClientTest, ExplicitCapture) {
  root_window()->SetCapture();
  EXPECT_TRUE(root_window()->HasCapture());
  ASSERT_TRUE(window_tree()->AckSingleChangeOfType(
      WindowTreeChangeType::CAPTURE, false));
  EXPECT_FALSE(root_window()->HasCapture());

  root_window()->SetCapture();
  EXPECT_TRUE(root_window()->HasCapture());
  ASSERT_TRUE(window_tree()->AckSingleChangeOfType(
      WindowTreeChangeType::CAPTURE, true));
  EXPECT_TRUE(root_window()->HasCapture());

  root_window()->ReleaseCapture();
  EXPECT_FALSE(root_window()->HasCapture());
  ASSERT_TRUE(window_tree()->AckSingleChangeOfType(
      WindowTreeChangeType::CAPTURE, false));
  EXPECT_TRUE(root_window()->HasCapture());

  root_window()->ReleaseCapture();
  ASSERT_TRUE(window_tree()->AckSingleChangeOfType(
      WindowTreeChangeType::CAPTURE, true));
  EXPECT_FALSE(root_window()->HasCapture());
}

// Tests that when capture is lost, while there is a release capture request
// inflight, that the revert value of that request is updated correctly.
TEST_F(WindowTreeClientTest, LostCaptureDifferentInFlightChange) {
  root_window()->SetCapture();
  EXPECT_TRUE(root_window()->HasCapture());
  ASSERT_TRUE(window_tree()->AckSingleChangeOfType(
      WindowTreeChangeType::CAPTURE, true));
  EXPECT_TRUE(root_window()->HasCapture());

  // The ReleaseCapture should be updated to the revert of the SetCapture.
  root_window()->ReleaseCapture();

  window_tree_client()->OnCaptureChanged(0, server_id(root_window()));
  EXPECT_FALSE(root_window()->HasCapture());

  ASSERT_TRUE(window_tree()->AckSingleChangeOfType(
      WindowTreeChangeType::CAPTURE, false));
  EXPECT_FALSE(root_window()->HasCapture());
}

// Tests that while two windows can inflight capture requests, that the
// WindowTreeClient only identifies one as having the current capture.
TEST_F(WindowTreeClientTest, TwoWindowsRequestCapture) {
  Window child(nullptr);
  child.Init(ui::LAYER_NOT_DRAWN);
  root_window()->AddChild(&child);
  child.Show();

  root_window()->SetCapture();
  EXPECT_TRUE(root_window()->HasCapture());

  child.SetCapture();
  EXPECT_TRUE(child.HasCapture());
  EXPECT_FALSE(root_window()->HasCapture());

  ASSERT_TRUE(
      window_tree()->AckFirstChangeOfType(WindowTreeChangeType::CAPTURE, true));
  EXPECT_FALSE(root_window()->HasCapture());
  EXPECT_TRUE(child.HasCapture());

  ASSERT_TRUE(window_tree()->AckSingleChangeOfType(
      WindowTreeChangeType::CAPTURE, false));
  EXPECT_FALSE(child.HasCapture());
  EXPECT_TRUE(root_window()->HasCapture());

  window_tree_client()->OnCaptureChanged(0, server_id(root_window()));
  EXPECT_FALSE(root_window()->HasCapture());
}

TEST_F(WindowTreeClientTest, WindowDestroyedWhileTransientChildHasCapture) {
  std::unique_ptr<Window> transient_parent(std::make_unique<Window>(nullptr));
  transient_parent->Init(ui::LAYER_NOT_DRAWN);
  // Owned by |transient_parent|.
  Window* transient_child = new Window(nullptr);
  transient_child->Init(ui::LAYER_NOT_DRAWN);
  transient_parent->Show();
  transient_child->Show();
  root_window()->AddChild(transient_parent.get());
  root_window()->AddChild(transient_child);

  client::GetTransientWindowClient()->AddTransientChild(transient_parent.get(),
                                                        transient_child);

  WindowTracker tracker;
  tracker.Add(transient_parent.get());
  tracker.Add(transient_child);
  // Request a capture on the transient child, then destroy the transient
  // parent. That will destroy both windows, and should reset the capture window
  // correctly.
  transient_child->SetCapture();
  transient_parent.reset();
  EXPECT_TRUE(tracker.windows().empty());

  // Create a new Window, and attempt to place capture on that.
  Window child(nullptr);
  child.Init(ui::LAYER_NOT_DRAWN);
  child.Show();
  root_window()->AddChild(&child);
  child.SetCapture();
  EXPECT_TRUE(child.HasCapture());
}

namespace {

class CaptureRecorder : public client::CaptureClientObserver {
 public:
  explicit CaptureRecorder(Window* root_window) : root_window_(root_window) {
    client::GetCaptureClient(root_window)->AddObserver(this);
  }

  ~CaptureRecorder() override {
    client::GetCaptureClient(root_window_)->RemoveObserver(this);
  }

  void reset_capture_captured_count() { capture_changed_count_ = 0; }
  int capture_changed_count() const { return capture_changed_count_; }
  int last_gained_capture_window_id() const {
    return last_gained_capture_window_id_;
  }
  int last_lost_capture_window_id() const {
    return last_lost_capture_window_id_;
  }

  // client::CaptureClientObserver:
  void OnCaptureChanged(Window* lost_capture, Window* gained_capture) override {
    capture_changed_count_++;
    last_gained_capture_window_id_ = gained_capture ? gained_capture->id() : 0;
    last_lost_capture_window_id_ = lost_capture ? lost_capture->id() : 0;
  }

 private:
  Window* root_window_;
  int capture_changed_count_ = 0;
  int last_gained_capture_window_id_ = 0;
  int last_lost_capture_window_id_ = 0;

  DISALLOW_COPY_AND_ASSIGN(CaptureRecorder);
};

}  // namespace

TEST_F(WindowTreeClientTest, OnWindowTreeCaptureChanged) {
  CaptureRecorder capture_recorder(root_window());

  std::unique_ptr<Window> child1(std::make_unique<Window>(nullptr));
  const int child1_id = 1;
  child1->Init(ui::LAYER_NOT_DRAWN);
  child1->set_id(child1_id);
  child1->Show();
  root_window()->AddChild(child1.get());

  Window child2(nullptr);
  const int child2_id = 2;
  child2.Init(ui::LAYER_NOT_DRAWN);
  child2.set_id(child2_id);
  child2.Show();
  root_window()->AddChild(&child2);

  EXPECT_EQ(0, capture_recorder.capture_changed_count());
  // Give capture to child1 and ensure everyone is notified correctly.
  child1->SetCapture();
  ASSERT_TRUE(window_tree()->AckSingleChangeOfType(
      WindowTreeChangeType::CAPTURE, true));
  EXPECT_EQ(1, capture_recorder.capture_changed_count());
  EXPECT_EQ(child1_id, capture_recorder.last_gained_capture_window_id());
  EXPECT_EQ(0, capture_recorder.last_lost_capture_window_id());
  capture_recorder.reset_capture_captured_count();

  // Deleting a window with capture should notify observers as well.
  child1.reset();

  // No capture change is sent during deletion (the server side sees the window
  // deletion too and resets internal state).
  EXPECT_EQ(
      0u, window_tree()->GetChangeCountForType(WindowTreeChangeType::CAPTURE));

  EXPECT_EQ(1, capture_recorder.capture_changed_count());
  EXPECT_EQ(0, capture_recorder.last_gained_capture_window_id());
  EXPECT_EQ(child1_id, capture_recorder.last_lost_capture_window_id());
  capture_recorder.reset_capture_captured_count();

  // Changes originating from server should notify observers too.
  window_tree_client()->OnCaptureChanged(server_id(&child2), 0);
  EXPECT_EQ(1, capture_recorder.capture_changed_count());
  EXPECT_EQ(child2_id, capture_recorder.last_gained_capture_window_id());
  EXPECT_EQ(0, capture_recorder.last_lost_capture_window_id());
  capture_recorder.reset_capture_captured_count();
}

TEST_F(WindowTreeClientTest, TwoWindowTreesRequestCapture) {
  std::unique_ptr<TopLevel> top_level1 = CreateTopLevel();
  std::unique_ptr<TopLevel> top_level2 = CreateTopLevel();

  aura::Window* root1 = top_level1->host->window();
  aura::Window* root2 = top_level2->host->window();
  auto capture_recorder1 = std::make_unique<CaptureRecorder>(root1);
  auto capture_recorder2 = std::make_unique<CaptureRecorder>(root2);
  EXPECT_NE(client::GetCaptureClient(root1), client::GetCaptureClient(root2));

  EXPECT_EQ(0, capture_recorder1->capture_changed_count());
  EXPECT_EQ(0, capture_recorder2->capture_changed_count());
  // Give capture to root2 and ensure everyone is notified correctly.
  root2->SetCapture();
  ASSERT_TRUE(window_tree()->AckSingleChangeOfType(
      WindowTreeChangeType::CAPTURE, true));
  EXPECT_EQ(0, capture_recorder1->capture_changed_count());
  EXPECT_EQ(1, capture_recorder2->capture_changed_count());
  EXPECT_EQ(root2->id(), capture_recorder2->last_gained_capture_window_id());
  EXPECT_EQ(0, capture_recorder2->last_lost_capture_window_id());
  root2->ReleaseCapture();
  capture_recorder1->reset_capture_captured_count();
  capture_recorder2->reset_capture_captured_count();

  // Releasing capture of root2 shouldn't affect root1 capture.
  root2->SetCapture();
  root1->SetCapture();
  root2->ReleaseCapture();
  EXPECT_EQ(1, capture_recorder1->capture_changed_count());
  EXPECT_EQ(2, capture_recorder2->capture_changed_count());
  EXPECT_EQ(root1->id(), capture_recorder1->last_gained_capture_window_id());
  EXPECT_EQ(0, capture_recorder1->last_lost_capture_window_id());
  EXPECT_EQ(0, capture_recorder2->last_gained_capture_window_id());
  EXPECT_EQ(root2->id(), capture_recorder2->last_lost_capture_window_id());
  capture_recorder1->reset_capture_captured_count();
  capture_recorder2->reset_capture_captured_count();

  // Destroying top_level2 shouldn't affect root1 capture; see crbug.com/873743.
  auto* synchronizer = window_tree_client_impl()->capture_synchronizer();
  EXPECT_EQ(WindowMus::Get(root1), synchronizer->capture_window());
  synchronizer->DetachFromCaptureClient(top_level2->capture_client.get());
  capture_recorder2.reset();
  top_level2->host.reset();
  EXPECT_EQ(WindowMus::Get(root1), synchronizer->capture_window());
  EXPECT_EQ(0, capture_recorder1->capture_changed_count());
  EXPECT_EQ(root1->id(), capture_recorder1->last_gained_capture_window_id());
  EXPECT_EQ(0, capture_recorder1->last_lost_capture_window_id());
}

TEST_F(WindowTreeClientTest, ModalTypeWindowFail) {
  Window window(nullptr);
  window.Init(ui::LAYER_NOT_DRAWN);
  window.SetProperty(client::kModalKey, ui::MODAL_TYPE_WINDOW);
  // Make sure server was told about it, and have the server say it failed.
  ASSERT_TRUE(
      window_tree()->AckSingleChangeOfType(WindowTreeChangeType::MODAL, false));
  // Type should be back to MODAL_TYPE_NONE as the server didn't accept the
  // change.
  EXPECT_EQ(ui::MODAL_TYPE_NONE, window.GetProperty(client::kModalKey));
  // Server is told that the type is set back to MODAL_TYPE_NONE.
  EXPECT_TRUE(
      window_tree()->AckSingleChangeOfType(WindowTreeChangeType::MODAL, true));
  // Type should still remain MODAL_TYPE_NONE.
  EXPECT_EQ(ui::MODAL_TYPE_NONE, window.GetProperty(client::kModalKey));
}

TEST_F(WindowTreeClientTest, ModalTypeNoneFail) {
  Window window(nullptr);
  window.Init(ui::LAYER_NOT_DRAWN);
  // First, set modality type to window sucessfully.
  window.SetProperty(client::kModalKey, ui::MODAL_TYPE_WINDOW);
  ASSERT_TRUE(
      window_tree()->AckSingleChangeOfType(WindowTreeChangeType::MODAL, true));
  EXPECT_EQ(ui::MODAL_TYPE_WINDOW, window.GetProperty(client::kModalKey));
  // Now, set type to MODAL_TYPE_NONE, and have the server say it failed.
  window.SetProperty(client::kModalKey, ui::MODAL_TYPE_NONE);
  ASSERT_TRUE(
      window_tree()->AckSingleChangeOfType(WindowTreeChangeType::MODAL, false));
  // Type should be back to MODAL_TYPE_WINDOW as the server didn't accept the
  // change.
  EXPECT_EQ(ui::MODAL_TYPE_WINDOW, window.GetProperty(client::kModalKey));
  // Server is told that the type is set back to MODAL_TYPE_WINDOW.
  EXPECT_TRUE(
      window_tree()->AckSingleChangeOfType(WindowTreeChangeType::MODAL, true));
  // Type should still remain MODAL_TYPE_WINDOW.
  EXPECT_EQ(ui::MODAL_TYPE_WINDOW, window.GetProperty(client::kModalKey));
}

TEST_F(WindowTreeClientTest, ModalTypeSuccess) {
  Window window(nullptr);
  window.Init(ui::LAYER_NOT_DRAWN);

  // Set modality type to MODAL_TYPE_WINDOW, MODAL_TYPE_SYSTEM, and then back to
  // MODAL_TYPE_NONE, and make sure it succeeds each time.
  ui::ModalType kModalTypes[] = {ui::MODAL_TYPE_WINDOW, ui::MODAL_TYPE_SYSTEM,
                                 ui::MODAL_TYPE_NONE};
  for (size_t i = 0; i < base::size(kModalTypes); i++) {
    window.SetProperty(client::kModalKey, kModalTypes[i]);
    // Ack change as succeeding.
    ASSERT_TRUE(window_tree()->AckSingleChangeOfType(
        WindowTreeChangeType::MODAL, true));
    EXPECT_EQ(kModalTypes[i], window.GetProperty(client::kModalKey));
  }

  // There should be no more modal changes.
  EXPECT_FALSE(
      window_tree()->AckSingleChangeOfType(WindowTreeChangeType::MODAL, false));
}

// Verifies OnWindowHierarchyChanged() deals correctly with identifying existing
// windows.
TEST_F(WindowTreeClientTest, OnWindowHierarchyChangedWithExistingWindow) {
  Window* window1 = new Window(nullptr);
  window1->Init(ui::LAYER_NOT_DRAWN);
  Window* window2 = new Window(nullptr);
  window2->Init(ui::LAYER_NOT_DRAWN);
  window_tree()->AckAllChanges();
  const ws::Id server_window_id = server_id(root_window()) + 11;
  ws::mojom::WindowDataPtr data1 = ws::mojom::WindowData::New();
  ws::mojom::WindowDataPtr data2 = ws::mojom::WindowData::New();
  ws::mojom::WindowDataPtr data3 = ws::mojom::WindowData::New();
  data1->parent_id = server_id(root_window());
  data1->window_id = server_window_id;
  data1->bounds = gfx::Rect(1, 2, 3, 4);
  data2->parent_id = server_window_id;
  data2->window_id = WindowMus::Get(window1)->server_id();
  data2->bounds = gfx::Rect(1, 2, 3, 4);
  data3->parent_id = server_window_id;
  data3->window_id = WindowMus::Get(window2)->server_id();
  data3->bounds = gfx::Rect(1, 2, 3, 4);
  std::vector<ws::mojom::WindowDataPtr> data_array(3);
  data_array[0] = std::move(data1);
  data_array[1] = std::move(data2);
  data_array[2] = std::move(data3);
  window_tree_client()->OnWindowHierarchyChanged(
      server_window_id, 0, server_id(root_window()), std::move(data_array));
  ASSERT_FALSE(window_tree()->has_change());
  ASSERT_EQ(1u, root_window()->children().size());
  Window* server_window = root_window()->children()[0];
  EXPECT_EQ(window1->parent(), server_window);
  EXPECT_EQ(window2->parent(), server_window);
  ASSERT_EQ(2u, server_window->children().size());
  EXPECT_EQ(window1, server_window->children()[0]);
  EXPECT_EQ(window2, server_window->children()[1]);
}

// Ensures when WindowTreeClient::OnWindowDeleted() is called nothing is
// scheduled on the server side.
TEST_F(WindowTreeClientTest, OnWindowDeletedDoesntNotifyServer) {
  Window window1(nullptr);
  window1.Init(ui::LAYER_NOT_DRAWN);
  Window* window2 = new Window(nullptr);
  window2->Init(ui::LAYER_NOT_DRAWN);
  window1.AddChild(window2);
  window_tree()->AckAllChanges();
  window_tree_client()->OnWindowDeleted(server_id(window2));
  EXPECT_FALSE(window_tree()->has_change());
}

TEST_F(WindowTreeClientTestHighDPI, SetBounds) {
  const gfx::Rect new_bounds(gfx::Rect(0, 0, 100, 100));
  ASSERT_NE(new_bounds, root_window()->bounds());
  root_window()->SetBounds(new_bounds);
  EXPECT_EQ(new_bounds, root_window()->bounds());

  // Simulate the server responding with a bounds change. Server operates in
  // dips.
  const gfx::Rect server_changed_bounds(gfx::Rect(0, 0, 200, 200));
  window_tree_client()->OnWindowBoundsChanged(
      server_id(root_window()), server_changed_bounds,
      GenerateLocalSurfaceIdForNewTopLevel());
  EXPECT_EQ(server_changed_bounds, root_window()->bounds());
}

TEST_F(WindowTreeClientTestHighDPI, NewTopLevelWindowBounds) {
  WindowTreeHostMus window_tree_host(
      CreateInitParamsForTopLevel(window_tree_client_impl()));
  Window* top_level = window_tree_host.window();
  window_tree_host.InitHost();

  gfx::Rect bounds(2, 4, 6, 8);
  ws::mojom::WindowDataPtr data = ws::mojom::WindowData::New();
  data->window_id = server_id(top_level);
  data->bounds = bounds;
  const int64_t display_id = 10;
  uint32_t change_id;
  ASSERT_TRUE(window_tree()->GetAndRemoveFirstChangeOfType(
      WindowTreeChangeType::NEW_TOP_LEVEL, &change_id));
  window_tree_client()->OnTopLevelCreated(
      change_id, std::move(data), display_id, true,
      GenerateLocalSurfaceIdForNewTopLevel());

  // aura::Window should operate in DIP and aura::WindowTreeHost should operate
  // in pixels. Only the size is compared for |top_level| as the WindowTreeHost
  // is the place that maintains the location.
  EXPECT_EQ(bounds.size(), top_level->bounds().size());
  const float device_scale_factor = 2.0f;
  EXPECT_EQ(gfx::ConvertRectToPixel(device_scale_factor, bounds),
            top_level->GetHost()->GetBoundsInPixels());
}

TEST_F(WindowTreeClientTestHighDPI, HostCtorInitializesDisplayScale) {
  // WindowTreeHost's ctor attempts to initialize the display scale factor.
  WindowTreeHostMus window_tree_host(
      CreateInitParamsForTopLevel(window_tree_client_impl()));
  EXPECT_EQ(2.0f, window_tree_host.device_scale_factor());
  // This test sets pixel bounds before calling WindowTreeHost::InitHost() to
  // simulate circumstances similar to <http://crbug.com/899084>. Pixel bounds
  // should still be scaled to DIP bounds for the window tree before InitHost.
  gfx::Rect bounds(2, 4, 60, 80);
  gfx::Rect pixel_bounds = gfx::ConvertRectToPixel(2.0f, bounds);
  static_cast<WindowTreeHost*>(&window_tree_host)
      ->SetBoundsInPixels(pixel_bounds);
  EXPECT_EQ(bounds, window_tree()->last_set_window_bounds());
}

TEST_F(WindowTreeClientTestHighDPI, ObservedInputEventsInDip) {
  display::Screen* screen = display::Screen::GetScreen();
  const display::Display primary_display = screen->GetPrimaryDisplay();
  ASSERT_EQ(2.0f, primary_display.device_scale_factor());

  std::unique_ptr<Window> top_level(std::make_unique<Window>(nullptr));
  top_level->SetType(client::WINDOW_TYPE_NORMAL);
  top_level->Init(ui::LAYER_NOT_DRAWN);
  top_level->SetBounds(gfx::Rect(0, 0, 100, 100));
  top_level->Show();

  // Start observing touch press events.
  TestEventObserver test_event_observer;
  top_level->env()->AddEventObserver(&test_event_observer, top_level->env(),
                                     {ui::ET_TOUCH_PRESSED});

  // Simulate the server sending an observed event in screen dip coordinates.
  const gfx::Point location(10, 12);
  ui::TouchEvent touch_press(
      ui::ET_TOUCH_PRESSED, location, ui::EventTimeForNow(),
      ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 1));
  window_tree_client()->OnObservedInputEvent(ui::Event::Clone(touch_press));

  // The observer should have received the event in screen dip coordinates.
  const ui::Event* last_event = test_event_observer.last_event();
  ASSERT_TRUE(last_event);
  EXPECT_EQ(location, last_event->AsLocatedEvent()->location());
  EXPECT_EQ(location, last_event->AsLocatedEvent()->root_location());
}

TEST_F(WindowTreeClientTestHighDPI, InputEventsInDip) {
  WindowTreeHostMus window_tree_host(
      CreateInitParamsForTopLevel(window_tree_client_impl()));
  display::Screen* screen = display::Screen::GetScreen();
  display::Display display;
  ASSERT_TRUE(
      screen->GetDisplayWithDisplayId(window_tree_host.display_id(), &display));
  ASSERT_EQ(2.0f, display.device_scale_factor());

  Window* top_level = window_tree_host.window();
  const gfx::Rect bounds_in_pixels(0, 0, 100, 100);
  static_cast<WindowTreeHost*>(&window_tree_host)
      ->SetBoundsInPixels(bounds_in_pixels);
  window_tree_host.InitHost();
  window_tree_host.Show();
  EXPECT_EQ(gfx::ConvertRectToDIP(2.0f, bounds_in_pixels), top_level->bounds());
  EXPECT_EQ(bounds_in_pixels, window_tree_host.GetBoundsInPixels());

  InputEventBasicTestWindowDelegate window_delegate1(window_tree());
  Window child1(&window_delegate1);
  child1.Init(ui::LAYER_NOT_DRAWN);
  child1.SetEventTargeter(std::make_unique<test::TestWindowTargeter>());
  top_level->AddChild(&child1);
  child1.SetBounds(gfx::Rect(10, 10, 100, 100));
  child1.Show();
  InputEventBasicTestWindowDelegate window_delegate2(window_tree());
  Window child2(&window_delegate2);
  child2.Init(ui::LAYER_NOT_DRAWN);
  child1.AddChild(&child2);
  child2.SetBounds(gfx::Rect(20, 30, 100, 100));
  child2.Show();

  EXPECT_EQ(0, window_delegate1.move_count());
  EXPECT_EQ(0, window_delegate2.move_count());

  // child1 has a custom targeter set which would always return itself as the
  // target window therefore event should go to child1 and should be in dip.
  const gfx::Point event_location(50, 60);
  uint32_t event_id = 1;
  window_delegate1.set_event_id(event_id);
  window_delegate2.set_event_id(event_id);
  std::unique_ptr<ui::Event> ui_event(
      new ui::MouseEvent(ui::ET_MOUSE_MOVED, event_location, event_location,
                         ui::EventTimeForNow(), ui::EF_NONE, 0));
  window_tree_client()->OnWindowInputEvent(
      event_id, server_id(&child1), window_tree_host.display_id(),
      ui::Event::Clone(*ui_event.get()), 0);
  EXPECT_TRUE(window_tree()->WasEventAcked(event_id));
  EXPECT_EQ(ws::mojom::EventResult::HANDLED,
            window_tree()->GetEventResult(event_id));
  EXPECT_EQ(1, window_delegate1.move_count());
  EXPECT_EQ(0, window_delegate2.move_count());
  EXPECT_EQ(event_location, window_delegate1.last_event_location());
  window_delegate1.reset();
  window_delegate2.reset();

  // Event location will be transformed and should be in dip.
  event_id = 2;
  window_delegate1.set_event_id(event_id);
  window_delegate2.set_event_id(event_id);
  window_tree_client()->OnWindowInputEvent(
      event_id, server_id(&child2), window_tree_host.display_id(),
      ui::Event::Clone(*ui_event.get()), 0);
  EXPECT_TRUE(window_tree()->WasEventAcked(event_id));
  EXPECT_EQ(ws::mojom::EventResult::HANDLED,
            window_tree()->GetEventResult(event_id));
  EXPECT_EQ(1, window_delegate1.move_count());
  EXPECT_EQ(0, window_delegate2.move_count());
  gfx::Point transformed_event_location(event_location.x() + 20,
                                        event_location.y() + 30);
  EXPECT_EQ(transformed_event_location, window_delegate1.last_event_location());
}

using WindowTreeClientDestructionTest = test::AuraTestBaseMus;

TEST_F(WindowTreeClientDestructionTest, Shutdown) {
  // Windows should be able to outlive the WindowTreeClient.
  aura::Window window(nullptr);
  window.Init(ui::LAYER_NOT_DRAWN);
  DeleteWindowTreeClient();

  // And it should be possible to create Windows after the WindowTreeClient has
  // been deleted.
  aura::Window window2(nullptr);
  window2.Init(ui::LAYER_NOT_DRAWN);
}

TEST_F(WindowTreeClientDestructionTest, WindowsFromOtherConnectionsDeleted) {
  std::unique_ptr<Window> other_client_window =
      CreateWindowUsingId(window_tree_client_impl(), 10, nullptr);
  WindowTracker window_tracker;
  window_tracker.Add(other_client_window.get());
  other_client_window.release();
  DeleteWindowTreeClient();
  // Deleting WindowTreeClient should delete the Window that was in
  // |window_tracker|.
  EXPECT_TRUE(window_tracker.windows().empty());
}

class TestEmbedRootDelegate : public EmbedRootDelegate {
 public:
  TestEmbedRootDelegate() = default;
  ~TestEmbedRootDelegate() override = default;

  // EmbedRootDelegate:
  void OnEmbedTokenAvailable(const base::UnguessableToken& token) override {}
  void OnEmbed(Window* window) override {}
  void OnUnembed() override {}

 private:
  DISALLOW_COPY_AND_ASSIGN(TestEmbedRootDelegate);
};

// Verifies we don't crash when focus changes to a window in an EmbedRoot.
TEST_F(WindowTreeClientTest, ChangeFocusInEmbedRootWindow) {
  TestEmbedRootDelegate embed_root_delegate;
  std::unique_ptr<EmbedRoot> embed_root =
      window_tree_client_impl()->CreateEmbedRoot(&embed_root_delegate);
  WindowTreeClientTestApi(window_tree_client_impl())
      .CallOnEmbedFromToken(embed_root.get());
  ASSERT_TRUE(embed_root->window());
  window_tree_client()->OnWindowFocused(server_id(embed_root->window()));
}

// Verifies visibility from server is applied properly when an embed root is
// created.
TEST_F(WindowTreeClientTest, EmbedRootVisibility) {
  for (bool visible : {true, false}) {
    TestEmbedRootDelegate embed_root_delegate;
    std::unique_ptr<EmbedRoot> embed_root =
        window_tree_client_impl()->CreateEmbedRoot(&embed_root_delegate);
    WindowTreeClientTestApi(window_tree_client_impl())
        .CallOnEmbedFromToken(embed_root.get(), visible);
    ASSERT_TRUE(embed_root->window());
    EXPECT_EQ(visible, embed_root->window()->TargetVisibility());
    EXPECT_EQ(visible,
              embed_root->window()->GetHost()->compositor()->IsVisible());
  }
}

TEST_F(WindowTreeClientTest, PerformWindowMove) {
  int call_count = 0;
  bool last_result = false;

  WindowTreeHostMus* host_mus = static_cast<WindowTreeHostMus*>(host());
  host_mus->PerformWindowMove(
      host_mus->window(), ws::mojom::MoveLoopSource::MOUSE, gfx::Point(),
      HTCAPTION, base::BindOnce(&OnWindowMoveDone, &call_count, &last_result));
  EXPECT_EQ(0, call_count);

  window_tree()->AckAllChanges();
  EXPECT_EQ(1, call_count);
  EXPECT_TRUE(last_result);

  host_mus->PerformWindowMove(
      host_mus->window(), ws::mojom::MoveLoopSource::MOUSE, gfx::Point(),
      HTCAPTION, base::BindOnce(&OnWindowMoveDone, &call_count, &last_result));
  window_tree()->AckAllChangesOfType(WindowTreeChangeType::OTHER, false);
  EXPECT_EQ(2, call_count);
  EXPECT_FALSE(last_result);
}

TEST_F(WindowTreeClientTest, PerformWindowMoveDoneAfterDelete) {
  int call_count = 0;
  bool last_result = false;

  auto host_mus = std::make_unique<WindowTreeHostMus>(
      CreateInitParamsForTopLevel(window_tree_client_impl()));
  host_mus->InitHost();
  window_tree()->AckAllChanges();

  host_mus->PerformWindowMove(
      host_mus->window(), ws::mojom::MoveLoopSource::MOUSE, gfx::Point(),
      HTCAPTION, base::BindOnce(&OnWindowMoveDone, &call_count, &last_result));
  EXPECT_EQ(0, call_count);

  host_mus.reset();
  window_tree()->AckAllChanges();

  EXPECT_EQ(1, call_count);
  EXPECT_TRUE(last_result);
}

TEST_F(WindowTreeClientTest, PerformWindowMoveTransferEvents) {
  int call_count = 0;
  bool last_result = false;

  aura::Window* window = CreateNormalWindow(10, host()->window(), nullptr);
  WindowTreeHostMus* host_mus = static_cast<WindowTreeHostMus*>(host());
  window->SetCapture();
  host_mus->PerformWindowMove(
      window, ws::mojom::MoveLoopSource::TOUCH, gfx::Point(), HTCAPTION,
      base::BindOnce(&OnWindowMoveDone, &call_count, &last_result));
  EXPECT_EQ(0, call_count);
  EXPECT_EQ(WindowPortMus::Get(window)->server_id(),
            window_tree()->last_transfer_current());
  EXPECT_EQ(WindowPortMus::Get(host_mus->window())->server_id(),
            window_tree()->last_transfer_new());
  EXPECT_FALSE(window->HasCapture());

  window_tree()->AckAllChanges();
  EXPECT_EQ(1, call_count);
  EXPECT_TRUE(last_result);
  EXPECT_EQ(WindowPortMus::Get(host_mus->window())->server_id(),
            window_tree()->last_transfer_current());
  EXPECT_EQ(WindowPortMus::Get(window)->server_id(),
            window_tree()->last_transfer_new());
}

// Verifies occlusion state from server is applied to underlying window.
TEST_F(WindowTreeClientTest, OcclusionStateFromServer) {
  struct {
    const char* name;
    bool window_is_visible;
    ws::mojom::OcclusionState changed_state_from_server;
    Window::OcclusionState expected_state;
  } kTestCases[] = {
      // VISIBLE is set when window is visible.
      {"visible-set", true, ws::mojom::OcclusionState::kVisible,
       Window::OcclusionState::VISIBLE},
      // VISIBLE is not set when window hidden.
      {"visible-not-set", false, ws::mojom::OcclusionState::kVisible,
       Window::OcclusionState::HIDDEN},

      // OCCLUDED is always set.
      {"occluded-with-visible", true, ws::mojom::OcclusionState::kOccluded,
       Window::OcclusionState::OCCLUDED},
      {"occluded-with-invisible", false, ws::mojom::OcclusionState::kOccluded,
       Window::OcclusionState::OCCLUDED},

      // HIDDEN is set when window target visibility is false.
      {"hidden-set", false, ws::mojom::OcclusionState::kHidden,
       Window::OcclusionState::HIDDEN},
      // HIDDEN is not set when window target visibility is true.
      {"hidden-not-set", true, ws::mojom::OcclusionState::kHidden,
       Window::OcclusionState::VISIBLE},
  };

  for (const auto& test : kTestCases) {
    Window window(nullptr);
    window.Init(ui::LAYER_NOT_DRAWN);
    window.set_owned_by_parent(false);
    root_window()->AddChild(&window);

    window.TrackOcclusionState();
    ASSERT_EQ(Window::OcclusionState::HIDDEN, window.occlusion_state());

    if (test.window_is_visible && !window.IsVisible()) {
      window.Show();
    } else if (!test.window_is_visible && window.IsVisible()) {
      window.Hide();
    }

    window_tree_client()->OnOcclusionStatesChanged(
        {{server_id(&window), test.changed_state_from_server}});
    EXPECT_EQ(test.expected_state, window.occlusion_state()) << test.name;
  }
}

// Assertions around LocalSurfaceIds for top-levels.
TEST_F(WindowTreeClientTest, TopLevelSurfaceIds) {
  std::unique_ptr<TopLevel> top_level = std::make_unique<TopLevel>();
  top_level->host = std::make_unique<WindowTreeHostMus>(
      CreateInitParamsForTopLevel(window_tree_client_impl()));
  top_level->host->InitHost();
  CreateCaptureClientForTopLevel(top_level.get());

  viz::LocalSurfaceIdAllocation initial_lsia =
      parent_local_surface_id_allocator_.GetCurrentLocalSurfaceIdAllocation();
  uint32_t new_top_level_change_id = 0;
  ASSERT_TRUE(window_tree()->GetAndRemoveFirstChangeOfType(
      WindowTreeChangeType::NEW_TOP_LEVEL, &new_top_level_change_id));
  EXPECT_EQ(0u,
            window_tree()->GetChangeCountForType(WindowTreeChangeType::BOUNDS));
  static_cast<WindowTreeHost*>(top_level->host.get())
      ->SetBoundsInPixels(gfx::Rect(1, 2, 3, 4));
  EXPECT_EQ(1u,
            window_tree()->GetChangeCountForType(WindowTreeChangeType::BOUNDS));
  // As the initial LocalSurfaceId comes from the server, there shouldn't be
  // a LocalSurfaceId in the client yet.
  EXPECT_FALSE(window_tree()->last_local_surface_id());
  EXPECT_FALSE(top_level->host->compositor()
                   ->GetLocalSurfaceIdAllocation()
                   .local_surface_id()
                   .is_valid());

  size_t number_of_changes = window_tree()->number_of_changes();
  AckNewTopLevelWindow(top_level.get(), new_top_level_change_id);

  // Still no surface id as bounds still in flight.
  EXPECT_FALSE(window_tree()->last_local_surface_id());

  // No new changes.
  EXPECT_EQ(number_of_changes, window_tree()->number_of_changes());

  EXPECT_EQ(
      0u,
      window_tree()->get_and_clear_update_local_surface_id_from_child_count());
  // Ack the bounds change.
  EXPECT_TRUE(
      window_tree()->AckFirstChangeOfType(WindowTreeChangeType::BOUNDS, true));

  EXPECT_EQ(
      1u,
      window_tree()->get_and_clear_update_local_surface_id_from_child_count());
  viz::LocalSurfaceIdAllocation lsia =
      GenerateChildLocalIdFromParentAllocator();
  ASSERT_TRUE(window_tree()->last_local_surface_id());
  Window* top_level_window = top_level->host->window();
  EXPECT_EQ(top_level_window->GetLocalSurfaceIdAllocation().local_surface_id(),
            *window_tree()->last_local_surface_id());
  EXPECT_EQ(top_level->host->compositor()
                ->GetLocalSurfaceIdAllocation()
                .local_surface_id(),
            *window_tree()->last_local_surface_id());
  EXPECT_EQ(lsia.local_surface_id(),
            top_level_window->GetLocalSurfaceIdAllocation().local_surface_id());
}

TEST_F(WindowTreeClientTest, TopLevelBoundsChangeFails) {
  std::unique_ptr<TopLevel> top_level = std::make_unique<TopLevel>();
  top_level->host = std::make_unique<WindowTreeHostMus>(
      CreateInitParamsForTopLevel(window_tree_client_impl()));
  top_level->host->InitHost();
  CreateCaptureClientForTopLevel(top_level.get());

  aura::Window* root = top_level->host->window();

  AckNewTopLevelWindow(top_level.get());
  EXPECT_EQ(0u,
            window_tree()->GetChangeCountForType(WindowTreeChangeType::BOUNDS));
  ASSERT_TRUE(root->GetLocalSurfaceIdAllocation().IsValid());
  EXPECT_EQ(
      parent_local_surface_id_allocator_.GetCurrentLocalSurfaceIdAllocation()
          .local_surface_id()
          .parent_sequence_number(),
      root->GetLocalSurfaceIdAllocation()
          .local_surface_id()
          .parent_sequence_number());

  // Resize the window.
  const gfx::Rect initial_bounds(1, 2, 3, 4);
  static_cast<WindowTreeHost*>(top_level->host.get())
      ->SetBoundsInPixels(initial_bounds);
  auto initial_lsia = root->GetLocalSurfaceIdAllocation();
  EXPECT_TRUE(initial_lsia.IsValid());
  EXPECT_EQ(1u,
            window_tree()->GetChangeCountForType(WindowTreeChangeType::BOUNDS));
  // The client should increment the child_sequence_number when asking for a new
  // bounds.
  auto expected_lsia = GenerateChildLocalIdFromParentAllocator();
  EXPECT_EQ(expected_lsia.local_surface_id(),
            window_tree()->last_local_surface_id());
  parent_local_surface_id_allocator_.UpdateFromChild(expected_lsia);

  // Server responds with a bounds change. This isn't immediately processed as
  // client waiting for ack from SetBoundsInPixels() call above.
  parent_local_surface_id_allocator_.GenerateId();
  const gfx::Rect server_changed_bounds(gfx::Rect(0, 0, 200, 200));
  window_tree_client()->OnWindowBoundsChanged(
      server_id(root), server_changed_bounds,
      parent_local_surface_id_allocator_.GetCurrentLocalSurfaceIdAllocation());
  const viz::LocalSurfaceId local_surface_id1 =
      root->GetLocalSurfaceIdAllocation().local_surface_id();
  EXPECT_EQ(expected_lsia.local_surface_id(), local_surface_id1);
  // There should still only be 1 bounds change.
  EXPECT_EQ(1u,
            window_tree()->GetChangeCountForType(WindowTreeChangeType::BOUNDS));

  // Server responds with false to first bounds changes. Results in reverting to
  // |server_changed_bounds| *and* increasing the parent_sequence_number.
  EXPECT_TRUE(
      window_tree()->AckFirstChangeOfType(WindowTreeChangeType::BOUNDS, false));
  expected_lsia =
      parent_local_surface_id_allocator_.GetCurrentLocalSurfaceIdAllocation();
  const viz::LocalSurfaceId local_surface_id2 =
      root->GetLocalSurfaceIdAllocation().local_surface_id();
  EXPECT_EQ(server_changed_bounds, root->bounds());
  EXPECT_EQ(server_changed_bounds, top_level->host->GetBoundsInPixels());
  EXPECT_EQ(expected_lsia.local_surface_id(), local_surface_id2);
  // No new bounds changes should be generated.
  EXPECT_EQ(0u,
            window_tree()->GetChangeCountForType(WindowTreeChangeType::BOUNDS));

  // As the server supplied a new LocalSurfaceId the pending LocalSurfaceId
  // should be cleared.
  EXPECT_FALSE(top_level->host->has_pending_local_surface_id_from_server());
}

TEST_F(WindowTreeClientTest, OnEmbedGetsLocalSurfaceId) {
  viz::ParentLocalSurfaceIdAllocator parent_local_surface_id_allocator;
  parent_local_surface_id_allocator.GenerateId();
  TestEmbedRootDelegate embed_root_delegate;
  auto initial_lsia =
      parent_local_surface_id_allocator.GetCurrentLocalSurfaceIdAllocation();
  std::unique_ptr<EmbedRoot> embed_root =
      window_tree_client_impl()->CreateEmbedRoot(&embed_root_delegate);
  WindowTreeClientTestApi(window_tree_client_impl())
      .CallOnEmbedFromToken(embed_root.get(), false, initial_lsia);
  ASSERT_TRUE(embed_root->window());
  const viz::LocalSurfaceIdAllocation lsia =
      embed_root->window()->GetLocalSurfaceIdAllocation();
  EXPECT_EQ(initial_lsia, lsia);
  EXPECT_EQ(initial_lsia, embed_root->window()
                              ->GetHost()
                              ->compositor()
                              ->GetLocalSurfaceIdAllocation());
}

TEST_F(WindowTreeClientTest,
       NotifyServerOnDidGenerateLocalSurfaceIdAllocation) {
  TestEmbedRootDelegate embed_root_delegate;
  std::unique_ptr<EmbedRoot> embed_root =
      window_tree_client_impl()->CreateEmbedRoot(&embed_root_delegate);
  WindowTreeClientTestApi(window_tree_client_impl())
      .CallOnEmbedFromToken(embed_root.get());
  ASSERT_TRUE(embed_root->window());
  const viz::LocalSurfaceIdAllocation lsia =
      embed_root->window()->GetLocalSurfaceIdAllocation();
  viz::ChildLocalSurfaceIdAllocator child_allocator;
  child_allocator.UpdateFromParent(lsia);
  child_allocator.GenerateId();
  auto updated_lsia = child_allocator.GetCurrentLocalSurfaceIdAllocation();
  EmbeddedAllocator* allocator = static_cast<EmbeddedAllocator*>(
      WindowPortMusTestHelper(embed_root->window()).GetAllocator());
  ASSERT_TRUE(allocator);
  window_tree()->get_and_clear_update_local_surface_id_from_child_count();
  // This mirrors what happens when LayerTreeHostImpl generates a new id.
  allocator->DidGenerateLocalSurfaceIdAllocation(
      embed_root->window()->GetHost()->compositor(), updated_lsia);
  EXPECT_EQ(
      1u,
      window_tree()->get_and_clear_update_local_surface_id_from_child_count());
  EXPECT_EQ(updated_lsia.local_surface_id(),
            window_tree()->last_local_surface_id());
  EXPECT_EQ(updated_lsia, embed_root->window()
                              ->GetHost()
                              ->compositor()
                              ->GetLocalSurfaceIdAllocation());
  EXPECT_EQ(updated_lsia, embed_root->window()->GetLocalSurfaceIdAllocation());
}

}  // namespace aura
