Flutter Linux Embedder
fl_engine_test.cc File Reference
#include "gtest/gtest.h"
#include "flutter/shell/platform/embedder/test_utils/proc_table_replacement.h"
#include "flutter/shell/platform/linux/fl_engine_private.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_engine.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_json_message_codec.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_string_codec.h"
#include "flutter/shell/platform/linux/testing/mock_renderable.h"

Go to the source code of this file.

Functions

 TEST (FlEngineTest, NotifyDisplayUpdate)
 
 TEST (FlEngineTest, WindowMetrics)
 
 TEST (FlEngineTest, MousePointer)
 
 TEST (FlEngineTest, PointerPanZoom)
 
 TEST (FlEngineTest, DispatchSemanticsAction)
 
 TEST (FlEngineTest, PlatformMessage)
 
 TEST (FlEngineTest, PlatformMessageResponse)
 
 TEST (FlEngineTest, SettingsHandler)
 
void on_pre_engine_restart_cb (FlEngine *engine, gpointer user_data)
 
 TEST (FlEngineTest, OnPreEngineRestart)
 
 TEST (FlEngineTest, DartEntrypointArgs)
 
 TEST (FlEngineTest, EngineId)
 
 TEST (FlEngineTest, UIIsolateOnPlatformTaskRunner)
 
 TEST (FlEngineTest, UIIsolateOnSeparateThread)
 
 TEST (FlEngineTest, Locales)
 
 TEST (FlEngineTest, CLocale)
 
 TEST (FlEngineTest, DuplicateLocale)
 
 TEST (FlEngineTest, EmptyLocales)
 
static void add_view_cb (GObject *object, GAsyncResult *result, gpointer user_data)
 
 TEST (FlEngineTest, AddView)
 
static void add_view_error_cb (GObject *object, GAsyncResult *result, gpointer user_data)
 
 TEST (FlEngineTest, AddViewError)
 
static void add_view_engine_error_cb (GObject *object, GAsyncResult *result, gpointer user_data)
 
 TEST (FlEngineTest, AddViewEngineError)
 
static void remove_view_cb (GObject *object, GAsyncResult *result, gpointer user_data)
 
 TEST (FlEngineTest, RemoveView)
 
static void remove_view_error_cb (GObject *object, GAsyncResult *result, gpointer user_data)
 
 TEST (FlEngineTest, RemoveViewError)
 
static void remove_view_engine_error_cb (GObject *object, GAsyncResult *result, gpointer user_data)
 
 TEST (FlEngineTest, RemoveViewEngineError)
 
 TEST (FlEngineTest, SendKeyEvent)
 
 TEST (FlEngineTest, SendKeyEventNotHandled)
 
 TEST (FlEngineTest, SendKeyEventError)
 
 TEST (FlEngineTest, ChildObjects)
 

Function Documentation

◆ add_view_cb()

static void add_view_cb ( GObject *  object,
GAsyncResult *  result,
gpointer  user_data 
)
static

Definition at line 672 of file fl_engine_test.cc.

674  {
675  g_autoptr(GError) error = nullptr;
676  gboolean r = fl_engine_add_view_finish(FL_ENGINE(object), result, &error);
677  EXPECT_TRUE(r);
678  EXPECT_EQ(error, nullptr);
679 
680  g_main_loop_quit(static_cast<GMainLoop*>(user_data));
681 }
gboolean fl_engine_add_view_finish(FlEngine *self, GAsyncResult *result, GError **error)
Definition: fl_engine.cc:931
G_BEGIN_DECLS G_MODULE_EXPORT FlValue gpointer user_data
const uint8_t uint32_t uint32_t GError ** error

References error, fl_engine_add_view_finish(), and user_data.

Referenced by TEST().

◆ add_view_engine_error_cb()

static void add_view_engine_error_cb ( GObject *  object,
GAsyncResult *  result,
gpointer  user_data 
)
static

Definition at line 755 of file fl_engine_test.cc.

757  {
758  g_autoptr(GError) error = nullptr;
759  gboolean r = fl_engine_add_view_finish(FL_ENGINE(object), result, &error);
760  EXPECT_FALSE(r);
761  EXPECT_NE(error, nullptr);
762 
763  g_main_loop_quit(static_cast<GMainLoop*>(user_data));
764 }

References error, fl_engine_add_view_finish(), and user_data.

Referenced by TEST().

◆ add_view_error_cb()

static void add_view_error_cb ( GObject *  object,
GAsyncResult *  result,
gpointer  user_data 
)
static

Definition at line 717 of file fl_engine_test.cc.

719  {
720  g_autoptr(GError) error = nullptr;
721  gboolean r = fl_engine_add_view_finish(FL_ENGINE(object), result, &error);
722  EXPECT_FALSE(r);
723  EXPECT_NE(error, nullptr);
724 
725  g_main_loop_quit(static_cast<GMainLoop*>(user_data));
726 }

References error, fl_engine_add_view_finish(), and user_data.

Referenced by TEST().

◆ on_pre_engine_restart_cb()

void on_pre_engine_restart_cb ( FlEngine *  engine,
gpointer  user_data 
)

Definition at line 334 of file fl_engine_test.cc.

334  {
335  int* count = reinterpret_cast<int*>(user_data);
336  *count += 1;
337 }

References user_data.

Referenced by TEST().

◆ remove_view_cb()

static void remove_view_cb ( GObject *  object,
GAsyncResult *  result,
gpointer  user_data 
)
static

Definition at line 787 of file fl_engine_test.cc.

789  {
790  g_autoptr(GError) error = nullptr;
791  gboolean r = fl_engine_remove_view_finish(FL_ENGINE(object), result, &error);
792  EXPECT_TRUE(r);
793  EXPECT_EQ(error, nullptr);
794 
795  g_main_loop_quit(static_cast<GMainLoop*>(user_data));
796 }
gboolean fl_engine_remove_view_finish(FlEngine *self, GAsyncResult *result, GError **error)
Definition: fl_engine.cc:973

References error, fl_engine_remove_view_finish(), and user_data.

Referenced by TEST().

◆ remove_view_engine_error_cb()

static void remove_view_engine_error_cb ( GObject *  object,
GAsyncResult *  result,
gpointer  user_data 
)
static

Definition at line 860 of file fl_engine_test.cc.

862  {
863  g_autoptr(GError) error = nullptr;
864  gboolean r = fl_engine_remove_view_finish(FL_ENGINE(object), result, &error);
865  EXPECT_FALSE(r);
866  EXPECT_NE(error, nullptr);
867 
868  g_main_loop_quit(static_cast<GMainLoop*>(user_data));
869 }

References error, fl_engine_remove_view_finish(), and user_data.

Referenced by TEST().

◆ remove_view_error_cb()

static void remove_view_error_cb ( GObject *  object,
GAsyncResult *  result,
gpointer  user_data 
)
static

Definition at line 826 of file fl_engine_test.cc.

828  {
829  g_autoptr(GError) error = nullptr;
830  gboolean r = fl_engine_remove_view_finish(FL_ENGINE(object), result, &error);
831  EXPECT_FALSE(r);
832  EXPECT_NE(error, nullptr);
833 
834  g_main_loop_quit(static_cast<GMainLoop*>(user_data));
835 }

References error, fl_engine_remove_view_finish(), and user_data.

Referenced by TEST().

◆ TEST() [1/27]

TEST ( FlEngineTest  ,
AddView   
)

Definition at line 683 of file fl_engine_test.cc.

