// Copyright 2013 The Flutter 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 "flutter/shell/platform/common/json_message_codec.h"
#include "flutter/shell/platform/embedder/embedder.h"
#include "flutter/shell/platform/embedder/test_utils/proc_table_replacement.h"
#include "flutter/shell/platform/windows/flutter_windows_engine.h"
#include "flutter/shell/platform/windows/keyboard_key_channel_handler.h"
#include "flutter/shell/platform/windows/keyboard_key_handler.h"
#include "flutter/shell/platform/windows/testing/engine_modifier.h"
#include "flutter/shell/platform/windows/testing/flutter_window_win32_test.h"
#include "flutter/shell/platform/windows/testing/mock_window_binding_handler.h"
#include "flutter/shell/platform/windows/text_input_plugin.h"
#include "flutter/shell/platform/windows/text_input_plugin_delegate.h"

#include "gmock/gmock.h"
#include "gtest/gtest.h"

#include <rapidjson/document.h>

using testing::_;
using testing::Invoke;
using testing::Return;

namespace flutter {
namespace testing {

namespace {
// Creates a valid Windows LPARAM for WM_KEYDOWN and WM_CHAR from parameters
// given.
static LPARAM CreateKeyEventLparam(USHORT scancode,
                                   bool extended = false,
                                   bool was_down = 1,
                                   USHORT repeat_count = 1,
                                   bool context_code = 0,
                                   bool transition_state = 1) {
  return ((LPARAM(transition_state) << 31) | (LPARAM(was_down) << 30) |
          (LPARAM(context_code) << 29) | (LPARAM(extended ? 0x1 : 0x0) << 24) |
          (LPARAM(scancode) << 16) | LPARAM(repeat_count));
}

// A struc to hold simulated events that will be delivered after the framework
// response is handled.
struct SimulatedEvent {
  UINT message;
  WPARAM wparam;
  LPARAM lparam;
};

// A key event handler that can be spied on while it forwards calls to the real
// key event handler.
class SpyKeyboardKeyHandler : public KeyboardHandlerBase {
 public:
  SpyKeyboardKeyHandler(
      flutter::BinaryMessenger* messenger,
      KeyboardKeyHandler::EventRedispatcher redispatch_event) {
    real_implementation_ =
        std::make_unique<KeyboardKeyHandler>(redispatch_event);
    real_implementation_->AddDelegate(
        std::make_unique<KeyboardKeyChannelHandler>(messenger));
    ON_CALL(*this, KeyboardHook(_, _, _, _, _, _, _))
        .WillByDefault(Invoke(real_implementation_.get(),
                              &KeyboardKeyHandler::KeyboardHook));
    ON_CALL(*this, TextHook(_, _))
        .WillByDefault(
            Invoke(real_implementation_.get(), &KeyboardKeyHandler::TextHook));
  }

  MOCK_METHOD7(KeyboardHook,
               bool(FlutterWindowsView* window,
                    int key,
                    int scancode,
                    int action,
                    char32_t character,
                    bool extended,
                    bool was_down));
  MOCK_METHOD2(TextHook,
               void(FlutterWindowsView* window, const std::u16string& text));
  MOCK_METHOD0(ComposeBeginHook, void());
  MOCK_METHOD0(ComposeCommitHook, void());
  MOCK_METHOD0(ComposeEndHook, void());
  MOCK_METHOD2(ComposeChangeHook,
               void(const std::u16string& text, int cursor_pos));

