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

#include "components/exo/pointer.h"

#include <memory>

#include "ash/constants/ash_features.h"
#include "ash/drag_drop/drag_drop_controller.h"
#include "ash/shell.h"
#include "ash/wm/desks/desk_animation_impl.h"
#include "ash/wm/desks/desks_test_util.h"
#include "ash/wm/desks/desks_util.h"
#include "ash/wm/desks/root_window_desk_switch_animator_test_api.h"
#include "ash/wm/gestures/wm_gesture_handler.h"
#include "ash/wm/window_positioning_utils.h"
#include "base/command_line.h"
#include "base/functional/bind.h"
#include "base/memory/raw_ptr.h"
#include "base/run_loop.h"
#include "base/test/bind.h"
#include "base/test/scoped_feature_list.h"
#include "chromeos/ui/base/window_properties.h"
#include "components/exo/buffer.h"
#include "components/exo/data_source.h"
#include "components/exo/data_source_delegate.h"
#include "components/exo/pointer_constraint_delegate.h"
#include "components/exo/pointer_delegate.h"
#include "components/exo/pointer_stylus_delegate.h"
#include "components/exo/relative_pointer_delegate.h"
#include "components/exo/seat.h"
#include "components/exo/shell_surface.h"
#include "components/exo/sub_surface.h"
#include "components/exo/surface.h"
#include "components/exo/test/exo_test_base.h"
#include "components/exo/test/exo_test_data_exchange_delegate.h"
#include "components/exo/test/exo_test_helper.h"
#include "components/exo/test/shell_surface_builder.h"
#include "components/exo/test/surface_tree_host_test_util.h"
#include "components/exo/test/test_data_device_delegate.h"
#include "components/exo/test/test_data_source_delegate.h"
#include "components/exo/wm_helper.h"
#include "components/viz/common/quads/compositor_frame.h"
#include "components/viz/common/resources/shared_image_format.h"
#include "components/viz/service/surfaces/surface.h"
#include "components/viz/service/surfaces/surface_manager.h"
#include "components/viz/test/test_context_provider.h"
#include "gpu/command_buffer/common/shared_image_usage.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkColor.h"
#include "third_party/skia/include/core/SkImageInfo.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/client/cursor_client.h"
#include "ui/aura/client/drag_drop_client.h"
#include "ui/aura/client/focus_client.h"
#include "ui/aura/window.h"
#include "ui/aura/window_tree_host.h"
#include "ui/base/cursor/mojom/cursor_type.mojom-shared.h"
#include "ui/base/dragdrop/mojom/drag_drop_types.mojom-shared.h"
#include "ui/compositor/compositor_switches.h"
#include "ui/compositor/layer.h"
#include "ui/compositor/scoped_animation_duration_scale_mode.h"
#include "ui/compositor/test/draw_waiter_for_test.h"
#include "ui/events/base_event_utils.h"
#include "ui/events/event.h"
#include "ui/events/test/event_generator.h"
#include "ui/events/test/events_test_utils.h"
#include "ui/events/types/event_type.h"
#include "ui/gfx/geometry/vector2d_f.h"
#include "ui/gl/test/gl_test_support.h"
#include "ui/views/widget/widget.h"

using ::exo::test::TestDataSourceDelegate;
using ::testing::_;
using ::testing::AnyNumber;

namespace exo {
namespace {

// A host window that ensures a root frame sink commit happens
// before OnFirstSurfaceActivation updates host window surface id.
// Used in `SetCursorWithSurfaceChange`.
class PointerTestHostWindow : public aura::Window {
 public:
  PointerTestHostWindow()
      : aura::Window(nullptr, aura::client::WINDOW_TYPE_CONTROL) {}

  PointerTestHostWindow(const PointerTestHostWindow&) = delete;
  PointerTestHostWindow& operator=(const PointerTestHostWindow) = delete;

  // Overridden from viz::HostFrameSinkClient:
  void OnFirstSurfaceActivation(const viz::SurfaceInfo& surface_info) override {
    // Ensure there is a draw on root frame sink and
    // BeginFrame is handled before OnFirstSurfaceActivation.
    ui::DrawWaiterForTest::WaitForCommit(layer()->GetCompositor());

    aura::Window::OnFirstSurfaceActivation(surface_info);
  }
};

void DispatchGesture(ui::EventType gesture_type, gfx::Point location) {
  ui::GestureEventDetails event_details(gesture_type);
  ui::GestureEvent gesture_event(location.x(), location.y(), 0,
                                 ui::EventTimeForNow(), event_details);
  ui::EventSource* event_source =
      ash::Shell::GetPrimaryRootWindow()->GetHost()->GetEventSource();
  ui::EventSourceTestApi event_source_test(event_source);
  ui::EventDispatchDetails details =
      event_source_test.SendEventToSink(&gesture_event);
  CHECK(!details.dispatcher_destroyed);
}

class MockPointerDelegate : public PointerDelegate {
 public:
  MockPointerDelegate() = default;

  // Overridden from PointerDelegate:
  MOCK_METHOD1(OnPointerDestroying, void(Pointer*));
  MOCK_CONST_METHOD1(CanAcceptPointerEventsForSurface, bool(Surface*));
  MOCK_METHOD3(OnPointerEnter, void(Surface*, const gfx::PointF&, int));
  MOCK_METHOD1(OnPointerLeave, void(Surface*));
  MOCK_METHOD2(OnPointerMotion, void(base::TimeTicks, const gfx::PointF&));
  MOCK_METHOD3(OnPointerButton, void(base::TimeTicks, int, bool));
  MOCK_METHOD3(OnPointerScroll,
               void(base::TimeTicks, const gfx::Vector2dF&, bool));
  MOCK_METHOD1(OnFingerScrollStop, void(base::TimeTicks));
  MOCK_METHOD0(OnPointerFrame, void());
};

class MockRelativePointerDelegate : public RelativePointerDelegate {
 public:
  MockRelativePointerDelegate() = default;
  ~MockRelativePointerDelegate() override = default;

  // Overridden from RelativePointerDelegate:
  MOCK_METHOD1(OnPointerDestroying, void(Pointer*));
  MOCK_METHOD3(OnPointerRelativeMotion,
               void(base::TimeTicks,
                    const gfx::Vector2dF&,
                    const gfx::Vector2dF&));
};

class MockPointerConstraintDelegate : public PointerConstraintDelegate {
 public:
  MockPointerConstraintDelegate() {
    ON_CALL(*this, OnConstraintActivated).WillByDefault([this]() {
      activated_count++;
    });
    ON_CALL(*this, OnConstraintBroken).WillByDefault([this]() {
      broken_count++;
    });
  }
  ~MockPointerConstraintDelegate() override = default;

  // Overridden from PointerConstraintDelegate:
  MOCK_METHOD0(OnConstraintActivated, void());
  MOCK_METHOD0(OnAlreadyConstrained, void());
  MOCK_METHOD0(OnConstraintBroken, void());
  MOCK_METHOD0(IsPersistent, bool());
  MOCK_METHOD0(GetConstrainedSurface, Surface*());
  MOCK_METHOD0(OnDefunct, void());

  int activated_count = 0;
  int broken_count = 0;
};

class MockPointerStylusDelegate : public PointerStylusDelegate {
 public:
  MockPointerStylusDelegate() = default;

  // Overridden from PointerStylusDelegate:
  MOCK_METHOD(void, OnPointerDestroying, (Pointer*));
  MOCK_METHOD(void, OnPointerToolChange, (ui::EventPointerType));
  MOCK_METHOD(void, OnPointerForce, (base::TimeTicks, float));
  MOCK_METHOD(void, OnPointerTilt, (base::TimeTicks, const gfx::Vector2dF&));
};

class PointerTest : public test::ExoTestBase {
 public:
  PointerTest() = default;

  PointerTest(const PointerTest&) = delete;
  PointerTest& operator=(const PointerTest&) = delete;

  void SetUp() override {
    // The `SetCursorWithSurfaceChange` test requires pixel output.
    base::CommandLine::ForCurrentProcess()->AppendSwitch(
        switches::kEnablePixelOutputInTests);

    test::ExoTestBase::SetUp();
    seat_ =
        std::make_unique<Seat>(std::make_unique<TestDataExchangeDelegate>());
    data_device_ =
        std::make_unique<DataDevice>(&data_device_delegate_, seat_.get());

    // TODO(oshima): This is no longer necessary. Remove this.
    base::RunLoop().RunUntilIdle();
  }

  void TearDown() override {
    data_device_.reset();
    seat_.reset();
    test::ExoTestBase::TearDown();
  }

 protected:
  base::test::ScopedFeatureList feature_list_;
  std::unique_ptr<Seat> seat_;
  test::TestDataDeviceDelegate data_device_delegate_;
  std::unique_ptr<DataDevice> data_device_;
};

class PointerConstraintTest : public PointerTest {
 public:
  PointerConstraintTest() = default;
  PointerConstraintTest(const PointerConstraintTest&) = delete;
  PointerConstraintTest& operator=(const PointerConstraintTest&) = delete;

  void SetUp() override {
    PointerTest::SetUp();

    shell_surface_ = BuildShellSurfaceWhichPermitsPointerLock();
    surface_ = shell_surface_->surface_for_testing();
    pointer_ = std::make_unique<Pointer>(&delegate_, seat_.get());

    focus_client_ =
        aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow());
    focus_client_->FocusWindow(surface_->window());

    generator_ = std::make_unique<ui::test::EventGenerator>(
        ash::Shell::GetPrimaryRootWindow());

    EXPECT_CALL(delegate_, CanAcceptPointerEventsForSurface(surface_.get()))
        .WillRepeatedly(testing::Return(true));

    EXPECT_CALL(constraint_delegate_, GetConstrainedSurface())
        .WillRepeatedly(testing::Return(surface_.get()));
  }

  void TearDown() override {
    // Many objects need to be destroyed before teardown for various reasons.
    shell_surface_.reset();
    surface_ = nullptr;

    // Some tests generate mouse events which Pointer::OnMouseEvent() handles
    // during the run loop. That routine accesses WMHelper. So, make sure any
    // such pending tasks finish before TearDown() destroys the WMHelper.
    base::RunLoop().RunUntilIdle();

    PointerTest::TearDown();
  }

  std::unique_ptr<ShellSurface> BuildShellSurfaceWhichPermitsPointerLock() {
    std::unique_ptr<ShellSurface> shell_surface =
        test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
    shell_surface->GetWidget()->GetNativeWindow()->SetProperty(
        chromeos::kUseOverviewToExitPointerLock, true);
    return shell_surface;
  }

  std::unique_ptr<ui::test::EventGenerator> generator_;
  std::unique_ptr<Pointer> pointer_;
  testing::NiceMock<MockPointerConstraintDelegate> constraint_delegate_;
  testing::NiceMock<MockPointerDelegate> delegate_;
  std::unique_ptr<ShellSurface> shell_surface_;
  raw_ptr<Surface, DanglingUntriaged> surface_;
  raw_ptr<aura::client::FocusClient, DanglingUntriaged> focus_client_;
};

TEST_F(PointerTest, SetCursor) {
  auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  auto* surface = shell_surface->surface_for_testing();

  MockPointerDelegate delegate;
  auto pointer = std::make_unique<Pointer>(&delegate, seat_.get());

  ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());

  EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface))
      .WillRepeatedly(testing::Return(true));
  EXPECT_CALL(delegate, OnPointerFrame()).Times(1);
  EXPECT_CALL(delegate, OnPointerEnter(surface, gfx::PointF(), 0));
  generator.MoveMouseTo(surface->window()->GetBoundsInScreen().origin());

  constexpr gfx::Size buffer_size(10, 10);
  std::unique_ptr<Surface> pointer_surface(new Surface);
  std::unique_ptr<Buffer> pointer_buffer =
      std::make_unique<SolidColorBuffer>(SkColors::kRed, buffer_size);
  pointer_surface->Attach(pointer_buffer.get());
  pointer_surface->Commit();

  // Set pointer surface.
  pointer->SetCursor(pointer_surface.get(), gfx::Point(5, 5));
  test::WaitForLastFrameAck(pointer.get());

  const viz::CompositorRenderPass* last_render_pass;
  {
    viz::SurfaceId surface_id =
        *pointer->host_window()->layer()->GetSurfaceId();
    viz::SurfaceManager* surface_manager = GetSurfaceManager();
    ASSERT_TRUE(surface_manager->GetSurfaceForId(surface_id)->HasActiveFrame());
    const viz::CompositorFrame& frame =
        surface_manager->GetSurfaceForId(surface_id)->GetActiveFrame();
    EXPECT_EQ(gfx::Rect(0, 0, 10, 10),
              frame.render_pass_list.back()->output_rect);
    last_render_pass = frame.render_pass_list.back().get();
  }

  // Adjust hotspot.
  pointer->SetCursor(pointer_surface.get(), gfx::Point());
  test::WaitForLastFrameAck(pointer.get());

  // Verify that adjustment to hotspot resulted in new frame.
  {
    viz::SurfaceId surface_id =
        *pointer->host_window()->layer()->GetSurfaceId();
    viz::SurfaceManager* surface_manager = GetSurfaceManager();
    ASSERT_TRUE(surface_manager->GetSurfaceForId(surface_id)->HasActiveFrame());
    const viz::CompositorFrame& frame =
        surface_manager->GetSurfaceForId(surface_id)->GetActiveFrame();
    EXPECT_TRUE(frame.render_pass_list.back().get() != last_render_pass);
  }

  // Unset pointer surface.
  pointer->SetCursor(nullptr, gfx::Point());

  EXPECT_CALL(delegate, OnPointerDestroying(pointer.get()));
  pointer.reset();
}

TEST_F(PointerTest, SetCursorNull) {
  auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  auto* surface = shell_surface->surface_for_testing();

  MockPointerDelegate delegate;
  auto pointer = std::make_unique<Pointer>(&delegate, seat_.get());
  ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());

  EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface))
      .WillRepeatedly(testing::Return(true));
  EXPECT_CALL(delegate, OnPointerFrame()).Times(1);
  EXPECT_CALL(delegate, OnPointerEnter(surface, gfx::PointF(), 0));
  generator.MoveMouseTo(surface->window()->GetBoundsInScreen().origin());

  pointer->SetCursor(nullptr, gfx::Point());

  EXPECT_EQ(nullptr, pointer->root_surface());
  aura::client::CursorClient* cursor_client = aura::client::GetCursorClient(
      shell_surface->GetWidget()->GetNativeWindow()->GetRootWindow());
  EXPECT_EQ(ui::mojom::CursorType::kNone, cursor_client->GetCursor().type());

  EXPECT_CALL(delegate, OnPointerDestroying(pointer.get()));
  pointer.reset();
}

TEST_F(PointerTest, SetCursorType) {
  auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  auto* surface = shell_surface->surface_for_testing();

  MockPointerDelegate delegate;
  auto pointer = std::make_unique<Pointer>(&delegate, seat_.get());
  ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());

  EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface))
      .WillRepeatedly(testing::Return(true));
  EXPECT_CALL(delegate, OnPointerFrame()).Times(1);
  EXPECT_CALL(delegate, OnPointerEnter(surface, gfx::PointF(), 0));
  generator.MoveMouseTo(surface->window()->GetBoundsInScreen().origin());

  pointer->SetCursorType(ui::mojom::CursorType::kIBeam);

  EXPECT_EQ(nullptr, pointer->root_surface());
  aura::client::CursorClient* cursor_client = aura::client::GetCursorClient(
      shell_surface->GetWidget()->GetNativeWindow()->GetRootWindow());
  EXPECT_EQ(ui::mojom::CursorType::kIBeam, cursor_client->GetCursor().type());

  // Set the pointer with surface after setting pointer type.
  constexpr gfx::Size buffer_size(10, 10);
  std::unique_ptr<Surface> pointer_surface(new Surface);
  std::unique_ptr<Buffer> pointer_buffer =
      std::make_unique<SolidColorBuffer>(SkColors::kRed, buffer_size);
  pointer_surface->Attach(pointer_buffer.get());
  pointer_surface->Commit();

  pointer->SetCursor(pointer_surface.get(), gfx::Point());
  test::WaitForLastFrameAck(pointer.get());

  {
    viz::SurfaceId surface_id =
        *pointer->host_window()->layer()->GetSurfaceId();
    viz::SurfaceManager* surface_manager = GetSurfaceManager();
    ASSERT_TRUE(surface_manager->GetSurfaceForId(surface_id)->HasActiveFrame());
    const viz::CompositorFrame& frame =
        surface_manager->GetSurfaceForId(surface_id)->GetActiveFrame();
    EXPECT_EQ(gfx::Rect(0, 0, 10, 10),
              frame.render_pass_list.back()->output_rect);
  }

  // Set the pointer type after the pointer surface is specified.
  pointer->SetCursorType(ui::mojom::CursorType::kCross);

  EXPECT_EQ(nullptr, pointer->root_surface());
  EXPECT_EQ(ui::mojom::CursorType::kCross, cursor_client->GetCursor().type());

  EXPECT_CALL(delegate, OnPointerDestroying(pointer.get()));
  pointer.reset();
}

TEST_F(PointerTest, SetCursorTypeOutsideOfSurface) {
  auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  auto* surface = shell_surface->surface_for_testing();

  MockPointerDelegate delegate;
  auto pointer = std::make_unique<Pointer>(&delegate, seat_.get());
  ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());

  EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface))
      .WillRepeatedly(testing::Return(true));
  generator.MoveMouseTo(surface->window()->GetBoundsInScreen().origin() -
                        gfx::Vector2d(1, 1));

  pointer->SetCursorType(ui::mojom::CursorType::kIBeam);

  EXPECT_EQ(nullptr, pointer->root_surface());
  aura::client::CursorClient* cursor_client = aura::client::GetCursorClient(
      shell_surface->GetWidget()->GetNativeWindow()->GetRootWindow());
  // The cursor type shouldn't be the specified one, since the pointer is
  // located outside of the surface.
  EXPECT_NE(ui::mojom::CursorType::kIBeam, cursor_client->GetCursor().type());

  EXPECT_CALL(delegate, OnPointerDestroying(pointer.get()));
  pointer.reset();
}

TEST_F(PointerTest, SetCursorAndSetCursorType) {
  auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  auto* surface = shell_surface->surface_for_testing();

  MockPointerDelegate delegate;
  auto pointer = std::make_unique<Pointer>(&delegate, seat_.get());
  ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());

  EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface))
      .WillRepeatedly(testing::Return(true));
  EXPECT_CALL(delegate, OnPointerFrame()).Times(1);
  EXPECT_CALL(delegate, OnPointerEnter(surface, gfx::PointF(), 0));
  generator.MoveMouseTo(surface->window()->GetBoundsInScreen().origin());

  constexpr gfx::Size buffer_size(10, 10);
  std::unique_ptr<Surface> pointer_surface(new Surface);
  std::unique_ptr<Buffer> pointer_buffer =
      std::make_unique<SolidColorBuffer>(SkColors::kRed, buffer_size);
  pointer_surface->Attach(pointer_buffer.get());
  pointer_surface->Commit();

  // Set pointer surface.
  pointer->SetCursor(pointer_surface.get(), gfx::Point());
  EXPECT_EQ(1u, pointer->GetActivePresentationCallbacksForTesting().size());
  test::WaitForLastFramePresentation(pointer.get());

  {
    viz::SurfaceId surface_id =
        *pointer->host_window()->layer()->GetSurfaceId();
    viz::SurfaceManager* surface_manager = GetSurfaceManager();
    ASSERT_TRUE(surface_manager->GetSurfaceForId(surface_id)->HasActiveFrame());
    const viz::CompositorFrame& frame =
        surface_manager->GetSurfaceForId(surface_id)->GetActiveFrame();
    EXPECT_EQ(gfx::Rect(0, 0, 10, 10),
              frame.render_pass_list.back()->output_rect);
  }

  // Set the cursor type to the kNone through SetCursorType.
  pointer->SetCursorType(ui::mojom::CursorType::kNone);
  EXPECT_TRUE(pointer->GetActivePresentationCallbacksForTesting().empty());
  EXPECT_EQ(nullptr, pointer->root_surface());

  // Set the same pointer surface again.
  pointer->SetCursor(pointer_surface.get(), gfx::Point());
  EXPECT_EQ(1u, pointer->GetActivePresentationCallbacksForTesting().size());
  test::WaitForLastFramePresentation(pointer.get());

  {
    viz::SurfaceId surface_id =
        *pointer->host_window()->layer()->GetSurfaceId();
    viz::SurfaceManager* surface_manager = GetSurfaceManager();
    ASSERT_TRUE(surface_manager->GetSurfaceForId(surface_id)->HasActiveFrame());
    const viz::CompositorFrame& frame =
        surface_manager->GetSurfaceForId(surface_id)->GetActiveFrame();
    EXPECT_EQ(gfx::Rect(0, 0, 10, 10),
              frame.render_pass_list.back()->output_rect);
  }

  EXPECT_CALL(delegate, OnPointerDestroying(pointer.get()));
  pointer.reset();
}

TEST_F(PointerTest, SetCursorNullAndSetCursorType) {
  auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  auto* surface = shell_surface->surface_for_testing();

  MockPointerDelegate delegate;
  auto pointer = std::make_unique<Pointer>(&delegate, seat_.get());
  ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());

  EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface))
      .WillRepeatedly(testing::Return(true));
  EXPECT_CALL(delegate, OnPointerFrame()).Times(1);
  EXPECT_CALL(delegate, OnPointerEnter(surface, gfx::PointF(), 0));
  generator.MoveMouseTo(surface->window()->GetBoundsInScreen().origin());

  // Set nullptr surface.
  pointer->SetCursor(nullptr, gfx::Point());

  EXPECT_EQ(nullptr, pointer->root_surface());
  aura::client::CursorClient* cursor_client = aura::client::GetCursorClient(
      shell_surface->GetWidget()->GetNativeWindow()->GetRootWindow());
  EXPECT_EQ(ui::mojom::CursorType::kNone, cursor_client->GetCursor().type());

  // Set the cursor type.
  pointer->SetCursorType(ui::mojom::CursorType::kIBeam);
  EXPECT_EQ(nullptr, pointer->root_surface());
  EXPECT_EQ(ui::mojom::CursorType::kIBeam, cursor_client->GetCursor().type());

  // Set nullptr surface again.
  pointer->SetCursor(nullptr, gfx::Point());
  EXPECT_EQ(nullptr, pointer->root_surface());
  EXPECT_EQ(ui::mojom::CursorType::kNone, cursor_client->GetCursor().type());

  EXPECT_CALL(delegate, OnPointerDestroying(pointer.get()));
  pointer.reset();
}

TEST_F(PointerTest, OnPointerEnter) {
  auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  auto* surface = shell_surface->surface_for_testing();

  MockPointerDelegate delegate;
  auto pointer = std::make_unique<Pointer>(&delegate, seat_.get());
  ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());

  EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface))
      .WillRepeatedly(testing::Return(true));
  EXPECT_CALL(delegate, OnPointerFrame()).Times(1);
  EXPECT_CALL(delegate, OnPointerEnter(surface, gfx::PointF(), 0));
  generator.MoveMouseTo(surface->window()->GetBoundsInScreen().origin());

  EXPECT_CALL(delegate, OnPointerDestroying(pointer.get()));
  pointer.reset();
}

TEST_F(PointerTest, OnPointerLeave) {
  auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  auto* surface = shell_surface->surface_for_testing();

  MockPointerDelegate delegate;
  auto pointer = std::make_unique<Pointer>(&delegate, seat_.get());
  ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());

  EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface))
      .WillRepeatedly(testing::Return(true));
  EXPECT_CALL(delegate, OnPointerFrame()).Times(4);
  EXPECT_CALL(delegate, OnPointerEnter(surface, gfx::PointF(), 0));
  generator.MoveMouseTo(surface->window()->GetBoundsInScreen().origin());

  EXPECT_CALL(delegate, OnPointerLeave(surface));
  generator.MoveMouseTo(surface->window()->GetBoundsInScreen().bottom_right());

  EXPECT_CALL(delegate, OnPointerEnter(surface, gfx::PointF(), 0));
  generator.MoveMouseTo(surface->window()->GetBoundsInScreen().origin());

  EXPECT_CALL(delegate, OnPointerLeave(surface));
  shell_surface.reset();

  EXPECT_CALL(delegate, OnPointerDestroying(pointer.get()));
  pointer.reset();
}