683  {
684  g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0);
685 
686  g_autoptr(FlDartProject) project = fl_dart_project_new();
687  g_autoptr(FlEngine) engine = fl_engine_new(project);
688 
689  bool called = false;
690  fl_engine_get_embedder_api(engine)->AddView = MOCK_ENGINE_PROC(
691  AddView, ([&called](auto engine, const FlutterAddViewInfo* info) {
692  called = true;
693  EXPECT_EQ(info->view_metrics->width, 123u);
694  EXPECT_EQ(info->view_metrics->height, 456u);
695  EXPECT_EQ(info->view_metrics->pixel_ratio, 2.0);
696 
697  FlutterAddViewResult result;
698  result.struct_size = sizeof(FlutterAddViewResult);
699  result.added = true;
700  result.user_data = info->user_data;
701  info->add_view_callback(&result);
702 
703  return kSuccess;
704  }));
705 
706  g_autoptr(FlMockRenderable) renderable = fl_mock_renderable_new();
707  FlutterViewId view_id =
708  fl_engine_add_view(engine, FL_RENDERABLE(renderable), 123, 456, 2.0,
709  nullptr, add_view_cb, loop);
710  EXPECT_GT(view_id, 0);
711  EXPECT_TRUE(called);
712 
713  // Blocks here until add_view_cb is called.
714  g_main_loop_run(loop);
715 }
G_MODULE_EXPORT FlDartProject * fl_dart_project_new()
FlutterEngineProcTable * fl_engine_get_embedder_api(FlEngine *self)
Definition: fl_engine.cc:858
FlutterViewId fl_engine_add_view(FlEngine *self, FlRenderable *renderable, size_t width, size_t height, double pixel_ratio, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
Definition: fl_engine.cc:882
G_MODULE_EXPORT FlEngine * fl_engine_new(FlDartProject *project)
Definition: fl_engine.cc:691
static void add_view_cb(GObject *object, GAsyncResult *result, gpointer user_data)
G_BEGIN_DECLS FlutterViewId view_id

References add_view_cb(), fl_dart_project_new(), fl_engine_add_view(), fl_engine_get_embedder_api(), fl_engine_new(), and view_id.

◆ TEST() [2/27]

TEST ( FlEngineTest  ,
AddViewEngineError   
)

Definition at line 766 of file fl_engine_test.cc.

766  {
767  g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0);
768 
769  g_autoptr(FlDartProject) project = fl_dart_project_new();
770  g_autoptr(FlEngine) engine = fl_engine_new(project);
771 
772  fl_engine_get_embedder_api(engine)->AddView = MOCK_ENGINE_PROC(
773  AddView, ([](auto engine, const FlutterAddViewInfo* info) {
774  return kInvalidArguments;
775  }));
776 
777  g_autoptr(FlMockRenderable) renderable = fl_mock_renderable_new();
778  FlutterViewId view_id =
779  fl_engine_add_view(engine, FL_RENDERABLE(renderable), 123, 456, 2.0,
780  nullptr, add_view_engine_error_cb, loop);
781  EXPECT_GT(view_id, 0);
782 
783  // Blocks here until remove_view_engine_error_cb is called.
784  g_main_loop_run(loop);
785 }
static void add_view_engine_error_cb(GObject *object, GAsyncResult *result, gpointer user_data)

References add_view_engine_error_cb(), fl_dart_project_new(), fl_engine_add_view(), fl_engine_get_embedder_api(), fl_engine_new(), and view_id.

◆ TEST() [3/27]

TEST ( FlEngineTest  ,
AddViewError   
)

Definition at line 728 of file fl_engine_test.cc.

728  {
729  g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0);
730 
731  g_autoptr(FlDartProject) project = fl_dart_project_new();
732  g_autoptr(FlEngine) engine = fl_engine_new(project);
733 
734  fl_engine_get_embedder_api(engine)->AddView = MOCK_ENGINE_PROC(
735  AddView, ([](auto engine, const FlutterAddViewInfo* info) {
736  FlutterAddViewResult result;
737  result.struct_size = sizeof(FlutterAddViewResult);
738  result.added = false;
739  result.user_data = info->user_data;
740  info->add_view_callback(&result);
741 
742  return kSuccess;
743  }));
744 
745  g_autoptr(FlMockRenderable) renderable = fl_mock_renderable_new();
746  FlutterViewId view_id =
747  fl_engine_add_view(engine, FL_RENDERABLE(renderable), 123, 456, 2.0,
748  nullptr, add_view_error_cb, loop);
749  EXPECT_GT(view_id, 0);
750 
751  // Blocks here until add_view_error_cb is called.
752  g_main_loop_run(loop);
753 }
static void add_view_error_cb(GObject *object, GAsyncResult *result, gpointer user_data)

References add_view_error_cb(), fl_dart_project_new(), fl_engine_add_view(), fl_engine_get_embedder_api(), fl_engine_new(), and view_id.

◆ TEST() [4/27]

TEST ( FlEngineTest  ,
ChildObjects   
)

Definition at line 1029 of file fl_engine_test.cc.

1029  {
1030  g_autoptr(FlDartProject) project = fl_dart_project_new();
1031  g_autoptr(FlEngine) engine = fl_engine_new(project);
1032 
1033  // Check objects exist before engine started.
1034  EXPECT_NE(fl_engine_get_binary_messenger(engine), nullptr);
1035  EXPECT_NE(fl_engine_get_display_monitor(engine), nullptr);
1036  EXPECT_NE(fl_engine_get_task_runner(engine), nullptr);
1037  EXPECT_NE(fl_engine_get_keyboard_manager(engine), nullptr);
1038  EXPECT_NE(fl_engine_get_mouse_cursor_handler(engine), nullptr);
1039  EXPECT_NE(fl_engine_get_windowing_handler(engine), nullptr);
1040 }
FlMouseCursorHandler * fl_engine_get_mouse_cursor_handler(FlEngine *self)
Definition: fl_engine.cc:1466
FlWindowingHandler * fl_engine_get_windowing_handler(FlEngine *self)
Definition: fl_engine.cc:1451
FlTaskRunner * fl_engine_get_task_runner(FlEngine *self)
Definition: fl_engine.cc:1419
FlKeyboardManager * fl_engine_get_keyboard_manager(FlEngine *self)
Definition: fl_engine.cc:1456
FlDisplayMonitor * fl_engine_get_display_monitor(FlEngine *self)
Definition: fl_engine.cc:715
G_MODULE_EXPORT FlBinaryMessenger * fl_engine_get_binary_messenger(FlEngine *self)
Definition: fl_engine.cc:1413

References fl_dart_project_new(), fl_engine_get_binary_messenger(), fl_engine_get_display_monitor(), fl_engine_get_keyboard_manager(), fl_engine_get_mouse_cursor_handler(), fl_engine_get_task_runner(), fl_engine_get_windowing_handler(), and fl_engine_new().

◆ TEST() [5/27]

TEST ( FlEngineTest  ,
CLocale   
)

Definition at line 544 of file fl_engine_test.cc.

544  {
545  g_autofree gchar* initial_language = g_strdup(g_getenv("LANGUAGE"));
546  g_setenv("LANGUAGE", "C", TRUE);
547  g_autoptr(FlDartProject) project = fl_dart_project_new();
548 
549  g_autoptr(FlEngine) engine = fl_engine_new(project);
550 
551  bool called = false;
552  fl_engine_get_embedder_api(engine)->UpdateLocales = MOCK_ENGINE_PROC(
553  UpdateLocales, ([&called](auto engine, const FlutterLocale** locales,
554  size_t locales_count) {
555  called = true;
556 
557  EXPECT_EQ(locales_count, static_cast<size_t>(1));
558 
559  EXPECT_STREQ(locales[0]->language_code, "C");
560  EXPECT_STREQ(locales[0]->country_code, nullptr);
561  EXPECT_STREQ(locales[0]->script_code, nullptr);
562  EXPECT_STREQ(locales[0]->variant_code, nullptr);
563 
564  return kSuccess;
565  }));
566 
567  g_autoptr(GError) error = nullptr;
568  EXPECT_TRUE(fl_engine_start(engine, &error));
569  EXPECT_EQ(error, nullptr);
570 
571  EXPECT_TRUE(called);
572 
573  if (initial_language) {
574  g_setenv("LANGUAGE", initial_language, TRUE);
575  } else {
576  g_unsetenv("LANGUAGE");
577  }
578 }
gboolean fl_engine_start(FlEngine *self, GError **error)
Definition: fl_engine.cc:720

