Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Handle construction/destruction of GObject private data containing C++ objects in Linux embedder tests #50022

Merged
Merged
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
141 changes: 95 additions & 46 deletions shell/platform/linux/fl_keyboard_manager_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,9 @@ MATCHER_P(MethodSuccessResponse, result, "") {

struct _FlMockKeyBinaryMessenger {
GObject parent_instance;
};

struct FlMockKeyBinaryMessengerPrivate {
ChannelCallHandler callback_handler;
};

Expand All @@ -175,10 +177,29 @@ 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))
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();
}

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_class_init(
FlMockKeyBinaryMessengerClass* klass) {}
FlMockKeyBinaryMessengerClass* klass) {
G_OBJECT_CLASS(klass)->finalize = fl_mock_key_binary_messenger_finalize;
}

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

if (callback != nullptr) {
EXPECT_STREQ(channel, kKeyEventChannelName);
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));
});
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));
});
}
}

Expand Down Expand Up @@ -255,8 +277,6 @@ static void fl_mock_key_binary_messenger_iface_init(
fl_mock_binary_messenger_set_warns_on_channel_overflow;
}

static void fl_mock_key_binary_messenger_init(FlMockKeyBinaryMessenger* self) {}

static FlMockKeyBinaryMessenger* fl_mock_key_binary_messenger_new() {
FlMockKeyBinaryMessenger* self = FL_MOCK_KEY_BINARY_MESSENGER(
g_object_new(fl_mock_key_binary_messenger_get_type(), NULL));
Expand All @@ -270,14 +290,17 @@ static FlMockKeyBinaryMessenger* fl_mock_key_binary_messenger_new() {
static void fl_mock_key_binary_messenger_set_callback_handler(
FlMockKeyBinaryMessenger* self,
ChannelCallHandler handler) {
self->callback_handler = std::move(handler);
FL_MOCK_KEY_BINARY_MESSENGER_GET_PRIVATE(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 @@ -294,20 +317,33 @@ 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))
fl_mock_view_keyboard_delegate_iface_init);
G_ADD_PRIVATE(FlMockViewDelegate))

