blob: bcadb6f5126629c5ad37ab5d48926cdd1f7d30ac [file] [log] [blame]
// 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_