References error, fl_dart_project_new(), fl_engine_get_embedder_api(), fl_engine_new(), fl_engine_start(), and TRUE.

◆ TEST() [6/27]

TEST ( FlEngineTest  ,
DartEntrypointArgs   
)

Definition at line 385 of file fl_engine_test.cc.

385  {
386  GPtrArray* args_array = g_ptr_array_new();
387  g_ptr_array_add(args_array, const_cast<char*>("arg_one"));
388  g_ptr_array_add(args_array, const_cast<char*>("arg_two"));
389  g_ptr_array_add(args_array, const_cast<char*>("arg_three"));
390  g_ptr_array_add(args_array, nullptr);
391  gchar** args = reinterpret_cast<gchar**>(g_ptr_array_free(args_array, false));
392 
393  g_autoptr(FlDartProject) project = fl_dart_project_new();
395  g_autoptr(FlEngine) engine = fl_engine_new(project);
396 
397  bool called = false;
398  fl_engine_get_embedder_api(engine)->Initialize = MOCK_ENGINE_PROC(
399  Initialize, ([&called, &set_args = args](
400  size_t version, const FlutterRendererConfig* config,
401  const FlutterProjectArgs* args, void* user_data,
402  FLUTTER_API_SYMBOL(FlutterEngine) * engine_out) {
403  called = true;
404  EXPECT_NE(set_args, args->dart_entrypoint_argv);
405  EXPECT_EQ(args->dart_entrypoint_argc, 3);
406 
407  return kSuccess;
408  }));
409  fl_engine_get_embedder_api(engine)->RunInitialized =
410  MOCK_ENGINE_PROC(RunInitialized, ([](auto engine) { return kSuccess; }));
411 
412  g_autoptr(GError) error = nullptr;
413  EXPECT_TRUE(fl_engine_start(engine, &error));
414  EXPECT_EQ(error, nullptr);
415 
416  EXPECT_TRUE(called);
417 }
G_MODULE_EXPORT void fl_dart_project_set_dart_entrypoint_arguments(FlDartProject *self, char **argv)
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args

References args, error, fl_dart_project_new(), fl_dart_project_set_dart_entrypoint_arguments(), fl_engine_get_embedder_api(), fl_engine_new(), fl_engine_start(), and user_data.

◆ TEST() [7/27]

TEST ( FlEngineTest  ,
DispatchSemanticsAction   
)

Definition at line 179 of file fl_engine_test.cc.

179  {
180  g_autoptr(FlDartProject) project = fl_dart_project_new();
181  g_autoptr(FlEngine) engine = fl_engine_new(project);
182 
183  bool called = false;
184  fl_engine_get_embedder_api(engine)->SendSemanticsAction = MOCK_ENGINE_PROC(
185  SendSemanticsAction,
186  ([&called](auto engine, const FlutterSendSemanticsActionInfo* info) {
187  EXPECT_EQ(info->view_id, static_cast<int64_t>(456));
188  EXPECT_EQ(info->node_id, static_cast<uint64_t>(42));
189  EXPECT_EQ(info->action, kFlutterSemanticsActionTap);
190  EXPECT_EQ(info->data_length, static_cast<size_t>(4));
191  EXPECT_EQ(info->data[0], 't');
192  EXPECT_EQ(info->data[1], 'e');
193  EXPECT_EQ(info->data[2], 's');
194  EXPECT_EQ(info->data[3], 't');
195  called = true;
196 
197  return kSuccess;
198  }));
199 
200  g_autoptr(GError) error = nullptr;
201  EXPECT_TRUE(fl_engine_start(engine, &error));
202  EXPECT_EQ(error, nullptr);
203  g_autoptr(GBytes) data = g_bytes_new_static("test", 4);
204  fl_engine_dispatch_semantics_action(engine, 456, 42,
205  kFlutterSemanticsActionTap, data);
206 
207  EXPECT_TRUE(called);
208 }
void fl_engine_dispatch_semantics_action(FlEngine *self, FlutterViewId view_id, uint64_t node_id, FlutterSemanticsAction action, GBytes *data)
Definition: fl_engine.cc:1364

References error, fl_dart_project_new(), fl_engine_dispatch_semantics_action(), fl_engine_get_embedder_api(), fl_engine_new(), and fl_engine_start().

◆ TEST() [8/27]

TEST ( FlEngineTest  ,
DuplicateLocale   
)

Definition at line 580 of file fl_engine_test.cc.

580  {
581  g_autofree gchar* initial_language = g_strdup(g_getenv("LANGUAGE"));
582  g_setenv("LANGUAGE", "en:en", TRUE);
583  g_autoptr(FlDartProject) project = fl_dart_project_new();
584 
585  g_autoptr(FlEngine) engine = fl_engine_new(project);
586 
587  bool called = false;
588  fl_engine_get_embedder_api(engine)->UpdateLocales = MOCK_ENGINE_PROC(
589  UpdateLocales, ([&called](auto engine, const FlutterLocale** locales,
590  size_t locales_count) {
591  called = true;
592 
593  EXPECT_EQ(locales_count, static_cast<size_t>(2));
594 
595  EXPECT_STREQ(locales[0]->language_code, "en");
596  EXPECT_STREQ(locales[0]->country_code, nullptr);
597  EXPECT_STREQ(locales[0]->script_code, nullptr);
598  EXPECT_STREQ(locales[0]->variant_code, nullptr);
599 
600  EXPECT_STREQ(locales[1]->language_code, "C");
601  EXPECT_STREQ(locales[1]->country_code, nullptr);
602  EXPECT_STREQ(locales[1]->script_code, nullptr);
603  EXPECT_STREQ(locales[1]->variant_code, nullptr);
604 
605  return kSuccess;
606  }));
607 
608  g_autoptr(GError) error = nullptr;
609  EXPECT_TRUE(fl_engine_start(engine, &error));
610  EXPECT_EQ(error, nullptr);
611 
612  EXPECT_TRUE(called);
613 
614  if (initial_language) {
615  g_setenv("LANGUAGE", initial_language, TRUE);
616  } else {
617  g_unsetenv("LANGUAGE");
618  }
619 }

References error, fl_dart_project_new(), fl_engine_get_embedder_api(), fl_engine_new(), fl_engine_start(), and TRUE.

◆ TEST() [9/27]

TEST ( FlEngineTest  ,
EmptyLocales   
)

Definition at line 621 of file fl_engine_test.cc.