 private:
  std::unique_ptr<KeyboardKeyHandler> real_implementation_;
};

// A text input plugin that can be spied on while it forwards calls to the real
// text input plugin.
class SpyTextInputPlugin : public KeyboardHandlerBase,
                           public TextInputPluginDelegate {
 public:
  SpyTextInputPlugin(flutter::BinaryMessenger* messenger) {
    real_implementation_ = std::make_unique<TextInputPlugin>(messenger, this);
    ON_CALL(*this, KeyboardHook(_, _, _, _, _, _, _))
        .WillByDefault(
            Invoke(real_implementation_.get(), &TextInputPlugin::KeyboardHook));
    ON_CALL(*this, TextHook(_, _))
        .WillByDefault(
            Invoke(real_implementation_.get(), &TextInputPlugin::TextHook));
  }

  MOCK_METHOD7(KeyboardHook,
               bool(FlutterWindowsView* window,
                    int key,
                    int scancode,
                    int action,
                    char32_t character,
                    bool extended,
                    bool was_down));
  MOCK_METHOD2(TextHook,
               void(FlutterWindowsView* window, const std::u16string& text));
  MOCK_METHOD0(ComposeBeginHook, void());
  MOCK_METHOD0(ComposeCommitHook, void());
  MOCK_METHOD0(ComposeEndHook, void());
  MOCK_METHOD2(ComposeChangeHook,
               void(const std::u16string& text, int cursor_pos));

  virtual void OnCursorRectUpdated(const Rect& rect) {}

 private:
  std::unique_ptr<TextInputPlugin> real_implementation_;
};

class MockFlutterWindowWin32 : public FlutterWindowWin32 {
 public:
  MockFlutterWindowWin32() : FlutterWindowWin32(800, 600) {
    ON_CALL(*this, GetDpiScale())
        .WillByDefault(Return(this->FlutterWindowWin32::GetDpiScale()));
  }
  virtual ~MockFlutterWindowWin32() {}

  // Prevent copying.
  MockFlutterWindowWin32(MockFlutterWindowWin32 const&) = delete;
  MockFlutterWindowWin32& operator=(MockFlutterWindowWin32 const&) = delete;

  // Wrapper for GetCurrentDPI() which is a protected method.
  UINT GetDpi() { return GetCurrentDPI(); }

  // Simulates a WindowProc message from the OS.
  LRESULT InjectWindowMessage(UINT const message,
                              WPARAM const wparam,
                              LPARAM const lparam) {
    return HandleMessage(message, wparam, lparam);
  }

  MOCK_METHOD1(OnDpiScale, void(unsigned int));
  MOCK_METHOD2(OnResize, void(unsigned int, unsigned int));
  MOCK_METHOD2(OnPointerMove, void(double, double));
  MOCK_METHOD3(OnPointerDown, void(double, double, UINT));
  MOCK_METHOD3(OnPointerUp, void(double, double, UINT));
  MOCK_METHOD0(OnPointerLeave, void());
  MOCK_METHOD0(OnSetCursor, void());
  MOCK_METHOD2(OnScroll, void(double, double));
  MOCK_METHOD4(DefaultWindowProc, LRESULT(HWND, UINT, WPARAM, LPARAM));
  MOCK_METHOD0(GetDpiScale, float());
  MOCK_METHOD1(UpdateCursorRect, void(const Rect&));
};

class MockWindowBindingHandlerDelegate : public WindowBindingHandlerDelegate {
 public:
  MockWindowBindingHandlerDelegate() {}

  // Prevent copying.
  MockWindowBindingHandlerDelegate(MockWindowBindingHandlerDelegate const&) =
      delete;
  MockWindowBindingHandlerDelegate& operator=(
      MockWindowBindingHandlerDelegate const&) = delete;

