| // 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. | |
| #ifndef FLUTTER_SHELL_PLATFORM_WINDOWS_TESTING_TEST_KEYBOARD_H_ | |
| #define FLUTTER_SHELL_PLATFORM_WINDOWS_TESTING_TEST_KEYBOARD_H_ | |
| #include <windows.h> | |
| #include <functional> | |
| #include <string> | |
| #include "flutter/fml/macros.h" | |
| #include "flutter/shell/platform/embedder/embedder.h" | |
| #include "flutter/shell/platform/windows/testing/engine_modifier.h" | |
| #include "flutter/shell/platform/windows/testing/wm_builders.h" | |
| #include "gtest/gtest.h" | |
| struct _FlutterPlatformMessageResponseHandle { | |
| FlutterDesktopBinaryReply callback; | |
| void* user_data; | |
| }; | |
| namespace flutter { | |
| namespace testing { | |
| ::testing::AssertionResult _EventEquals(const char* expr_event, | |
| const char* expr_expected, | |
| const FlutterKeyEvent& event, | |
| const FlutterKeyEvent& expected); | |
| // Clone string onto the heap. | |
| // | |
| // If #string is nullptr, returns nullptr. Otherwise, the returned pointer must | |
| // be freed with delete[]. | |
| char* clone_string(const char* string); | |
| // Creates a valid Windows LPARAM for WM_KEYDOWN and WM_CHAR from parameters | |
| // given. | |
| // | |
| // While |CreateKeyEventLparam| is flexible, it's recommended to use dedicated | |
| // functions in wm_builders.h, such as |WmKeyDownInfo|. | |
| LPARAM CreateKeyEventLparam(USHORT scancode, | |
| bool extended, | |
| bool was_down, | |
| USHORT repeat_count = 1, | |
| bool context_code = 0, | |
| bool transition_state = 1); | |
| class MockKeyResponseController { | |
| public: | |
| using ResponseCallback = std::function<void(bool)>; | |
| using EmbedderCallbackHandler = | |
| std::function<void(const FlutterKeyEvent*, ResponseCallback)>; | |
| using ChannelCallbackHandler = std::function<void(ResponseCallback)>; | |
| using TextInputCallbackHandler = | |
| std::function<void(std::unique_ptr<rapidjson::Document>)>; | |
| MockKeyResponseController() | |
| : channel_response_(ChannelRespondFalse), | |
| embedder_response_(EmbedderRespondFalse), | |
| text_input_response_( | |
| [](std::unique_ptr<rapidjson::Document> document) {}) {} | |
| void SetChannelResponse(ChannelCallbackHandler handler) { | |
| channel_response_ = std::move(handler); | |
| } | |
| void SetEmbedderResponse(EmbedderCallbackHandler handler) { | |
| embedder_response_ = std::move(handler); | |
| } | |
| void SetTextInputResponse(TextInputCallbackHandler handler) { | |
| text_input_response_ = std::move(handler); | |
| } | |
| void HandleChannelMessage(ResponseCallback callback) { | |
| channel_response_(callback); | |
| } | |
| void HandleEmbedderMessage(const FlutterKeyEvent* event, | |
| ResponseCallback callback) { | |
| embedder_response_(event, std::move(callback)); | |
| } | |
| void HandleTextInputMessage(std::unique_ptr<rapidjson::Document> document) { | |
| text_input_response_(std::move(document)); | |
| } | |
| private: | |
| EmbedderCallbackHandler embedder_response_; | |
| ChannelCallbackHandler channel_response_; | |
| TextInputCallbackHandler text_input_response_; | |
| static void ChannelRespondFalse(ResponseCallback callback) { | |
| callback(false); | |
| } | |
| static void EmbedderRespondFalse(const FlutterKeyEvent* event, | |
| ResponseCallback callback) { | |
| callback(false); | |
| } | |
| FML_DISALLOW_COPY_AND_ASSIGN(MockKeyResponseController); | |
| }; | |
| void MockEmbedderApiForKeyboard( | |
| EngineModifier& modifier, | |
| std::shared_ptr<MockKeyResponseController> response_controller); | |
| // Simulate a message queue for WM messages. | |
| // | |
| // Subclasses must implement |Win32SendMessage| for how dispatched messages are | |
| // processed. | |
| class MockMessageQueue { | |
| protected: | |
| // Push a message to the message queue without dispatching it. | |
| void PushBack(const Win32Message* message); | |
| // Dispatch the first message of the message queue and return its result. | |
| // | |
| // This method asserts that the queue is not empty. | |
| LRESULT DispatchFront(); | |
| // Peak the next message in the message queue. | |
| // | |
| // See Win32's |PeekMessage| for documentation. | |
| BOOL Win32PeekMessage(LPMSG lpMsg, | |
| UINT wMsgFilterMin, | |
| UINT wMsgFilterMax, | |
| UINT wRemoveMsg); | |
| // Simulate dispatching a message to the system. | |
| virtual LRESULT Win32SendMessage(UINT const message, | |
| WPARAM const wparam, | |
| LPARAM const lparam) = 0; | |
| std::list<Win32Message> _pending_messages; | |
| std::list<Win32Message> _sent_messages; | |
| }; | |
| } // namespace testing | |
| } // namespace flutter | |
| // Expect the |_target| FlutterKeyEvent has the required properties. | |
| #define EXPECT_EVENT_EQUALS(_target, _type, _physical, _logical, _character, \ | |
| _synthesized) \ | |
| EXPECT_PRED_FORMAT2( \ | |
| _EventEquals, _target, \ | |
| (FlutterKeyEvent{ \ | |
| /* struct_size = */ sizeof(FlutterKeyEvent), \ | |
| /* timestamp = */ 0, \ | |
| /* type = */ _type, \ | |
| /* physical = */ _physical, \ | |
| /* logical = */ _logical, \ | |
| /* character = */ _character, \ | |
| /* synthesized = */ _synthesized, \ | |
| /* device_type = */ kFlutterKeyEventDeviceTypeKeyboard, \ | |
| })); | |
| #endif // FLUTTER_SHELL_PLATFORM_WINDOWS_TESTING_TEST_KEYBOARD_H_ |