621  {
622  g_autofree gchar* initial_language = g_strdup(g_getenv("LANGUAGE"));
623  g_setenv("LANGUAGE", "de:: :en_US", TRUE);
624  g_autoptr(FlDartProject) project = fl_dart_project_new();
625 
626  g_autoptr(FlEngine) engine = fl_engine_new(project);
627 
628  bool called = false;
629  fl_engine_get_embedder_api(engine)->UpdateLocales = MOCK_ENGINE_PROC(
630  UpdateLocales, ([&called](auto engine, const FlutterLocale** locales,
631  size_t locales_count) {
632  called = true;
633 
634  EXPECT_EQ(locales_count, static_cast<size_t>(4));
635 
636  EXPECT_STREQ(locales[0]->language_code, "de");
637  EXPECT_STREQ(locales[0]->country_code, nullptr);
638  EXPECT_STREQ(locales[0]->script_code, nullptr);
639  EXPECT_STREQ(locales[0]->variant_code, nullptr);
640 
641  EXPECT_STREQ(locales[1]->language_code, "en");
642  EXPECT_STREQ(locales[1]->country_code, "US");
643  EXPECT_STREQ(locales[1]->script_code, nullptr);
644  EXPECT_STREQ(locales[1]->variant_code, nullptr);
645 
646  EXPECT_STREQ(locales[2]->language_code, "en");
647  EXPECT_STREQ(locales[2]->country_code, nullptr);
648  EXPECT_STREQ(locales[2]->script_code, nullptr);
649  EXPECT_STREQ(locales[2]->variant_code, nullptr);
650 
651  EXPECT_STREQ(locales[3]->language_code, "C");
652  EXPECT_STREQ(locales[3]->country_code, nullptr);
653  EXPECT_STREQ(locales[3]->script_code, nullptr);
654  EXPECT_STREQ(locales[3]->variant_code, nullptr);
655 
656  return kSuccess;
657  }));
658 
659  g_autoptr(GError) error = nullptr;
660  EXPECT_TRUE(fl_engine_start(engine, &error));
661  EXPECT_EQ(error, nullptr);
662 
663  EXPECT_TRUE(called);
664 
665  if (initial_language) {
666  g_setenv("LANGUAGE", initial_language, TRUE);
667  } else {
668  g_unsetenv("LANGUAGE");
669  }
670 }

References error, fl_dart_project_new(), fl_engine_get_embedder_api(), fl_engine_new(), fl_engine_start(), and TRUE.

◆ TEST() [10/27]

TEST ( FlEngineTest  ,
EngineId   
)

Definition at line 419 of file fl_engine_test.cc.

419  {
420  g_autoptr(FlDartProject) project = fl_dart_project_new();
421  g_autoptr(FlEngine) engine = fl_engine_new(project);
422  int64_t engine_id;
423  fl_engine_get_embedder_api(engine)->Initialize = MOCK_ENGINE_PROC(
424  Initialize,
425  ([&engine_id](size_t version, const FlutterRendererConfig* config,
426  const FlutterProjectArgs* args, void* user_data,
427  FLUTTER_API_SYMBOL(FlutterEngine) * engine_out) {
428  engine_id = args->engine_id;
429  return kSuccess;
430  }));
431  fl_engine_get_embedder_api(engine)->RunInitialized =
432  MOCK_ENGINE_PROC(RunInitialized, ([](auto engine) { return kSuccess; }));
433 
434  g_autoptr(GError) error = nullptr;
435  EXPECT_TRUE(fl_engine_start(engine, &error));
436  EXPECT_EQ(error, nullptr);
437  EXPECT_TRUE(engine_id != 0);
438 
439  EXPECT_EQ(fl_engine_for_id(engine_id), engine);
440 }
FlEngine * fl_engine_for_id(int64_t id)
Definition: fl_engine.cc:685

References args, error, fl_dart_project_new(), fl_engine_for_id(), fl_engine_get_embedder_api(), fl_engine_new(), fl_engine_start(), and user_data.

◆ TEST() [11/27]

TEST ( FlEngineTest  ,
Locales   
)

Definition at line 493 of file fl_engine_test.cc.

493  {
494  g_autofree gchar* initial_language = g_strdup(g_getenv("LANGUAGE"));
495  g_setenv("LANGUAGE", "de:en_US", TRUE);
496  g_autoptr(FlDartProject) project = fl_dart_project_new();
497 
498  g_autoptr(FlEngine) engine = fl_engine_new(project);
499 
500  bool called = false;
501  fl_engine_get_embedder_api(engine)->UpdateLocales = MOCK_ENGINE_PROC(
502  UpdateLocales, ([&called](auto engine, const FlutterLocale** locales,
503  size_t locales_count) {
504  called = true;
505 
506  EXPECT_EQ(locales_count, static_cast<size_t>(4));
507 
508  EXPECT_STREQ(locales[0]->language_code, "de");
509  EXPECT_STREQ(locales[0]->country_code, nullptr);
510  EXPECT_STREQ(locales[0]->script_code, nullptr);
511  EXPECT_STREQ(locales[0]->variant_code, nullptr);
512 
513  EXPECT_STREQ(locales[1]->language_code, "en");
514  EXPECT_STREQ(locales[1]->country_code, "US");
515  EXPECT_STREQ(locales[1]->script_code, nullptr);
516  EXPECT_STREQ(locales[1]->variant_code, nullptr);
517 
518  EXPECT_STREQ(locales[2]->language_code, "en");
519  EXPECT_STREQ(locales[2]->country_code, nullptr);
520  EXPECT_STREQ(locales[2]->script_code, nullptr);
521  EXPECT_STREQ(locales[2]->variant_code, nullptr);
522 
523  EXPECT_STREQ(locales[3]->language_code, "C");
524  EXPECT_STREQ(locales[3]->country_code, nullptr);
525  EXPECT_STREQ(locales[3]->script_code, nullptr);
526  EXPECT_STREQ(locales[3]->variant_code, nullptr);
527 
528  return kSuccess;
529  }));
530 
531  g_autoptr(GError) error = nullptr;
532  EXPECT_TRUE(fl_engine_start(engine, &error));
533  EXPECT_EQ(error, nullptr);
534 
535  EXPECT_TRUE(called);
536 
537  if (initial_language) {
538  g_setenv("LANGUAGE", initial_language, TRUE);
539  } else {
540  g_unsetenv("LANGUAGE");
541  }
542 }

References error, fl_dart_project_new(), fl_engine_get_embedder_api(), fl_engine_new(), fl_engine_start(), and TRUE.

◆ TEST() [12/27]

TEST ( FlEngineTest  ,
MousePointer   
)

Definition at line 104 of file fl_engine_test.cc.

104  {
105  g_autoptr(FlDartProject) project = fl_dart_project_new();
106  g_autoptr(FlEngine) engine = fl_engine_new(project);
107 
108  bool called = false;
109  fl_engine_get_embedder_api(engine)->SendPointerEvent = MOCK_ENGINE_PROC(
110  SendPointerEvent,
111  ([&called](auto engine, const FlutterPointerEvent* events,
112  size_t events_count) {
113  called = true;
114  EXPECT_EQ(events_count, static_cast<size_t>(1));
115  EXPECT_EQ(events[0].view_id, 1);
116  EXPECT_EQ(events[0].phase, kDown);
117  EXPECT_EQ(events[0].timestamp, static_cast<size_t>(1234567890));
118  EXPECT_EQ(events[0].x, 800);
119  EXPECT_EQ(events[0].y, 600);
120  EXPECT_EQ(events[0].device, static_cast<int32_t>(0));
121  EXPECT_EQ(events[0].signal_kind, kFlutterPointerSignalKindScroll);
122  EXPECT_EQ(events[0].scroll_delta_x, 1.2);
123  EXPECT_EQ(events[0].scroll_delta_y, -3.4);
124  EXPECT_EQ(events[0].device_kind, kFlutterPointerDeviceKindMouse);
125  EXPECT_EQ(events[0].buttons, kFlutterPointerButtonMouseSecondary);
126 
127  return kSuccess;
128  }));
129 
130  g_autoptr(GError) error = nullptr;
131  EXPECT_TRUE(fl_engine_start(engine, &error));
132  EXPECT_EQ(error, nullptr);
133  fl_engine_send_mouse_pointer_event(engine, 1, kDown, 1234567890, 800, 600,
134  kFlutterPointerDeviceKindMouse, 1.2, -3.4,
135  kFlutterPointerButtonMouseSecondary);
136 
137  EXPECT_TRUE(called);
138 }
void fl_engine_send_mouse_pointer_event(FlEngine *self, FlutterViewId view_id, FlutterPointerPhase phase, size_t timestamp, double x, double y, FlutterPointerDeviceKind device_kind, double scroll_delta_x, double scroll_delta_y, int64_t buttons)
Definition: fl_engine.cc:1121

