Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Closed
Show file tree
Hide file tree
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
6 changes: 0 additions & 6 deletions shell/platform/linux/fl_key_event.cc
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,3 @@ void fl_key_event_dispose(FlKeyEvent* event) {
}
g_free(event);
}

FlKeyEvent* fl_key_event_clone(const FlKeyEvent* event) {
FlKeyEvent* new_event = g_new(FlKeyEvent, 1);
*new_event = *event;
return new_event;
}
2 changes: 0 additions & 2 deletions shell/platform/linux/fl_key_event.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,4 @@ FlKeyEvent* fl_key_event_new_from_gdk_event(GdkEvent* event);
*/
void fl_key_event_dispose(FlKeyEvent* event);

FlKeyEvent* fl_key_event_clone(const FlKeyEvent* source);

#endif // FLUTTER_SHELL_PLATFORM_LINUX_FL_KEY_EVENT_H_
164 changes: 51 additions & 113 deletions shell/platform/linux/fl_keyboard_handler_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -88,19 +88,6 @@ typedef struct {
std::unique_ptr<char[]> event_character;
} CallRecord;

// Clone a C-string.
//
// Must be deleted by delete[].
char* cloneString(const char* source) {
if (source == nullptr) {
return nullptr;
}
size_t charLen = strlen(source);
char* target = new char[charLen + 1];
strncpy(target, source, charLen + 1);
return target;
}

constexpr guint16 kKeyCodeKeyA = 0x26u;
constexpr guint16 kKeyCodeKeyB = 0x38u;
constexpr guint16 kKeyCodeKeyM = 0x3au;
Expand Down Expand Up @@ -163,9 +150,7 @@ MATCHER_P(MethodSuccessResponse, result, "") {

struct _FlMockKeyBinaryMessenger {
GObject parent_instance;
};

struct FlMockKeyBinaryMessengerPrivate {
ChannelCallHandler callback_handler;
};

Expand All @@ -177,29 +162,12 @@ G_DEFINE_TYPE_WITH_CODE(
fl_mock_key_binary_messenger,
G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE(fl_binary_messenger_get_type(),
fl_mock_key_binary_messenger_iface_init);
G_ADD_PRIVATE(FlMockKeyBinaryMessenger))

#define FL_MOCK_KEY_BINARY_MESSENGER_GET_PRIVATE(obj) \
static_cast<FlMockKeyBinaryMessengerPrivate*>( \
fl_mock_key_binary_messenger_get_instance_private( \
FL_MOCK_KEY_BINARY_MESSENGER(obj)))

static void fl_mock_key_binary_messenger_init(FlMockKeyBinaryMessenger* self) {
FlMockKeyBinaryMessengerPrivate* priv =
FL_MOCK_KEY_BINARY_MESSENGER_GET_PRIVATE(self);
new (priv) FlMockKeyBinaryMessengerPrivate();
}
fl_mock_key_binary_messenger_iface_init))

static void fl_mock_key_binary_messenger_finalize(GObject* object) {
FL_MOCK_KEY_BINARY_MESSENGER_GET_PRIVATE(object)
->~FlMockKeyBinaryMessengerPrivate();
}
static void fl_mock_key_binary_messenger_init(FlMockKeyBinaryMessenger* self) {}

static void fl_mock_key_binary_messenger_class_init(
FlMockKeyBinaryMessengerClass* klass) {
G_OBJECT_CLASS(klass)->finalize = fl_mock_key_binary_messenger_finalize;
}
FlMockKeyBinaryMessengerClass* klass) {}

