Handle construction/destruction of GObject private data containing C++ objects in Linux embedder tests (#50022)
See https://github.com/flutter/flutter/issues/140183
diff --git a/shell/platform/linux/fl_keyboard_manager_test.cc b/shell/platform/linux/fl_keyboard_manager_test.cc
index 2add32b..84310de 100644
--- a/shell/platform/linux/fl_keyboard_manager_test.cc
+++ b/shell/platform/linux/fl_keyboard_manager_test.cc
@@ -163,7 +163,9 @@
struct _FlMockKeyBinaryMessenger {
GObject parent_instance;
+};
+struct FlMockKeyBinaryMessengerPrivate {
ChannelCallHandler callback_handler;
};
@@ -175,10 +177,29 @@
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,
@@ -191,20 +212,21 @@
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);
+ 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));
- });
+ g_task_return_pointer(
+ task, data, reinterpret_cast<GDestroyNotify>(g_bytes_unref));
+ });
}
}
@@ -255,8 +277,6 @@
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));
@@ -270,14 +290,17 @@
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;
@@ -294,20 +317,33 @@
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))
-static void fl_mock_view_delegate_init(FlMockViewDelegate* self) {}
+#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_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);
@@ -317,8 +353,9 @@
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);
}
@@ -328,38 +365,41 @@
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;
@@ -394,31 +434,36 @@
// 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();
}
}
@@ -557,16 +602,20 @@
}
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,
diff --git a/shell/platform/linux/fl_scrolling_manager_test.cc b/shell/platform/linux/fl_scrolling_manager_test.cc
index 4f8617a..59b67bc 100644
--- a/shell/platform/linux/fl_scrolling_manager_test.cc
+++ b/shell/platform/linux/fl_scrolling_manager_test.cc
@@ -62,7 +62,9 @@
struct _FlMockScrollingViewDelegate {
GObject parent_instance;
+};
+struct FlMockScrollingViewDelegatePrivate {
MousePointerCallHandler mouse_handler;
PointerPanZoomCallHandler pan_zoom_handler;
};
@@ -75,10 +77,26 @@
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);
@@ -87,6 +105,7 @@
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(
@@ -98,8 +117,9 @@
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);
}
@@ -113,8 +133,9 @@
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(
@@ -136,13 +157,19 @@
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 *****/