TEST_F(PointerTest, OnPointerMotion) {
  auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  auto* surface = shell_surface->surface_for_testing();

  MockPointerDelegate delegate;
  auto pointer = std::make_unique<Pointer>(&delegate, seat_.get());
  ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());

  EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface))
      .WillRepeatedly(testing::Return(true));
  EXPECT_CALL(delegate, OnPointerFrame()).Times(8);

  EXPECT_CALL(delegate, OnPointerEnter(surface, gfx::PointF(), 0));
  generator.MoveMouseTo(surface->window()->GetBoundsInScreen().origin());

  EXPECT_CALL(delegate, OnPointerMotion(testing::_, gfx::PointF(1, 1)));
  generator.MoveMouseTo(surface->window()->GetBoundsInScreen().origin() +
                        gfx::Vector2d(1, 1));

  std::unique_ptr<Surface> sub_surface(new Surface);
  std::unique_ptr<SubSurface> sub(new SubSurface(sub_surface.get(), surface));
  surface->SetSubSurfacePosition(sub_surface.get(), gfx::PointF(5, 5));
  constexpr gfx::Size sub_buffer_size(5, 5);
  auto sub_buffer = test::ExoTestHelper::CreateBuffer(sub_buffer_size);
  sub_surface->Attach(sub_buffer.get());
  sub_surface->Commit();
  surface->Commit();

  EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(sub_surface.get()))
      .WillRepeatedly(testing::Return(true));

  EXPECT_CALL(delegate, OnPointerLeave(surface));
  EXPECT_CALL(delegate, OnPointerEnter(sub_surface.get(), gfx::PointF(), 0));
  generator.MoveMouseTo(sub_surface->window()->GetBoundsInScreen().origin());

  EXPECT_CALL(delegate, OnPointerMotion(testing::_, gfx::PointF(1, 1)));
  generator.MoveMouseTo(sub_surface->window()->GetBoundsInScreen().origin() +
                        gfx::Vector2d(1, 1));

  std::unique_ptr<Surface> child_surface(new Surface);
  std::unique_ptr<ShellSurface> child_shell_surface(new ShellSurface(
      child_surface.get(), gfx::Point(9, 9), /*can_minimize=*/false,
      ash::desks_util::GetActiveDeskContainerId()));
  child_shell_surface->DisableMovement();
  child_shell_surface->SetParent(shell_surface.get());
  constexpr gfx::Size child_buffer_size(15, 15);
  auto child_buffer = test::ExoTestHelper::CreateBuffer(child_buffer_size);
  child_surface->Attach(child_buffer.get());
  child_surface->Commit();

  EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(child_surface.get()))
      .WillRepeatedly(testing::Return(true));

  EXPECT_CALL(delegate, OnPointerLeave(sub_surface.get()));
  EXPECT_CALL(delegate, OnPointerEnter(child_surface.get(), gfx::PointF(), 0));
  generator.MoveMouseTo(child_surface->window()->GetBoundsInScreen().origin());

  EXPECT_CALL(delegate, OnPointerMotion(testing::_, gfx::PointF(10, 10)));
  generator.MoveMouseTo(child_surface->window()->GetBoundsInScreen().origin() +
                        gfx::Vector2d(10, 10));

  EXPECT_CALL(delegate, OnPointerDestroying(pointer.get()));
  pointer.reset();
}

TEST_F(PointerTest, OnPointerButton) {
  auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  auto* surface = shell_surface->surface_for_testing();

  MockPointerDelegate delegate;
  auto pointer = std::make_unique<Pointer>(&delegate, seat_.get());
  ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());

  EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface))
      .WillRepeatedly(testing::Return(true));
  EXPECT_CALL(delegate, OnPointerFrame()).Times(3);

  EXPECT_CALL(delegate, OnPointerEnter(surface, gfx::PointF(), 0));
  generator.MoveMouseTo(surface->window()->GetBoundsInScreen().origin());

  EXPECT_CALL(delegate,
              OnPointerButton(testing::_, ui::EF_LEFT_MOUSE_BUTTON, true));
  EXPECT_CALL(delegate,
              OnPointerButton(testing::_, ui::EF_LEFT_MOUSE_BUTTON, false));
  generator.ClickLeftButton();

  EXPECT_CALL(delegate, OnPointerDestroying(pointer.get()));
  pointer.reset();
}

TEST_F(PointerTest, OnPointerButtonWithAttemptToStartDrag) {
  auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  auto* surface = shell_surface->surface_for_testing();

  MockPointerDelegate delegate;
  auto pointer = std::make_unique<Pointer>(&delegate, seat_.get());
  ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());

  EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface))
      .WillRepeatedly(testing::Return(true));
  EXPECT_CALL(delegate, OnPointerFrame()).Times(3);

  EXPECT_CALL(delegate, OnPointerEnter(surface, gfx::PointF(), 0));
  generator.MoveMouseTo(surface->window()->GetBoundsInScreen().origin());

  EXPECT_CALL(delegate,
              OnPointerButton(testing::_, ui::EF_LEFT_MOUSE_BUTTON, true));
  EXPECT_CALL(delegate,
              OnPointerButton(testing::_, ui::EF_LEFT_MOUSE_BUTTON, false));
  generator.PressLeftButton();
  ASSERT_TRUE(shell_surface->StartMove());

  generator.ReleaseLeftButton();

  EXPECT_CALL(delegate, OnPointerDestroying(pointer.get()));
  pointer.reset();
}

TEST_F(PointerTest, OnPointerScroll) {
  auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  auto* surface = shell_surface->surface_for_testing();

  MockPointerDelegate delegate;
  auto pointer = std::make_unique<Pointer>(&delegate, seat_.get());
  ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  gfx::Point location = surface->window()->GetBoundsInScreen().origin();

  EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface))
      .WillRepeatedly(testing::Return(true));
  EXPECT_CALL(delegate, OnPointerFrame()).Times(3);

  EXPECT_CALL(delegate, OnPointerEnter(surface, gfx::PointF(), 0));
  generator.MoveMouseTo(location);

  {
    // Expect fling stop followed by scroll and scroll stop.
    testing::InSequence sequence;

    EXPECT_CALL(delegate,
                OnPointerScroll(testing::_, gfx::Vector2dF(1.2, 1.2), false));
    EXPECT_CALL(delegate, OnFingerScrollStop(testing::_));
  }
  generator.ScrollSequence(location, base::TimeDelta(), 1, 1, 1, 1);

  EXPECT_CALL(delegate, OnPointerDestroying(pointer.get()));
  pointer.reset();
}

TEST_F(PointerTest, OnPointerScrollWithThreeFinger) {
  auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  auto* surface = shell_surface->surface_for_testing();

  MockPointerDelegate delegate;
  auto pointer = std::make_unique<Pointer>(&delegate, seat_.get());
  ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  gfx::Point location = surface->window()->GetBoundsInScreen().origin();

  EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface))
      .WillRepeatedly(testing::Return(true));
  EXPECT_CALL(delegate, OnPointerFrame()).Times(2);

  EXPECT_CALL(delegate, OnPointerEnter(surface, gfx::PointF(), 0));
  generator.MoveMouseTo(location);

  {
    // Expect no scroll.
    testing::InSequence sequence;
    EXPECT_CALL(delegate, OnFingerScrollStop(testing::_));
  }

  // Three fingers scroll.
  generator.ScrollSequence(location, base::TimeDelta(), 1, 1, 1,
                           3 /* num_fingers */);

  EXPECT_CALL(delegate, OnPointerDestroying(pointer.get()));
  pointer.reset();
}

TEST_F(PointerTest, OnPointerScrollDiscrete) {
  auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  auto* surface = shell_surface->surface_for_testing();

  MockPointerDelegate delegate;
  auto pointer = std::make_unique<Pointer>(&delegate, seat_.get());
  ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());

  EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface))
      .WillRepeatedly(testing::Return(true));
  EXPECT_CALL(delegate, OnPointerFrame()).Times(2);

  EXPECT_CALL(delegate, OnPointerEnter(surface, gfx::PointF(), 0));
  generator.MoveMouseTo(surface->window()->GetBoundsInScreen().origin());

  EXPECT_CALL(delegate,
              OnPointerScroll(testing::_, gfx::Vector2dF(1, 1), true));
  generator.MoveMouseWheel(1, 1);

  EXPECT_CALL(delegate, OnPointerDestroying(pointer.get()));
  pointer.reset();
}

TEST_F(PointerTest, RegisterPointerEventsOnModal) {
  // Create modal surface.
  auto shell_surface = test::ShellSurfaceBuilder({5, 5})
                           .SetCentered()
                           .SetCanMinimize(false)
                           .SetUseSystemModalContainer()
                           .SetDisableMovement()
                           .BuildShellSurface();
  auto* surface = shell_surface->surface_for_testing();

  // Make the window modal.
  shell_surface->SetSystemModal(true);
  EXPECT_TRUE(ash::Shell::IsSystemModalWindowOpen());

  MockPointerDelegate delegate;
  auto pointer = std::make_unique<Pointer>(&delegate, seat_.get());
  ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());

  EXPECT_CALL(delegate, OnPointerFrame()).Times(testing::AnyNumber());
  EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface))
      .WillRepeatedly(testing::Return(true));

  // Pointer events on modal window should be registered.
  gfx::Point origin = surface->window()->GetBoundsInScreen().origin();
  {
    testing::InSequence sequence;
    EXPECT_CALL(delegate, OnPointerEnter(surface, gfx::PointF(), 0));
    generator.MoveMouseTo(origin);

    EXPECT_CALL(delegate, OnPointerMotion(testing::_, gfx::PointF(1, 1)));
    generator.MoveMouseTo(origin + gfx::Vector2d(1, 1));

    EXPECT_CALL(delegate,
                OnPointerButton(testing::_, ui::EF_LEFT_MOUSE_BUTTON, true));
    EXPECT_CALL(delegate,
                OnPointerButton(testing::_, ui::EF_LEFT_MOUSE_BUTTON, false));
    generator.ClickLeftButton();

    EXPECT_CALL(delegate,
                OnPointerScroll(testing::_, gfx::Vector2dF(1.2, 1.2), false));
    EXPECT_CALL(delegate, OnFingerScrollStop(testing::_));
    generator.ScrollSequence(origin, base::TimeDelta(), 1, 1, 1, 1);
  }

  EXPECT_CALL(delegate, OnPointerDestroying(pointer.get()));
  pointer.reset();
}

TEST_F(PointerTest, IgnorePointerEventsOnNonModalWhenModalIsOpen) {
  // Create surface for non-modal window.
  auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  auto* surface = shell_surface->surface_for_testing();

  // Create surface for modal window.
  auto shell_surface2 = test::ShellSurfaceBuilder({5, 5})
                            .SetCentered()
                            .SetCanMinimize(false)
                            .SetUseSystemModalContainer()
                            .SetDisableMovement()
                            .BuildShellSurface();
  auto* surface2 = shell_surface->surface_for_testing();

  // Make the window modal.
  shell_surface2->SetSystemModal(true);
  EXPECT_TRUE(ash::Shell::IsSystemModalWindowOpen());

  MockPointerDelegate delegate;
  auto pointer = std::make_unique<Pointer>(&delegate, seat_.get());
  ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());

  EXPECT_CALL(delegate, OnPointerFrame()).Times(testing::AnyNumber());
  EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface))
      .WillRepeatedly(testing::Return(true));
  EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface2))
      .WillRepeatedly(testing::Return(true));

  // Check if pointer events on non-modal window are ignored.
  gfx::Point nonModalOrigin = surface->window()->GetBoundsInScreen().origin();
  {
    testing::InSequence sequence;
    EXPECT_CALL(delegate, OnPointerEnter(surface, gfx::PointF(), 0)).Times(0);
    generator.MoveMouseTo(nonModalOrigin);

    EXPECT_CALL(delegate, OnPointerMotion(testing::_, gfx::PointF(1, 1)))
        .Times(0);
    generator.MoveMouseTo(nonModalOrigin + gfx::Vector2d(1, 1));

    EXPECT_CALL(delegate,
                OnPointerButton(testing::_, ui::EF_LEFT_MOUSE_BUTTON, true))
        .Times(0);
    EXPECT_CALL(delegate,
                OnPointerButton(testing::_, ui::EF_LEFT_MOUSE_BUTTON, false))
        .Times(0);
    generator.ClickLeftButton();

    EXPECT_CALL(delegate,
                OnPointerScroll(testing::_, gfx::Vector2dF(1.2, 1.2), false))
        .Times(0);
    EXPECT_CALL(delegate, OnFingerScrollStop(testing::_)).Times(0);
    generator.ScrollSequence(nonModalOrigin, base::TimeDelta(), 1, 1, 1, 1);

    EXPECT_CALL(delegate, OnPointerLeave(surface)).Times(0);
    generator.MoveMouseTo(
        surface->window()->GetBoundsInScreen().bottom_right());
  }

  EXPECT_CALL(delegate, OnPointerDestroying(pointer.get()));
  pointer.reset();
}