References error, fl_dart_project_new(), fl_engine_get_embedder_api(), fl_engine_new(), fl_engine_send_mouse_pointer_event(), fl_engine_start(), and view_id.

◆ TEST() [13/27]

TEST ( FlEngineTest  ,
NotifyDisplayUpdate   
)

Definition at line 19 of file fl_engine_test.cc.

19  {
20  g_autoptr(FlDartProject) project = fl_dart_project_new();
21  g_autoptr(FlEngine) engine = fl_engine_new(project);
22 
23  g_autoptr(GError) error = nullptr;
24  EXPECT_TRUE(fl_engine_start(engine, &error));
25  EXPECT_EQ(error, nullptr);
26 
27  bool called = false;
28  fl_engine_get_embedder_api(engine)->NotifyDisplayUpdate = MOCK_ENGINE_PROC(
29  NotifyDisplayUpdate,
30  ([&called](auto engine, FlutterEngineDisplaysUpdateType update_type,
31  const FlutterEngineDisplay* displays, size_t displays_length) {
32  called = true;
33  EXPECT_EQ(update_type, kFlutterEngineDisplaysUpdateTypeStartup);
34  EXPECT_EQ(displays_length, 2u);
35 
36  EXPECT_EQ(displays[0].display_id, 1u);
37  EXPECT_EQ(displays[0].refresh_rate, 60);
38  EXPECT_EQ(displays[0].width, 1024u);
39  EXPECT_EQ(displays[0].height, 768u);
40  EXPECT_EQ(displays[0].device_pixel_ratio, 1.0);
41 
42  EXPECT_EQ(displays[1].display_id, 2u);
43  EXPECT_EQ(displays[1].refresh_rate, 120);
44  EXPECT_EQ(displays[1].width, 3840u);
45  EXPECT_EQ(displays[1].height, 2160u);
46  EXPECT_EQ(displays[1].device_pixel_ratio, 2.0);
47 
48  return kSuccess;
49  }));
50 
51  FlutterEngineDisplay displays[2] = {
52  {
53  .struct_size = sizeof(FlutterEngineDisplay),
54  .display_id = 1,
55  .single_display = false,
56  .refresh_rate = 60.0,
57  .width = 1024,
58  .height = 768,
59  .device_pixel_ratio = 1.0,
60  },
61  {
62  .struct_size = sizeof(FlutterEngineDisplay),
63  .display_id = 2,
64  .single_display = false,
65  .refresh_rate = 120.0,
66  .width = 3840,
67  .height = 2160,
68  .device_pixel_ratio = 2.0,
69  }};
70  fl_engine_notify_display_update(engine, displays, 2);
71 
72  EXPECT_TRUE(called);
73 }
void fl_engine_notify_display_update(FlEngine *self, const FlutterEngineDisplay *displays, size_t displays_length)
Definition: fl_engine.cc:862
const uint8_t uint32_t uint32_t * height
const uint8_t uint32_t * width

References error, fl_dart_project_new(), fl_engine_get_embedder_api(), fl_engine_new(), fl_engine_notify_display_update(), fl_engine_start(), height, and width.

◆ TEST() [14/27]

TEST ( FlEngineTest  ,
OnPreEngineRestart   
)

Definition at line 340 of file fl_engine_test.cc.

340  {
341  g_autoptr(FlDartProject) project = fl_dart_project_new();
342  g_autoptr(FlEngine) engine = fl_engine_new(project);
343 
344  OnPreEngineRestartCallback callback;
345  void* callback_user_data;
346 
347  bool called = false;
348  fl_engine_get_embedder_api(engine)->Initialize = MOCK_ENGINE_PROC(
349  Initialize, ([&callback, &callback_user_data, &called](
350  size_t version, const FlutterRendererConfig* config,
351  const FlutterProjectArgs* args, void* user_data,
352  FLUTTER_API_SYMBOL(FlutterEngine) * engine_out) {
353  called = true;
354  callback = args->on_pre_engine_restart_callback;
355  callback_user_data = user_data;
356 
357  return kSuccess;
358  }));
359  fl_engine_get_embedder_api(engine)->RunInitialized =
360  MOCK_ENGINE_PROC(RunInitialized, ([](auto engine) { return kSuccess; }));
361 
362  g_autoptr(GError) error = nullptr;
363  EXPECT_TRUE(fl_engine_start(engine, &error));
364  EXPECT_EQ(error, nullptr);
365 
366  EXPECT_TRUE(called);
367  EXPECT_NE(callback, nullptr);
368 
369  // The following call has no effect but should not crash.
370  callback(callback_user_data);
371 
372  int count = 0;
373 
374  // Set handler so that:
375  //
376  // * When the engine restarts, count += 1;
377  // * When the engine is freed, count += 10.
378  g_signal_connect(engine, "on-pre-engine-restart",
379  G_CALLBACK(on_pre_engine_restart_cb), &count);
380 
381  callback(callback_user_data);
382  EXPECT_EQ(count, 1);
383 }
void on_pre_engine_restart_cb(FlEngine *engine, gpointer user_data)

References args, error, fl_dart_project_new(), fl_engine_get_embedder_api(), fl_engine_new(), fl_engine_start(), on_pre_engine_restart_cb(), and user_data.

◆ TEST() [15/27]

TEST ( FlEngineTest  ,
PlatformMessage   
)

Definition at line 211 of file fl_engine_test.cc.

211  {
212  g_autoptr(FlDartProject) project = fl_dart_project_new();
213  g_autoptr(FlEngine) engine = fl_engine_new(project);
214 
215  bool called = false;
216  FlutterEngineSendPlatformMessageFnPtr old_handler =
217  fl_engine_get_embedder_api(engine)->SendPlatformMessage;
218  fl_engine_get_embedder_api(engine)->SendPlatformMessage = MOCK_ENGINE_PROC(
219  SendPlatformMessage,
220  ([&called, old_handler](auto engine,
221  const FlutterPlatformMessage* message) {
222  if (strcmp(message->channel, "test") != 0) {
223  return old_handler(engine, message);
224  }
225 
226  called = true;
227 
228  EXPECT_EQ(message->message_size, static_cast<size_t>(4));
229  EXPECT_EQ(message->message[0], 't');
230  EXPECT_EQ(message->message[1], 'e');
231  EXPECT_EQ(message->message[2], 's');
232  EXPECT_EQ(message->message[3], 't');
233 
234  return kSuccess;
235  }));
236 
237  g_autoptr(GError) error = nullptr;
238  EXPECT_TRUE(fl_engine_start(engine, &error));
239  EXPECT_EQ(error, nullptr);
240  g_autoptr(GBytes) message = g_bytes_new_static("test", 4);
241  fl_engine_send_platform_message(engine, "test", message, nullptr, nullptr,
242  nullptr);
243 
244  EXPECT_TRUE(called);
245 }
void fl_engine_send_platform_message(FlEngine *self, const gchar *channel, GBytes *message, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
Definition: fl_engine.cc:1031

References error, fl_dart_project_new(), fl_engine_get_embedder_api(), fl_engine_new(), fl_engine_send_platform_message(), and fl_engine_start().

◆ TEST() [16/27]

TEST ( FlEngineTest  ,
PlatformMessageResponse   
)

Definition at line 248 of file fl_engine_test.cc.

248  {
249  g_autoptr(FlDartProject) project = fl_dart_project_new();
250  g_autoptr(FlEngine) engine = fl_engine_new(project);
251 
252  bool called = false;
253  fl_engine_get_embedder_api(engine)->SendPlatformMessageResponse =
254  MOCK_ENGINE_PROC(
255  SendPlatformMessageResponse,
256  ([&called](auto engine,
257  const FlutterPlatformMessageResponseHandle* handle,
258  const uint8_t* data, size_t data_length) {
259  called = true;
260 
261  EXPECT_EQ(
262  handle,
263  reinterpret_cast<const FlutterPlatformMessageResponseHandle*>(
264  42));
265  EXPECT_EQ(data_length, static_cast<size_t>(4));
266  EXPECT_EQ(data[0], 't');
267  EXPECT_EQ(data[1], 'e');
268  EXPECT_EQ(data[2], 's');
269  EXPECT_EQ(data[3], 't');
270 
271  return kSuccess;
272  }));
273 
274  g_autoptr(GError) error = nullptr;
275  EXPECT_TRUE(fl_engine_start(engine, &error));
276  EXPECT_EQ(error, nullptr);
277  g_autoptr(GBytes) response = g_bytes_new_static("test", 4);
279  engine, reinterpret_cast<const FlutterPlatformMessageResponseHandle*>(42),
280  response, &error));
281  EXPECT_EQ(error, nullptr);
282 
283  EXPECT_TRUE(called);
284 }
gboolean fl_engine_send_platform_message_response(FlEngine *self, const FlutterPlatformMessageResponseHandle *handle, GBytes *response, GError **error)
Definition: fl_engine.cc:999