  MOCK_METHOD2(OnWindowSizeChanged, void(size_t, size_t));
  MOCK_METHOD3(OnPointerMove, void(double, double, FlutterPointerDeviceKind));
  MOCK_METHOD4(OnPointerDown,
               void(double,
                    double,
                    FlutterPointerDeviceKind,
                    FlutterPointerMouseButtons));
  MOCK_METHOD4(OnPointerUp,
               void(double,
                    double,
                    FlutterPointerDeviceKind,
                    FlutterPointerMouseButtons));
  MOCK_METHOD1(OnPointerLeave, void(FlutterPointerDeviceKind));
  MOCK_METHOD1(OnText, void(const std::u16string&));
  MOCK_METHOD6(OnKey, bool(int, int, int, char32_t, bool, bool));
  MOCK_METHOD0(OnComposeBegin, void());
  MOCK_METHOD0(OnComposeCommit, void());
  MOCK_METHOD0(OnComposeEnd, void());
  MOCK_METHOD2(OnComposeChange, void(const std::u16string&, int));
  MOCK_METHOD5(OnScroll, void(double, double, double, double, int));
};

// A FlutterWindowsView that overrides the RegisterKeyboardHandlers function
// to register the keyboard hook handlers that can be spied upon.
class TestFlutterWindowsView : public FlutterWindowsView {
 public:
  TestFlutterWindowsView(std::unique_ptr<WindowBindingHandler> window_binding,
                         WPARAM virtual_key,
                         bool is_printable = true)
      : FlutterWindowsView(std::move(window_binding)),
        virtual_key_(virtual_key),
        is_printable_(is_printable) {}

  SpyKeyboardKeyHandler* key_event_handler;
  SpyTextInputPlugin* text_input_plugin;

  void InjectPendingEvents(MockFlutterWindowWin32* win32window) {
    while (pending_responds_.size() > 0) {
      SimulatedEvent event = pending_responds_.front();
      win32window->InjectWindowMessage(event.message, event.wparam,
                                       event.lparam);
      pending_responds_.pop_front();
    }
  }

 protected:
  void RegisterKeyboardHandlers(flutter::BinaryMessenger* messenger) override {
    auto spy_key_event_handler = std::make_unique<SpyKeyboardKeyHandler>(
        messenger, [this](UINT cInputs, LPINPUT pInputs, int cbSize) -> UINT {
          return this->SendInput(cInputs, pInputs, cbSize);
        });
    auto spy_text_input_plugin =
        std::make_unique<SpyTextInputPlugin>(messenger);
    key_event_handler = spy_key_event_handler.get();
    text_input_plugin = spy_text_input_plugin.get();
    AddKeyboardHandler(std::move(spy_key_event_handler));
    AddKeyboardHandler(std::move(spy_text_input_plugin));
  }

 private:
  UINT SendInput(UINT cInputs, LPINPUT pInputs, int cbSize) {
    // Simulate the event loop by just sending the event sent to
    // "SendInput" directly to the window.
    const KEYBDINPUT kbdinput = pInputs->ki;
    const UINT message =
        (kbdinput.dwFlags & KEYEVENTF_KEYUP) ? WM_KEYUP : WM_KEYDOWN;
    const LPARAM lparam = CreateKeyEventLparam(
        kbdinput.wScan, kbdinput.dwFlags & KEYEVENTF_EXTENDEDKEY);
    // Windows would normally fill in the virtual key code for us, so we
    // simulate it for the test with the key we know is in the test. The
    // KBDINPUT we're passed doesn't have it filled in (on purpose, so that
    // Windows will fill it in).
    pending_responds_.push_back(SimulatedEvent{message, virtual_key_, lparam});
    if (is_printable_ && (kbdinput.dwFlags & KEYEVENTF_KEYUP) == 0) {
      pending_responds_.push_back(
          SimulatedEvent{WM_CHAR, virtual_key_, lparam});
    }
    return 1;
  }