TEST_F(PointerTest, IgnorePointerLeaveOnModal) {
  // Create modal surface.
  auto shell_surface = test::ShellSurfaceBuilder({5, 5})
                           .SetCentered()
                           .SetCanMinimize(false)
                           .SetUseSystemModalContainer()
                           .SetDisableMovement()
                           .BuildShellSurface();
  auto* surface = shell_surface->surface_for_testing();

  // Make the window modal.
  shell_surface->SetSystemModal(true);
  EXPECT_TRUE(ash::Shell::IsSystemModalWindowOpen());

  MockPointerDelegate delegate;
  auto pointer = std::make_unique<Pointer>(&delegate, seat_.get());
  ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());

  EXPECT_CALL(delegate, OnPointerFrame()).Times(testing::AnyNumber());
  EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface))
      .WillRepeatedly(testing::Return(true));

  gfx::Point origin = surface->window()->GetBoundsInScreen().origin();

  {
    testing::InSequence sequence;
    EXPECT_CALL(delegate, OnPointerEnter(surface, gfx::PointF(), 0));
    generator.MoveMouseTo(origin);

    // OnPointerLeave should not be called on the modal surface when the pointer
    // moves out of its bounds.
    EXPECT_CALL(delegate, OnPointerLeave(surface)).Times(0);
    generator.MoveMouseTo(
        surface->window()->GetBoundsInScreen().bottom_right());
  }

  EXPECT_CALL(delegate, OnPointerDestroying(pointer.get()));
  pointer.reset();
}

TEST_F(PointerTest, RegisterPointerEventsOnNonModal) {
  // Create surface for non-modal window.
  auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  auto* surface = shell_surface->surface_for_testing();

  // Create another surface for a non-modal window.
  auto shell_surface2 = test::ShellSurfaceBuilder({5, 5})
                            .SetCentered()
                            .SetCanMinimize(false)
                            .SetUseSystemModalContainer()
                            .SetDisableMovement()
                            .BuildShellSurface();
  auto* surface2 = shell_surface2->surface_for_testing();

  MockPointerDelegate delegate;
  std::unique_ptr<Pointer> pointer(new Pointer(&delegate, seat_.get()));
  ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());

  EXPECT_CALL(delegate, OnPointerFrame()).Times(testing::AnyNumber());
  EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface))
      .WillRepeatedly(testing::Return(true));
  EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface2))
      .WillRepeatedly(testing::Return(true));

  // Ensure second window is non-modal.
  shell_surface2->SetSystemModal(false);
  EXPECT_FALSE(ash::Shell::IsSystemModalWindowOpen());

  // Check if pointer events on first non-modal window are registered.
  gfx::Point firstWindowOrigin =
      surface->window()->GetBoundsInScreen().origin();
  {
    testing::InSequence sequence;
    EXPECT_CALL(delegate, OnPointerEnter(surface, gfx::PointF(), 0));
    generator.MoveMouseTo(firstWindowOrigin);

    EXPECT_CALL(delegate, OnPointerMotion(testing::_, gfx::PointF(1, 1)));
    generator.MoveMouseTo(firstWindowOrigin + gfx::Vector2d(1, 1));

    EXPECT_CALL(delegate,
                OnPointerButton(testing::_, ui::EF_LEFT_MOUSE_BUTTON, true));
    EXPECT_CALL(delegate,
                OnPointerButton(testing::_, ui::EF_LEFT_MOUSE_BUTTON, false));
    generator.ClickLeftButton();

    EXPECT_CALL(delegate,
                OnPointerScroll(testing::_, gfx::Vector2dF(1.2, 1.2), false));
    EXPECT_CALL(delegate, OnFingerScrollStop(testing::_));
    generator.ScrollSequence(firstWindowOrigin, base::TimeDelta(), 1, 1, 1, 1);

    EXPECT_CALL(delegate, OnPointerLeave(surface));
    generator.MoveMouseTo(
        surface->window()->GetBoundsInScreen().bottom_right());
  }

  EXPECT_CALL(delegate, OnPointerDestroying(pointer.get()));
  pointer.reset();
}

TEST_F(PointerTest, DragDropAbortBeforeStart) {
  MockPointerDelegate delegate;
  auto pointer = std::make_unique<Pointer>(&delegate, seat_.get());
  TestDataSourceDelegate data_source_delegate;
  DataSource source(&data_source_delegate);

  auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  auto* origin = shell_surface->surface_for_testing();

  ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());

  EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(origin))
      .WillRepeatedly(testing::Return(true));
  EXPECT_CALL(delegate, OnPointerFrame()).Times(3);
  EXPECT_CALL(delegate, OnPointerEnter(origin, gfx::PointF(), 0));
  generator.MoveMouseTo(origin->window()->GetBoundsInScreen().origin());

  Surface icon;
  data_device_->StartDrag(&source, origin, &icon,
                          ui::mojom::DragEventSource::kMouse);
  EXPECT_TRUE(seat_->get_drag_drop_operation_for_testing());

  EXPECT_CALL(delegate, OnPointerButton).Times(2);
  generator.PressLeftButton();
  EXPECT_TRUE(seat_->get_drag_drop_operation_for_testing());
  generator.ReleaseLeftButton();
  EXPECT_FALSE(seat_->get_drag_drop_operation_for_testing());

  EXPECT_CALL(delegate, OnPointerDestroying(pointer.get()));
  pointer.reset();
}

TEST_F(PointerTest, DragDropAndPointerEnterLeaveEvents) {
  MockPointerDelegate delegate;
  std::unique_ptr<Pointer> pointer(new Pointer(&delegate, seat_.get()));
  TestDataSourceDelegate data_source_delegate;
  DataSource source(&data_source_delegate);

  auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  auto* origin = shell_surface->surface_for_testing();

  ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());

  EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(origin))
      .WillRepeatedly(testing::Return(true));
  EXPECT_CALL(delegate, OnPointerFrame()).Times(AnyNumber());
  EXPECT_CALL(delegate, OnPointerEnter(origin, gfx::PointF(), 0));
  generator.MoveMouseTo(origin->window()->GetBoundsInScreen().origin());

  auto* drag_drop_controller = static_cast<ash::DragDropController*>(
      aura::client::GetDragDropClient(ash::Shell::GetPrimaryRootWindow()));
  ASSERT_TRUE(drag_drop_controller);

  generator.PressLeftButton();
  data_device_->StartDrag(&source, origin, /*icon=*/nullptr,
                          ui::mojom::DragEventSource::kMouse);
  EXPECT_TRUE(seat_->get_drag_drop_operation_for_testing());

  // As soon as the runloop gets triggered, emit a mouse release event.
  drag_drop_controller->SetLoopClosureForTesting(
      base::BindLambdaForTesting([&]() {
        // Mouse move should not produce mouse enter.
        generator.MoveMouseBy(1, 1);
        generator.ReleaseLeftButton();
        // A user may move and click again, after the drag drop in ash is
        // finished but before exo haven't sent the finished events.
        // These events should not be sent to clients.
        generator.MoveMouseBy(1, 1);
        generator.ClickLeftButton();
      }),
      base::DoNothing());

  // Pointer leave should be called only once upon start.
  EXPECT_CALL(delegate, OnPointerLeave(_)).Times(1);
  EXPECT_CALL(delegate, OnPointerFrame()).Times(1);
  EXPECT_CALL(delegate, OnPointerEnter(_, _, _)).Times(0);
  EXPECT_CALL(delegate, OnPointerButton(testing::_, testing::_, testing::_))
      .Times(0);

  base::RunLoop().RunUntilIdle();
  ::testing::Mock::VerifyAndClearExpectations(&delegate);

  // Mouse release event happened during drag and drop will be issued on next
  // mouse event.
  EXPECT_CALL(delegate,
              OnPointerButton(testing::_, ui::EF_LEFT_MOUSE_BUTTON, false))
      .Times(1);
  EXPECT_CALL(delegate, OnPointerFrame()).Times(1);

  generator.MoveMouseBy(1, 1);

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

  EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(origin))
      .WillRepeatedly(testing::Return(true));
  EXPECT_FALSE(seat_->get_drag_drop_operation_for_testing());

  // Pointer leave should be called again after drag and drop.
  EXPECT_CALL(delegate, OnPointerEnter(_, _, _));

  EXPECT_CALL(delegate, OnPointerDestroying(pointer.get()));

  generator.MoveMouseBy(1, 1);

  pointer.reset();
}

TEST_F(PointerTest, DragDropAndPointerEnterLeaveEvents_NoOpOnTouchDrag) {
  MockPointerDelegate delegate;
  std::unique_ptr<Pointer> pointer(new Pointer(&delegate, seat_.get()));
  TestDataSourceDelegate data_source_delegate;
  DataSource source(&data_source_delegate);

  auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  auto* origin = shell_surface->surface_for_testing();

  ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());

  EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(origin))
      .WillRepeatedly(testing::Return(true));
  EXPECT_CALL(delegate, OnPointerFrame()).Times(AnyNumber());
  EXPECT_CALL(delegate, OnPointerEnter(origin, gfx::PointF(), 0));
  generator.MoveMouseTo(origin->window()->GetBoundsInScreen().origin());

  auto* drag_drop_controller = static_cast<ash::DragDropController*>(
      aura::client::GetDragDropClient(ash::Shell::GetPrimaryRootWindow()));
  ASSERT_TRUE(drag_drop_controller);

  data_device_->StartDrag(&source, origin, /*icon=*/nullptr,
                          ui::mojom::DragEventSource::kTouch);
  EXPECT_TRUE(seat_->get_drag_drop_operation_for_testing());

  // Initiate the gesture sequence.
  DispatchGesture(ui::EventType::kGestureBegin, gfx::Point(10, 10));

  // As soon as the runloop gets triggered, emit a mouse release event.
  drag_drop_controller->SetLoopClosureForTesting(
      base::BindLambdaForTesting([&]() {
        EXPECT_CALL(delegate, OnPointerEnter(_, _, _)).Times(0);
        // generator.ReleaseLeftButton();
        generator.set_current_screen_location(gfx::Point(10, 10));
        generator.PressMoveAndReleaseTouchBy(50, 50);
      }),
      base::DoNothing());

  EXPECT_CALL(delegate, OnPointerLeave(_)).Times(0);
  base::RunLoop().RunUntilIdle();

  EXPECT_CALL(delegate, OnPointerDestroying(pointer.get()));
  pointer.reset();
}

TEST_F(PointerTest, IgnoresHandledEvents) {
  // A very dumb handler that simply marks all events as handled. This is needed
  // allows us to mark a mouse event as handled as it gets processed by the
  // event processor.
  class SetHandledHandler : public ui::EventHandler {
    void OnMouseEvent(ui::MouseEvent* event) override { event->SetHandled(); }
  };
  SetHandledHandler handler;
  ash::Shell::Get()->AddPreTargetHandler(&handler);

  testing::NiceMock<MockPointerDelegate> delegate;
  std::unique_ptr<Pointer> pointer(new Pointer(&delegate, seat_.get()));

  // Make origin into a real window so the touch can click it
  std::unique_ptr<ShellSurface> shell_surface =
      test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();

  EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(testing::_))
      .WillRepeatedly(testing::Return(true));
  ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());

  // The SetHandlerHandler should have marked the event as processed. Therefore
  // the event should simply be ignored.
  EXPECT_CALL(delegate, OnPointerButton(testing::_, testing::_, testing::_))
      .Times(0);

  // This event should be ignored because it has already been handled.
  auto window_point = shell_surface->surface_for_testing()
                          ->window()
                          ->GetBoundsInScreen()
                          .CenterPoint();
  generator.MoveMouseTo(window_point);
  generator.ClickLeftButton();

  ash::Shell::Get()->RemovePreTargetHandler(&handler);
}