#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) {}
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_dispose(GObject* object) {
FlMockViewDelegate* self = FL_MOCK_VIEW_DELEGATE(object);
FlMockViewDelegatePrivate* priv = FL_MOCK_VIEW_DELEGATE_GET_PRIVATE(object);

g_clear_object(&self->messenger);
g_clear_object(&priv->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 FlKeyEvent* fl_key_event_clone_information_only(FlKeyEvent* event);
Expand All @@ -317,8 +353,9 @@ static void fl_mock_view_keyboard_send_key_event(
const FlutterKeyEvent* event,
FlutterKeyEventCallback callback,
void* user_data) {
FlMockViewDelegate* self = FL_MOCK_VIEW_DELEGATE(view_delegate);
self->embedder_handler(event, [callback, user_data](bool handled) {
FlMockViewDelegatePrivate* priv =
FL_MOCK_VIEW_DELEGATE_GET_PRIVATE(view_delegate);
priv->embedder_handler(event, [callback, user_data](bool handled) {
if (callback != nullptr) {
callback(handled, user_data);
}
Expand All @@ -328,38 +365,41 @@ static void fl_mock_view_keyboard_send_key_event(
static gboolean fl_mock_view_keyboard_text_filter_key_press(
FlKeyboardViewDelegate* view_delegate,
FlKeyEvent* event) {
FlMockViewDelegate* self = FL_MOCK_VIEW_DELEGATE(view_delegate);
return self->text_filter_result;
FlMockViewDelegatePrivate* priv =
FL_MOCK_VIEW_DELEGATE_GET_PRIVATE(view_delegate);
return priv->text_filter_result;
}

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

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

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

static guint fl_mock_view_keyboard_lookup_key(FlKeyboardViewDelegate* delegate,
const GdkKeymapKey* key) {
FlMockViewDelegate* self = FL_MOCK_VIEW_DELEGATE(delegate);
FlMockViewDelegatePrivate* priv = FL_MOCK_VIEW_DELEGATE_GET_PRIVATE(delegate);
guint8 group = static_cast<guint8>(key->group);
EXPECT_LT(group, self->layout_data->size());
const MockGroupLayoutData* group_layout = (*self->layout_data)[group];
EXPECT_LT(group, priv->layout_data->size());
const MockGroupLayoutData* group_layout = (*priv->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 @@ -394,31 +434,36 @@ static FlMockViewDelegate* fl_mock_view_delegate_new() {
// Added to stop compiler complaining about an unused function.
FL_IS_MOCK_VIEW_DELEGATE(self);

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

return self;
}

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

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

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

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

Expand Down Expand Up @@ -557,16 +602,20 @@ class KeyboardTester {
}

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

fl_mock_key_binary_messenger_set_callback_handler(
view_->messenger, [response, this](const AsyncKeyCallback& callback) {
priv->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(
view_->messenger, [&storage, this](AsyncKeyCallback callback) {
priv->messenger, [&storage, this](AsyncKeyCallback callback) {
EXPECT_FALSE(during_redispatch_);
storage.push_back(CallRecord{
.type = CallRecord::kKeyCallChannel,
Expand Down
43 changes: 35 additions & 8 deletions shell/platform/linux/fl_scrolling_manager_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,9 @@ G_END_DECLS

struct _FlMockScrollingViewDelegate {
GObject parent_instance;
};

struct FlMockScrollingViewDelegatePrivate {
MousePointerCallHandler mouse_handler;
PointerPanZoomCallHandler pan_zoom_handler;
};
Expand All @@ -75,10 +77,26 @@ G_DEFINE_TYPE_WITH_CODE(
fl_mock_scrolling_view_delegate,
G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE(fl_scrolling_view_delegate_get_type(),
fl_mock_view_scroll_delegate_iface_init))
fl_mock_view_scroll_delegate_iface_init);
G_ADD_PRIVATE(FlMockScrollingViewDelegate))

#define FL_MOCK_SCROLLING_VIEW_DELEGATE_GET_PRIVATE(obj) \
static_cast<FlMockScrollingViewDelegatePrivate*>( \
fl_mock_scrolling_view_delegate_get_instance_private( \
FL_MOCK_SCROLLING_VIEW_DELEGATE(obj)))

static void fl_mock_scrolling_view_delegate_init(
FlMockScrollingViewDelegate* self) {}
FlMockScrollingViewDelegate* self) {
FlMockScrollingViewDelegatePrivate* priv =
FL_MOCK_SCROLLING_VIEW_DELEGATE_GET_PRIVATE(self);

new (priv) FlMockScrollingViewDelegatePrivate();
}

static void fl_mock_scrolling_view_delegate_finalize(GObject* object) {
FL_MOCK_SCROLLING_VIEW_DELEGATE_GET_PRIVATE(object)
->~FlMockScrollingViewDelegatePrivate();
}

static void fl_mock_scrolling_view_delegate_dispose(GObject* object) {
G_OBJECT_CLASS(fl_mock_scrolling_view_delegate_parent_class)->dispose(object);
Expand All @@ -87,6 +105,7 @@ static void fl_mock_scrolling_view_delegate_dispose(GObject* object) {
static void fl_mock_scrolling_view_delegate_class_init(
FlMockScrollingViewDelegateClass* klass) {
G_OBJECT_CLASS(klass)->dispose = fl_mock_scrolling_view_delegate_dispose;
G_OBJECT_CLASS(klass)->finalize = fl_mock_scrolling_view_delegate_finalize;
}

static void fl_mock_view_send_mouse_pointer_event(
Expand All @@ -98,8 +117,9 @@ static void fl_mock_view_send_mouse_pointer_event(
double scroll_delta_x,
double scroll_delta_y,
int64_t buttons) {
FlMockScrollingViewDelegate* self = FL_MOCK_SCROLLING_VIEW_DELEGATE(delegate);
self->mouse_handler(phase, timestamp, x, y, scroll_delta_x, scroll_delta_y,
FlMockScrollingViewDelegatePrivate* priv =
FL_MOCK_SCROLLING_VIEW_DELEGATE_GET_PRIVATE(delegate);
priv->mouse_handler(phase, timestamp, x, y, scroll_delta_x, scroll_delta_y,
buttons);
}

Expand All @@ -113,8 +133,9 @@ static void fl_mock_view_send_pointer_pan_zoom_event(
double pan_y,
double scale,
double rotation) {
FlMockScrollingViewDelegate* self = FL_MOCK_SCROLLING_VIEW_DELEGATE(delegate);
self->pan_zoom_handler(timestamp, x, y, phase, pan_x, pan_y, scale, rotation);
FlMockScrollingViewDelegatePrivate* priv =
FL_MOCK_SCROLLING_VIEW_DELEGATE_GET_PRIVATE(delegate);
priv->pan_zoom_handler(timestamp, x, y, phase, pan_x, pan_y, scale, rotation);
}

static void fl_mock_view_scroll_delegate_iface_init(
Expand All @@ -136,13 +157,19 @@ static FlMockScrollingViewDelegate* fl_mock_scrolling_view_delegate_new() {
static void fl_mock_scrolling_view_set_mouse_handler(
FlMockScrollingViewDelegate* self,
MousePointerCallHandler handler) {
self->mouse_handler = std::move(handler);
FlMockScrollingViewDelegatePrivate* priv =
FL_MOCK_SCROLLING_VIEW_DELEGATE_GET_PRIVATE(self);

priv->mouse_handler = std::move(handler);
}

static void fl_mock_scrolling_view_set_pan_zoom_handler(
FlMockScrollingViewDelegate* self,
PointerPanZoomCallHandler handler) {
self->pan_zoom_handler = std::move(handler);
FlMockScrollingViewDelegatePrivate* priv =
FL_MOCK_SCROLLING_VIEW_DELEGATE_GET_PRIVATE(self);

priv->pan_zoom_handler = std::move(handler);
}

/***** End FlMockScrollingViewDelegate *****/
Expand Down