  std::deque<SimulatedEvent> pending_responds_;
  WPARAM virtual_key_;
  bool is_printable_;
};

// A struct to use as a FlutterPlatformMessageResponseHandle so it can keep the
// callbacks and user data passed to the engine's
// PlatformMessageCreateResponseHandle for use in the SendPlatformMessage
// overridden function.
struct TestResponseHandle {
  FlutterDesktopBinaryReply callback;
  void* user_data;
};

// The static value to return as the "handled" value from the framework for key
// events. Individual tests set this to change the framework response that the
// test engine simulates.
static bool test_response = false;

// Returns an engine instance configured with dummy project path values, and
// overridden methods for sending platform messages, so that the engine can
// respond as if the framework were connected.
std::unique_ptr<FlutterWindowsEngine> GetTestEngine() {
  FlutterDesktopEngineProperties properties = {};
  properties.assets_path = L"C:\\foo\\flutter_assets";
  properties.icu_data_path = L"C:\\foo\\icudtl.dat";
  properties.aot_library_path = L"C:\\foo\\aot.so";
  FlutterProjectBundle project(properties);
  auto engine = std::make_unique<FlutterWindowsEngine>(project);

  EngineModifier modifier(engine.get());
  // Force the non-AOT path unless overridden by the test.
  modifier.embedder_api().RunsAOTCompiledDartCode = []() { return false; };

  modifier.embedder_api().PlatformMessageCreateResponseHandle =
      [](auto engine, auto data_callback, auto user_data, auto response_out) {
        TestResponseHandle* response_handle = new TestResponseHandle();
        response_handle->user_data = user_data;
        response_handle->callback = data_callback;
        *response_out = reinterpret_cast<FlutterPlatformMessageResponseHandle*>(
            response_handle);
        return kSuccess;
      };

  modifier.embedder_api().SendPlatformMessage =
      [](FLUTTER_API_SYMBOL(FlutterEngine) engine,
         const FlutterPlatformMessage* message) {
        rapidjson::Document document;
        auto& allocator = document.GetAllocator();
        document.SetObject();
        document.AddMember("handled", test_response, allocator);
        auto encoded =
            flutter::JsonMessageCodec::GetInstance().EncodeMessage(document);
        const TestResponseHandle* response_handle =
            reinterpret_cast<const TestResponseHandle*>(
                message->response_handle);
        if (response_handle->callback != nullptr) {
          response_handle->callback(encoded->data(), encoded->size(),
                                    response_handle->user_data);
        }
        return kSuccess;
      };

  modifier.embedder_api().PlatformMessageReleaseResponseHandle =
      [](FLUTTER_API_SYMBOL(FlutterEngine) engine,
         FlutterPlatformMessageResponseHandle* response) {
        const TestResponseHandle* response_handle =
            reinterpret_cast<const TestResponseHandle*>(response);
        delete response_handle;
        return kSuccess;
      };

  return engine;
}

}  // namespace

TEST(FlutterWindowWin32Test, CreateDestroy) {
  FlutterWindowWin32Test window(800, 600);
  ASSERT_TRUE(TRUE);
}

// Tests key event propagation of non-printable, non-modifier key down events.
TEST(FlutterWindowWin32Test, NonPrintableKeyDownPropagation) {
  ::testing::InSequence in_sequence;

  constexpr WPARAM virtual_key = VK_LEFT;
  constexpr WPARAM scan_code = 10;
  constexpr char32_t character = 0;
  MockFlutterWindowWin32 win32window;
  std::deque<SimulatedEvent> pending_events;
  auto window_binding_handler =
      std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
  TestFlutterWindowsView flutter_windows_view(
      std::move(window_binding_handler), virtual_key, false /* is_printable */);
  win32window.SetView(&flutter_windows_view);
  LPARAM lparam = CreateKeyEventLparam(scan_code, false /* extended */,
                                       false /* PrevState */);

  // Test an event not handled by the framework
  {
    test_response = false;
    flutter_windows_view.SetEngine(std::move(GetTestEngine()));
    EXPECT_CALL(*flutter_windows_view.key_event_handler,
                KeyboardHook(_, virtual_key, scan_code, WM_KEYDOWN, character,
                             false /* extended */, _))
        .Times(2)
        .RetiresOnSaturation();
    EXPECT_CALL(*flutter_windows_view.text_input_plugin,
                KeyboardHook(_, _, _, _, _, _, _))
        .Times(1)
        .RetiresOnSaturation();
    EXPECT_CALL(win32window, DefaultWindowProc(_, _, _, _))
        .Times(0)
        .RetiresOnSaturation();
    EXPECT_CALL(*flutter_windows_view.key_event_handler, TextHook(_, _))
        .Times(0);
    EXPECT_CALL(*flutter_windows_view.text_input_plugin, TextHook(_, _))
        .Times(0);
    EXPECT_EQ(win32window.InjectWindowMessage(WM_KEYDOWN, virtual_key, lparam),
              0);
    flutter_windows_view.InjectPendingEvents(&win32window);
  }

  // Test an event handled by the framework
  {
    test_response = true;
    EXPECT_CALL(*flutter_windows_view.key_event_handler,
                KeyboardHook(_, virtual_key, scan_code, WM_KEYDOWN, character,
                             false /* extended */, false /* PrevState */))
        .Times(1)
        .RetiresOnSaturation();
    EXPECT_CALL(*flutter_windows_view.text_input_plugin,
                KeyboardHook(_, _, _, _, _, _, _))
        .Times(0);
    EXPECT_EQ(win32window.InjectWindowMessage(WM_KEYDOWN, virtual_key, lparam),
              0);
    flutter_windows_view.InjectPendingEvents(&win32window);
  }
}

// Tests key event propagation of printable character key down events. These
// differ from non-printable characters in that they follow a different code
// path in the WndProc (HandleMessage), producing a follow-on WM_CHAR event.
TEST(FlutterWindowWin32Test, CharKeyDownPropagation) {
  // ::testing::InSequence in_sequence;

  constexpr WPARAM virtual_key = 65;  // The "A" key, which produces a character
  constexpr WPARAM scan_code = 30;
  constexpr char32_t character = 65;

  MockFlutterWindowWin32 win32window;
  auto window_binding_handler =
      std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
  TestFlutterWindowsView flutter_windows_view(
      std::move(window_binding_handler), virtual_key, true /* is_printable */);
  win32window.SetView(&flutter_windows_view);
  LPARAM lparam = CreateKeyEventLparam(scan_code, false /* extended */,
                                       true /* PrevState */);

  // Test an event not handled by the framework
  {
    test_response = false;
    flutter_windows_view.SetEngine(std::move(GetTestEngine()));
    EXPECT_CALL(*flutter_windows_view.key_event_handler,
                KeyboardHook(_, virtual_key, scan_code, WM_KEYDOWN, character,
                             false, true))
        .Times(2)
        .RetiresOnSaturation();
    EXPECT_CALL(*flutter_windows_view.text_input_plugin,
                KeyboardHook(_, _, _, _, _, _, _))
        .Times(1)
        .RetiresOnSaturation();
    EXPECT_CALL(*flutter_windows_view.key_event_handler, TextHook(_, _))
        .Times(1)
        .RetiresOnSaturation();
    EXPECT_CALL(*flutter_windows_view.text_input_plugin, TextHook(_, _))
        .Times(1)
        .RetiresOnSaturation();
    EXPECT_EQ(win32window.InjectWindowMessage(WM_KEYDOWN, virtual_key, lparam),
              0);
    EXPECT_EQ(win32window.InjectWindowMessage(WM_CHAR, virtual_key, lparam), 0);
    flutter_windows_view.InjectPendingEvents(&win32window);
  }
  return;

  // Test an event handled by the framework
  {
    test_response = true;
    EXPECT_CALL(*flutter_windows_view.key_event_handler,
                KeyboardHook(_, virtual_key, scan_code, WM_KEYDOWN, character,
                             false /* is_printable */, true))
        .Times(1)
        .RetiresOnSaturation();
    EXPECT_CALL(*flutter_windows_view.text_input_plugin,
                KeyboardHook(_, _, _, _, _, _, _))
        .Times(0);
    EXPECT_CALL(*flutter_windows_view.key_event_handler, TextHook(_, _))
        .Times(0);
    EXPECT_CALL(*flutter_windows_view.text_input_plugin, TextHook(_, _))
        .Times(0);
    EXPECT_EQ(win32window.InjectWindowMessage(WM_KEYDOWN, virtual_key, lparam),
              0);
    EXPECT_EQ(win32window.InjectWindowMessage(WM_CHAR, virtual_key, lparam), 0);
    flutter_windows_view.InjectPendingEvents(&win32window);
  }
}

// Tests key event propagation of modifier key down events. This are different
// from non-printable events in that they call MapVirtualKey, resulting in a
// slightly different code path.
TEST(FlutterWindowWin32Test, ModifierKeyDownPropagation) {
  constexpr WPARAM virtual_key = VK_LSHIFT;
  constexpr WPARAM scan_code = 20;
  constexpr char32_t character = 0;
  MockFlutterWindowWin32 win32window;
  std::deque<SimulatedEvent> pending_events;
  auto window_binding_handler =
      std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
  TestFlutterWindowsView flutter_windows_view(
      std::move(window_binding_handler), virtual_key, false /* is_printable */);
  win32window.SetView(&flutter_windows_view);
  LPARAM lparam = CreateKeyEventLparam(scan_code);

  // Test an event not handled by the framework
  {
    test_response = false;
    flutter_windows_view.SetEngine(std::move(GetTestEngine()));
    EXPECT_CALL(*flutter_windows_view.key_event_handler,
                KeyboardHook(_, virtual_key, scan_code, WM_KEYDOWN, character,
                             false /* extended */, true))
        .Times(2)
        .RetiresOnSaturation();
    EXPECT_CALL(*flutter_windows_view.text_input_plugin,
                KeyboardHook(_, _, _, _, _, _, _))
        .Times(1)
        .RetiresOnSaturation();
    EXPECT_CALL(*flutter_windows_view.key_event_handler, TextHook(_, _))
        .Times(0);
    EXPECT_CALL(*flutter_windows_view.text_input_plugin, TextHook(_, _))
        .Times(0);
    EXPECT_EQ(win32window.InjectWindowMessage(WM_KEYDOWN, virtual_key, lparam),
              0);
    flutter_windows_view.InjectPendingEvents(&win32window);
  }

  // Test an event handled by the framework
  {
    test_response = true;
    EXPECT_CALL(*flutter_windows_view.key_event_handler,
                KeyboardHook(_, virtual_key, scan_code, WM_KEYDOWN, character,
                             false /* extended */, true))
        .Times(1)
        .RetiresOnSaturation();
    EXPECT_CALL(*flutter_windows_view.text_input_plugin,
                KeyboardHook(_, _, _, _, _, _, _))
        .Times(0);
    EXPECT_EQ(win32window.InjectWindowMessage(WM_KEYDOWN, virtual_key, lparam),
              0);
    flutter_windows_view.InjectPendingEvents(&win32window);
  }
}

// Tests that composing rect updates are transformed from Flutter logical
// coordinates to device coordinates and passed to the text input manager
// when the DPI scale is 100% (96 DPI).
TEST(FlutterWindowWin32Test, OnCursorRectUpdatedRegularDPI) {
  MockFlutterWindowWin32 win32window;
  ON_CALL(win32window, GetDpiScale()).WillByDefault(Return(1.0));
  EXPECT_CALL(win32window, GetDpiScale()).Times(1);

  Rect cursor_rect(Point(10, 20), Size(30, 40));
  EXPECT_CALL(win32window, UpdateCursorRect(cursor_rect)).Times(1);

  win32window.OnCursorRectUpdated(cursor_rect);
}

// Tests that composing rect updates are transformed from Flutter logical
// coordinates to device coordinates and passed to the text input manager
// when the DPI scale is 150% (144 DPI).
TEST(FlutterWindowWin32Test, OnCursorRectUpdatedHighDPI) {
  MockFlutterWindowWin32 win32window;
  ON_CALL(win32window, GetDpiScale()).WillByDefault(Return(1.5));
  EXPECT_CALL(win32window, GetDpiScale()).Times(1);

  Rect expected_cursor_rect(Point(15, 30), Size(45, 60));
  EXPECT_CALL(win32window, UpdateCursorRect(expected_cursor_rect)).Times(1);

  Rect cursor_rect(Point(10, 20), Size(30, 40));
  win32window.OnCursorRectUpdated(cursor_rect);
}

TEST(FlutterWindowWin32Test, OnPointerStarSendsDeviceType) {
  FlutterWindowWin32 win32window(100, 100);
  MockWindowBindingHandlerDelegate delegate;
  win32window.SetView(&delegate);
  // Move
  EXPECT_CALL(delegate,
              OnPointerMove(10.0, 10.0, kFlutterPointerDeviceKindMouse))
      .Times(1);
  EXPECT_CALL(delegate,
              OnPointerMove(10.0, 10.0, kFlutterPointerDeviceKindTouch))
      .Times(1);
  EXPECT_CALL(delegate,
              OnPointerMove(10.0, 10.0, kFlutterPointerDeviceKindStylus))
      .Times(1);

  // Down
  EXPECT_CALL(delegate,
              OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindMouse,
                            kFlutterPointerButtonMousePrimary))
      .Times(1);
  EXPECT_CALL(delegate,
              OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindTouch,
                            kFlutterPointerButtonMousePrimary))
      .Times(1);
  EXPECT_CALL(delegate,
              OnPointerDown(10.0, 10.0, kFlutterPointerDeviceKindStylus,
                            kFlutterPointerButtonMousePrimary))
      .Times(1);