TEST_F(PointerTest, IgnoresCursorHideEvents) {
  testing::NiceMock<MockPointerDelegate> delegate;
  auto pointer = std::make_unique<Pointer>(&delegate, seat_.get());

  // Make origin into a real window so the touch can click it
  std::unique_ptr<ShellSurface> shell_surface =
      test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();

  // If the pointer event is targeting something other than |shell_surface|,
  // it's not what we want so block here.
  // Note that, gmock puts priority to the later call, so the specific one
  // should come after the default one.
  EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(testing::_))
      .WillRepeatedly(testing::Return(false));
  EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(
                            shell_surface->surface_for_testing()))
      .WillRepeatedly(testing::Return(true));

  // Set up multi-display environment, and emulate the story that we hit
  // an issue on event dispatching. (see crbug.com/1395256 for details).
  // - Create two displays.
  // - Move the cursor to the secondary display, then move it back to the
  //   primary display.
  UpdateDisplay("800x600, 800x600");
  auto* generator = GetEventGenerator();
  generator->MoveMouseTo({1000, 10});
  auto window_point = shell_surface->surface_for_testing()
                          ->window()
                          ->GetBoundsInScreen()
                          .CenterPoint();
  generator->MoveMouseTo(window_point);
  ::testing::Mock::VerifyAndClearExpectations(&delegate);

  // Now dispatch a key event.
  // This key event internally generates MOUSE_EXITED pointer event with
  // CURSOR_HIDE|IS_SYNTHESIZED flags and dispatches to the tree.
  // Currently, wayland leave/enter events should be suppressed temporarily.
  // See also crbug.com/1395073 what is the eventually expected state.
  EXPECT_CALL(delegate, OnPointerLeave(testing::_)).Times(0);
  EXPECT_CALL(delegate, OnPointerEnter(testing::_, testing::_, testing::_))
      .Times(0);
  EXPECT_CALL(delegate, OnPointerFrame()).Times(0);

  // Re-set up CanAcceptPointerEventsForSurface, which was reset above.
  EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(testing::_))
      .WillRepeatedly(testing::Return(false));
  EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(
                            shell_surface->surface_for_testing()))
      .WillRepeatedly(testing::Return(true));

  // All set up of expectations is done, so dispatch the key event now.
  generator->PressKey(ui::VKEY_A, 0, 0);

  ::testing::Mock::VerifyAndClearExpectations(&delegate);
}

namespace {

class TestDataDevice : public DataDevice {
 public:
  using TestCallback = base::OnceCallback<void(ui::mojom::DragOperation&)>;

  TestDataDevice(TestCallback closure, DataDeviceDelegate* delegate, Seat* seat)
      : DataDevice(delegate, seat), closure_(std::move(closure)) {}
  TestDataDevice(const TestDataDevice&) = delete;
  const TestDataDevice operator=(const TestDataDevice&) = delete;

  aura::client::DragDropDelegate::DropCallback GetDropCallback(
      const ui::DropTargetEvent& event) override {
    auto callback = DataDevice::GetDropCallback(event);
    return base::BindOnce(&TestDataDevice::PerformDrop, base::Unretained(this),
                          std::move(callback));
  }

 private:
  void PerformDrop(
      aura::client::DragDropDelegate::DropCallback original_callback,
      std::unique_ptr<ui::OSExchangeData> data,
      ui::mojom::DragOperation& output_drag_op,
      std::unique_ptr<ui::LayerTreeOwner> drag_image_layer_owner) {
    std::move(closure_).Run(output_drag_op);
    std::move(original_callback)
        .Run(std::move(data), output_drag_op,
             std::move(drag_image_layer_owner));
  }

  TestCallback closure_;
};

}  // namespace

// Test for crbug.com/1307143: It ensures no "pointer enter" event is
// processed in case the target surface is destroyed during the drop action.
TEST_F(PointerTest,
       DragDropAndPointerEnterLeaveEvents_NoEnterOnSurfaceDestroy) {
  MockPointerDelegate delegate;
  std::unique_ptr<Pointer> pointer(new Pointer(&delegate, seat_.get()));
  TestDataSourceDelegate data_source_delegate;
  DataSource source(&data_source_delegate);

  auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  auto* origin_ptr = shell_surface->surface_for_testing();

  auto closure = base::BindOnce([](std::unique_ptr<ShellSurface> shell_surface,
                                   ui::mojom::DragOperation& output_drag_op) {},
                                std::move(shell_surface));
  TestDataDevice data_device(std::move(closure), &data_device_delegate_,
                             seat_.get());

  ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());

  EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(origin_ptr))
      .WillRepeatedly(testing::Return(true));
  EXPECT_CALL(delegate, OnPointerFrame()).Times(AnyNumber());
  EXPECT_CALL(delegate, OnPointerEnter(origin_ptr, gfx::PointF(), 0));
  generator.MoveMouseTo(origin_ptr->window()->GetBoundsInScreen().origin());

  auto* drag_drop_controller = static_cast<ash::DragDropController*>(
      aura::client::GetDragDropClient(ash::Shell::GetPrimaryRootWindow()));
  ASSERT_TRUE(drag_drop_controller);

  generator.PressLeftButton();
  data_device.StartDrag(&source, origin_ptr, /*icon=*/nullptr,
                        ui::mojom::DragEventSource::kMouse);
  EXPECT_TRUE(seat_->get_drag_drop_operation_for_testing());

  // As soon as the runloop gets triggered, emit a mouse release event.
  drag_drop_controller->SetLoopClosureForTesting(
      base::BindLambdaForTesting([&]() {
        EXPECT_FALSE(drag_drop_controller->IsDragDropCompleted());
        generator.ReleaseLeftButton();
      }),
      base::DoNothing());

  // OnPointerLeave() gets called when the drag starts;
  EXPECT_CALL(delegate, OnPointerLeave(_)).Times(1);
  EXPECT_CALL(delegate, OnPointerEnter(_, _, _)).Times(0);

  base::RunLoop().RunUntilIdle();

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

  EXPECT_TRUE(drag_drop_controller->IsDragDropCompleted());
  // There should be no mouse enter after dnd session either.
  EXPECT_CALL(delegate, OnPointerEnter(_, _, _)).Times(0);

  generator.MoveMouseBy(1, 1);

  EXPECT_CALL(delegate, OnPointerDestroying(pointer.get()));
  pointer.reset();
}

// Test for crbug.com/1307143: It ensures no "pointer enter" event is
// processed in case the target surface parent is destroyed during the drop
// action.
TEST_F(PointerTest,
       DragDropAndPointerEnterLeaveEvents_NoEnterOnParentSurfaceDestroy) {
  MockPointerDelegate delegate;
  std::unique_ptr<Pointer> pointer(new Pointer(&delegate, seat_.get()));
  TestDataSourceDelegate data_source_delegate;
  DataSource source(&data_source_delegate);

  auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  auto* surface = shell_surface->surface_for_testing();

  auto closure = base::BindOnce([](std::unique_ptr<ShellSurface> shell_surface,
                                   ui::mojom::DragOperation& output_drag_op) {},
                                std::move(shell_surface));
  TestDataDevice data_device(std::move(closure), &data_device_delegate_,
                             seat_.get());

  ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());

  EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(testing::_))
      .WillRepeatedly(testing::Return(true));
  EXPECT_CALL(delegate, OnPointerFrame()).Times(AnyNumber());
  EXPECT_CALL(delegate, OnPointerEnter(surface, gfx::PointF(), 0));
  generator.MoveMouseTo(surface->window()->GetBoundsInScreen().origin());

  auto* drag_drop_controller = static_cast<ash::DragDropController*>(
      aura::client::GetDragDropClient(ash::Shell::GetPrimaryRootWindow()));
  ASSERT_TRUE(drag_drop_controller);

  generator.PressLeftButton();
  data_device.StartDrag(&source, surface, /*icon=*/nullptr,
                        ui::mojom::DragEventSource::kMouse);
  EXPECT_TRUE(seat_->get_drag_drop_operation_for_testing());

  // As soon as the runloop gets triggered, emit a mouse release event.
  drag_drop_controller->SetLoopClosureForTesting(
      base::BindLambdaForTesting([&]() {
        EXPECT_FALSE(drag_drop_controller->IsDragDropCompleted());
        generator.ReleaseLeftButton();
      }),
      base::DoNothing());

  // OnPointerLeave() gets called twice:
  // 1/ when the drag starts;
  // 2/ when the dragging window gets destroyed.
  EXPECT_CALL(delegate, OnPointerLeave(_)).Times(1);
  EXPECT_CALL(delegate, OnPointerEnter(_, _, _)).Times(0);
  base::RunLoop().RunUntilIdle();

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

  EXPECT_TRUE(drag_drop_controller->IsDragDropCompleted());

  EXPECT_CALL(delegate, OnPointerDestroying(pointer.get()));
  pointer.reset();
}

TEST_F(PointerTest, OnPointerRelativeMotion) {
  auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  auto* surface = shell_surface->surface_for_testing();

  MockPointerDelegate delegate;
  MockRelativePointerDelegate relative_delegate;
  auto pointer = std::make_unique<Pointer>(&delegate, seat_.get());
  ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  pointer->RegisterRelativePointerDelegate(&relative_delegate);

  EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface))
      .WillRepeatedly(testing::Return(true));
  EXPECT_CALL(delegate, OnPointerFrame()).Times(11);

  EXPECT_CALL(delegate, OnPointerEnter(surface, gfx::PointF(), 0));
  generator.MoveMouseTo(surface->window()->GetBoundsInScreen().origin());

  EXPECT_CALL(delegate, OnPointerMotion(testing::_, gfx::PointF(1, 1)));
  EXPECT_CALL(
      relative_delegate,
      OnPointerRelativeMotion(testing::_, gfx::Vector2dF(1, 1), testing::_));
  generator.MoveMouseTo(surface->window()->GetBoundsInScreen().origin() +
                        gfx::Vector2d(1, 1));

  EXPECT_CALL(delegate, OnPointerMotion(testing::_, gfx::PointF(2, 2)));
  EXPECT_CALL(
      relative_delegate,
      OnPointerRelativeMotion(testing::_, gfx::Vector2dF(1, 1), testing::_));
  generator.MoveMouseTo(surface->window()->GetBoundsInScreen().origin() +
                        gfx::Vector2d(2, 2));

  auto sub_surface = std::make_unique<Surface>();
  auto sub = std::make_unique<SubSurface>(sub_surface.get(), surface);
  surface->SetSubSurfacePosition(sub_surface.get(), gfx::PointF(5, 5));
  constexpr gfx::Size sub_buffer_size(5, 5);
  auto sub_buffer = test::ExoTestHelper::CreateBuffer(sub_buffer_size);
  sub_surface->Attach(sub_buffer.get());
  sub_surface->Commit();
  surface->Commit();

  EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(sub_surface.get()))
      .WillRepeatedly(testing::Return(true));

  EXPECT_CALL(delegate, OnPointerLeave(surface));
  EXPECT_CALL(delegate, OnPointerEnter(sub_surface.get(), gfx::PointF(), 0));
  // OnPointerMotion will not be called, because the pointer location is already
  // sent with OnPointerEnter, but we should still receive
  // OnPointerRelativeMotion.
  EXPECT_CALL(
      relative_delegate,
      OnPointerRelativeMotion(testing::_, gfx::Vector2dF(3, 3), testing::_));
  generator.MoveMouseTo(sub_surface->window()->GetBoundsInScreen().origin());

  EXPECT_CALL(delegate, OnPointerMotion(testing::_, gfx::PointF(1, 1)));
  EXPECT_CALL(
      relative_delegate,
      OnPointerRelativeMotion(testing::_, gfx::Vector2dF(1, 1), testing::_));
  generator.MoveMouseTo(sub_surface->window()->GetBoundsInScreen().origin() +
                        gfx::Vector2d(1, 1));

  const gfx::Point child_surface_origin =
      sub_surface->window()->GetBoundsInScreen().origin() +
      gfx::Vector2d(10, 10);
  auto child_surface = std::make_unique<Surface>();
  auto child_shell_surface = std::make_unique<ShellSurface>(
      child_surface.get(), child_surface_origin, /*can_minimize=*/false,
      ash::desks_util::GetActiveDeskContainerId());
  child_shell_surface->DisableMovement();
  child_shell_surface->SetParent(shell_surface.get());
  constexpr gfx::Size child_buffer_size(15, 15);
  auto child_buffer = test::ExoTestHelper::CreateBuffer(child_buffer_size);
  child_surface->Attach(child_buffer.get());
  child_surface->Commit();

  EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(child_surface.get()))
      .WillRepeatedly(testing::Return(true));

  EXPECT_CALL(delegate, OnPointerLeave(sub_surface.get()));
  EXPECT_CALL(delegate, OnPointerEnter(child_surface.get(), gfx::PointF(), 0));
  // OnPointerMotion will not be called, because the pointer location is already
  // sent with OnPointerEnter, but we should still receive
  // OnPointerRelativeMotion.
  EXPECT_CALL(
      relative_delegate,
      OnPointerRelativeMotion(testing::_, gfx::Vector2dF(9, 9), testing::_));
  generator.MoveMouseTo(child_surface->window()->GetBoundsInScreen().origin());

  EXPECT_CALL(delegate, OnPointerMotion(testing::_, gfx::PointF(10, 10)));
  EXPECT_CALL(
      relative_delegate,
      OnPointerRelativeMotion(testing::_, gfx::Vector2dF(10, 10), testing::_));
  generator.MoveMouseTo(child_surface->window()->GetBoundsInScreen().origin() +
                        gfx::Vector2d(10, 10));

  EXPECT_CALL(delegate, OnPointerDestroying(pointer.get()));
  EXPECT_CALL(relative_delegate, OnPointerDestroying(pointer.get()));
  pointer.reset();
}

