12 #include "flutter/shell/platform/embedder/embedder.h"
96 FlPluginRegistryInterface* iface);
106 G_IMPLEMENT_INTERFACE(fl_plugin_registry_get_type(),
117 gchar* l = g_strdup(locale);
120 gchar* match = strrchr(l,
'@');
121 if (match !=
nullptr) {
122 if (modifier !=
nullptr) {
123 *modifier = g_strdup(match + 1);
126 }
else if (modifier !=
nullptr) {
130 match = strrchr(l,
'.');
131 if (match !=
nullptr) {
132 if (codeset !=
nullptr) {
133 *codeset = g_strdup(match + 1);
136 }
else if (codeset !=
nullptr) {
140 match = strrchr(l,
'_');
141 if (match !=
nullptr) {
142 if (territory !=
nullptr) {
143 *territory = g_strdup(match + 1);
146 }
else if (territory !=
nullptr) {
147 *territory =
nullptr;
150 if (language !=
nullptr) {
156 g_autoptr(GTask) task = G_TASK(result->user_data);
159 g_task_return_boolean(task,
TRUE);
167 g_autoptr(GTask) task = G_TASK(result->user_data);
169 if (result->removed) {
170 g_task_return_boolean(task,
TRUE);
178 free(
const_cast<gchar*
>(locale->language_code));
179 free(
const_cast<gchar*
>(locale->country_code));
185 const gchar*
const* languages = g_get_language_names();
186 g_autoptr(GPtrArray) locales_array = g_ptr_array_new_with_free_func(
188 for (
int i = 0; languages[
i] !=
nullptr;
i++) {
189 g_autofree gchar* locale_string = g_strstrip(g_strdup(languages[
i]));
192 if (strcmp(locale_string,
"") == 0) {
196 g_autofree gchar* language =
nullptr;
197 g_autofree gchar* territory =
nullptr;
198 parse_locale(locale_string, &language, &territory,
nullptr,
nullptr);
202 gboolean has_locale = FALSE;
203 for (guint j = 0; !has_locale && j < locales_array->len; j++) {
204 FlutterLocale* locale =
205 reinterpret_cast<FlutterLocale*
>(g_ptr_array_index(locales_array, j));
206 has_locale = g_strcmp0(locale->language_code, language) == 0 &&
207 g_strcmp0(locale->country_code, territory) == 0;
213 FlutterLocale* locale =
214 static_cast<FlutterLocale*
>(g_malloc0(
sizeof(FlutterLocale)));
215 g_ptr_array_add(locales_array, locale);
216 locale->struct_size =
sizeof(FlutterLocale);
217 locale->language_code =
218 reinterpret_cast<const gchar*
>(g_steal_pointer(&language));
219 locale->country_code =
220 reinterpret_cast<const gchar*
>(g_steal_pointer(&territory));
221 locale->script_code =
nullptr;
222 locale->variant_code =
nullptr;
224 FlutterLocale** locales =
225 reinterpret_cast<FlutterLocale**
>(locales_array->pdata);
226 FlutterEngineResult result =
self->embedder_api.UpdateLocales(
227 self->engine,
const_cast<const FlutterLocale**
>(locales),
229 if (result != kSuccess) {
230 g_warning(
"Failed to set up Flutter locales");
236 const FlutterBackingStoreConfig* config,
237 FlutterBackingStore* backing_store_out,
239 g_return_val_if_fail(FL_IS_RENDERER(
user_data),
false);
246 const FlutterBackingStore* backing_store,
248 g_return_val_if_fail(FL_IS_RENDERER(
user_data),
false);
255 const FlutterPresentViewInfo* info) {
256 g_return_val_if_fail(FL_IS_RENDERER(info->user_data),
false);
258 info->layers, info->layers_count);
264 FlEngine*
self =
static_cast<FlEngine*
>(
user_data);
269 FlEngine*
self =
static_cast<FlEngine*
>(
user_data);
275 FlEngine*
self =
static_cast<FlEngine*
>(
user_data);
281 FlEngine*
self =
static_cast<FlEngine*
>(
user_data);
292 FlEngine*
self =
static_cast<FlEngine*
>(
user_data);
303 FlutterOpenGLTexture* opengl_texture) {
304 FlEngine*
self =
static_cast<FlEngine*
>(
user_data);
305 if (!self->texture_registrar) {
311 if (texture ==
nullptr) {
312 g_warning(
"Unable to find texture %" G_GINT64_FORMAT,
texture_id);
317 g_autoptr(GError)
error =
nullptr;
318 if (FL_IS_TEXTURE_GL(texture)) {
320 opengl_texture, &
error);
321 }
else if (FL_IS_PIXEL_BUFFER_TEXTURE(texture)) {
326 g_warning(
"Unsupported texture type %" G_GINT64_FORMAT,
texture_id);
331 g_warning(
"%s",
error->message);
340 FlEngine*
self =
static_cast<FlEngine*
>(
user_data);
341 return self->thread == g_thread_self();
346 uint64_t target_time_nanos,
348 FlEngine*
self =
static_cast<FlEngine*
>(
user_data);
358 gboolean handled = FALSE;
359 if (self->platform_message_handler !=
nullptr) {
360 g_autoptr(GBytes) data =
361 g_bytes_new(message->message, message->message_size);
362 handled =
self->platform_message_handler(
363 self, message->channel, data, message->response_handle,
364 self->platform_message_handler_data);
378 if (self->update_semantics_handler !=
nullptr) {
379 self->update_semantics_handler(
self, update,
380 self->update_semantics_handler_data);
400 g_autoptr(GTask) task = G_TASK(
user_data);
401 g_task_return_pointer(task, g_bytes_new(data, data_length),
402 reinterpret_cast<GDestroyNotify
>(g_bytes_unref));
407 FlPluginRegistry* registry,
409 FlEngine*
self = FL_ENGINE(registry);
412 self->texture_registrar);
416 FlPluginRegistryInterface* iface) {
424 FlEngine*
self = FL_ENGINE(
object);
426 case PROP_BINARY_MESSENGER:
427 g_set_object(&self->binary_messenger,
428 FL_BINARY_MESSENGER(g_value_get_object(
value)));
431 G_OBJECT_WARN_INVALID_PROPERTY_ID(
object,
prop_id,
pspec);
437 FlEngine*
self = FL_ENGINE(
object);
439 if (self->engine !=
nullptr) {
440 self->embedder_api.Shutdown(self->engine);
441 self->engine =
nullptr;
444 if (self->aot_data !=
nullptr) {
445 self->embedder_api.CollectAOTData(self->aot_data);
446 self->aot_data =
nullptr;
452 g_clear_object(&self->project);
453 g_clear_object(&self->renderer);
454 g_clear_object(&self->texture_registrar);
455 g_clear_object(&self->binary_messenger);
456 g_clear_object(&self->settings_handler);
457 g_clear_object(&self->platform_handler);
458 g_clear_object(&self->mouse_cursor_handler);
459 g_clear_object(&self->task_runner);
461 if (self->platform_message_handler_destroy_notify) {
462 self->platform_message_handler_destroy_notify(
463 self->platform_message_handler_data);
465 self->platform_message_handler_data =
nullptr;
466 self->platform_message_handler_destroy_notify =
nullptr;
468 if (self->update_semantics_handler_destroy_notify) {
469 self->update_semantics_handler_destroy_notify(
470 self->update_semantics_handler_data);
472 self->update_semantics_handler_data =
nullptr;
473 self->update_semantics_handler_destroy_notify =
nullptr;
475 G_OBJECT_CLASS(fl_engine_parent_class)->dispose(
object);
482 g_object_class_install_property(
483 G_OBJECT_CLASS(klass), PROP_BINARY_MESSENGER,
485 "binary-messenger",
"messenger",
"Binary messenger",
486 fl_binary_messenger_get_type(),
487 static_cast<GParamFlags
>(G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
488 G_PARAM_STATIC_STRINGS)));
491 "on-pre-engine-restart", fl_engine_get_type(), G_SIGNAL_RUN_LAST, 0,
492 nullptr,
nullptr,
nullptr, G_TYPE_NONE, 0);
496 self->thread = g_thread_self();
498 self->embedder_api.struct_size =
sizeof(FlutterEngineProcTable);
499 if (FlutterEngineGetProcAddresses(&self->embedder_api) != kSuccess) {
500 g_warning(
"Failed get get engine function pointers");
504 self->next_view_id = 1;
510 FlRenderer* renderer) {
511 g_return_val_if_fail(FL_IS_DART_PROJECT(project),
nullptr);
512 g_return_val_if_fail(FL_IS_RENDERER(renderer),
nullptr);
514 FlEngine*
self = FL_ENGINE(g_object_new(fl_engine_get_type(),
nullptr));
515 self->project = FL_DART_PROJECT(g_object_ref(project));
516 self->renderer = FL_RENDERER(g_object_ref(renderer));
535 g_return_val_if_fail(FL_IS_ENGINE(
self),
nullptr);
536 return self->renderer;
540 g_return_val_if_fail(FL_IS_ENGINE(
self),
nullptr);
541 return self->display_monitor;
545 g_return_val_if_fail(FL_IS_ENGINE(
self), FALSE);
549 FlutterRendererConfig config = {};
550 config.type = kOpenGL;
551 config.open_gl.struct_size =
sizeof(FlutterOpenGLRendererConfig);
558 config.open_gl.gl_external_texture_frame_callback =
561 FlutterTaskRunnerDescription platform_task_runner = {};
562 platform_task_runner.struct_size =
sizeof(FlutterTaskRunnerDescription);
563 platform_task_runner.user_data =
self;
564 platform_task_runner.runs_task_on_current_thread_callback =
569 FlutterCustomTaskRunners custom_task_runners = {};
570 custom_task_runners.struct_size =
sizeof(FlutterCustomTaskRunners);
571 custom_task_runners.platform_task_runner = &platform_task_runner;
572 custom_task_runners.render_task_runner = &platform_task_runner;
574 g_autoptr(GPtrArray) command_line_args =
575 g_ptr_array_new_with_free_func(g_free);
576 g_ptr_array_insert(command_line_args, 0, g_strdup(
"flutter"));
578 g_ptr_array_add(command_line_args, g_strdup(env_switch.c_str()));
581 gchar** dart_entrypoint_args =
584 FlutterProjectArgs
args = {};
585 args.struct_size =
sizeof(FlutterProjectArgs);
588 args.command_line_argc = command_line_args->len;
589 args.command_line_argv =
590 reinterpret_cast<const char* const*
>(command_line_args->pdata);
593 args.custom_task_runners = &custom_task_runners;
594 args.shutdown_dart_vm_when_done =
true;
596 args.dart_entrypoint_argc =
597 dart_entrypoint_args !=
nullptr ? g_strv_length(dart_entrypoint_args) : 0;
598 args.dart_entrypoint_argv =
599 reinterpret_cast<const char* const*
>(dart_entrypoint_args);
601 FlutterCompositor compositor = {};
602 compositor.struct_size =
sizeof(FlutterCompositor);
603 compositor.user_data =
self->renderer;
604 compositor.create_backing_store_callback =
606 compositor.collect_backing_store_callback =
609 args.compositor = &compositor;
611 if (self->embedder_api.RunsAOTCompiledDartCode()) {
612 FlutterEngineAOTDataSource source = {};
613 source.type = kFlutterEngineAOTDataSourceTypeElfPath;
615 if (self->embedder_api.CreateAOTData(&source, &self->aot_data) !=
618 "Failed to create AOT data");
621 args.aot_data =
self->aot_data;
624 FlutterEngineResult result =
self->embedder_api.Initialize(
625 FLUTTER_ENGINE_VERSION, &config, &
args,
self, &self->engine);
626 if (result != kSuccess) {
628 "Failed to initialize Flutter engine");
632 result =
self->embedder_api.RunInitialized(self->engine);
633 if (result != kSuccess) {
635 "Failed to run Flutter engine");
646 self->mouse_cursor_handler =
649 result =
self->embedder_api.UpdateSemanticsEnabled(self->engine,
TRUE);
650 if (result != kSuccess) {
651 g_warning(
"Failed to enable accessibility features on Flutter engine");
654 self->display_monitor =
662 return &(
self->embedder_api);
666 const FlutterEngineDisplay* displays,
667 size_t displays_length) {
668 g_return_if_fail(FL_IS_ENGINE(
self));
670 FlutterEngineResult result =
self->embedder_api.NotifyDisplayUpdate(
671 self->engine, kFlutterEngineDisplaysUpdateTypeStartup, displays,
673 if (result != kSuccess) {
674 g_warning(
"Failed to notify display update to Flutter engine: %d", result);
682 GCancellable* cancellable,
683 GAsyncReadyCallback callback,
685 g_return_val_if_fail(FL_IS_ENGINE(
self), -1);
687 g_autoptr(GTask) task = g_task_new(
self, cancellable, callback,
user_data);
689 FlutterViewId view_id =
self->next_view_id;
690 self->next_view_id++;
694 FlutterEngineDisplayId display_id = 0;
696 FlutterWindowMetricsEvent metrics;
697 metrics.struct_size =
sizeof(FlutterWindowMetricsEvent);
698 metrics.width =
width;
700 metrics.pixel_ratio = pixel_ratio;
701 metrics.display_id = display_id;
702 metrics.view_id = view_id;
703 FlutterAddViewInfo info;
704 info.struct_size =
sizeof(FlutterAddViewInfo);
705 info.view_id = view_id;
706 info.view_metrics = &metrics;
707 info.user_data = g_object_ref(task);
709 FlutterEngineResult result =
self->embedder_api.AddView(self->engine, &info);
710 if (result != kSuccess) {
715 g_object_unref(task);
722 GAsyncResult* result,
724 g_return_val_if_fail(FL_IS_ENGINE(
self), FALSE);
725 return g_task_propagate_boolean(G_TASK(result),
error);
729 FlutterViewId view_id,
730 GCancellable* cancellable,
731 GAsyncReadyCallback callback,
733 g_return_if_fail(FL_IS_ENGINE(
self));
735 g_autoptr(GTask) task = g_task_new(
self, cancellable, callback,
user_data);
737 FlutterRemoveViewInfo info;
738 info.struct_size =
sizeof(FlutterRemoveViewInfo);
739 info.view_id = view_id;
740 info.user_data = g_object_ref(task);
742 FlutterEngineResult result =
743 self->embedder_api.RemoveView(self->engine, &info);
744 if (result != kSuccess) {
749 g_object_unref(task);
754 GAsyncResult* result,
756 g_return_val_if_fail(FL_IS_ENGINE(
self), FALSE);
757 return g_task_propagate_boolean(G_TASK(result),
error);
764 GDestroyNotify destroy_notify) {
765 g_return_if_fail(FL_IS_ENGINE(
self));
766 g_return_if_fail(handler !=
nullptr);
768 if (self->platform_message_handler_destroy_notify) {
769 self->platform_message_handler_destroy_notify(
770 self->platform_message_handler_data);
773 self->platform_message_handler = handler;
774 self->platform_message_handler_data =
user_data;
775 self->platform_message_handler_destroy_notify = destroy_notify;
782 GDestroyNotify destroy_notify) {
783 g_return_if_fail(FL_IS_ENGINE(
self));
785 if (self->update_semantics_handler_destroy_notify) {
786 self->update_semantics_handler_destroy_notify(
787 self->update_semantics_handler_data);
790 self->update_semantics_handler = handler;
791 self->update_semantics_handler_data =
user_data;
792 self->update_semantics_handler_destroy_notify = destroy_notify;
798 const FlutterPlatformMessageResponseHandle* handle,
801 g_return_val_if_fail(FL_IS_ENGINE(
self), FALSE);
802 g_return_val_if_fail(handle !=
nullptr, FALSE);
804 if (self->engine ==
nullptr) {
806 "No engine to send response to");
810 gsize data_length = 0;
811 const uint8_t* data =
nullptr;
812 if (response !=
nullptr) {
814 static_cast<const uint8_t*
>(g_bytes_get_data(response, &data_length));
816 FlutterEngineResult result =
self->embedder_api.SendPlatformMessageResponse(
817 self->engine, handle, data, data_length);
819 if (result != kSuccess) {
821 "Failed to send platform message response");
829 const gchar* channel,
831 GCancellable* cancellable,
832 GAsyncReadyCallback callback,
834 g_return_if_fail(FL_IS_ENGINE(
self));
836 GTask* task =
nullptr;
837 FlutterPlatformMessageResponseHandle* response_handle =
nullptr;
838 if (callback !=
nullptr) {
839 task = g_task_new(
self, cancellable, callback,
user_data);
841 if (self->engine ==
nullptr) {
847 FlutterEngineResult result =
848 self->embedder_api.PlatformMessageCreateResponseHandle(
851 if (result != kSuccess) {
854 "Failed to create response handle");
855 g_object_unref(task);
858 }
else if (self->engine ==
nullptr) {
862 FlutterPlatformMessage fl_message = {};
863 fl_message.struct_size =
sizeof(fl_message);
864 fl_message.channel = channel;
867 ?
static_cast<const uint8_t*
>(g_bytes_get_data(message,
nullptr))
869 fl_message.message_size = message !=
nullptr ? g_bytes_get_size(message) : 0;
870 fl_message.response_handle = response_handle;
871 FlutterEngineResult result =
872 self->embedder_api.SendPlatformMessage(self->engine, &fl_message);
874 if (result != kSuccess && task !=
nullptr) {
877 "Failed to send platform messages");
878 g_object_unref(task);
881 if (response_handle !=
nullptr) {
882 self->embedder_api.PlatformMessageReleaseResponseHandle(self->engine,
888 GAsyncResult* result,
890 g_return_val_if_fail(FL_IS_ENGINE(
self), FALSE);
891 g_return_val_if_fail(g_task_is_valid(result,
self), FALSE);
893 return static_cast<GBytes*
>(g_task_propagate_pointer(G_TASK(result),
error));
897 FlutterEngineDisplayId display_id,
898 FlutterViewId view_id,
901 double pixel_ratio) {
902 g_return_if_fail(FL_IS_ENGINE(
self));
904 if (self->engine ==
nullptr) {
908 FlutterWindowMetricsEvent
event = {};
909 event.struct_size =
sizeof(FlutterWindowMetricsEvent);
912 event.pixel_ratio = pixel_ratio;
913 event.display_id = display_id;
914 event.view_id = view_id;
915 self->embedder_api.SendWindowMetricsEvent(self->engine, &event);
919 FlutterViewId view_id,
920 FlutterPointerPhase phase,
924 FlutterPointerDeviceKind device_kind,
925 double scroll_delta_x,
926 double scroll_delta_y,
928 g_return_if_fail(FL_IS_ENGINE(
self));
930 if (self->engine ==
nullptr) {
934 FlutterPointerEvent fl_event = {};
935 fl_event.struct_size =
sizeof(fl_event);
936 fl_event.phase = phase;
937 fl_event.timestamp = timestamp;
940 if (scroll_delta_x != 0 || scroll_delta_y != 0) {
941 fl_event.signal_kind = kFlutterPointerSignalKindScroll;
943 fl_event.scroll_delta_x = scroll_delta_x;
944 fl_event.scroll_delta_y = scroll_delta_y;
945 fl_event.device_kind = device_kind;
946 fl_event.buttons = buttons;
948 fl_event.view_id = view_id;
949 self->embedder_api.SendPointerEvent(self->engine, &fl_event, 1);
953 FlutterViewId view_id,
958 g_return_if_fail(FL_IS_ENGINE(
self));
960 if (self->engine ==
nullptr) {
964 FlutterPointerEvent event;
965 event.timestamp = timestamp;
968 event.device_kind = kFlutterPointerDeviceKindTouch;
969 event.device = device;
971 event.view_id = view_id;
972 event.phase = FlutterPointerPhase::kUp;
973 event.struct_size =
sizeof(event);
975 self->embedder_api.SendPointerEvent(self->engine, &event, 1);
979 FlutterViewId view_id,
984 g_return_if_fail(FL_IS_ENGINE(
self));
986 if (self->engine ==
nullptr) {
990 FlutterPointerEvent event;
991 event.timestamp = timestamp;
994 event.device_kind = kFlutterPointerDeviceKindTouch;
995 event.device = device;
996 event.buttons = FlutterPointerMouseButtons::kFlutterPointerButtonMousePrimary;
997 event.view_id = view_id;
998 event.phase = FlutterPointerPhase::kDown;
999 event.struct_size =
sizeof(event);
1001 self->embedder_api.SendPointerEvent(self->engine, &event, 1);
1005 FlutterViewId view_id,
1010 g_return_if_fail(FL_IS_ENGINE(
self));
1012 if (self->engine ==
nullptr) {
1016 FlutterPointerEvent event;
1017 event.timestamp = timestamp;
1020 event.device_kind = kFlutterPointerDeviceKindTouch;
1021 event.device = device;
1022 event.buttons = FlutterPointerMouseButtons::kFlutterPointerButtonMousePrimary;
1023 event.view_id = view_id;
1024 event.phase = FlutterPointerPhase::kMove;
1025 event.struct_size =
sizeof(event);
1027 self->embedder_api.SendPointerEvent(self->engine, &event, 1);
1031 FlutterViewId view_id,
1036 g_return_if_fail(FL_IS_ENGINE(
self));
1038 if (self->engine ==
nullptr) {
1042 FlutterPointerEvent event;
1043 event.timestamp = timestamp;
1046 event.device_kind = kFlutterPointerDeviceKindTouch;
1047 event.device = device;
1049 event.view_id = view_id;
1050 event.phase = FlutterPointerPhase::kAdd;
1051 event.struct_size =
sizeof(event);
1053 self->embedder_api.SendPointerEvent(self->engine, &event, 1);
1057 FlutterViewId view_id,
1062 g_return_if_fail(FL_IS_ENGINE(
self));
1064 if (self->engine ==
nullptr) {
1068 FlutterPointerEvent event;
1069 event.timestamp = timestamp;
1072 event.device_kind = kFlutterPointerDeviceKindTouch;
1073 event.device = device;
1075 event.view_id = view_id;
1076 event.phase = FlutterPointerPhase::kRemove;
1077 event.struct_size =
sizeof(event);
1079 self->embedder_api.SendPointerEvent(self->engine, &event, 1);
1083 FlutterViewId view_id,
1087 FlutterPointerPhase phase,
1092 g_return_if_fail(FL_IS_ENGINE(
self));
1094 if (self->engine ==
nullptr) {
1098 FlutterPointerEvent fl_event = {};
1099 fl_event.struct_size =
sizeof(fl_event);
1100 fl_event.timestamp = timestamp;
1103 fl_event.phase = phase;
1104 fl_event.pan_x = pan_x;
1105 fl_event.pan_y = pan_y;
1106 fl_event.scale = scale;
1107 fl_event.rotation = rotation;
1109 fl_event.device_kind = kFlutterPointerDeviceKindTrackpad;
1110 fl_event.view_id = view_id;
1111 self->embedder_api.SendPointerEvent(self->engine, &fl_event, 1);
1115 g_autoptr(GTask) task = G_TASK(
user_data);
1116 gboolean* return_value = g_new0(gboolean, 1);
1117 *return_value = handled;
1118 g_task_return_pointer(task, return_value, g_free);
1122 const FlutterKeyEvent* event,
1123 GCancellable* cancellable,
1124 GAsyncReadyCallback callback,
1126 g_return_if_fail(FL_IS_ENGINE(
self));
1128 g_autoptr(GTask) task = g_task_new(
self, cancellable, callback,
user_data);
1130 if (self->engine ==
nullptr) {
1137 g_object_ref(task)) != kSuccess) {
1140 g_object_unref(task);
1145 GAsyncResult* result,
1148 g_return_val_if_fail(FL_IS_ENGINE(
self), FALSE);
1149 g_return_val_if_fail(g_task_is_valid(result,
self), FALSE);
1151 g_autofree gboolean* return_value =
1152 static_cast<gboolean*
>(g_task_propagate_pointer(G_TASK(result),
error));
1153 if (return_value ==
nullptr) {
1157 *handled = *return_value;
1163 FlutterSemanticsAction action,
1165 g_return_if_fail(FL_IS_ENGINE(
self));
1167 if (self->engine ==
nullptr) {
1171 const uint8_t* action_data =
nullptr;
1172 size_t action_data_length = 0;
1173 if (data !=
nullptr) {
1174 action_data =
static_cast<const uint8_t*
>(
1175 g_bytes_get_data(data, &action_data_length));
1178 self->embedder_api.DispatchSemanticsAction(self->engine,
id, action,
1179 action_data, action_data_length);
1184 g_return_val_if_fail(FL_IS_ENGINE(
self), FALSE);
1185 return self->embedder_api.MarkExternalTextureFrameAvailable(
1191 g_return_val_if_fail(FL_IS_ENGINE(
self), FALSE);
1192 return self->embedder_api.RegisterExternalTexture(self->engine,
texture_id) ==
1198 g_return_val_if_fail(FL_IS_ENGINE(
self), FALSE);
1199 return self->embedder_api.UnregisterExternalTexture(self->engine,
1205 g_return_val_if_fail(FL_IS_ENGINE(
self),
nullptr);
1206 return self->binary_messenger;
1210 g_return_val_if_fail(FL_IS_ENGINE(
self),
nullptr);
1211 return self->task_runner;
1215 g_return_if_fail(FL_IS_ENGINE(
self));
1216 self->embedder_api.RunTask(self->engine, task);
1221 g_return_val_if_fail(FL_IS_ENGINE(
self),
nullptr);
1222 return self->texture_registrar;
1226 g_return_if_fail(FL_IS_ENGINE(
self));
1228 if (self->engine ==
nullptr) {
1232 self->embedder_api.UpdateAccessibilityFeatures(
1233 self->engine,
static_cast<FlutterAccessibilityFeature
>(
flags));
1237 g_return_if_fail(FL_IS_ENGINE(
self));
1242 g_return_val_if_fail(FL_IS_ENGINE(
self),
nullptr);
1243 return self->mouse_cursor_handler;