References error, fl_dart_project_new(), fl_engine_get_embedder_api(), fl_engine_new(), fl_engine_send_platform_message_response(), and fl_engine_start().

◆ TEST() [17/27]

TEST ( FlEngineTest  ,
PointerPanZoom   
)

Definition at line 141 of file fl_engine_test.cc.

141  {
142  g_autoptr(FlDartProject) project = fl_dart_project_new();
143  g_autoptr(FlEngine) engine = fl_engine_new(project);
144 
145  bool called = false;
146  fl_engine_get_embedder_api(engine)->SendPointerEvent = MOCK_ENGINE_PROC(
147  SendPointerEvent,
148  ([&called](auto engine, const FlutterPointerEvent* events,
149  size_t events_count) {
150  called = true;
151  EXPECT_EQ(events_count, static_cast<size_t>(1));
152  EXPECT_EQ(events[0].view_id, 1);
153  EXPECT_EQ(events[0].phase, kPanZoomUpdate);
154  EXPECT_EQ(events[0].timestamp, static_cast<size_t>(1234567890));
155  EXPECT_EQ(events[0].x, 800);
156  EXPECT_EQ(events[0].y, 600);
157  EXPECT_EQ(events[0].device, static_cast<int32_t>(1));
158  EXPECT_EQ(events[0].signal_kind, kFlutterPointerSignalKindNone);
159  EXPECT_EQ(events[0].pan_x, 1.5);
160  EXPECT_EQ(events[0].pan_y, 2.5);
161  EXPECT_EQ(events[0].scale, 3.5);
162  EXPECT_EQ(events[0].rotation, 4.5);
163  EXPECT_EQ(events[0].device_kind, kFlutterPointerDeviceKindTrackpad);
164  EXPECT_EQ(events[0].buttons, 0);
165 
166  return kSuccess;
167  }));
168 
169  g_autoptr(GError) error = nullptr;
170  EXPECT_TRUE(fl_engine_start(engine, &error));
171  EXPECT_EQ(error, nullptr);
172  fl_engine_send_pointer_pan_zoom_event(engine, 1, 1234567890, 800, 600,
173  kPanZoomUpdate, 1.5, 2.5, 3.5, 4.5);
174 
175  EXPECT_TRUE(called);
176 }
void fl_engine_send_pointer_pan_zoom_event(FlEngine *self, FlutterViewId view_id, size_t timestamp, double x, double y, FlutterPointerPhase phase, double pan_x, double pan_y, double scale, double rotation)
Definition: fl_engine.cc:1285

References error, fl_dart_project_new(), fl_engine_get_embedder_api(), fl_engine_new(), fl_engine_send_pointer_pan_zoom_event(), fl_engine_start(), and view_id.

◆ TEST() [18/27]

TEST ( FlEngineTest  ,
RemoveView   
)

Definition at line 798 of file fl_engine_test.cc.

798  {
799  g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0);
800 
801  g_autoptr(FlDartProject) project = fl_dart_project_new();
802  g_autoptr(FlEngine) engine = fl_engine_new(project);
803 
804  bool called = false;
805  fl_engine_get_embedder_api(engine)->RemoveView = MOCK_ENGINE_PROC(
806  RemoveView, ([&called](auto engine, const FlutterRemoveViewInfo* info) {
807  called = true;
808  EXPECT_EQ(info->view_id, 123);
809 
810  FlutterRemoveViewResult result;
811  result.struct_size = sizeof(FlutterRemoveViewResult);
812  result.removed = true;
813  result.user_data = info->user_data;
814  info->remove_view_callback(&result);
815 
816  return kSuccess;
817  }));
818 
819  fl_engine_remove_view(engine, 123, nullptr, remove_view_cb, loop);
820  EXPECT_TRUE(called);
821 
822  // Blocks here until remove_view_cb is called.
823  g_main_loop_run(loop);
824 }
void fl_engine_remove_view(FlEngine *self, FlutterViewId view_id, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
Definition: fl_engine.cc:946
static void remove_view_cb(GObject *object, GAsyncResult *result, gpointer user_data)

References fl_dart_project_new(), fl_engine_get_embedder_api(), fl_engine_new(), fl_engine_remove_view(), and remove_view_cb().

◆ TEST() [19/27]

TEST ( FlEngineTest  ,
RemoveViewEngineError   
)

Definition at line 871 of file fl_engine_test.cc.

871  {
872  g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0);
873 
874  g_autoptr(FlDartProject) project = fl_dart_project_new();
875  g_autoptr(FlEngine) engine = fl_engine_new(project);
876 
877  fl_engine_get_embedder_api(engine)->RemoveView = MOCK_ENGINE_PROC(
878  RemoveView, ([](auto engine, const FlutterRemoveViewInfo* info) {
879  return kInvalidArguments;
880  }));
881 
883  loop);
884 
885  // Blocks here until remove_view_engine_error_cb is called.
886  g_main_loop_run(loop);
887 }
static void remove_view_engine_error_cb(GObject *object, GAsyncResult *result, gpointer user_data)

References fl_dart_project_new(), fl_engine_get_embedder_api(), fl_engine_new(), fl_engine_remove_view(), and remove_view_engine_error_cb().

◆ TEST() [20/27]

TEST ( FlEngineTest  ,
RemoveViewError   
)

Definition at line 837 of file fl_engine_test.cc.

837  {
838  g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0);
839 
840  g_autoptr(FlDartProject) project = fl_dart_project_new();
841  g_autoptr(FlEngine) engine = fl_engine_new(project);
842 
843  fl_engine_get_embedder_api(engine)->RemoveView = MOCK_ENGINE_PROC(
844  RemoveView, ([](auto engine, const FlutterRemoveViewInfo* info) {
845  FlutterRemoveViewResult result;
846  result.struct_size = sizeof(FlutterRemoveViewResult);
847  result.removed = false;
848  result.user_data = info->user_data;
849  info->remove_view_callback(&result);
850 
851  return kSuccess;
852  }));
853 
854  fl_engine_remove_view(engine, 123, nullptr, remove_view_error_cb, loop);
855 
856  // Blocks here until remove_view_error_cb is called.
857  g_main_loop_run(loop);
858 }
static void remove_view_error_cb(GObject *object, GAsyncResult *result, gpointer user_data)

References fl_dart_project_new(), fl_engine_get_embedder_api(), fl_engine_new(), fl_engine_remove_view(), and remove_view_error_cb().

◆ TEST() [21/27]