class PointerOrdinalMotionTest : public PointerTest {
 public:
  PointerOrdinalMotionTest() {
    scoped_feature_list_.InitAndEnableFeature(ash::features::kExoOrdinalMotion);
  }

 private:
  base::test::ScopedFeatureList scoped_feature_list_;
};

TEST_F(PointerOrdinalMotionTest, OrdinalMotionOverridesRelativeMotion) {
  auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  auto* surface = shell_surface->surface_for_testing();

  // Set up the pointer and move it to the origin.
  testing::NiceMock<MockPointerDelegate> delegate;
  auto pointer = std::make_unique<Pointer>(&delegate, seat_.get());
  ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface))
      .WillRepeatedly(testing::Return(true));
  gfx::Point origin = surface->window()->GetBoundsInScreen().origin();
  generator.MoveMouseTo(origin);

  // Start sending relative motion events.
  testing::StrictMock<MockRelativePointerDelegate> relative_delegate;
  pointer->RegisterRelativePointerDelegate(&relative_delegate);

  // By default, ordinal and relative are the same.
  gfx::Point new_location = origin + gfx::Vector2d(1, 1);
  ui::MouseEvent ev1(ui::EventType::kMouseMoved, new_location, new_location,
                     ui::EventTimeForNow(), generator.flags(), 0);
  EXPECT_CALL(relative_delegate,
              OnPointerRelativeMotion(testing::_, gfx::Vector2dF(1, 1),
                                      gfx::Vector2dF(1, 1)));
  generator.Dispatch(&ev1);

  // When set, ordinal overrides the relative motion.
  new_location = new_location + gfx::Vector2d(1, 1);
  ui::MouseEvent ev2(ui::EventType::kMouseMoved, new_location, new_location,
                     ui::EventTimeForNow(), generator.flags(), 0);
  ui::MouseEvent::DispatcherApi(&ev2).set_movement(gfx::Vector2dF(99, 99));
  EXPECT_CALL(relative_delegate,
              OnPointerRelativeMotion(testing::_, gfx::Vector2dF(1, 1),
                                      gfx::Vector2dF(99, 99)));
  generator.Dispatch(&ev2);

  pointer->UnregisterRelativePointerDelegate(&relative_delegate);
}

TEST_F(PointerConstraintTest, ConstrainPointer) {
  EXPECT_TRUE(pointer_->ConstrainPointer(&constraint_delegate_));

  EXPECT_CALL(delegate_, OnPointerEnter(surface_.get(), gfx::PointF(), 0));
  EXPECT_CALL(delegate_, OnPointerFrame());
  generator_->MoveMouseTo(surface_->window()->GetBoundsInScreen().origin());

  EXPECT_CALL(delegate_, OnPointerMotion(testing::_, testing::_)).Times(0);
  generator_->MoveMouseTo(surface_->window()->GetBoundsInScreen().origin() +
                          gfx::Vector2d(-1, -1));

  auto child_shell_surface = test::ShellSurfaceBuilder({15, 15})
                                 .SetParent(shell_surface_.get())
                                 .SetDisableMovement()
                                 .SetCanMinimize(false)
                                 .BuildShellSurface();
  Surface* child_surface = child_shell_surface->surface_for_testing();
  EXPECT_CALL(delegate_, CanAcceptPointerEventsForSurface(child_surface))
      .WillRepeatedly(testing::Return(true));

  generator_->MoveMouseTo(
      child_surface->window()->GetBoundsInScreen().origin());

  EXPECT_CALL(delegate_, OnPointerLeave(surface_.get()));
  EXPECT_CALL(delegate_, OnPointerEnter(child_surface, gfx::PointF(), 0));
  EXPECT_CALL(delegate_, OnPointerFrame()).Times(2);
  // Moving the cursor to a different surface should change the focus when
  // the pointer is unconstrained.
  pointer_->UnconstrainPointerByUserAction();
  generator_->MoveMouseTo(
      child_surface->window()->GetBoundsInScreen().origin());

  pointer_->OnPointerConstraintDelegateDestroying(&constraint_delegate_);
  EXPECT_CALL(delegate_, OnPointerDestroying(pointer_.get()));
  pointer_.reset();
}

TEST_F(PointerConstraintTest, CanOnlyConstrainPermittedWindows) {
  std::unique_ptr<ShellSurface> shell_surface =
      test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  EXPECT_CALL(constraint_delegate_, GetConstrainedSurface())
      .WillRepeatedly(testing::Return(shell_surface->surface_for_testing()));
  // Called once when ConstrainPointer is denied, and again when the delegate
  // is destroyed.
  EXPECT_CALL(constraint_delegate_, OnDefunct()).Times(2);

  EXPECT_FALSE(pointer_->ConstrainPointer(&constraint_delegate_));

  pointer_->OnPointerConstraintDelegateDestroying(&constraint_delegate_);
  EXPECT_CALL(delegate_, OnPointerDestroying(pointer_.get()));
  pointer_.reset();
}

TEST_F(PointerConstraintTest, OneConstraintPerSurface) {
  ON_CALL(constraint_delegate_, IsPersistent())
      .WillByDefault(testing::Return(false));
  EXPECT_TRUE(pointer_->ConstrainPointer(&constraint_delegate_));

  EXPECT_CALL(delegate_, OnPointerEnter(surface_.get(), gfx::PointF(), 0));
  EXPECT_CALL(delegate_, OnPointerFrame()).Times(testing::AtLeast(1));
  generator_->MoveMouseTo(surface_->window()->GetBoundsInScreen().origin());

  // Add a second constraint for the same surface, it should fail.
  MockPointerConstraintDelegate second_constraint;
  EXPECT_CALL(second_constraint, GetConstrainedSurface())
      .WillRepeatedly(testing::Return(surface_.get()));
  ON_CALL(second_constraint, IsPersistent())
      .WillByDefault(testing::Return(false));
  EXPECT_CALL(second_constraint, OnAlreadyConstrained());
  EXPECT_CALL(second_constraint, OnDefunct());
  EXPECT_FALSE(pointer_->ConstrainPointer(&second_constraint));

  pointer_->OnPointerConstraintDelegateDestroying(&constraint_delegate_);
  EXPECT_CALL(delegate_, OnPointerDestroying(pointer_.get()));
  pointer_.reset();
}

TEST_F(PointerConstraintTest, OneShotConstraintActivatedOnFirstFocus) {
  auto second_shell_surface = BuildShellSurfaceWhichPermitsPointerLock();
  Surface* second_surface = second_shell_surface->surface_for_testing();

  EXPECT_CALL(delegate_, CanAcceptPointerEventsForSurface(second_surface))
      .WillRepeatedly(testing::Return(true));

  focus_client_->FocusWindow(second_surface->window());

  // Assert: Can no longer activate the constraint on the first surface.
  EXPECT_FALSE(pointer_->ConstrainPointer(&constraint_delegate_));
  EXPECT_EQ(constraint_delegate_.activated_count, 0);

  // Assert: Constraint is activated when first surface gains focus.
  focus_client_->FocusWindow(surface_->window());
  EXPECT_EQ(constraint_delegate_.activated_count, 1);

  EXPECT_CALL(delegate_, OnPointerEnter(surface_.get(), gfx::PointF(), 0));
  EXPECT_CALL(delegate_, OnPointerFrame());
  generator_->MoveMouseTo(surface_->window()->GetBoundsInScreen().origin());

  // Teardown
  pointer_->OnPointerConstraintDelegateDestroying(&constraint_delegate_);
  EXPECT_CALL(delegate_, OnPointerDestroying(pointer_.get()));
  pointer_.reset();
}

TEST_F(PointerConstraintTest, UnconstrainPointerWhenSurfaceIsDestroyed) {
  EXPECT_TRUE(pointer_->ConstrainPointer(&constraint_delegate_));

  EXPECT_CALL(delegate_, OnPointerEnter(surface_.get(), gfx::PointF(), 0));
  EXPECT_CALL(delegate_, OnPointerFrame());
  generator_->MoveMouseTo(surface_->window()->GetBoundsInScreen().origin());

  // Constraint should be broken if surface is destroyed.
  EXPECT_CALL(constraint_delegate_, OnConstraintBroken());
  EXPECT_CALL(delegate_, OnPointerLeave(surface_.get()));
  EXPECT_CALL(delegate_, OnPointerFrame());
  shell_surface_.reset();

  EXPECT_CALL(delegate_, OnPointerDestroying(pointer_.get()));
  pointer_.reset();
}

TEST_F(PointerConstraintTest, UnconstrainPointerWhenWindowLosesFocus) {
  ON_CALL(constraint_delegate_, IsPersistent())
      .WillByDefault(testing::Return(false));
  EXPECT_TRUE(pointer_->ConstrainPointer(&constraint_delegate_));

  EXPECT_CALL(delegate_, OnPointerEnter(surface_.get(), gfx::PointF(), 0));
  EXPECT_CALL(delegate_, OnPointerFrame());
  generator_->MoveMouseTo(surface_->window()->GetBoundsInScreen().origin());

  EXPECT_CALL(constraint_delegate_, OnConstraintBroken());
  EXPECT_CALL(constraint_delegate_, OnConstraintActivated()).Times(0);
  focus_client_->FocusWindow(nullptr);
  focus_client_->FocusWindow(surface_->window());

  pointer_->OnPointerConstraintDelegateDestroying(&constraint_delegate_);
  EXPECT_CALL(delegate_, OnPointerDestroying(pointer_.get()));
  pointer_.reset();
}

TEST_F(PointerConstraintTest, PersistentConstraintActivatedOnRefocus) {
  ON_CALL(constraint_delegate_, IsPersistent())
      .WillByDefault(testing::Return(true));
  EXPECT_TRUE(pointer_->ConstrainPointer(&constraint_delegate_));

  EXPECT_CALL(delegate_, OnPointerEnter(surface_.get(), gfx::PointF(), 0));
  EXPECT_CALL(delegate_, OnPointerFrame());
  generator_->MoveMouseTo(surface_->window()->GetBoundsInScreen().origin());

  EXPECT_CALL(constraint_delegate_, OnConstraintBroken());
  focus_client_->FocusWindow(nullptr);
  EXPECT_CALL(constraint_delegate_, OnConstraintActivated());
  focus_client_->FocusWindow(surface_->window());

  pointer_->OnPointerConstraintDelegateDestroying(&constraint_delegate_);
  EXPECT_CALL(delegate_, OnPointerDestroying(pointer_.get()));
  pointer_.reset();
}