  // Up
  EXPECT_CALL(delegate, OnPointerUp(10.0, 10.0, kFlutterPointerDeviceKindMouse,
                                    kFlutterPointerButtonMousePrimary))
      .Times(1);
  EXPECT_CALL(delegate, OnPointerUp(10.0, 10.0, kFlutterPointerDeviceKindTouch,
                                    kFlutterPointerButtonMousePrimary))
      .Times(1);
  EXPECT_CALL(delegate, OnPointerUp(10.0, 10.0, kFlutterPointerDeviceKindStylus,
                                    kFlutterPointerButtonMousePrimary))
      .Times(1);

  // Leave
  EXPECT_CALL(delegate, OnPointerLeave(kFlutterPointerDeviceKindMouse))
      .Times(1);
  EXPECT_CALL(delegate, OnPointerLeave(kFlutterPointerDeviceKindTouch))
      .Times(1);
  EXPECT_CALL(delegate, OnPointerLeave(kFlutterPointerDeviceKindStylus))
      .Times(1);

  win32window.OnPointerMove(10.0, 10.0);
  win32window.OnPointerDown(10.0, 10.0, WM_LBUTTONDOWN);
  win32window.OnPointerUp(10.0, 10.0, WM_LBUTTONDOWN);
  win32window.OnPointerLeave();

  // Touch
  LPARAM original_lparam = SetMessageExtraInfo(0xFF51578b);
  win32window.OnPointerMove(10.0, 10.0);
  win32window.OnPointerDown(10.0, 10.0, WM_LBUTTONDOWN);
  win32window.OnPointerUp(10.0, 10.0, WM_LBUTTONDOWN);
  win32window.OnPointerLeave();

  // Pen
  SetMessageExtraInfo(0xFF515700);
  win32window.OnPointerMove(10.0, 10.0);
  win32window.OnPointerDown(10.0, 10.0, WM_LBUTTONDOWN);
  win32window.OnPointerUp(10.0, 10.0, WM_LBUTTONDOWN);
  win32window.OnPointerLeave();

  // Reset extra info for other tests.
  SetMessageExtraInfo(original_lparam);
}

}  // namespace testing
}  // namespace flutter