TEST ( FlEngineTest  ,
SendKeyEvent   
)

Definition at line 889 of file fl_engine_test.cc.

889  {
890  g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0);
891 
892  g_autoptr(FlDartProject) project = fl_dart_project_new();
893  g_autoptr(FlEngine) engine = fl_engine_new(project);
894 
895  g_autoptr(GError) error = nullptr;
896  EXPECT_TRUE(fl_engine_start(engine, &error));
897  EXPECT_EQ(error, nullptr);
898 
899  bool called;
900  fl_engine_get_embedder_api(engine)->SendKeyEvent = MOCK_ENGINE_PROC(
901  SendKeyEvent,
902  ([&called](auto engine, const FlutterKeyEvent* event,
903  FlutterKeyEventCallback callback, void* user_data) {
904  called = true;
905  EXPECT_EQ(event->timestamp, 1234);
906  EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
907  EXPECT_EQ(event->physical, static_cast<uint64_t>(42));
908  EXPECT_EQ(event->logical, static_cast<uint64_t>(123));
909  EXPECT_TRUE(event->synthesized);
910  EXPECT_EQ(event->device_type, kFlutterKeyEventDeviceTypeKeyboard);
911  callback(TRUE, user_data);
912  return kSuccess;
913  }));
914 
915  FlutterKeyEvent event = {.struct_size = sizeof(FlutterKeyEvent),
916  .timestamp = 1234,
917  .type = kFlutterKeyEventTypeUp,
918  .physical = 42,
919  .logical = 123,
920  .character = nullptr,
921  .synthesized = true,
922  .device_type = kFlutterKeyEventDeviceTypeKeyboard};
924  engine, &event, nullptr,
925  [](GObject* object, GAsyncResult* result, gpointer user_data) {
926  gboolean handled;
927  g_autoptr(GError) error = nullptr;
928  EXPECT_TRUE(fl_engine_send_key_event_finish(FL_ENGINE(object), result,
929  &handled, &error));
930  EXPECT_EQ(error, nullptr);
931  EXPECT_TRUE(handled);
932  g_main_loop_quit(static_cast<GMainLoop*>(user_data));
933  },
934  loop);
935 
936  g_main_loop_run(loop);
937  EXPECT_TRUE(called);
938 }
gboolean fl_engine_send_key_event_finish(FlEngine *self, GAsyncResult *result, gboolean *handled, GError **error)
Definition: fl_engine.cc:1347
void fl_engine_send_key_event(FlEngine *self, const FlutterKeyEvent *event, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
Definition: fl_engine.cc:1324

References error, fl_dart_project_new(), fl_engine_get_embedder_api(), fl_engine_new(), fl_engine_send_key_event(), fl_engine_send_key_event_finish(), fl_engine_start(), TRUE, type, and user_data.

◆ TEST() [22/27]

TEST ( FlEngineTest  ,
SendKeyEventError   
)

Definition at line 985 of file fl_engine_test.cc.

985  {
986  g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0);
987 
988  g_autoptr(FlDartProject) project = fl_dart_project_new();
989  g_autoptr(FlEngine) engine = fl_engine_new(project);
990 
991  g_autoptr(GError) error = nullptr;
992  EXPECT_TRUE(fl_engine_start(engine, &error));
993  EXPECT_EQ(error, nullptr);
994 
995  bool called;
996  fl_engine_get_embedder_api(engine)->SendKeyEvent = MOCK_ENGINE_PROC(
997  SendKeyEvent,
998  ([&called](auto engine, const FlutterKeyEvent* event,
999  FlutterKeyEventCallback callback, void* user_data) {
1000  called = true;
1001  return kInvalidArguments;
1002  }));
1003 
1004  FlutterKeyEvent event = {.struct_size = sizeof(FlutterKeyEvent),
1005  .timestamp = 1234,
1006  .type = kFlutterKeyEventTypeUp,
1007  .physical = 42,
1008  .logical = 123,
1009  .character = nullptr,
1010  .synthesized = true,
1011  .device_type = kFlutterKeyEventDeviceTypeKeyboard};
1013  engine, &event, nullptr,
1014  [](GObject* object, GAsyncResult* result, gpointer user_data) {
1015  gboolean handled;
1016  g_autoptr(GError) error = nullptr;
1017  EXPECT_FALSE(fl_engine_send_key_event_finish(FL_ENGINE(object), result,
1018  &handled, &error));
1019  EXPECT_NE(error, nullptr);
1020  EXPECT_STREQ(error->message, "Failed to send key event");
1021  g_main_loop_quit(static_cast<GMainLoop*>(user_data));
1022  },
1023  loop);
1024 
1025  g_main_loop_run(loop);
1026  EXPECT_TRUE(called);
1027 }

References error, fl_dart_project_new(), fl_engine_get_embedder_api(), fl_engine_new(), fl_engine_send_key_event(), fl_engine_send_key_event_finish(), fl_engine_start(), type, and user_data.

◆ TEST() [23/27]

TEST ( FlEngineTest  ,
SendKeyEventNotHandled   
)

Definition at line 940 of file fl_engine_test.cc.

940  {
941  g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0);
942 
943  g_autoptr(FlDartProject) project = fl_dart_project_new();
944  g_autoptr(FlEngine) engine = fl_engine_new(project);
945 
946  g_autoptr(GError) error = nullptr;
947  EXPECT_TRUE(fl_engine_start(engine, &error));
948  EXPECT_EQ(error, nullptr);
949 
950  bool called;
951  fl_engine_get_embedder_api(engine)->SendKeyEvent = MOCK_ENGINE_PROC(
952  SendKeyEvent,
953  ([&called](auto engine, const FlutterKeyEvent* event,
954  FlutterKeyEventCallback callback, void* user_data) {
955  called = true;
956  callback(FALSE, user_data);
957  return kSuccess;
958  }));
959 
960  FlutterKeyEvent event = {.struct_size = sizeof(FlutterKeyEvent),
961  .timestamp = 1234,
962  .type = kFlutterKeyEventTypeUp,
963  .physical = 42,
964  .logical = 123,
965  .character = nullptr,
966  .synthesized = true,
967  .device_type = kFlutterKeyEventDeviceTypeKeyboard};
969  engine, &event, nullptr,
970  [](GObject* object, GAsyncResult* result, gpointer user_data) {
971  gboolean handled;
972  g_autoptr(GError) error = nullptr;
973  EXPECT_TRUE(fl_engine_send_key_event_finish(FL_ENGINE(object), result,
974  &handled, &error));
975  EXPECT_EQ(error, nullptr);
976  EXPECT_FALSE(handled);
977  g_main_loop_quit(static_cast<GMainLoop*>(user_data));
978  },
979  loop);
980 
981  g_main_loop_run(loop);
982  EXPECT_TRUE(called);
983 }

References error, fl_dart_project_new(), fl_engine_get_embedder_api(), fl_engine_new(), fl_engine_send_key_event(), fl_engine_send_key_event_finish(), fl_engine_start(), type, and user_data.

◆ TEST() [24/27]

TEST ( FlEngineTest  ,
SettingsHandler   
)

Definition at line 287 of file fl_engine_test.cc.