TEST_F(PointerConstraintTest, MultipleSurfacesCanBeConstrained) {
  // Arrange: First surface + persistent constraint
  ON_CALL(constraint_delegate_, IsPersistent())
      .WillByDefault(testing::Return(true));
  EXPECT_TRUE(pointer_->ConstrainPointer(&constraint_delegate_));

  EXPECT_CALL(delegate_, OnPointerEnter(surface_.get(), gfx::PointF(), 0));
  EXPECT_CALL(delegate_, OnPointerFrame());
  generator_->MoveMouseTo(surface_->window()->GetBoundsInScreen().origin());

  EXPECT_EQ(constraint_delegate_.activated_count, 1);

  // Arrange: Second surface + persistent constraint
  auto second_shell_surface = BuildShellSurfaceWhichPermitsPointerLock();
  Surface* second_surface = second_shell_surface->surface_for_testing();
  focus_client_->FocusWindow(second_surface->window());
  EXPECT_CALL(delegate_, CanAcceptPointerEventsForSurface(second_surface))
      .WillRepeatedly(testing::Return(true));
  testing::NiceMock<MockPointerConstraintDelegate> second_constraint;
  EXPECT_CALL(second_constraint, GetConstrainedSurface())
      .WillRepeatedly(testing::Return(second_surface));
  ON_CALL(second_constraint, IsPersistent())
      .WillByDefault(testing::Return(true));
  EXPECT_TRUE(pointer_->ConstrainPointer(&second_constraint));

  EXPECT_EQ(constraint_delegate_.activated_count, 1);
  EXPECT_EQ(second_constraint.activated_count, 1);

  // Act: Toggle focus, first surface's constraint should activate.
  focus_client_->FocusWindow(surface_->window());

  EXPECT_EQ(constraint_delegate_.activated_count, 2);
  EXPECT_EQ(second_constraint.activated_count, 1);

  // Act: Toggle focus, second surface's constraint should activate.
  focus_client_->FocusWindow(second_surface->window());

  EXPECT_EQ(constraint_delegate_.activated_count, 2);
  EXPECT_EQ(second_constraint.activated_count, 2);

  pointer_->OnPointerConstraintDelegateDestroying(&constraint_delegate_);
  pointer_->OnPointerConstraintDelegateDestroying(&second_constraint);
  EXPECT_CALL(delegate_, OnPointerDestroying(pointer_.get()));
  pointer_.reset();
}

TEST_F(PointerConstraintTest, UserActionPreventsConstraint) {
  ON_CALL(constraint_delegate_, IsPersistent())
      .WillByDefault(testing::Return(false));
  EXPECT_TRUE(pointer_->ConstrainPointer(&constraint_delegate_));

  EXPECT_CALL(delegate_, OnPointerEnter(surface_.get(), gfx::PointF(), 0));
  EXPECT_CALL(delegate_, OnPointerFrame()).Times(testing::AtLeast(1));
  generator_->MoveMouseTo(surface_->window()->GetBoundsInScreen().origin());

  EXPECT_CALL(constraint_delegate_, OnConstraintBroken());
  pointer_->UnconstrainPointerByUserAction();

  // New constraints are no longer permitted.
  MockPointerConstraintDelegate second_constraint;
  EXPECT_CALL(second_constraint, GetConstrainedSurface())
      .WillRepeatedly(testing::Return(surface_.get()));
  ON_CALL(second_constraint, IsPersistent())
      .WillByDefault(testing::Return(false));
  EXPECT_FALSE(pointer_->ConstrainPointer(&second_constraint));
  EXPECT_EQ(second_constraint.activated_count, 0);

  // A click event will activate the pending constraint.
  generator_->ClickLeftButton();
  EXPECT_EQ(second_constraint.activated_count, 1);

  pointer_->OnPointerConstraintDelegateDestroying(&second_constraint);

  // New constraints are now permitted too.
  MockPointerConstraintDelegate third_constraint;
  EXPECT_CALL(third_constraint, GetConstrainedSurface())
      .WillRepeatedly(testing::Return(surface_.get()));
  ON_CALL(third_constraint, IsPersistent())
      .WillByDefault(testing::Return(false));
  EXPECT_TRUE(pointer_->ConstrainPointer(&third_constraint));
  pointer_->OnPointerConstraintDelegateDestroying(&third_constraint);

  pointer_->OnPointerConstraintDelegateDestroying(&constraint_delegate_);
  EXPECT_CALL(delegate_, OnPointerDestroying(pointer_.get()));
  pointer_.reset();
}

TEST_F(PointerConstraintTest, UserCanBreakAndActivatePersistentConstraint) {
  ON_CALL(constraint_delegate_, IsPersistent())
      .WillByDefault(testing::Return(true));
  EXPECT_TRUE(pointer_->ConstrainPointer(&constraint_delegate_));
  EXPECT_EQ(constraint_delegate_.activated_count, 1);
  EXPECT_EQ(constraint_delegate_.broken_count, 0);

  EXPECT_CALL(delegate_, OnPointerEnter(surface_.get(), gfx::PointF(), 0));
  EXPECT_CALL(delegate_, OnPointerFrame()).Times(testing::AtLeast(1));
  generator_->MoveMouseTo(surface_->window()->GetBoundsInScreen().origin());

  EXPECT_CALL(constraint_delegate_, OnConstraintBroken());
  pointer_->UnconstrainPointerByUserAction();
  EXPECT_EQ(constraint_delegate_.activated_count, 1);
  EXPECT_EQ(constraint_delegate_.broken_count, 1);

  // Click events re-enable the constraint.
  generator_->ClickLeftButton();
  EXPECT_EQ(constraint_delegate_.activated_count, 2);

  pointer_->OnPointerConstraintDelegateDestroying(&constraint_delegate_);
  EXPECT_CALL(delegate_, OnPointerDestroying(pointer_.get()));
  pointer_.reset();
}

TEST_F(PointerConstraintTest, NoPointerMotionEventWhenUnconstrainingPointer) {
  testing::MockFunction<void(std::string check_point_name)> check;
  {
    testing::InSequence s;

    EXPECT_CALL(check, Call("Unconstrain pointer"));
    EXPECT_CALL(delegate_, OnPointerMotion(testing::_, testing::_)).Times(0);
  }

  generator_->MoveMouseTo(
      surface_->window()->GetBoundsInScreen().CenterPoint() +
      gfx::Vector2d(4, 4));

  EXPECT_TRUE(pointer_->ConstrainPointer(&constraint_delegate_));

  generator_->MoveMouseTo(
      surface_->window()->GetBoundsInScreen().CenterPoint() +
      gfx::Vector2d(-4, -4));

  check.Call("Unconstrain pointer");

  pointer_->UnconstrainPointerByUserAction();

  // Ensure the posted task for synthesized mouse move event is run.
  base::RunLoop().RunUntilIdle();

  pointer_.reset();
}

TEST_F(PointerConstraintTest, ConstrainPointerWithUncommittedShellSurface) {
  std::unique_ptr<ShellSurface> uncommitted_shell_surface =
      test::ShellSurfaceBuilder({10, 10}).SetNoCommit().BuildShellSurface();

  Surface* surface = uncommitted_shell_surface->surface_for_testing();
  surface->window()->GetToplevelWindow()->SetProperty(
      chromeos::kUseOverviewToExitPointerLock, true);

  focus_client_->FocusWindow(surface->window());
  EXPECT_CALL(delegate_, CanAcceptPointerEventsForSurface(surface))
      .WillRepeatedly(testing::Return(true));
  testing::NiceMock<MockPointerConstraintDelegate> second_constraint;
  EXPECT_CALL(second_constraint, GetConstrainedSurface())
      .WillRepeatedly(testing::Return(surface));
  ON_CALL(second_constraint, IsPersistent())
      .WillByDefault(testing::Return(true));

  // Verify that the operation doesn't crash.
  // The operation fails because the window associated with |surface| (or its
  // ancestors) cannot be activated before a widget is created in the commit
  // process, while pointer capture is not allowed on an inactive window.
  EXPECT_FALSE(pointer_->ConstrainPointer(&second_constraint));

  pointer_.reset();
}

// This test verifies that if pointer lock is activated during a desk switch
// swipe animation, that the animation is able to complete and pointer lock is
// correctly set. Regression test for b/324146178.
TEST_F(PointerConstraintTest, DeskSwitchSwipeGesture) {
  ui::ScopedAnimationDurationScaleMode animation_scale(
      ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);

  // Start with a surface that has a constrained pointer.
  EXPECT_TRUE(pointer_->ConstrainPointer(&constraint_delegate_));
  EXPECT_CALL(delegate_, OnPointerFrame()).Times(3);
  generator_->MoveMouseTo(surface_->window()->GetBoundsInScreen().origin());

  EXPECT_CALL(delegate_, OnPointerMotion(testing::_, testing::_)).Times(0);
  generator_->MoveMouseTo(surface_->window()->GetBoundsInScreen().origin() +
                          gfx::Vector2d(-1, -1));

  EXPECT_TRUE(pointer_->GetIsPointerConstrainedForTesting());

  // Swapping desks will unconstrain the pointer.
  EXPECT_CALL(delegate_, OnPointerLeave(surface_.get()));
  auto* desks_controller = ash::DesksController::Get();
  desks_controller->NewDesk(ash::DesksCreationRemovalSource::kButton);
  desks_controller->ActivateAdjacentDesk(
      /*going_left=*/false, ash::DesksSwitchSource::kDeskSwitchShortcut);
  {
    ash::DeskActivationAnimation* animation =
        static_cast<ash::DeskActivationAnimation*>(
            desks_controller->animation());
    ASSERT_TRUE(animation);

    // End the swipe animation and wait for the desk activation animation to
    // finish. This is required to prevent flakiness.
    base::RunLoop run_loop;
    animation->AddOnAnimationFinishedCallbackForTesting(run_loop.QuitClosure());
    run_loop.Run();
  }
  EXPECT_FALSE(desks_controller->animation());
  EXPECT_FALSE(pointer_->GetIsPointerConstrainedForTesting());
  EXPECT_EQ(desks_controller->GetActiveDeskIndex(), 1);

  // Trigger a desk switch gesture.
  // Start off with a fling cancel (touchpad start) to start the touchpad swipe
  // sequence.
  int kNumFingersForDesksSwitch = 4;
  base::TimeTicks timestamp = ui::EventTimeForNow();
  ui::ScrollEvent fling_cancel(ui::EventType::kScrollFlingCancel, gfx::Point(),
                               timestamp, 0, 0, 0, 0, 0,
                               kNumFingersForDesksSwitch);
  generator_->Dispatch(&fling_cancel);

  // Continue with a large enough scroll to the left to start the desk switch
  // animation. The animation does not start on fling cancel since there is no
  // finger data in production code.
  const base::TimeDelta step_delay = base::Milliseconds(5);
  timestamp += step_delay;
  // Use a negative scroll direction to scroll to the left.
  const int direction = -1;
  const int initial_move_x =
      (ash::WmGestureHandler::kContinuousGestureMoveThresholdDp + 5) *
      direction;
  ui::ScrollEvent initial_move(ui::EventType::kScroll, gfx::Point(), timestamp,
                               0, initial_move_x, 0, initial_move_x, 0,
                               kNumFingersForDesksSwitch);
  generator_->Dispatch(&initial_move);

  // Wait for the animation, and verify things work properly during the
  // animation.
  ash::DeskActivationAnimation* animation =
      static_cast<ash::DeskActivationAnimation*>(desks_controller->animation());
  EXPECT_TRUE(animation);
  {
    // Wait until the animations ending screenshot has been taken. Otherwise,
    // we will just stay at the initial desk if no screenshot has been taken.
    ash::WaitUntilEndingScreenshotTaken(animation);

    // Verify that during the animation that the pointer is constrained
    // properly.
    EXPECT_TRUE(pointer_->ConstrainPointer(&constraint_delegate_));
    EXPECT_TRUE(pointer_->GetIsPointerConstrainedForTesting());

    // Send some more move events, enough to shift to the next desk.
    const int steps = 100;
    const float x_offset =
        direction * ash::WmGestureHandler::kHorizontalThresholdDp;
    float dx = x_offset / steps;
    for (int i = 0; i < steps; ++i) {
      timestamp += step_delay;
      ui::ScrollEvent move(ui::EventType::kScroll, gfx::Point(), timestamp, 0,
                           dx, 0, dx, 0, kNumFingersForDesksSwitch);
      generator_->Dispatch(&move);
    }

    // End the swipe and wait for the animation to finish.
    ui::ScrollEvent fling_start(ui::EventType::kScrollFlingStart, gfx::Point(),
                                timestamp, 0, x_offset, 0, x_offset, 0,
                                kNumFingersForDesksSwitch);
    ash::DeskSwitchAnimationWaiter animation_finished_waiter;
    generator_->Dispatch(&fling_start);
    animation_finished_waiter.Wait();
  }

  // Verify that the desk switch animation was completed, and that the pointer
  // is still correctly constrained.
  EXPECT_EQ(desks_controller->GetActiveDeskIndex(), 0);
  EXPECT_TRUE(pointer_->GetIsPointerConstrainedForTesting());
  EXPECT_FALSE(desks_controller->animation());

  pointer_->OnPointerConstraintDelegateDestroying(&constraint_delegate_);
  EXPECT_CALL(delegate_, OnPointerDestroying(pointer_.get()));
  pointer_.reset();
}

