Skip to content

Commit b56b5b6

Browse files
Keyboard tidy ups (flutter#162054)
Make async calls use standard GLib async API. Remove test specific methods. Smaller cleanups.
1 parent 2919003 commit b56b5b6

11 files changed

+1459
-697
lines changed

engine/src/flutter/shell/platform/linux/fl_engine.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,15 @@ G_MODULE_EXPORT FlEngine* fl_engine_new(FlDartProject* project) {
545545
return fl_engine_new_with_renderer(project, FL_RENDERER(renderer));
546546
}
547547

548+
FlEngine* fl_engine_new_with_binary_messenger(
549+
FlBinaryMessenger* binary_messenger) {
550+
g_autoptr(FlDartProject) project = fl_dart_project_new();
551+
FlEngine* self = fl_engine_new(project);
552+
g_object_unref(self->binary_messenger);
553+
self->binary_messenger = FL_BINARY_MESSENGER(g_object_ref(binary_messenger));
554+
return self;
555+
}
556+
548557
G_MODULE_EXPORT FlEngine* fl_engine_new_headless(FlDartProject* project) {
549558
g_autoptr(FlRendererHeadless) renderer = fl_renderer_headless_new();
550559
return fl_engine_new_with_renderer(project, FL_RENDERER(renderer));

engine/src/flutter/shell/platform/linux/fl_engine_private.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,17 @@ typedef void (*FlEngineUpdateSemanticsHandler)(
6161
const FlutterSemanticsUpdate2* update,
6262
gpointer user_data);
6363

64+
/**
65+
* fl_engine_new_with_binary_messenger:
66+
* @binary_messenger: an #FlBinaryMessenger.
67+
*
68+
* Creates a new engine with a custom binary messenger. Used for testing.
69+
*
70+
* Returns: a new #FlEngine.
71+
*/
72+
FlEngine* fl_engine_new_with_binary_messenger(
73+
FlBinaryMessenger* binary_messenger);
74+
6475
/**
6576
* fl_engine_new_with_renderer:
6677
* @project: an #FlDartProject.

engine/src/flutter/shell/platform/linux/fl_key_embedder_responder.cc

Lines changed: 83 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -73,55 +73,6 @@ static uint64_t to_lower(uint64_t n) {
7373
return n;
7474
}
7575

76-
/**
77-
* FlKeyEmbedderUserData:
78-
* The user_data used when #FlKeyEmbedderResponder sends message through the
79-
* embedder.SendKeyEvent API.
80-
*/
81-
G_DECLARE_FINAL_TYPE(FlKeyEmbedderUserData,
82-
fl_key_embedder_user_data,
83-
FL,
84-
KEY_EMBEDDER_USER_DATA,
85-
GObject);
86-
87-
struct _FlKeyEmbedderUserData {
88-
GObject parent_instance;
89-
90-
FlKeyEmbedderResponderAsyncCallback callback;
91-
gpointer user_data;
92-
};
93-
94-
G_DEFINE_TYPE(FlKeyEmbedderUserData, fl_key_embedder_user_data, G_TYPE_OBJECT)
95-
96-
static void fl_key_embedder_user_data_dispose(GObject* object);
97-
98-
static void fl_key_embedder_user_data_class_init(
99-
FlKeyEmbedderUserDataClass* klass) {
100-
G_OBJECT_CLASS(klass)->dispose = fl_key_embedder_user_data_dispose;
101-
}
102-
103-
static void fl_key_embedder_user_data_init(FlKeyEmbedderUserData* self) {}
104-
105-
static void fl_key_embedder_user_data_dispose(GObject* object) {
106-
// The following line suppresses a warning for unused function
107-
// FL_IS_KEY_EMBEDDER_USER_DATA.
108-
g_return_if_fail(FL_IS_KEY_EMBEDDER_USER_DATA(object));
109-
}
110-
111-
// Creates a new FlKeyChannelUserData private class with all information.
112-
//
113-
// The callback and the user_data might be nullptr.
114-
static FlKeyEmbedderUserData* fl_key_embedder_user_data_new(
115-
FlKeyEmbedderResponderAsyncCallback callback,
116-
gpointer user_data) {
117-
FlKeyEmbedderUserData* self = FL_KEY_EMBEDDER_USER_DATA(
118-
g_object_new(fl_key_embedder_user_data_get_type(), nullptr));
119-
120-
self->callback = callback;
121-
self->user_data = user_data;
122-
return self;
123-
}
124-
12576
namespace {
12677

12778
typedef enum {
@@ -135,8 +86,8 @@ typedef enum {
13586
struct _FlKeyEmbedderResponder {
13687
GObject parent_instance;
13788

138-
EmbedderSendKeyEvent send_key_event;
139-
void* send_key_event_user_data;
89+
// Engine sending key events to.
90+
GWeakRef engine;
14091

14192
// Internal record for states of whether a key is pressed.
14293
//
@@ -190,6 +141,8 @@ struct _FlKeyEmbedderResponder {
190141
// It is a map from primary physical keys to lock bits. Both keys and values
191142
// are directly stored uint64s. This table is freed by the responder.
192143
GHashTable* logical_key_to_lock_bit;
144+
145+
GCancellable* cancellable;
193146
};
194147

195148
static void fl_key_embedder_responder_dispose(GObject* object);
@@ -203,17 +156,23 @@ static void fl_key_embedder_responder_class_init(
203156
}
204157

205158
// Initializes an FlKeyEmbedderResponder instance.
206-
static void fl_key_embedder_responder_init(FlKeyEmbedderResponder* self) {}
159+
static void fl_key_embedder_responder_init(FlKeyEmbedderResponder* self) {
160+
self->cancellable = g_cancellable_new();
161+
}
207162

208163
// Disposes of an FlKeyEmbedderResponder instance.
209164
static void fl_key_embedder_responder_dispose(GObject* object) {
210165
FlKeyEmbedderResponder* self = FL_KEY_EMBEDDER_RESPONDER(object);
211166

167+
g_cancellable_cancel(self->cancellable);
168+
169+
g_weak_ref_clear(&self->engine);
212170
g_clear_pointer(&self->pressing_records, g_hash_table_unref);
213171
g_clear_pointer(&self->mapping_records, g_hash_table_unref);
214172
g_clear_pointer(&self->modifier_bit_to_checked_keys, g_hash_table_unref);
215173
g_clear_pointer(&self->lock_bit_to_checked_keys, g_hash_table_unref);
216174
g_clear_pointer(&self->logical_key_to_lock_bit, g_hash_table_unref);
175+
g_clear_object(&self->cancellable);
217176

218177
G_OBJECT_CLASS(fl_key_embedder_responder_parent_class)->dispose(object);
219178
}
@@ -234,14 +193,11 @@ static void initialize_logical_key_to_lock_bit_loop_body(gpointer lock_bit,
234193
}
235194

236195
// Creates a new FlKeyEmbedderResponder instance.
237-
FlKeyEmbedderResponder* fl_key_embedder_responder_new(
238-
EmbedderSendKeyEvent send_key_event,
239-
void* send_key_event_user_data) {
196+
FlKeyEmbedderResponder* fl_key_embedder_responder_new(FlEngine* engine) {
240197
FlKeyEmbedderResponder* self = FL_KEY_EMBEDDER_RESPONDER(
241198
g_object_new(fl_key_embedder_responder_get_type(), nullptr));
242199

243-
self->send_key_event = send_key_event;
244-
self->send_key_event_user_data = send_key_event_user_data;
200+
g_weak_ref_init(&self->engine, engine);
245201

246202
self->pressing_records = g_hash_table_new(g_direct_hash, g_direct_equal);
247203
self->mapping_records = g_hash_table_new(g_direct_hash, g_direct_equal);
@@ -311,16 +267,6 @@ static char* event_to_character(FlKeyEvent* event) {
311267
return result;
312268
}
313269

314-
// Handles a response from the embedder API to a key event sent to the framework
315-
// earlier.
316-
static void handle_response(bool handled, gpointer user_data) {
317-
g_autoptr(FlKeyEmbedderUserData) data = FL_KEY_EMBEDDER_USER_DATA(user_data);
318-
319-
g_return_if_fail(data->callback != nullptr);
320-
321-
data->callback(handled, data->user_data);
322-
}
323-
324270
// Sends a synthesized event to the framework with no demand for callback.
325271
static void synthesize_simple_event(FlKeyEmbedderResponder* self,
326272
FlutterKeyEventType type,
@@ -336,8 +282,11 @@ static void synthesize_simple_event(FlKeyEmbedderResponder* self,
336282
out_event.character = nullptr;
337283
out_event.synthesized = true;
338284
self->sent_any_events = true;
339-
self->send_key_event(&out_event, nullptr, nullptr,
340-
self->send_key_event_user_data);
285+
g_autoptr(FlEngine) engine = FL_ENGINE(g_weak_ref_get(&self->engine));
286+
if (engine != nullptr) {
287+
fl_engine_send_key_event(engine, &out_event, self->cancellable, nullptr,
288+
nullptr);
289+
}
341290
}
342291

343292
namespace {
@@ -750,13 +699,9 @@ static void fl_key_embedder_responder_handle_event_impl(
750699
FlKeyEmbedderResponder* responder,
751700
FlKeyEvent* event,
752701
uint64_t specified_logical_key,
753-
FlKeyEmbedderResponderAsyncCallback callback,
754-
gpointer user_data) {
702+
GTask* task) {
755703
FlKeyEmbedderResponder* self = FL_KEY_EMBEDDER_RESPONDER(responder);
756704

757-
g_return_if_fail(event != nullptr);
758-
g_return_if_fail(callback != nullptr);
759-
760705
const uint64_t logical_key = specified_logical_key != 0
761706
? specified_logical_key
762707
: event_to_logical_key(event);
@@ -811,7 +756,9 @@ static void fl_key_embedder_responder_handle_event_impl(
811756
// The physical key has been released before. It might indicate a missed
812757
// event due to loss of focus, or multiple keyboards pressed keys with the
813758
// same physical key. Ignore the up event.
814-
callback(true, user_data);
759+
gboolean* return_value = g_new0(gboolean, 1);
760+
*return_value = TRUE;
761+
g_task_return_pointer(task, return_value, g_free);
815762
return;
816763
} else {
817764
out_event.type = kFlutterKeyEventTypeUp;
@@ -825,41 +772,85 @@ static void fl_key_embedder_responder_handle_event_impl(
825772
if (is_down_event) {
826773
update_mapping_record(self, physical_key, logical_key);
827774
}
828-
FlKeyEmbedderUserData* response_data =
829-
fl_key_embedder_user_data_new(callback, user_data);
830775
self->sent_any_events = true;
831-
self->send_key_event(&out_event, handle_response, response_data,
832-
self->send_key_event_user_data);
776+
g_autoptr(FlEngine) engine = FL_ENGINE(g_weak_ref_get(&self->engine));
777+
if (engine != nullptr) {
778+
fl_engine_send_key_event(
779+
engine, &out_event, self->cancellable,
780+
[](GObject* object, GAsyncResult* result, gpointer user_data) {
781+
g_autoptr(GTask) task = G_TASK(user_data);
782+
783+
gboolean handled;
784+
g_autoptr(GError) error = nullptr;
785+
if (!fl_engine_send_key_event_finish(FL_ENGINE(object), result,
786+
&handled, &error)) {
787+
if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
788+
return;
789+
}
790+
g_warning("Failed to handle key event: %s", error->message);
791+
handled = FALSE;
792+
}
793+
794+
gboolean* return_value = g_new0(gboolean, 1);
795+
*return_value = handled;
796+
g_task_return_pointer(task, return_value, g_free);
797+
},
798+
g_object_ref(task));
799+
}
833800
}
834801

835-
void fl_key_embedder_responder_handle_event(
836-
FlKeyEmbedderResponder* self,
837-
FlKeyEvent* event,
838-
uint64_t specified_logical_key,
839-
FlKeyEmbedderResponderAsyncCallback callback,
840-
gpointer user_data) {
802+
void fl_key_embedder_responder_handle_event(FlKeyEmbedderResponder* self,
803+
FlKeyEvent* event,
804+
uint64_t specified_logical_key,
805+
GCancellable* cancellable,
806+
GAsyncReadyCallback callback,
807+
gpointer user_data) {
808+
g_autoptr(GTask) task = g_task_new(self, cancellable, callback, user_data);
809+
841810
self->sent_any_events = false;
842-
fl_key_embedder_responder_handle_event_impl(
843-
self, event, specified_logical_key, callback, user_data);
811+
fl_key_embedder_responder_handle_event_impl(self, event,
812+
specified_logical_key, task);
844813
if (!self->sent_any_events) {
845-
self->send_key_event(&kEmptyEvent, nullptr, nullptr,
846-
self->send_key_event_user_data);
814+
g_autoptr(FlEngine) engine = FL_ENGINE(g_weak_ref_get(&self->engine));
815+
if (engine != nullptr) {
816+
fl_engine_send_key_event(engine, &kEmptyEvent, self->cancellable, nullptr,
817+
nullptr);
818+
}
847819
}
848820
}
849821

822+
gboolean fl_key_embedder_responder_handle_event_finish(
823+
FlKeyEmbedderResponder* self,
824+
GAsyncResult* result,
825+
gboolean* handled,
826+
GError** error) {
827+
g_return_val_if_fail(g_task_is_valid(result, self), FALSE);
828+
829+
g_autofree gboolean* return_value =
830+
static_cast<gboolean*>(g_task_propagate_pointer(G_TASK(result), error));
831+
if (return_value == nullptr) {
832+
return FALSE;
833+
}
834+
835+
*handled = *return_value;
836+
return TRUE;
837+
}
838+
850839
void fl_key_embedder_responder_sync_modifiers_if_needed(
851-
FlKeyEmbedderResponder* responder,
840+
FlKeyEmbedderResponder* self,
852841
guint state,
853842
double event_time) {
843+
g_return_if_fail(FL_IS_KEY_EMBEDDER_RESPONDER(self));
844+
854845
const double timestamp = event_time * kMicrosecondsPerMillisecond;
855846

856847
SyncStateLoopContext sync_state_context;
857-
sync_state_context.self = responder;
848+
sync_state_context.self = self;
858849
sync_state_context.state = state;
859850
sync_state_context.timestamp = timestamp;
860851

861852
// Update pressing states.
862-
g_hash_table_foreach(responder->modifier_bit_to_checked_keys,
853+
g_hash_table_foreach(self->modifier_bit_to_checked_keys,
863854
synchronize_pressed_states_loop_body,
864855
&sync_state_context);
865856
}

0 commit comments

Comments
 (0)