287  {
288  g_autoptr(FlDartProject) project = fl_dart_project_new();
289  g_autoptr(FlEngine) engine = fl_engine_new(project);
290 
291  bool called = false;
292  fl_engine_get_embedder_api(engine)->SendPlatformMessage = MOCK_ENGINE_PROC(
293  SendPlatformMessage,
294  ([&called](auto engine, const FlutterPlatformMessage* message) {
295  called = true;
296 
297  EXPECT_STREQ(message->channel, "flutter/settings");
298 
299  g_autoptr(FlJsonMessageCodec) codec = fl_json_message_codec_new();
300  g_autoptr(GBytes) data =
301  g_bytes_new(message->message, message->message_size);
302  g_autoptr(GError) error = nullptr;
303  g_autoptr(FlValue) settings = fl_message_codec_decode_message(
304  FL_MESSAGE_CODEC(codec), data, &error);
305  EXPECT_NE(settings, nullptr);
306  EXPECT_EQ(error, nullptr);
307 
308  FlValue* text_scale_factor =
309  fl_value_lookup_string(settings, "textScaleFactor");
310  EXPECT_NE(text_scale_factor, nullptr);
311  EXPECT_EQ(fl_value_get_type(text_scale_factor), FL_VALUE_TYPE_FLOAT);
312 
313  FlValue* always_use_24hr_format =
314  fl_value_lookup_string(settings, "alwaysUse24HourFormat");
315  EXPECT_NE(always_use_24hr_format, nullptr);
316  EXPECT_EQ(fl_value_get_type(always_use_24hr_format),
318 
319  FlValue* platform_brightness =
320  fl_value_lookup_string(settings, "platformBrightness");
321  EXPECT_NE(platform_brightness, nullptr);
322  EXPECT_EQ(fl_value_get_type(platform_brightness), FL_VALUE_TYPE_STRING);
323 
324  return kSuccess;
325  }));
326 
327  g_autoptr(GError) error = nullptr;
328  EXPECT_TRUE(fl_engine_start(engine, &error));
329  EXPECT_EQ(error, nullptr);
330 
331  EXPECT_TRUE(called);
332 }
G_MODULE_EXPORT FlJsonMessageCodec * fl_json_message_codec_new()
G_MODULE_EXPORT FlValue * fl_message_codec_decode_message(FlMessageCodec *self, GBytes *message, GError **error)
G_MODULE_EXPORT FlValue * fl_value_lookup_string(FlValue *self, const gchar *key)
Definition: fl_value.cc:811
G_MODULE_EXPORT FlValueType fl_value_get_type(FlValue *self)
Definition: fl_value.cc:466
typedefG_BEGIN_DECLS struct _FlValue FlValue
Definition: fl_value.h:42
@ FL_VALUE_TYPE_STRING
Definition: fl_value.h:68
@ FL_VALUE_TYPE_BOOL
Definition: fl_value.h:65
@ FL_VALUE_TYPE_FLOAT
Definition: fl_value.h:67

References error, fl_dart_project_new(), fl_engine_get_embedder_api(), fl_engine_new(), fl_engine_start(), fl_json_message_codec_new(), fl_message_codec_decode_message(), fl_value_get_type(), fl_value_lookup_string(), FL_VALUE_TYPE_BOOL, FL_VALUE_TYPE_FLOAT, and FL_VALUE_TYPE_STRING.

◆ TEST() [25/27]

TEST ( FlEngineTest  ,
UIIsolateOnPlatformTaskRunner   
)

Definition at line 442 of file fl_engine_test.cc.

442  {
443  g_autoptr(FlDartProject) project = fl_dart_project_new();
444  g_autoptr(FlEngine) engine = fl_engine_new(project);
447 
448  bool same_task_runner = false;
449 
450  fl_engine_get_embedder_api(engine)->Initialize = MOCK_ENGINE_PROC(
451  Initialize,
452  ([&same_task_runner](size_t version, const FlutterRendererConfig* config,
453  const FlutterProjectArgs* args, void* user_data,
454  FLUTTER_API_SYMBOL(FlutterEngine) * engine_out) {
455  same_task_runner = args->custom_task_runners->platform_task_runner ==
456  args->custom_task_runners->ui_task_runner;
457  return kSuccess;
458  }));
459  fl_engine_get_embedder_api(engine)->RunInitialized =
460  MOCK_ENGINE_PROC(RunInitialized, ([](auto engine) { return kSuccess; }));
461 
462  g_autoptr(GError) error = nullptr;
463  EXPECT_TRUE(fl_engine_start(engine, &error));
464  EXPECT_EQ(error, nullptr);
465  EXPECT_TRUE(same_task_runner);
466 }
G_MODULE_EXPORT void fl_dart_project_set_ui_thread_policy(FlDartProject *project, FlUIThreadPolicy policy)
@ FL_UI_THREAD_POLICY_RUN_ON_PLATFORM_THREAD

References args, error, fl_dart_project_new(), fl_dart_project_set_ui_thread_policy(), fl_engine_get_embedder_api(), fl_engine_new(), fl_engine_start(), FL_UI_THREAD_POLICY_RUN_ON_PLATFORM_THREAD, and user_data.

◆ TEST() [26/27]

TEST ( FlEngineTest  ,
UIIsolateOnSeparateThread   
)

Definition at line 468 of file fl_engine_test.cc.

468  {
469  g_autoptr(FlDartProject) project = fl_dart_project_new();
470  g_autoptr(FlEngine) engine = fl_engine_new(project);
473 
474  bool separate_thread = false;
475 
476  fl_engine_get_embedder_api(engine)->Initialize = MOCK_ENGINE_PROC(
477  Initialize,
478  ([&separate_thread](size_t version, const FlutterRendererConfig* config,
479  const FlutterProjectArgs* args, void* user_data,
480  FLUTTER_API_SYMBOL(FlutterEngine) * engine_out) {
481  separate_thread = args->custom_task_runners->ui_task_runner == nullptr;
482  return kSuccess;
483  }));
484  fl_engine_get_embedder_api(engine)->RunInitialized =
485  MOCK_ENGINE_PROC(RunInitialized, ([](auto engine) { return kSuccess; }));
486 
487  g_autoptr(GError) error = nullptr;
488  EXPECT_TRUE(fl_engine_start(engine, &error));
489  EXPECT_EQ(error, nullptr);
490  EXPECT_TRUE(separate_thread);
491 }
@ FL_UI_THREAD_POLICY_RUN_ON_SEPARATE_THREAD

References args, error, fl_dart_project_new(), fl_dart_project_set_ui_thread_policy(), fl_engine_get_embedder_api(), fl_engine_new(), fl_engine_start(), FL_UI_THREAD_POLICY_RUN_ON_SEPARATE_THREAD, and user_data.

◆ TEST() [27/27]

TEST ( FlEngineTest  ,
WindowMetrics   
)

Definition at line 76 of file fl_engine_test.cc.

76  {
77  g_autoptr(FlDartProject) project = fl_dart_project_new();
78  g_autoptr(FlEngine) engine = fl_engine_new(project);
79 
80  g_autoptr(GError) error = nullptr;
81  EXPECT_TRUE(fl_engine_start(engine, &error));
82  EXPECT_EQ(error, nullptr);
83 
84  bool called = false;
85  fl_engine_get_embedder_api(engine)->SendWindowMetricsEvent = MOCK_ENGINE_PROC(
86  SendWindowMetricsEvent,
87  ([&called](auto engine, const FlutterWindowMetricsEvent* event) {
88  called = true;
89  EXPECT_EQ(event->display_id, 99u);
90  EXPECT_EQ(event->view_id, 1);
91  EXPECT_EQ(event->width, static_cast<size_t>(3840));
92  EXPECT_EQ(event->height, static_cast<size_t>(2160));
93  EXPECT_EQ(event->pixel_ratio, 2.0);
94 
95  return kSuccess;
96  }));
97 
98  fl_engine_send_window_metrics_event(engine, 99, 1, 3840, 2160, 2.0);
99 
100  EXPECT_TRUE(called);
101 }
void fl_engine_send_window_metrics_event(FlEngine *self, FlutterEngineDisplayId display_id, FlutterViewId view_id, size_t width, size_t height, double pixel_ratio)
Definition: fl_engine.cc:1099

References error, fl_dart_project_new(), fl_engine_get_embedder_api(), fl_engine_new(), fl_engine_send_window_metrics_event(), and fl_engine_start().