TEST_F(PointerTest, PointerStylus) {
  auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  auto* surface = shell_surface->surface_for_testing();

  MockPointerDelegate delegate;
  MockPointerStylusDelegate stylus_delegate;
  std::unique_ptr<Pointer> pointer(new Pointer(&delegate, seat_.get()));
  ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());

  pointer->SetStylusDelegate(&stylus_delegate);

  EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface))
      .WillRepeatedly(testing::Return(true));

  {
    testing::InSequence sequence;
    EXPECT_CALL(delegate, OnPointerEnter(surface, gfx::PointF(), 0));
    EXPECT_CALL(delegate, OnPointerFrame());
    EXPECT_CALL(stylus_delegate,
                OnPointerToolChange(ui::EventPointerType::kMouse));
    EXPECT_CALL(delegate, OnPointerFrame());
  }

  generator.MoveMouseTo(surface->window()->GetBoundsInScreen().origin());

  EXPECT_CALL(delegate, OnPointerDestroying(pointer.get()));
  EXPECT_CALL(stylus_delegate, OnPointerDestroying(pointer.get()));
  pointer.reset();
}

TEST_F(PointerTest, PointerStylus2) {
  auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  auto* surface = shell_surface->surface_for_testing();

  MockPointerDelegate delegate;
  MockPointerStylusDelegate stylus_delegate;
  std::unique_ptr<Pointer> pointer(new Pointer(&delegate, seat_.get()));
  ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());

  pointer->SetStylusDelegate(&stylus_delegate);

  EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface))
      .WillRepeatedly(testing::Return(true));

  EXPECT_CALL(delegate, OnPointerEnter(surface, testing::_, 0));
  EXPECT_CALL(delegate, OnPointerFrame()).Times(2);
  EXPECT_CALL(stylus_delegate,
              OnPointerToolChange(ui::EventPointerType::kMouse));

  auto location = surface->window()->GetBoundsInScreen().origin();
  generator.MoveMouseTo(location);

  EXPECT_CALL(delegate, OnPointerButton(testing::_, testing::_, testing::_))
      .Times(1);
  EXPECT_CALL(delegate, OnPointerFrame()).Times(1);
  EXPECT_CALL(stylus_delegate, OnPointerToolChange(ui::EventPointerType::kPen));

  ui::MouseEvent ev1(ui::EventType::kMousePressed, location, location,
                     ui::EventTimeForNow(), generator.flags(), 0,
                     ui::PointerDetails(ui::EventPointerType::kPen));
  generator.Dispatch(&ev1);

  EXPECT_CALL(delegate, OnPointerDestroying(pointer.get()));
  EXPECT_CALL(stylus_delegate, OnPointerDestroying(pointer.get()));
  pointer.reset();
}

TEST_F(PointerTest, DontSendMouseEventDuringMove) {
  testing::NiceMock<MockPointerDelegate> delegate;
  auto pointer = std::make_unique<Pointer>(&delegate, seat_.get());

  EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(testing::_))
      .WillRepeatedly(testing::Return(true));
  EXPECT_CALL(delegate, OnPointerMotion).Times(0);

  std::unique_ptr<ShellSurface> shell_surface =
      test::ShellSurfaceBuilder({64, 64})
          .SetOrigin({10, 10})
          .BuildShellSurface();

  ui::test::EventGenerator* generator = GetEventGenerator();
  generator->MoveMouseRelativeTo(shell_surface->GetWidget()->GetNativeWindow(),
                                 {1, 1});
  generator->PressLeftButton();
  ASSERT_TRUE(shell_surface->StartMove());
  EXPECT_EQ(shell_surface->GetWidget()->GetWindowBoundsInScreen().origin(),
            gfx::Point(10, 10));

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

  // Make sure that we don't send mouse motion event while dragging a window.
  EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(testing::_))
      .WillRepeatedly(testing::Return(true));
  EXPECT_CALL(delegate, OnPointerMotion).Times(0);
  generator->MoveMouseBy(1, 1);
  EXPECT_EQ(shell_surface->GetWidget()->GetWindowBoundsInScreen().origin(),
            gfx::Point(11, 11));

  ::testing::Mock::VerifyAndClearExpectations(&delegate);
}

TEST_F(PointerTest, SetCursorWithSurfaceChange) {
  auto shell_surface = test::ShellSurfaceBuilder({20, 20}).BuildShellSurface();
  auto* surface = shell_surface->surface_for_testing();

  MockPointerDelegate delegate;
  auto pointer = std::make_unique<Pointer>(
      &delegate, seat_.get(), std::make_unique<PointerTestHostWindow>());
  ui::test::EventGenerator* generator = AshTestBase::GetEventGenerator();

  EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface))
      .WillRepeatedly(testing::Return(true));
  EXPECT_CALL(delegate, OnPointerFrame()).Times(1);
  EXPECT_CALL(delegate, OnPointerEnter(surface, gfx::PointF(), 0));
  generator->MoveMouseTo(surface->window()->GetBoundsInScreen().origin());

  pointer->SetCursorType(ui::mojom::CursorType::kIBeam);

  EXPECT_EQ(nullptr, pointer->root_surface());
  aura::client::CursorClient* cursor_client = aura::client::GetCursorClient(
      shell_surface->GetWidget()->GetNativeWindow()->GetRootWindow());
  EXPECT_EQ(ui::mojom::CursorType::kIBeam, cursor_client->GetCursor().type());

  // Set a red cursor with the big size.
  constexpr gfx::Size kBigBufferSize(20, 20);
  auto red_surface = std::make_unique<Surface>();
  auto red_buffer =
      std::make_unique<SolidColorBuffer>(SkColors::kRed, kBigBufferSize);
  red_surface->Damage(gfx::Rect(kBigBufferSize));
  red_surface->Attach(red_buffer.get());
  red_surface->Commit();
  pointer->SetCursor(red_surface.get(), gfx::Point());
  test::WaitForLastFrameAck(pointer.get());

  // Pointer should have a surface by now.
  ASSERT_TRUE(pointer->host_window()->layer()->GetSurfaceId());

  // Immediately set a green cursor with the small size.
  constexpr gfx::Size kSmallBufferSize(10, 10);
  auto green_surface = std::make_unique<Surface>();
  auto green_buffer =
      std::make_unique<SolidColorBuffer>(SkColors::kGreen, kSmallBufferSize);
  green_surface->Damage(gfx::Rect(kSmallBufferSize));
  green_surface->Attach(green_buffer.get());
  green_surface->Commit();

  pointer->SetCursor(green_surface.get(), gfx::Point());

  // Wait for cursor to change.
  ui::Cursor previous_cursor = cursor_client->GetCursor();
  while (previous_cursor == cursor_client->GetCursor()) {
    base::RunLoop run_loop;
    base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
        FROM_HERE, run_loop.QuitClosure(), base::Milliseconds(100));
    run_loop.Run();
  }

  // Check that we get the correct cursor bitmap.
  SkBitmap cursor_bitmap = cursor_client->GetCursor().custom_bitmap();
  EXPECT_EQ(SK_ColorGREEN, cursor_bitmap.getColor(0, 0));

  EXPECT_CALL(delegate, OnPointerDestroying(pointer.get()));
  pointer.reset();
}

TEST_F(PointerTest, SetCursorBitmapFromBuffer) {
  auto shell_surface = test::ShellSurfaceBuilder({10, 10}).BuildShellSurface();
  auto* surface = shell_surface->surface_for_testing();

  MockPointerDelegate delegate;
  std::unique_ptr<Pointer> pointer(new Pointer(&delegate, seat_.get()));
  ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow());
  aura::client::CursorClient* cursor_client = aura::client::GetCursorClient(
      shell_surface->GetWidget()->GetNativeWindow()->GetRootWindow());

  EXPECT_CALL(delegate, CanAcceptPointerEventsForSurface(surface))
      .WillRepeatedly(testing::Return(true));
  EXPECT_CALL(delegate, OnPointerFrame()).Times(1);
  EXPECT_CALL(delegate, OnPointerEnter(surface, gfx::PointF(), 0));
  generator.MoveMouseTo(surface->window()->GetBoundsInScreen().origin());

  // Create a TestSharedImageInterface to create a mappable shared image.
  auto test_sii = base::MakeRefCounted<gpu::TestSharedImageInterface>();
  test_sii->UseTestGMBInSharedImageCreationWithBufferUsage();
  constexpr gfx::Size buffer_size(10, 10);
  const auto format = viz::SinglePlaneFormat::kRGBA_8888;
  // Setting some default usage in order to get a mappable shared image.
  const auto si_usage = gpu::SHARED_IMAGE_USAGE_CPU_WRITE_ONLY |
                        gpu::SHARED_IMAGE_USAGE_DISPLAY_READ;

  // Create a mappable shared image.
  auto shared_image = test_sii->CreateSharedImage(
      {format, buffer_size, gfx::ColorSpace(),
       gpu::SharedImageUsageSet(si_usage), "PointerTest"},
      gpu::kNullSurfaceHandle, gfx::BufferUsage::GPU_READ);
  ASSERT_TRUE(shared_image);

  auto scoped_mapping = shared_image->Map();
  ASSERT_TRUE(scoped_mapping);

  // Set the shared image to yellow.
  SkImageInfo image_info =
      SkImageInfo::Make(buffer_size.width(), buffer_size.height(),
                        kRGBA_8888_SkColorType, kPremul_SkAlphaType);
  sk_sp<SkSurface> sk_surface = SkSurfaces::WrapPixels(
      image_info, scoped_mapping->GetMemoryForPlane(0).data(),
      image_info.minRowBytes());
  sk_surface->getCanvas()->clear(SK_ColorYELLOW);

  scoped_mapping.reset();

  std::unique_ptr<Surface> pointer_surface(new Surface);
  std::unique_ptr<Buffer> pointer_buffer =
      test::ExoTestHelper::CreateBufferFromGMBHandle(
          shared_image->CloneGpuMemoryBufferHandle(), buffer_size, format);
  pointer_surface->Attach(pointer_buffer.get());
  pointer_surface->Commit();

  // Cursor bitmap should be created from the buffer.
  pointer->SetCursor(pointer_surface.get(), gfx::Point());

  // Check that we get the correct cursor bitmap.
  SkBitmap cursor_bitmap = cursor_client->GetCursor().custom_bitmap();
  // The color at (0,0) should be yellow.
  EXPECT_EQ(SK_ColorYELLOW, cursor_bitmap.getColor(0, 0));

  EXPECT_CALL(delegate, OnPointerDestroying(pointer.get()));
  pointer.reset();
}

TEST_F(PointerConstraintTest, ConstraintPointerLockPointer) {
  auto* cursor_client = WMHelper::GetInstance()->GetCursorClient();
  auto original_cursor = cursor_client->GetCursor();
  EXPECT_TRUE(pointer_->ConstrainPointer(&constraint_delegate_));

  EXPECT_TRUE(cursor_client->IsCursorLocked());
  EXPECT_TRUE(cursor_client->IsCursorVisible());
  EXPECT_EQ(original_cursor.type(), cursor_client->GetCursor().type());

  EXPECT_CALL(delegate_, OnPointerEnter(surface_.get(), gfx::PointF(), 0));
  EXPECT_CALL(delegate_, OnPointerFrame()).Times(testing::AtLeast(1));
  generator_->MoveMouseTo(surface_->window()->GetBoundsInScreen().origin());

  pointer_->SetCursorType(ui::mojom::CursorType::kNull);

  EXPECT_EQ(ui::mojom::CursorType::kNull, cursor_client->GetCursor().type());

  GetEventGenerator()->PressKey(ui::VKEY_A, 0, 0);
  EXPECT_TRUE(cursor_client->IsCursorLocked());
  EXPECT_TRUE(cursor_client->IsCursorVisible());

  pointer_->OnPointerConstraintDelegateDestroying(&constraint_delegate_);
  EXPECT_CALL(delegate_, OnPointerDestroying(pointer_.get()));

  EXPECT_FALSE(cursor_client->IsCursorLocked());

  pointer_.reset();
}

}  // namespace
}  // namespace exo
