Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
141 changes: 5 additions & 136 deletions shell/platform/windows/flutter_window_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,14 @@
// 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_test.h"
#include "flutter/shell/platform/windows/testing/mock_window_binding_handler.h"
#include "flutter/shell/platform/windows/testing/mock_window_binding_handler_delegate.h"
#include "flutter/shell/platform/windows/testing/test_keyboard.h"
#include "flutter/shell/platform/windows/text_input_plugin.h"
#include "flutter/shell/platform/windows/text_input_plugin_delegate.h"
#include "flutter/shell/platform/windows/testing/wm_builders.h"

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

#include <rapidjson/document.h>

using testing::_;
using testing::Invoke;
using testing::Return;
Expand All @@ -31,74 +20,6 @@ namespace testing {
namespace {
static constexpr int32_t kDefaultPointerDeviceId = 0;

// 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) {
real_implementation_ = std::make_unique<KeyboardKeyHandler>();
real_implementation_->AddDelegate(
std::make_unique<KeyboardKeyChannelHandler>(messenger));
ON_CALL(*this, KeyboardHook(_, _, _, _, _, _, _))
.WillByDefault(Invoke(real_implementation_.get(),
&KeyboardKeyHandler::KeyboardHook));
ON_CALL(*this, SyncModifiersIfNeeded(_))
.WillByDefault(Invoke(real_implementation_.get(),
&KeyboardKeyHandler::SyncModifiersIfNeeded));
}

MOCK_METHOD7(KeyboardHook,
void(int key,
int scancode,
int action,
char32_t character,
bool extended,
bool was_down,
KeyEventCallback callback));

MOCK_METHOD1(SyncModifiersIfNeeded, void(int modifiers_state));

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 TextInputPlugin,
public TextInputPluginDelegate {
public:
SpyTextInputPlugin(flutter::BinaryMessenger* messenger)
: TextInputPlugin(messenger, this) {
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_METHOD6(KeyboardHook,
void(int key,
int scancode,
int action,
char32_t character,
bool extended,
bool was_down));
MOCK_METHOD1(TextHook, void(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) {}
virtual void OnResetImeComposing() {}

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

class MockFlutterWindow : public FlutterWindow {
public:
MockFlutterWindow() : FlutterWindow(800, 600) {
Expand Down Expand Up @@ -154,68 +75,16 @@ class MockFlutterWindow : public FlutterWindow {
}
};

// A FlutterWindowsView that overrides the RegisterKeyboardHandlers function
// to register the keyboard hook handlers that can be spied upon.
class TestFlutterWindowsView : public FlutterWindowsView {
class MockFlutterWindowsView : public FlutterWindowsView {
public:
TestFlutterWindowsView(std::unique_ptr<WindowBindingHandler> window_binding)
MockFlutterWindowsView(std::unique_ptr<WindowBindingHandler> window_binding)
: FlutterWindowsView(std::move(window_binding)) {}
~TestFlutterWindowsView() {}

SpyKeyboardKeyHandler* key_event_handler;
SpyTextInputPlugin* text_input_plugin;
~MockFlutterWindowsView() {}

MOCK_METHOD2(NotifyWinEventWrapper,
void(ui::AXPlatformNodeWin*, ax::mojom::Event));

protected:
std::unique_ptr<KeyboardHandlerBase> CreateKeyboardKeyHandler(
flutter::BinaryMessenger* messenger,
flutter::KeyboardKeyEmbedderHandler::GetKeyStateHandler get_key_state,
KeyboardKeyEmbedderHandler::MapVirtualKeyToScanCode map_vk_to_scan)
override {
auto spy_key_event_handler =
std::make_unique<SpyKeyboardKeyHandler>(messenger);
key_event_handler = spy_key_event_handler.get();
return spy_key_event_handler;
}

std::unique_ptr<TextInputPlugin> CreateTextInputPlugin(
flutter::BinaryMessenger* messenger) override {
auto spy_key_event_handler =
std::make_unique<SpyTextInputPlugin>(messenger);
text_input_plugin = spy_key_event_handler.get();
return spy_key_event_handler;
}
};

// 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());
auto key_response_controller = std::make_shared<MockKeyResponseController>();
key_response_controller->SetChannelResponse(
[](MockKeyResponseController::ResponseCallback callback) {
callback(test_response);
});
MockEmbedderApiForKeyboard(modifier, key_response_controller);

return engine;
}

} // namespace

TEST(FlutterWindowTest, CreateDestroy) {
Expand Down Expand Up @@ -419,7 +288,7 @@ TEST(FlutterWindowTest, AlertNode) {
ON_CALL(*win32window, GetPlatformWindow()).WillByDefault(Return(nullptr));
ON_CALL(*win32window, GetAxFragmentRootDelegate())
.WillByDefault(Return(nullptr));
TestFlutterWindowsView view(std::move(win32window));
MockFlutterWindowsView view(std::move(win32window));
std::wstring message = L"Test alert";
EXPECT_CALL(view, NotifyWinEventWrapper(_, ax::mojom::Event::kAlert))
.Times(1);
Expand Down