Flutter Linux Embedder
fl_engine_test.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // Included first as it collides with the X11 headers.
6 #include "gtest/gtest.h"
7 
9 #include "flutter/shell/platform/embedder/test_utils/proc_table_replacement.h"
14 #include "flutter/shell/platform/linux/testing/fl_test.h"
15 
16 // MOCK_ENGINE_PROC is leaky by design
17 // NOLINTBEGIN(clang-analyzer-core.StackAddressEscape)
18 
19 // Checks sending window metrics events works.
20 TEST(FlEngineTest, WindowMetrics) {
21  g_autoptr(FlEngine) engine = make_mock_engine();
22  FlutterEngineProcTable* embedder_api = fl_engine_get_embedder_api(engine);
23 
24  bool called = false;
25  embedder_api->SendWindowMetricsEvent = MOCK_ENGINE_PROC(
26  SendWindowMetricsEvent,
27  ([&called](auto engine, const FlutterWindowMetricsEvent* event) {
28  called = true;
29  EXPECT_EQ(event->width, static_cast<size_t>(3840));
30  EXPECT_EQ(event->height, static_cast<size_t>(2160));
31  EXPECT_EQ(event->pixel_ratio, 2.0);
32 
33  return kSuccess;
34  }));
35 
36  g_autoptr(GError) error = nullptr;
37  EXPECT_TRUE(fl_engine_start(engine, &error));
38  EXPECT_EQ(error, nullptr);
40 
41  EXPECT_TRUE(called);
42 }
43 
44 // Checks sending mouse pointer events works.
45 TEST(FlEngineTest, MousePointer) {
46  g_autoptr(FlEngine) engine = make_mock_engine();
47  FlutterEngineProcTable* embedder_api = fl_engine_get_embedder_api(engine);
48 
49  bool called = false;
50  embedder_api->SendPointerEvent = MOCK_ENGINE_PROC(
51  SendPointerEvent,
52  ([&called](auto engine, const FlutterPointerEvent* events,
53  size_t events_count) {
54  called = true;
55  EXPECT_EQ(events_count, static_cast<size_t>(1));
56  EXPECT_EQ(events[0].phase, kDown);
57  EXPECT_EQ(events[0].timestamp, static_cast<size_t>(1234567890));
58  EXPECT_EQ(events[0].x, 800);
59  EXPECT_EQ(events[0].y, 600);
60  EXPECT_EQ(events[0].device, static_cast<int32_t>(0));
61  EXPECT_EQ(events[0].signal_kind, kFlutterPointerSignalKindScroll);
62  EXPECT_EQ(events[0].scroll_delta_x, 1.2);
63  EXPECT_EQ(events[0].scroll_delta_y, -3.4);
64  EXPECT_EQ(events[0].device_kind, kFlutterPointerDeviceKindMouse);
65  EXPECT_EQ(events[0].buttons, kFlutterPointerButtonMouseSecondary);
66 
67  return kSuccess;
68  }));
69 
70  g_autoptr(GError) error = nullptr;
71  EXPECT_TRUE(fl_engine_start(engine, &error));
72  EXPECT_EQ(error, nullptr);
73  fl_engine_send_mouse_pointer_event(engine, kDown, 1234567890, 800, 600, 1.2,
74  -3.4, kFlutterPointerButtonMouseSecondary);
75 
76  EXPECT_TRUE(called);
77 }
78 
79 // Checks sending pan/zoom events works.
80 TEST(FlEngineTest, PointerPanZoom) {
81  g_autoptr(FlEngine) engine = make_mock_engine();
82  FlutterEngineProcTable* embedder_api = fl_engine_get_embedder_api(engine);
83 
84  bool called = false;
85  embedder_api->SendPointerEvent = MOCK_ENGINE_PROC(
86  SendPointerEvent,
87  ([&called](auto engine, const FlutterPointerEvent* events,
88  size_t events_count) {
89  called = true;
90  EXPECT_EQ(events_count, static_cast<size_t>(1));
91  EXPECT_EQ(events[0].phase, kPanZoomUpdate);
92  EXPECT_EQ(events[0].timestamp, static_cast<size_t>(1234567890));
93  EXPECT_EQ(events[0].x, 800);
94  EXPECT_EQ(events[0].y, 600);
95  EXPECT_EQ(events[0].device, static_cast<int32_t>(1));
96  EXPECT_EQ(events[0].signal_kind, kFlutterPointerSignalKindNone);
97  EXPECT_EQ(events[0].pan_x, 1.5);
98  EXPECT_EQ(events[0].pan_y, 2.5);
99  EXPECT_EQ(events[0].scale, 3.5);
100  EXPECT_EQ(events[0].rotation, 4.5);
101  EXPECT_EQ(events[0].device_kind, kFlutterPointerDeviceKindTrackpad);
102  EXPECT_EQ(events[0].buttons, 0);
103 
104  return kSuccess;
105  }));
106 
107  g_autoptr(GError) error = nullptr;
108  EXPECT_TRUE(fl_engine_start(engine, &error));
109  EXPECT_EQ(error, nullptr);
110  fl_engine_send_pointer_pan_zoom_event(engine, 1234567890, 800, 600,
111  kPanZoomUpdate, 1.5, 2.5, 3.5, 4.5);
112 
113  EXPECT_TRUE(called);
114 }
115 
116 // Checks dispatching a semantics action works.
117 TEST(FlEngineTest, DispatchSemanticsAction) {
118  g_autoptr(FlEngine) engine = make_mock_engine();
119  FlutterEngineProcTable* embedder_api = fl_engine_get_embedder_api(engine);
120 
121  bool called = false;
122  embedder_api->DispatchSemanticsAction = MOCK_ENGINE_PROC(
123  DispatchSemanticsAction,
124  ([&called](auto engine, uint64_t id, FlutterSemanticsAction action,
125  const uint8_t* data, size_t data_length) {
126  EXPECT_EQ(id, static_cast<uint64_t>(42));
127  EXPECT_EQ(action, kFlutterSemanticsActionTap);
128  EXPECT_EQ(data_length, static_cast<size_t>(4));
129  EXPECT_EQ(data[0], 't');
130  EXPECT_EQ(data[1], 'e');
131  EXPECT_EQ(data[2], 's');
132  EXPECT_EQ(data[3], 't');
133  called = true;
134 
135  return kSuccess;
136  }));
137 
138  g_autoptr(GError) error = nullptr;
139  EXPECT_TRUE(fl_engine_start(engine, &error));
140  EXPECT_EQ(error, nullptr);
141  g_autoptr(GBytes) data = g_bytes_new_static("test", 4);
142  fl_engine_dispatch_semantics_action(engine, 42, kFlutterSemanticsActionTap,
143  data);
144 
145  EXPECT_TRUE(called);
146 }
147 
148 // Checks sending platform messages works.
149 TEST(FlEngineTest, PlatformMessage) {
150  g_autoptr(FlEngine) engine = make_mock_engine();
151  FlutterEngineProcTable* embedder_api = fl_engine_get_embedder_api(engine);
152 
153  bool called = false;
154  FlutterEngineSendPlatformMessageFnPtr old_handler =
155  embedder_api->SendPlatformMessage;
156  embedder_api->SendPlatformMessage = MOCK_ENGINE_PROC(
157  SendPlatformMessage,
158  ([&called, old_handler](auto engine,
159  const FlutterPlatformMessage* message) {
160  if (strcmp(message->channel, "test") != 0) {
161  return old_handler(engine, message);
162  }
163 
164  called = true;
165 
166  EXPECT_EQ(message->message_size, static_cast<size_t>(4));
167  EXPECT_EQ(message->message[0], 't');
168  EXPECT_EQ(message->message[1], 'e');
169  EXPECT_EQ(message->message[2], 's');
170  EXPECT_EQ(message->message[3], 't');
171 
172  return kSuccess;
173  }));
174 
175  g_autoptr(GError) error = nullptr;
176  EXPECT_TRUE(fl_engine_start(engine, &error));
177  EXPECT_EQ(error, nullptr);
178  g_autoptr(GBytes) message = g_bytes_new_static("test", 4);
179  fl_engine_send_platform_message(engine, "test", message, nullptr, nullptr,
180  nullptr);
181 
182  EXPECT_TRUE(called);
183 }
184 
185 // Checks sending platform message responses works.
186 TEST(FlEngineTest, PlatformMessageResponse) {
187  g_autoptr(FlEngine) engine = make_mock_engine();
188  FlutterEngineProcTable* embedder_api = fl_engine_get_embedder_api(engine);
189 
190  bool called = false;
191  embedder_api->SendPlatformMessageResponse = MOCK_ENGINE_PROC(
192  SendPlatformMessageResponse,
193  ([&called](auto engine,
194  const FlutterPlatformMessageResponseHandle* handle,
195  const uint8_t* data, size_t data_length) {
196  called = true;
197 
198  EXPECT_EQ(
199  handle,
200  reinterpret_cast<const FlutterPlatformMessageResponseHandle*>(42));
201  EXPECT_EQ(data_length, static_cast<size_t>(4));
202  EXPECT_EQ(data[0], 't');
203  EXPECT_EQ(data[1], 'e');
204  EXPECT_EQ(data[2], 's');
205  EXPECT_EQ(data[3], 't');
206 
207  return kSuccess;
208  }));
209 
210  g_autoptr(GError) error = nullptr;
211  EXPECT_TRUE(fl_engine_start(engine, &error));
212  EXPECT_EQ(error, nullptr);
213  g_autoptr(GBytes) response = g_bytes_new_static("test", 4);
215  engine, reinterpret_cast<const FlutterPlatformMessageResponseHandle*>(42),
216  response, &error));
217  EXPECT_EQ(error, nullptr);
218 
219  EXPECT_TRUE(called);
220 }
221 
222 // Checks settings plugin sends settings on startup.
223 TEST(FlEngineTest, SettingsPlugin) {
224  g_autoptr(FlEngine) engine = make_mock_engine();
225  FlutterEngineProcTable* embedder_api = fl_engine_get_embedder_api(engine);
226 
227  bool called = false;
228  embedder_api->SendPlatformMessage = MOCK_ENGINE_PROC(
229  SendPlatformMessage,
230  ([&called](auto engine, const FlutterPlatformMessage* message) {
231  called = true;
232 
233  EXPECT_STREQ(message->channel, "flutter/settings");
234 
235  g_autoptr(FlJsonMessageCodec) codec = fl_json_message_codec_new();
236  g_autoptr(GBytes) data =
237  g_bytes_new(message->message, message->message_size);
238  g_autoptr(GError) error = nullptr;
239  g_autoptr(FlValue) settings = fl_message_codec_decode_message(
240  FL_MESSAGE_CODEC(codec), data, &error);
241  EXPECT_NE(settings, nullptr);
242  EXPECT_EQ(error, nullptr);
243 
244  FlValue* text_scale_factor =
245  fl_value_lookup_string(settings, "textScaleFactor");
246  EXPECT_NE(text_scale_factor, nullptr);
247  EXPECT_EQ(fl_value_get_type(text_scale_factor), FL_VALUE_TYPE_FLOAT);
248 
249  FlValue* always_use_24hr_format =
250  fl_value_lookup_string(settings, "alwaysUse24HourFormat");
251  EXPECT_NE(always_use_24hr_format, nullptr);
252  EXPECT_EQ(fl_value_get_type(always_use_24hr_format),
254 
255  FlValue* platform_brightness =
256  fl_value_lookup_string(settings, "platformBrightness");
257  EXPECT_NE(platform_brightness, nullptr);
258  EXPECT_EQ(fl_value_get_type(platform_brightness), FL_VALUE_TYPE_STRING);
259 
260  return kSuccess;
261  }));
262 
263  g_autoptr(GError) error = nullptr;
264  EXPECT_TRUE(fl_engine_start(engine, &error));
265  EXPECT_EQ(error, nullptr);
266 
267  EXPECT_TRUE(called);
268 }
269 
270 void on_pre_engine_restart_cb(FlEngine* engine, gpointer user_data) {
271  int* count = reinterpret_cast<int*>(user_data);
272  *count += 1;
273 }
274 
276  int* count = reinterpret_cast<int*>(user_data);
277  *count += 10;
278 }
279 
280 // Checks restarting the engine invokes the correct callback.
281 TEST(FlEngineTest, OnPreEngineRestart) {
282  FlEngine* engine = make_mock_engine();
283  FlutterEngineProcTable* embedder_api = fl_engine_get_embedder_api(engine);
284 
285  OnPreEngineRestartCallback callback;
286  void* callback_user_data;
287 
288  bool called = false;
289  embedder_api->Initialize = MOCK_ENGINE_PROC(
290  Initialize, ([&callback, &callback_user_data, &called](
291  size_t version, const FlutterRendererConfig* config,
292  const FlutterProjectArgs* args, void* user_data,
293  FLUTTER_API_SYMBOL(FlutterEngine) * engine_out) {
294  called = true;
295  callback = args->on_pre_engine_restart_callback;
296  callback_user_data = user_data;
297 
298  return kSuccess;
299  }));
300 
301  g_autoptr(GError) error = nullptr;
302  EXPECT_TRUE(fl_engine_start(engine, &error));
303  EXPECT_EQ(error, nullptr);
304 
305  EXPECT_TRUE(called);
306  EXPECT_NE(callback, nullptr);
307 
308  // The following call has no effect but should not crash.
309  callback(callback_user_data);
310 
311  int count = 0;
312 
313  // Set handler so that:
314  //
315  // * When the engine restarts, count += 1;
316  // * When the engine is freed, count += 10.
320 
321  callback(callback_user_data);
322  EXPECT_EQ(count, 1);
323 
324  // Disposal should call the destroy notify.
325  g_object_unref(engine);
326  EXPECT_EQ(count, 11);
327 }
328 
329 TEST(FlEngineTest, DartEntrypointArgs) {
330  g_autoptr(FlDartProject) project = fl_dart_project_new();
331 
332  GPtrArray* args_array = g_ptr_array_new();
333  g_ptr_array_add(args_array, const_cast<char*>("arg_one"));
334  g_ptr_array_add(args_array, const_cast<char*>("arg_two"));
335  g_ptr_array_add(args_array, const_cast<char*>("arg_three"));
336  g_ptr_array_add(args_array, nullptr);
337  gchar** args = reinterpret_cast<gchar**>(g_ptr_array_free(args_array, false));
338 
340 
341  g_autoptr(FlEngine) engine = make_mock_engine_with_project(project);
342  FlutterEngineProcTable* embedder_api = fl_engine_get_embedder_api(engine);
343 
344  bool called = false;
345  embedder_api->Initialize = MOCK_ENGINE_PROC(
346  Initialize, ([&called, &set_args = args](
347  size_t version, const FlutterRendererConfig* config,
348  const FlutterProjectArgs* args, void* user_data,
349  FLUTTER_API_SYMBOL(FlutterEngine) * engine_out) {
350  called = true;
351  EXPECT_NE(set_args, args->dart_entrypoint_argv);
352  EXPECT_EQ(args->dart_entrypoint_argc, 3);
353 
354  return kSuccess;
355  }));
356 
357  g_autoptr(GError) error = nullptr;
358  EXPECT_TRUE(fl_engine_start(engine, &error));
359  EXPECT_EQ(error, nullptr);
360 
361  EXPECT_TRUE(called);
362 }
363 
364 TEST(FlEngineTest, Locales) {
365  gchar* initial_language = g_strdup(g_getenv("LANGUAGE"));
366  g_setenv("LANGUAGE", "de:en_US", TRUE);
367  g_autoptr(FlDartProject) project = fl_dart_project_new();
368 
369  g_autoptr(FlEngine) engine = make_mock_engine_with_project(project);
370  FlutterEngineProcTable* embedder_api = fl_engine_get_embedder_api(engine);
371 
372  bool called = false;
373  embedder_api->UpdateLocales = MOCK_ENGINE_PROC(
374  UpdateLocales, ([&called](auto engine, const FlutterLocale** locales,
375  size_t locales_count) {
376  called = true;
377 
378  EXPECT_EQ(locales_count, static_cast<size_t>(4));
379 
380  EXPECT_STREQ(locales[0]->language_code, "de");
381  EXPECT_STREQ(locales[0]->country_code, nullptr);
382  EXPECT_STREQ(locales[0]->script_code, nullptr);
383  EXPECT_STREQ(locales[0]->variant_code, nullptr);
384 
385  EXPECT_STREQ(locales[1]->language_code, "en");
386  EXPECT_STREQ(locales[1]->country_code, "US");
387  EXPECT_STREQ(locales[1]->script_code, nullptr);
388  EXPECT_STREQ(locales[1]->variant_code, nullptr);
389 
390  EXPECT_STREQ(locales[2]->language_code, "en");
391  EXPECT_STREQ(locales[2]->country_code, nullptr);
392  EXPECT_STREQ(locales[2]->script_code, nullptr);
393  EXPECT_STREQ(locales[2]->variant_code, nullptr);
394 
395  EXPECT_STREQ(locales[3]->language_code, "C");
396  EXPECT_STREQ(locales[3]->country_code, nullptr);
397  EXPECT_STREQ(locales[3]->script_code, nullptr);
398  EXPECT_STREQ(locales[3]->variant_code, nullptr);
399 
400  return kSuccess;
401  }));
402 
403  g_autoptr(GError) error = nullptr;
404  EXPECT_TRUE(fl_engine_start(engine, &error));
405  EXPECT_EQ(error, nullptr);
406 
407  EXPECT_TRUE(called);
408 
409  if (initial_language) {
410  g_setenv("LANGUAGE", initial_language, TRUE);
411  } else {
412  g_unsetenv("LANGUAGE");
413  }
414  g_free(initial_language);
415 }
416 
417 TEST(FlEngineTest, SwitchesEmpty) {
418  g_autoptr(FlEngine) engine = make_mock_engine();
419 
420  // Clear the main environment variable, since test order is not guaranteed.
421  unsetenv("FLUTTER_ENGINE_SWITCHES");
422 
423  g_autoptr(GPtrArray) switches = fl_engine_get_switches(engine);
424 
425  EXPECT_EQ(switches->len, 0U);
426 }
427 
428 TEST(FlEngineTest, SendWindowStateEvent) {
429  g_autoptr(FlEngine) engine = make_mock_engine();
430  FlutterEngineProcTable* embedder_api = fl_engine_get_embedder_api(engine);
431 
432  bool called = false;
433  std::string state;
434  embedder_api->SendPlatformMessage = MOCK_ENGINE_PROC(
435  SendPlatformMessage,
436  ([&called, &state](auto engine, const FlutterPlatformMessage* message) {
437  EXPECT_STREQ(message->channel, "flutter/lifecycle");
438  called = true;
439  g_autoptr(FlStringCodec) codec = fl_string_codec_new();
440  g_autoptr(GBytes) data =
441  g_bytes_new(message->message, message->message_size);
442  g_autoptr(GError) error = nullptr;
443  g_autoptr(FlValue) parsed_state = fl_message_codec_decode_message(
444  FL_MESSAGE_CODEC(codec), data, &error);
445 
446  state = fl_value_get_string(parsed_state);
447  return kSuccess;
448  }));
450  EXPECT_STREQ(state.c_str(), flutter::AppLifecycleStateToString(
453  EXPECT_STREQ(state.c_str(), flutter::AppLifecycleStateToString(
456  EXPECT_STREQ(state.c_str(), flutter::AppLifecycleStateToString(
459  EXPECT_STREQ(state.c_str(), flutter::AppLifecycleStateToString(
461  EXPECT_TRUE(called);
462 }
463 
464 #ifndef FLUTTER_RELEASE
465 TEST(FlEngineTest, Switches) {
466  g_autoptr(FlEngine) engine = make_mock_engine();
467 
468  setenv("FLUTTER_ENGINE_SWITCHES", "2", 1);
469  setenv("FLUTTER_ENGINE_SWITCH_1", "abc", 1);
470  setenv("FLUTTER_ENGINE_SWITCH_2", "foo=\"bar, baz\"", 1);
471 
472  g_autoptr(GPtrArray) switches = fl_engine_get_switches(engine);
473  EXPECT_EQ(switches->len, 2U);
474  EXPECT_STREQ(static_cast<const char*>(g_ptr_array_index(switches, 0)),
475  "--abc");
476  EXPECT_STREQ(static_cast<const char*>(g_ptr_array_index(switches, 1)),
477  "--foo=\"bar, baz\"");
478 
479  unsetenv("FLUTTER_ENGINE_SWITCHES");
480  unsetenv("FLUTTER_ENGINE_SWITCH_1");
481  unsetenv("FLUTTER_ENGINE_SWITCH_2");
482 }
483 #endif // !FLUTTER_RELEASE
484 
485 // NOLINTEND(clang-analyzer-core.StackAddressEscape)
event
FlKeyEvent * event
Definition: fl_key_channel_responder.cc:118
flutter::AppLifecycleState::kHidden
@ kHidden
fl_engine_get_embedder_api
FlutterEngineProcTable * fl_engine_get_embedder_api(FlEngine *self)
Definition: fl_engine.cc:579
fl_engine_send_mouse_pointer_event
void fl_engine_send_mouse_pointer_event(FlEngine *self, FlutterPointerPhase phase, size_t timestamp, double x, double y, double scroll_delta_x, double scroll_delta_y, int64_t buttons)
Definition: fl_engine.cc:770
on_pre_engine_restart_destroy_notify
void on_pre_engine_restart_destroy_notify(gpointer user_data)
Definition: fl_engine_test.cc:275
fl_string_codec.h
FlValue
typedefG_BEGIN_DECLS struct _FlValue FlValue
Definition: fl_value.h:42
fl_json_message_codec_new
G_MODULE_EXPORT FlJsonMessageCodec * fl_json_message_codec_new()
Definition: fl_json_message_codec.cc:306
fl_json_message_codec.h
user_data
FlKeyEvent uint64_t FlKeyResponderAsyncCallback gpointer user_data
Definition: fl_key_channel_responder.cc:121
fl_engine_dispatch_semantics_action
void fl_engine_dispatch_semantics_action(FlEngine *self, uint64_t id, FlutterSemanticsAction action, GBytes *data)
Definition: fl_engine.cc:852
fl_engine_send_window_metrics_event
void fl_engine_send_window_metrics_event(FlEngine *self, size_t width, size_t height, double pixel_ratio)
Definition: fl_engine.cc:748
fl_dart_project_new
G_MODULE_EXPORT FlDartProject * fl_dart_project_new()
Definition: fl_dart_project.cc:50
fl_value_lookup_string
G_MODULE_EXPORT FlValue * fl_value_lookup_string(FlValue *self, const gchar *key)
Definition: fl_value.cc:811
fl_value_get_string
const G_MODULE_EXPORT gchar * fl_value_get_string(FlValue *self)
Definition: fl_value.cc:682
state
AtkStateType state
Definition: fl_accessible_node.cc:10
make_mock_engine
static FlEngine * make_mock_engine()
Definition: fl_event_channel_test.cc:24
app_lifecycle_state.h
fl_message_codec_decode_message
G_MODULE_EXPORT FlValue * fl_message_codec_decode_message(FlMessageCodec *self, GBytes *message, GError **error)
Definition: fl_message_codec.cc:33
fl_engine_send_pointer_pan_zoom_event
void fl_engine_send_pointer_pan_zoom_event(FlEngine *self, size_t timestamp, double x, double y, FlutterPointerPhase phase, double pan_x, double pan_y, double scale, double rotation)
Definition: fl_engine.cc:805
flutter::AppLifecycleState::kInactive
@ kInactive
fl_value_get_type
G_MODULE_EXPORT FlValueType fl_value_get_type(FlValue *self)
Definition: fl_value.cc:466
FL_VALUE_TYPE_STRING
@ FL_VALUE_TYPE_STRING
Definition: fl_value.h:69
fl_dart_project_set_dart_entrypoint_arguments
G_MODULE_EXPORT void fl_dart_project_set_dart_entrypoint_arguments(FlDartProject *self, char **argv)
Definition: fl_dart_project.cc:110
fl_engine_private.h
TRUE
return TRUE
Definition: fl_pixel_buffer_texture_test.cc:53
TEST
TEST(FlEngineTest, WindowMetrics)
Definition: fl_engine_test.cc:20
args
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
Definition: fl_event_channel.h:89
fl_engine.h
error
const uint8_t uint32_t uint32_t GError ** error
Definition: fl_pixel_buffer_texture_test.cc:40
flutter::AppLifecycleState::kResumed
@ kResumed
fl_engine_send_platform_message
void fl_engine_send_platform_message(FlEngine *self, const gchar *channel, GBytes *message, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
Definition: fl_engine.cc:668
on_pre_engine_restart_cb
void on_pre_engine_restart_cb(FlEngine *engine, gpointer user_data)
Definition: fl_engine_test.cc:270
fl_string_codec_new
G_MODULE_EXPORT FlStringCodec * fl_string_codec_new()
Definition: fl_string_codec.cc:53
fl_engine_start
gboolean fl_engine_start(FlEngine *self, GError **error)
Definition: fl_engine.cc:471
FL_VALUE_TYPE_FLOAT
@ FL_VALUE_TYPE_FLOAT
Definition: fl_value.h:68
fl_engine_send_window_state_event
void fl_engine_send_window_state_event(FlEngine *self, gboolean visible, gboolean focused)
Definition: fl_engine.cc:736
flutter::AppLifecycleStateToString
constexpr const char * AppLifecycleStateToString(AppLifecycleState state)
Definition: app_lifecycle_state.h:72
engine
FlEngine * engine
Definition: fl_view_accessible.cc:26
callback
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
Definition: fl_key_channel_responder.cc:120
fl_engine_get_switches
GPtrArray * fl_engine_get_switches(FlEngine *self)
Definition: fl_engine.cc:927
FL_VALUE_TYPE_BOOL
@ FL_VALUE_TYPE_BOOL
Definition: fl_value.h:66
fl_engine_send_platform_message_response
gboolean fl_engine_send_platform_message_response(FlEngine *self, const FlutterPlatformMessageResponseHandle *handle, GBytes *response, GError **error)
Definition: fl_engine.cc:636
fl_engine_set_on_pre_engine_restart_handler
void fl_engine_set_on_pre_engine_restart_handler(FlEngine *self, FlEngineOnPreEngineRestartHandler handler, gpointer user_data, GDestroyNotify destroy_notify)
Definition: fl_engine.cc:618