static void fl_mock_key_binary_messenger_send_on_channel(
FlBinaryMessenger* messenger,
Expand All @@ -212,21 +180,20 @@ static void fl_mock_key_binary_messenger_send_on_channel(

if (callback != nullptr) {
EXPECT_STREQ(channel, kKeyEventChannelName);
FL_MOCK_KEY_BINARY_MESSENGER_GET_PRIVATE(self)->callback_handler(
[self, cancellable, callback, user_data](bool handled) {
g_autoptr(GTask) task =
g_task_new(self, cancellable, callback, user_data);
g_autoptr(FlValue) result = fl_value_new_map();
fl_value_set_string_take(result, "handled",
fl_value_new_bool(handled));
g_autoptr(FlJsonMessageCodec) codec = fl_json_message_codec_new();
g_autoptr(GError) error = nullptr;
GBytes* data = fl_message_codec_encode_message(
FL_MESSAGE_CODEC(codec), result, &error);

g_task_return_pointer(
task, data, reinterpret_cast<GDestroyNotify>(g_bytes_unref));
});
self->callback_handler([self, cancellable, callback,
user_data](bool handled) {
g_autoptr(GTask) task =
g_task_new(self, cancellable, callback, user_data);
g_autoptr(FlValue) result = fl_value_new_map();
fl_value_set_string_take(result, "handled", fl_value_new_bool(handled));
g_autoptr(FlJsonMessageCodec) codec = fl_json_message_codec_new();
g_autoptr(GError) error = nullptr;
GBytes* data = fl_message_codec_encode_message(FL_MESSAGE_CODEC(codec),
result, &error);

g_task_return_pointer(task, data,
reinterpret_cast<GDestroyNotify>(g_bytes_unref));
});
}
}

Expand Down Expand Up @@ -290,17 +257,14 @@ static FlMockKeyBinaryMessenger* fl_mock_key_binary_messenger_new() {
static void fl_mock_key_binary_messenger_set_callback_handler(
FlMockKeyBinaryMessenger* self,
ChannelCallHandler handler) {
FL_MOCK_KEY_BINARY_MESSENGER_GET_PRIVATE(self)->callback_handler =
std::move(handler);
self->callback_handler = std::move(handler);
}

/***** FlMockViewDelegate *****/

struct _FlMockViewDelegate {
GObject parent_instance;
};

struct FlMockViewDelegatePrivate {
FlMockKeyBinaryMessenger* messenger;
EmbedderCallHandler embedder_handler;
bool text_filter_result;
Expand All @@ -317,87 +281,70 @@ G_DEFINE_TYPE_WITH_CODE(
fl_mock_view_delegate,
G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE(fl_keyboard_view_delegate_get_type(),
fl_mock_view_keyboard_delegate_iface_init);
G_ADD_PRIVATE(FlMockViewDelegate))
fl_mock_view_keyboard_delegate_iface_init))

#define FL_MOCK_VIEW_DELEGATE_GET_PRIVATE(obj) \
static_cast<FlMockViewDelegatePrivate*>( \
fl_mock_view_delegate_get_instance_private(FL_MOCK_VIEW_DELEGATE(obj)))

static void fl_mock_view_delegate_init(FlMockViewDelegate* self) {
FlMockViewDelegatePrivate* priv = FL_MOCK_VIEW_DELEGATE_GET_PRIVATE(self);
new (priv) FlMockViewDelegatePrivate();
}

static void fl_mock_view_delegate_finalize(GObject* object) {
FL_MOCK_VIEW_DELEGATE_GET_PRIVATE(object)->~FlMockViewDelegatePrivate();
}
static void fl_mock_view_delegate_init(FlMockViewDelegate* self) {}

static void fl_mock_view_delegate_dispose(GObject* object) {
FlMockViewDelegatePrivate* priv = FL_MOCK_VIEW_DELEGATE_GET_PRIVATE(object);
FlMockViewDelegate* self = FL_MOCK_VIEW_DELEGATE(object);

g_clear_object(&priv->messenger);
g_clear_object(&self->messenger);

G_OBJECT_CLASS(fl_mock_view_delegate_parent_class)->dispose(object);
}

static void fl_mock_view_delegate_class_init(FlMockViewDelegateClass* klass) {
G_OBJECT_CLASS(klass)->dispose = fl_mock_view_delegate_dispose;
G_OBJECT_CLASS(klass)->finalize = fl_mock_view_delegate_finalize;
}

static void fl_mock_view_keyboard_send_key_event(
FlKeyboardViewDelegate* view_delegate,
FlKeyboardViewDelegate* delegate,
const FlutterKeyEvent* event,
FlutterKeyEventCallback callback,
void* user_data) {
FlMockViewDelegatePrivate* priv =
FL_MOCK_VIEW_DELEGATE_GET_PRIVATE(view_delegate);
priv->embedder_handler(event, [callback, user_data](bool handled) {
FlMockViewDelegate* self = FL_MOCK_VIEW_DELEGATE(delegate);
self->embedder_handler(event, [callback, user_data](bool handled) {
if (callback != nullptr) {
callback(handled, user_data);
}
});
}

static gboolean fl_mock_view_keyboard_text_filter_key_press(
FlKeyboardViewDelegate* view_delegate,
FlKeyboardViewDelegate* delegate,
FlKeyEvent* event) {
FlMockViewDelegatePrivate* priv =
FL_MOCK_VIEW_DELEGATE_GET_PRIVATE(view_delegate);
return priv->text_filter_result;
FlMockViewDelegate* self = FL_MOCK_VIEW_DELEGATE(delegate);
return self->text_filter_result;
}

static FlBinaryMessenger* fl_mock_view_keyboard_get_messenger(
FlKeyboardViewDelegate* view_delegate) {
FlMockViewDelegatePrivate* priv =
FL_MOCK_VIEW_DELEGATE_GET_PRIVATE(view_delegate);
return FL_BINARY_MESSENGER(priv->messenger);
FlKeyboardViewDelegate* delegate) {
FlMockViewDelegate* self = FL_MOCK_VIEW_DELEGATE(delegate);
return FL_BINARY_MESSENGER(self->messenger);
}

static void fl_mock_view_keyboard_redispatch_event(
FlKeyboardViewDelegate* view_delegate,
FlKeyboardViewDelegate* delegate,
std::unique_ptr<FlKeyEvent> event) {
FlMockViewDelegatePrivate* priv =
FL_MOCK_VIEW_DELEGATE_GET_PRIVATE(view_delegate);
if (priv->redispatch_handler) {
priv->redispatch_handler(std::move(event));
FlMockViewDelegate* self = FL_MOCK_VIEW_DELEGATE(delegate);
if (self->redispatch_handler) {
self->redispatch_handler(std::move(event));
}
}

static void fl_mock_view_keyboard_subscribe_to_layout_change(
FlKeyboardViewDelegate* delegate,
KeyboardLayoutNotifier notifier) {
FlMockViewDelegatePrivate* priv = FL_MOCK_VIEW_DELEGATE_GET_PRIVATE(delegate);
priv->layout_notifier = std::move(notifier);
FlMockViewDelegate* self = FL_MOCK_VIEW_DELEGATE(delegate);
self->layout_notifier = std::move(notifier);
}

static guint fl_mock_view_keyboard_lookup_key(FlKeyboardViewDelegate* delegate,
const GdkKeymapKey* key) {
FlMockViewDelegatePrivate* priv = FL_MOCK_VIEW_DELEGATE_GET_PRIVATE(delegate);
FlMockViewDelegate* self = FL_MOCK_VIEW_DELEGATE(delegate);
guint8 group = static_cast<guint8>(key->group);
EXPECT_LT(group, priv->layout_data->size());
const MockGroupLayoutData* group_layout = (*priv->layout_data)[group];
EXPECT_LT(group, self->layout_data->size());
const MockGroupLayoutData* group_layout = (*self->layout_data)[group];
EXPECT_TRUE(group_layout != nullptr);
EXPECT_TRUE(key->level == 0 || key->level == 1);
bool shift = key->level == 1;
Expand Down Expand Up @@ -432,36 +379,31 @@ static FlMockViewDelegate* fl_mock_view_delegate_new() {
// Added to stop compiler complaining about an unused function.
FL_IS_MOCK_VIEW_DELEGATE(self);

FlMockViewDelegatePrivate* priv = FL_MOCK_VIEW_DELEGATE_GET_PRIVATE(self);
priv->messenger = fl_mock_key_binary_messenger_new();
self->messenger = fl_mock_key_binary_messenger_new();

return self;
}

static void fl_mock_view_set_embedder_handler(FlMockViewDelegate* self,
EmbedderCallHandler handler) {
FlMockViewDelegatePrivate* priv = FL_MOCK_VIEW_DELEGATE_GET_PRIVATE(self);
priv->embedder_handler = std::move(handler);
self->embedder_handler = std::move(handler);
}

static void fl_mock_view_set_text_filter_result(FlMockViewDelegate* self,
bool result) {
FlMockViewDelegatePrivate* priv = FL_MOCK_VIEW_DELEGATE_GET_PRIVATE(self);
priv->text_filter_result = result;
self->text_filter_result = result;
}

static void fl_mock_view_set_redispatch_handler(FlMockViewDelegate* self,
RedispatchHandler handler) {
FlMockViewDelegatePrivate* priv = FL_MOCK_VIEW_DELEGATE_GET_PRIVATE(self);
priv->redispatch_handler = std::move(handler);
self->redispatch_handler = std::move(handler);
}

static void fl_mock_view_set_layout(FlMockViewDelegate* self,
const MockLayoutData* layout) {
FlMockViewDelegatePrivate* priv = FL_MOCK_VIEW_DELEGATE_GET_PRIVATE(self);
priv->layout_data = layout;
if (priv->layout_notifier != nullptr) {
priv->layout_notifier();
self->layout_data = layout;
if (self->layout_notifier != nullptr) {
self->layout_notifier();
}
}

Expand Down Expand Up @@ -553,7 +495,7 @@ class KeyboardTester {
AsyncKeyCallback callback) {
EXPECT_FALSE(during_redispatch_);
auto new_event = std::make_unique<FlutterKeyEvent>(*event);
char* new_event_character = cloneString(event->character);
char* new_event_character = g_strdup(event->character);
new_event->character = new_event_character;
storage.push_back(CallRecord{
.type = CallRecord::kKeyCallEmbedder,
Expand All @@ -572,7 +514,7 @@ class KeyboardTester {
const AsyncKeyCallback& callback) {
EXPECT_FALSE(during_redispatch_);
auto new_event = std::make_unique<FlutterKeyEvent>(*event);
char* new_event_character = cloneString(event->character);
char* new_event_character = g_strdup(event->character);
new_event->character = new_event_character;
storage.push_back(CallRecord{
.type = CallRecord::kKeyCallEmbedder,
Expand All @@ -584,20 +526,16 @@ class KeyboardTester {
}

void respondToChannelCallsWith(bool response) {
FlMockViewDelegatePrivate* priv = FL_MOCK_VIEW_DELEGATE_GET_PRIVATE(view_);

fl_mock_key_binary_messenger_set_callback_handler(
priv->messenger, [response, this](const AsyncKeyCallback& callback) {
view_->messenger, [response, this](const AsyncKeyCallback& callback) {
EXPECT_FALSE(during_redispatch_);
callback(response);
});
}

void recordChannelCallsTo(std::vector<CallRecord>& storage) {
FlMockViewDelegatePrivate* priv = FL_MOCK_VIEW_DELEGATE_GET_PRIVATE(view_);

fl_mock_key_binary_messenger_set_callback_handler(
priv->messenger, [&storage, this](AsyncKeyCallback callback) {
view_->messenger, [&storage, this](AsyncKeyCallback callback) {
EXPECT_FALSE(during_redispatch_);
storage.push_back(CallRecord{
.type = CallRecord::kKeyCallChannel,
Expand Down