| Flutter Linux Embedder |

Functions
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/fl_test.h"`

Go to the source code of this file.

## Functions
| 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, Locales)
| TEST (FlEngineTest, CLocale)
| TEST (FlEngineTest, DuplicateLocale)
| TEST (FlEngineTest, EmptyLocales)
| TEST (FlEngineTest, SwitchesEmpty)
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, Switches)

## Function Documentation

## ◆ add_view_cb()

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

Definition at line 551 of file fl_engine_test.cc.

553 {
554 g_autoptr(GError) error = nullptr;
555 gboolean r = fl_engine_add_view_finish(FL_ENGINE(object), result, &error);
556 EXPECT_TRUE(r);
557 EXPECT_EQ(error, nullptr);
558
559 g_main_loop_quit(static_cast<GMainLoop*>(user_data));
560 }

References error, fl_engine_add_view_finish(), result, 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 630 of file fl_engine_test.cc.

632 {
633 g_autoptr(GError) error = nullptr;
634 gboolean r = fl_engine_add_view_finish(FL_ENGINE(object), result, &error);
635 EXPECT_FALSE(r);
636 EXPECT_NE(error, nullptr);
637
638 g_main_loop_quit(static_cast<GMainLoop*>(user_data));
639 }

References error, fl_engine_add_view_finish(), result, 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 594 of file fl_engine_test.cc.

596 {
597 g_autoptr(GError) error = nullptr;
598 gboolean r = fl_engine_add_view_finish(FL_ENGINE(object), result, &error);
599 EXPECT_FALSE(r);
600 EXPECT_NE(error, nullptr);
601
602 g_main_loop_quit(static_cast<GMainLoop*>(user_data));
603 }

References error, fl_engine_add_view_finish(), result, 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 273 of file fl_engine_test.cc.

273 {
274 int* count = reinterpret_cast<int*>(user_data);
275 *count += 1;
276 }

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 660 of file fl_engine_test.cc.

662 {
663 g_autoptr(GError) error = nullptr;
664 gboolean r = fl_engine_remove_view_finish(FL_ENGINE(object), result, &error);
665 EXPECT_TRUE(r);
666 EXPECT_EQ(error, nullptr);
667
668 g_main_loop_quit(static_cast<GMainLoop*>(user_data));
669 }

References error, fl_engine_remove_view_finish(), result, 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 733 of file fl_engine_test.cc.

735 {
736 g_autoptr(GError) error = nullptr;
737 gboolean r = fl_engine_remove_view_finish(FL_ENGINE(object), result, &error);
738 EXPECT_FALSE(r);
739 EXPECT_NE(error, nullptr);
740
741 g_main_loop_quit(static_cast<GMainLoop*>(user_data));
742 }

References error, fl_engine_remove_view_finish(), result, 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 699 of file fl_engine_test.cc.

701 {
702 g_autoptr(GError) error = nullptr;
703 gboolean r = fl_engine_remove_view_finish(FL_ENGINE(object), result, &error);
704 EXPECT_FALSE(r);
705 EXPECT_NE(error, nullptr);
706
707 g_main_loop_quit(static_cast<GMainLoop*>(user_data));
708 }

References error, fl_engine_remove_view_finish(), result, and user_data.

Referenced by TEST().

## ◆ TEST() [1/21]

TEST | ( | FlEngineTest | ,
|  | AddView |
| ) |  |

Definition at line 562 of file fl_engine_test.cc.

562 {
563 g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0);
564
565 g_autoptr(FlEngine) engine = make_mock_engine();
566 FlutterEngineProcTable* embedder_api = fl_engine_get_embedder_api(engine);
567
568 bool called = false;
569 embedder_api->AddView = MOCK_ENGINE_PROC(
570 AddView, ([&called](auto engine, const FlutterAddViewInfo* info) {
571 called = true;
572 EXPECT_EQ(info->view_metrics->width, 123u);
573 EXPECT_EQ(info->view_metrics->height, 456u);
574 EXPECT_EQ(info->view_metrics->pixel_ratio, 2.0);
575
576 FlutterAddViewResult result;
577 result.struct_size = sizeof(FlutterAddViewResult);
578 result.added = true;
579 result.user_data = info->user_data;
580 info->add_view_callback(&result);
581
582 return kSuccess;
583 }));
584
585 FlutterViewId view_id =
586 fl_engine_add_view(engine, 123, 456, 2.0, nullptr, add_view_cb, loop);
587 EXPECT_GT(view_id, 0);
588 EXPECT_TRUE(called);
589
590 // Blocks here until add_view_cb is called.
591 g_main_loop_run(loop);
592 }

References add_view_cb(), fl_engine_add_view(), fl_engine_get_embedder_api(), make_mock_engine(), and result.

## ◆ TEST() [2/21]

TEST | ( | FlEngineTest | ,
|  | AddViewEngineError |
| ) |  |

Definition at line 641 of file fl_engine_test.cc.

641 {
642 g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0);
643
644 g_autoptr(FlEngine) engine = make_mock_engine();
645 FlutterEngineProcTable* embedder_api = fl_engine_get_embedder_api(engine);
646
647 embedder_api->AddView = MOCK_ENGINE_PROC(
648 AddView, ([](auto engine, const FlutterAddViewInfo* info) {
649 return kInvalidArguments;
650 }));
651
652 FlutterViewId view_id = fl_engine_add_view(engine, 123, 456, 2.0, nullptr,
653 add_view_engine_error_cb, loop);
654 EXPECT_GT(view_id, 0);
655
656 // Blocks here until remove_view_engine_error_cb is called.
657 g_main_loop_run(loop);
658 }

References add_view_engine_error_cb(), fl_engine_add_view(), fl_engine_get_embedder_api(), and make_mock_engine().

## ◆ TEST() [3/21]

TEST | ( | FlEngineTest | ,
|  | AddViewError |
| ) |  |

Definition at line 605 of file fl_engine_test.cc.

605 {
606 g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0);
607
608 g_autoptr(FlEngine) engine = make_mock_engine();
609 FlutterEngineProcTable* embedder_api = fl_engine_get_embedder_api(engine);
610
611 embedder_api->AddView = MOCK_ENGINE_PROC(
612 AddView, ([](auto engine, const FlutterAddViewInfo* info) {
613 FlutterAddViewResult result;
614 result.struct_size = sizeof(FlutterAddViewResult);
615 result.added = false;
616 result.user_data = info->user_data;
617 info->add_view_callback(&result);
618
619 return kSuccess;
620 }));
621
622 FlutterViewId view_id = fl_engine_add_view(engine, 123, 456, 2.0, nullptr,
623 add_view_error_cb, loop);
624 EXPECT_GT(view_id, 0);
625
626 // Blocks here until add_view_error_cb is called.
627 g_main_loop_run(loop);
628 }

References add_view_error_cb(), fl_engine_add_view(), fl_engine_get_embedder_api(), make_mock_engine(), and result.

## ◆ TEST() [4/21]

TEST | ( | FlEngineTest | ,
|  | CLocale |
| ) |  |

Definition at line 409 of file fl_engine_test.cc.

409 {
410 g_autofree gchar* initial_language = g_strdup(g_getenv("LANGUAGE"));
411 g_setenv("LANGUAGE", "C", TRUE);
412 g_autoptr(FlDartProject) project = fl_dart_project_new();
413
414 g_autoptr(FlEngine) engine = make_mock_engine_with_project(project);
415 FlutterEngineProcTable* embedder_api = fl_engine_get_embedder_api(engine);
416
417 bool called = false;
418 embedder_api->UpdateLocales = MOCK_ENGINE_PROC(
419 UpdateLocales, ([&called](auto engine, const FlutterLocale** locales,
420 size_t locales_count) {
421 called = true;
422
423 EXPECT_EQ(locales_count, static_cast<size_t>(1));
424
425 EXPECT_STREQ(locales[0]->language_code, "C");
426 EXPECT_STREQ(locales[0]->country_code, nullptr);
427 EXPECT_STREQ(locales[0]->script_code, nullptr);
428 EXPECT_STREQ(locales[0]->variant_code, nullptr);
429
430 return kSuccess;
431 }));
432
433 g_autoptr(GError) error = nullptr;
434 EXPECT_TRUE(fl_engine_start(engine, &error));
435 EXPECT_EQ(error, nullptr);
436
437 EXPECT_TRUE(called);
438
439 if (initial_language) {
440 g_setenv("LANGUAGE", initial_language, TRUE);
441 } else {
442 g_unsetenv("LANGUAGE");
443 }
444 }

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

## ◆ TEST() [5/21]

TEST | ( | FlEngineTest | ,
|  | DartEntrypointArgs |
| ) |  |

Definition at line 322 of file fl_engine_test.cc.

322 {
323 g_autoptr(FlDartProject) project = fl_dart_project_new();
324
325 GPtrArray* args_array = g_ptr_array_new();
326 g_ptr_array_add(args_array, const_cast<char*>("arg_one"));
327 g_ptr_array_add(args_array, const_cast<char*>("arg_two"));
328 g_ptr_array_add(args_array, const_cast<char*>("arg_three"));
329 g_ptr_array_add(args_array, nullptr);
330 gchar** args = reinterpret_cast<gchar**>(g_ptr_array_free(args_array, false));
331
332 fl_dart_project_set_dart_entrypoint_arguments(project, args);
333
334 g_autoptr(FlEngine) engine = make_mock_engine_with_project(project);
335 FlutterEngineProcTable* embedder_api = fl_engine_get_embedder_api(engine);
336
337 bool called = false;
338 embedder_api->Initialize = MOCK_ENGINE_PROC(
339 Initialize, ([&called, &set_args = args](
340 size_t version, const FlutterRendererConfig* config,
341 const FlutterProjectArgs* args, void* user_data,
342 FLUTTER_API_SYMBOL(FlutterEngine) * engine_out) {
343 called = true;
344 EXPECT_NE(set_args, args->dart_entrypoint_argv);
345 EXPECT_EQ(args->dart_entrypoint_argc, 3);
346
347 return kSuccess;
348 }));
349
350 g_autoptr(GError) error = nullptr;
351 EXPECT_TRUE(fl_engine_start(engine, &error));
352 EXPECT_EQ(error, nullptr);
353
354 EXPECT_TRUE(called);
355 }

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

## ◆ TEST() [6/21]

TEST | ( | FlEngineTest | ,
|  | DispatchSemanticsAction |
| ) |  |

Definition at line 120 of file fl_engine_test.cc.

120 {
121 g_autoptr(FlEngine) engine = make_mock_engine();
122 FlutterEngineProcTable* embedder_api = fl_engine_get_embedder_api(engine);
123
124 bool called = false;
125 embedder_api->DispatchSemanticsAction = MOCK_ENGINE_PROC(
126 DispatchSemanticsAction,
127 ([&called](auto engine, uint64_t id, FlutterSemanticsAction action,
128 const uint8_t* data, size_t data_length) {
129 EXPECT_EQ(id, static_cast<uint64_t>(42));
130 EXPECT_EQ(action, kFlutterSemanticsActionTap);
131 EXPECT_EQ(data_length, static_cast<size_t>(4));
132 EXPECT_EQ(data[0], 't');
133 EXPECT_EQ(data[1], 'e');
134 EXPECT_EQ(data[2], 's');
135 EXPECT_EQ(data[3], 't');
136 called = true;
137
138 return kSuccess;
139 }));
140
141 g_autoptr(GError) error = nullptr;
142 EXPECT_TRUE(fl_engine_start(engine, &error));
143 EXPECT_EQ(error, nullptr);
144 g_autoptr(GBytes) data = g_bytes_new_static("test", 4);
145 fl_engine_dispatch_semantics_action(engine, 42, kFlutterSemanticsActionTap,
146 data);
147
148 EXPECT_TRUE(called);
149 }

References error, fl_engine_dispatch_semantics_action(), fl_engine_get_embedder_api(), fl_engine_start(), and make_mock_engine().

## ◆ TEST() [7/21]

TEST | ( | FlEngineTest | ,
|  | DuplicateLocale |
| ) |  |

Definition at line 446 of file fl_engine_test.cc.

446 {
447 g_autofree gchar* initial_language = g_strdup(g_getenv("LANGUAGE"));
448 g_setenv("LANGUAGE", "en:en", TRUE);
449 g_autoptr(FlDartProject) project = fl_dart_project_new();
450
451 g_autoptr(FlEngine) engine = make_mock_engine_with_project(project);
452 FlutterEngineProcTable* embedder_api = fl_engine_get_embedder_api(engine);
453
454 bool called = false;
455 embedder_api->UpdateLocales = MOCK_ENGINE_PROC(
456 UpdateLocales, ([&called](auto engine, const FlutterLocale** locales,
457 size_t locales_count) {
458 called = true;
459
460 EXPECT_EQ(locales_count, static_cast<size_t>(2));
461
462 EXPECT_STREQ(locales[0]->language_code, "en");
463 EXPECT_STREQ(locales[0]->country_code, nullptr);
464 EXPECT_STREQ(locales[0]->script_code, nullptr);
465 EXPECT_STREQ(locales[0]->variant_code, nullptr);
466
467 EXPECT_STREQ(locales[1]->language_code, "C");
468 EXPECT_STREQ(locales[1]->country_code, nullptr);
469 EXPECT_STREQ(locales[1]->script_code, nullptr);
470 EXPECT_STREQ(locales[1]->variant_code, nullptr);
471
472 return kSuccess;
473 }));
474
475 g_autoptr(GError) error = nullptr;
476 EXPECT_TRUE(fl_engine_start(engine, &error));
477 EXPECT_EQ(error, nullptr);
478
479 EXPECT_TRUE(called);
480
481 if (initial_language) {
482 g_setenv("LANGUAGE", initial_language, TRUE);
483 } else {
484 g_unsetenv("LANGUAGE");
485 }
486 }

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

## ◆ TEST() [8/21]

TEST | ( | FlEngineTest | ,
|  | EmptyLocales |
| ) |  |

Definition at line 488 of file fl_engine_test.cc.

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

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

## ◆ TEST() [9/21]

TEST | ( | FlEngineTest | ,
|  | Locales |
| ) |  |

Definition at line 357 of file fl_engine_test.cc.

357 {
358 g_autofree gchar* initial_language = g_strdup(g_getenv("LANGUAGE"));
359 g_setenv("LANGUAGE", "de:en_US", TRUE);
360 g_autoptr(FlDartProject) project = fl_dart_project_new();
361
362 g_autoptr(FlEngine) engine = make_mock_engine_with_project(project);
363 FlutterEngineProcTable* embedder_api = fl_engine_get_embedder_api(engine);
364
365 bool called = false;
366 embedder_api->UpdateLocales = MOCK_ENGINE_PROC(
367 UpdateLocales, ([&called](auto engine, const FlutterLocale** locales,
368 size_t locales_count) {
369 called = true;
370
371 EXPECT_EQ(locales_count, static_cast<size_t>(4));
372
373 EXPECT_STREQ(locales[0]->language_code, "de");
374 EXPECT_STREQ(locales[0]->country_code, nullptr);
375 EXPECT_STREQ(locales[0]->script_code, nullptr);
376 EXPECT_STREQ(locales[0]->variant_code, nullptr);
377
378 EXPECT_STREQ(locales[1]->language_code, "en");
379 EXPECT_STREQ(locales[1]->country_code, "US");
380 EXPECT_STREQ(locales[1]->script_code, nullptr);
381 EXPECT_STREQ(locales[1]->variant_code, nullptr);
382
383 EXPECT_STREQ(locales[2]->language_code, "en");
384 EXPECT_STREQ(locales[2]->country_code, nullptr);
385 EXPECT_STREQ(locales[2]->script_code, nullptr);
386 EXPECT_STREQ(locales[2]->variant_code, nullptr);
387
388 EXPECT_STREQ(locales[3]->language_code, "C");
389 EXPECT_STREQ(locales[3]->country_code, nullptr);
390 EXPECT_STREQ(locales[3]->script_code, nullptr);
391 EXPECT_STREQ(locales[3]->variant_code, nullptr);
392
393 return kSuccess;
394 }));
395
396 g_autoptr(GError) error = nullptr;
397 EXPECT_TRUE(fl_engine_start(engine, &error));
398 EXPECT_EQ(error, nullptr);
399
400 EXPECT_TRUE(called);
401
402 if (initial_language) {
403 g_setenv("LANGUAGE", initial_language, TRUE);
404 } else {
405 g_unsetenv("LANGUAGE");
406 }
407 }

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

## ◆ TEST() [10/21]

TEST | ( | FlEngineTest | ,
|  | MousePointer |
| ) |  |

Definition at line 45 of file fl_engine_test.cc.

45 {
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].view_id, 1);
57 EXPECT_EQ(events[0].phase, kDown);
58 EXPECT_EQ(events[0].timestamp, static_cast<size_t>(1234567890));
59 EXPECT_EQ(events[0].x, 800);
60 EXPECT_EQ(events[0].y, 600);
61 EXPECT_EQ(events[0].device, static_cast<int32_t>(0));
62 EXPECT_EQ(events[0].signal_kind, kFlutterPointerSignalKindScroll);
63 EXPECT_EQ(events[0].scroll_delta_x, 1.2);
64 EXPECT_EQ(events[0].scroll_delta_y, -3.4);
65 EXPECT_EQ(events[0].device_kind, kFlutterPointerDeviceKindMouse);
66 EXPECT_EQ(events[0].buttons, kFlutterPointerButtonMouseSecondary);
67
68 return kSuccess;
69 }));
70
71 g_autoptr(GError) error = nullptr;
72 EXPECT_TRUE(fl_engine_start(engine, &error));
73 EXPECT_EQ(error, nullptr);
74 fl_engine_send_mouse_pointer_event(engine, 1, kDown, 1234567890, 800, 600,
75 kFlutterPointerDeviceKindMouse, 1.2, -3.4,
76 kFlutterPointerButtonMouseSecondary);
77
78 EXPECT_TRUE(called);
79 }

References error, fl_engine_get_embedder_api(), fl_engine_send_mouse_pointer_event(), fl_engine_start(), and make_mock_engine().

## ◆ TEST() [11/21]

TEST | ( | FlEngineTest | ,
|  | OnPreEngineRestart |
| ) |  |

Definition at line 279 of file fl_engine_test.cc.

279 {
280 g_autoptr(FlEngine) engine = make_mock_engine();
281 FlutterEngineProcTable* embedder_api = fl_engine_get_embedder_api(engine);
282
283 OnPreEngineRestartCallback callback;
284 void* callback_user_data;
285
286 bool called = false;
287 embedder_api->Initialize = MOCK_ENGINE_PROC(
288 Initialize, ([&callback, &callback_user_data, &called](
289 size_t version, const FlutterRendererConfig* config,
290 const FlutterProjectArgs* args, void* user_data,
291 FLUTTER_API_SYMBOL(FlutterEngine) * engine_out) {
292 called = true;
293 callback = args->on_pre_engine_restart_callback;
294 callback_user_data = user_data;
295
296 return kSuccess;
297 }));
298
299 g_autoptr(GError) error = nullptr;
300 EXPECT_TRUE(fl_engine_start(engine, &error));
301 EXPECT_EQ(error, nullptr);
302
303 EXPECT_TRUE(called);
304 EXPECT_NE(callback, nullptr);
305
306 // The following call has no effect but should not crash.
307 callback(callback_user_data);
308
309 int count = 0;
310
311 // Set handler so that:
312 //
313 // * When the engine restarts, count += 1;
314 // * When the engine is freed, count += 10.
315 g_signal_connect(engine, "on-pre-engine-restart",
316 G_CALLBACK(on_pre_engine_restart_cb), &count);
317
318 callback(callback_user_data);
319 EXPECT_EQ(count, 1);
320 }

References args, callback, error, fl_engine_get_embedder_api(), fl_engine_start(), make_mock_engine(), on_pre_engine_restart_cb(), and user_data.

## ◆ TEST() [12/21]

TEST | ( | FlEngineTest | ,
|  | PlatformMessage |
| ) |  |

Definition at line 152 of file fl_engine_test.cc.

152 {
153 g_autoptr(FlEngine) engine = make_mock_engine();
154 FlutterEngineProcTable* embedder_api = fl_engine_get_embedder_api(engine);
155
156 bool called = false;
157 FlutterEngineSendPlatformMessageFnPtr old_handler =
158 embedder_api->SendPlatformMessage;
159 embedder_api->SendPlatformMessage = MOCK_ENGINE_PROC(
160 SendPlatformMessage,
161 ([&called, old_handler](auto engine,
162 const FlutterPlatformMessage* message) {
163 if (strcmp(message->channel, "test") != 0) {
164 return old_handler(engine, message);
165 }
166
167 called = true;
168
169 EXPECT_EQ(message->message_size, static_cast<size_t>(4));
170 EXPECT_EQ(message->message[0], 't');
171 EXPECT_EQ(message->message[1], 'e');
172 EXPECT_EQ(message->message[2], 's');
173 EXPECT_EQ(message->message[3], 't');
174
175 return kSuccess;
176 }));
177
178 g_autoptr(GError) error = nullptr;
179 EXPECT_TRUE(fl_engine_start(engine, &error));
180 EXPECT_EQ(error, nullptr);
181 g_autoptr(GBytes) message = g_bytes_new_static("test", 4);
182 fl_engine_send_platform_message(engine, "test", message, nullptr, nullptr,
183 nullptr);
184
185 EXPECT_TRUE(called);
186 }

References error, fl_engine_get_embedder_api(), fl_engine_send_platform_message(), fl_engine_start(), and make_mock_engine().

## ◆ TEST() [13/21]

TEST | ( | FlEngineTest | ,
|  | PlatformMessageResponse |
| ) |  |

Definition at line 189 of file fl_engine_test.cc.

189 {
190 g_autoptr(FlEngine) engine = make_mock_engine();
191 FlutterEngineProcTable* embedder_api = fl_engine_get_embedder_api(engine);
192
193 bool called = false;
194 embedder_api->SendPlatformMessageResponse = MOCK_ENGINE_PROC(
195 SendPlatformMessageResponse,
196 ([&called](auto engine,
197 const FlutterPlatformMessageResponseHandle* handle,
198 const uint8_t* data, size_t data_length) {
199 called = true;
200
201 EXPECT_EQ(
202 handle,
203 reinterpret_cast<const FlutterPlatformMessageResponseHandle*>(42));
204 EXPECT_EQ(data_length, static_cast<size_t>(4));
205 EXPECT_EQ(data[0], 't');
206 EXPECT_EQ(data[1], 'e');
207 EXPECT_EQ(data[2], 's');
208 EXPECT_EQ(data[3], 't');
209
210 return kSuccess;
211 }));
212
213 g_autoptr(GError) error = nullptr;
214 EXPECT_TRUE(fl_engine_start(engine, &error));
215 EXPECT_EQ(error, nullptr);
216 g_autoptr(GBytes) response = g_bytes_new_static("test", 4);
217 EXPECT_TRUE(fl_engine_send_platform_message_response(
218 engine, reinterpret_cast<const FlutterPlatformMessageResponseHandle*>(42),
219 response, &error));
220 EXPECT_EQ(error, nullptr);
221
222 EXPECT_TRUE(called);
223 }

References error, fl_engine_get_embedder_api(), fl_engine_send_platform_message_response(), fl_engine_start(), and make_mock_engine().

## ◆ TEST() [14/21]

TEST | ( | FlEngineTest | ,
|  | PointerPanZoom |
| ) |  |

Definition at line 82 of file fl_engine_test.cc.

82 {
83 g_autoptr(FlEngine) engine = make_mock_engine();
84 FlutterEngineProcTable* embedder_api = fl_engine_get_embedder_api(engine);
85
86 bool called = false;
87 embedder_api->SendPointerEvent = MOCK_ENGINE_PROC(
88 SendPointerEvent,
89 ([&called](auto engine, const FlutterPointerEvent* events,
90 size_t events_count) {
91 called = true;
92 EXPECT_EQ(events_count, static_cast<size_t>(1));
93 EXPECT_EQ(events[0].view_id, 1);
94 EXPECT_EQ(events[0].phase, kPanZoomUpdate);
95 EXPECT_EQ(events[0].timestamp, static_cast<size_t>(1234567890));
96 EXPECT_EQ(events[0].x, 800);
97 EXPECT_EQ(events[0].y, 600);
98 EXPECT_EQ(events[0].device, static_cast<int32_t>(1));
99 EXPECT_EQ(events[0].signal_kind, kFlutterPointerSignalKindNone);
100 EXPECT_EQ(events[0].pan_x, 1.5);
101 EXPECT_EQ(events[0].pan_y, 2.5);
102 EXPECT_EQ(events[0].scale, 3.5);
103 EXPECT_EQ(events[0].rotation, 4.5);
104 EXPECT_EQ(events[0].device_kind, kFlutterPointerDeviceKindTrackpad);
105 EXPECT_EQ(events[0].buttons, 0);
106
107 return kSuccess;
108 }));
109
110 g_autoptr(GError) error = nullptr;
111 EXPECT_TRUE(fl_engine_start(engine, &error));
112 EXPECT_EQ(error, nullptr);
113 fl_engine_send_pointer_pan_zoom_event(engine, 1, 1234567890, 800, 600,
114 kPanZoomUpdate, 1.5, 2.5, 3.5, 4.5);
115
116 EXPECT_TRUE(called);
117 }

References error, fl_engine_get_embedder_api(), fl_engine_send_pointer_pan_zoom_event(), fl_engine_start(), and make_mock_engine().

## ◆ TEST() [15/21]

TEST | ( | FlEngineTest | ,
|  | RemoveView |
| ) |  |

Definition at line 671 of file fl_engine_test.cc.

671 {
672 g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0);
673
674 g_autoptr(FlEngine) engine = make_mock_engine();
675 FlutterEngineProcTable* embedder_api = fl_engine_get_embedder_api(engine);
676
677 bool called = false;
678 embedder_api->RemoveView = MOCK_ENGINE_PROC(
679 RemoveView, ([&called](auto engine, const FlutterRemoveViewInfo* info) {
680 called = true;
681 EXPECT_EQ(info->view_id, 123);
682
683 FlutterRemoveViewResult result;
684 result.struct_size = sizeof(FlutterRemoveViewResult);
685 result.removed = true;
686 result.user_data = info->user_data;
687 info->remove_view_callback(&result);
688
689 return kSuccess;
690 }));
691
692 fl_engine_remove_view(engine, 123, nullptr, remove_view_cb, loop);
693 EXPECT_TRUE(called);
694
695 // Blocks here until remove_view_cb is called.
696 g_main_loop_run(loop);
697 }

References fl_engine_get_embedder_api(), fl_engine_remove_view(), make_mock_engine(), remove_view_cb(), and result.

## ◆ TEST() [16/21]

TEST | ( | FlEngineTest | ,
|  | RemoveViewEngineError |
| ) |  |

Definition at line 744 of file fl_engine_test.cc.

744 {
745 g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0);
746
747 g_autoptr(FlEngine) engine = make_mock_engine();
748 FlutterEngineProcTable* embedder_api = fl_engine_get_embedder_api(engine);
749
750 embedder_api->RemoveView = MOCK_ENGINE_PROC(
751 RemoveView, ([](auto engine, const FlutterRemoveViewInfo* info) {
752 return kInvalidArguments;
753 }));
754
755 fl_engine_remove_view(engine, 123, nullptr, remove_view_engine_error_cb,
756 loop);
757
758 // Blocks here until remove_view_engine_error_cb is called.
759 g_main_loop_run(loop);
760 }

References fl_engine_get_embedder_api(), fl_engine_remove_view(), make_mock_engine(), and remove_view_engine_error_cb().

## ◆ TEST() [17/21]

TEST | ( | FlEngineTest | ,
|  | RemoveViewError |
| ) |  |

Definition at line 710 of file fl_engine_test.cc.

710 {
711 g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0);
712
713 g_autoptr(FlEngine) engine = make_mock_engine();
714 FlutterEngineProcTable* embedder_api = fl_engine_get_embedder_api(engine);
715
716 embedder_api->RemoveView = MOCK_ENGINE_PROC(
717 RemoveView, ([](auto engine, const FlutterRemoveViewInfo* info) {
718 FlutterRemoveViewResult result;
719 result.struct_size = sizeof(FlutterRemoveViewResult);
720 result.removed = false;
721 result.user_data = info->user_data;
722 info->remove_view_callback(&result);
723
724 return kSuccess;
725 }));
726
727 fl_engine_remove_view(engine, 123, nullptr, remove_view_error_cb, loop);
728
729 // Blocks here until remove_view_error_cb is called.
730 g_main_loop_run(loop);
731 }

References fl_engine_get_embedder_api(), fl_engine_remove_view(), make_mock_engine(), remove_view_error_cb(), and result.

## ◆ TEST() [18/21]

TEST | ( | FlEngineTest | ,
|  | SettingsHandler |
| ) |  |

Definition at line 226 of file fl_engine_test.cc.

226 {
227 g_autoptr(FlEngine) engine = make_mock_engine();
228 FlutterEngineProcTable* embedder_api = fl_engine_get_embedder_api(engine);
229
230 bool called = false;
231 embedder_api->SendPlatformMessage = MOCK_ENGINE_PROC(
232 SendPlatformMessage,
233 ([&called](auto engine, const FlutterPlatformMessage* message) {
234 called = true;
235
236 EXPECT_STREQ(message->channel, "flutter/settings");
237
238 g_autoptr(FlJsonMessageCodec) codec = fl_json_message_codec_new();
239 g_autoptr(GBytes) data =
240 g_bytes_new(message->message, message->message_size);
241 g_autoptr(GError) error = nullptr;
242 g_autoptr(FlValue) settings = fl_message_codec_decode_message(
243 FL_MESSAGE_CODEC(codec), data, &error);
244 EXPECT_NE(settings, nullptr);
245 EXPECT_EQ(error, nullptr);
246
247 FlValue* text_scale_factor =
248 fl_value_lookup_string(settings, "textScaleFactor");
249 EXPECT_NE(text_scale_factor, nullptr);
250 EXPECT_EQ(fl_value_get_type(text_scale_factor), FL_VALUE_TYPE_FLOAT);
251
252 FlValue* always_use_24hr_format =
253 fl_value_lookup_string(settings, "alwaysUse24HourFormat");
254 EXPECT_NE(always_use_24hr_format, nullptr);
255 EXPECT_EQ(fl_value_get_type(always_use_24hr_format),
256 FL_VALUE_TYPE_BOOL);
257
258 FlValue* platform_brightness =
259 fl_value_lookup_string(settings, "platformBrightness");
260 EXPECT_NE(platform_brightness, nullptr);
261 EXPECT_EQ(fl_value_get_type(platform_brightness), FL_VALUE_TYPE_STRING);
262
263 return kSuccess;
264 }));
265
266 g_autoptr(GError) error = nullptr;
267 EXPECT_TRUE(fl_engine_start(engine, &error));
268 EXPECT_EQ(error, nullptr);
269
270 EXPECT_TRUE(called);
271 }

References error, fl_engine_get_embedder_api(), 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, FL_VALUE_TYPE_STRING, and make_mock_engine().

## ◆ TEST() [19/21]

TEST | ( | FlEngineTest | ,
|  | Switches |
| ) |  |

Definition at line 763 of file fl_engine_test.cc.

763 {
764 g_autoptr(FlEngine) engine = make_mock_engine();
765
766 setenv("FLUTTER_ENGINE_SWITCHES", "2", 1);
767 setenv("FLUTTER_ENGINE_SWITCH_1", "abc", 1);
768 setenv("FLUTTER_ENGINE_SWITCH_2", "foo=\"bar, baz\"", 1);
769
770 g_autoptr(GPtrArray) switches = fl_engine_get_switches(engine);
771 EXPECT_EQ(switches->len, 2U);
772 EXPECT_STREQ(static_cast<const char*>(g_ptr_array_index(switches, 0)),
773 "--abc");
774 EXPECT_STREQ(static_cast<const char*>(g_ptr_array_index(switches, 1)),
775 "--foo=\"bar, baz\"");
776
777 unsetenv("FLUTTER_ENGINE_SWITCHES");
778 unsetenv("FLUTTER_ENGINE_SWITCH_1");
779 unsetenv("FLUTTER_ENGINE_SWITCH_2");
780 }

References fl_engine_get_switches(), and make_mock_engine().

## ◆ TEST() [20/21]

TEST | ( | FlEngineTest | ,
|  | SwitchesEmpty |
| ) |  |

Definition at line 540 of file fl_engine_test.cc.

540 {
541 g_autoptr(FlEngine) engine = make_mock_engine();
542
543 // Clear the main environment variable, since test order is not guaranteed.
544 unsetenv("FLUTTER_ENGINE_SWITCHES");
545
546 g_autoptr(GPtrArray) switches = fl_engine_get_switches(engine);
547
548 EXPECT_EQ(switches->len, 0U);
549 }

References fl_engine_get_switches(), and make_mock_engine().

## ◆ TEST() [21/21]

TEST | ( | FlEngineTest | ,
|  | WindowMetrics |
| ) |  |

Definition at line 19 of file fl_engine_test.cc.

19 {
20 g_autoptr(FlEngine) engine = make_mock_engine();
21 FlutterEngineProcTable* embedder_api = fl_engine_get_embedder_api(engine);
22
23 bool called = false;
24 embedder_api->SendWindowMetricsEvent = MOCK_ENGINE_PROC(
25 SendWindowMetricsEvent,
26 ([&called](auto engine, const FlutterWindowMetricsEvent* event) {
27 called = true;
28 EXPECT_EQ(event->view_id, 1);
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);
39 fl_engine_send_window_metrics_event(engine, 1, 3840, 2160, 2.0);
40
41 EXPECT_TRUE(called);
42 }

References error, event, fl_engine_get_embedder_api(), fl_engine_send_window_metrics_event(), fl_engine_start(), and make_mock_engine().

event
FlKeyEvent * event
Definition: fl_key_channel_responder.cc:118
fl_engine_get_embedder_api
FlutterEngineProcTable * fl_engine_get_embedder_api(FlEngine *self)
Definition: fl_engine.cc:637
add_view_engine_error_cb
static void add_view_engine_error_cb(GObject *object, GAsyncResult *result, gpointer user_data)
Definition: fl_engine_test.cc:630
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_engine_remove_view
void fl_engine_remove_view(FlEngine *self, FlutterViewId view_id, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
Definition: fl_engine.cc:686
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:953
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_engine_send_window_metrics_event
void fl_engine_send_window_metrics_event(FlEngine *self, FlutterViewId view_id, size_t width, size_t height, double pixel_ratio)
Definition: fl_engine.cc:854
make_mock_engine
static FlEngine * make_mock_engine()
Definition: fl_event_channel_test.cc:24
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_value_get_type
G_MODULE_EXPORT FlValueType fl_value_get_type(FlValue *self)
Definition: fl_value.cc:466
fl_engine_add_view_finish
gboolean fl_engine_add_view_finish(FlEngine *self, GAsyncResult *result, GError **error)
Definition: fl_engine.cc:679
fl_engine_remove_view_finish
gboolean fl_engine_remove_view_finish(FlEngine *self, GAsyncResult *result, GError **error)
Definition: fl_engine.cc:711
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
remove_view_engine_error_cb
static void remove_view_engine_error_cb(GObject *object, GAsyncResult *result, gpointer user_data)
Definition: fl_engine_test.cc:733
TRUE
return TRUE
Definition: fl_pixel_buffer_texture_test.cc:53
fl_engine_add_view
FlutterViewId fl_engine_add_view(FlEngine *self, size_t width, size_t height, double pixel_ratio, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
Definition: fl_engine.cc:641
add_view_error_cb
static void add_view_error_cb(GObject *object, GAsyncResult *result, gpointer user_data)
Definition: fl_engine_test.cc:594
add_view_cb
static void add_view_cb(GObject *object, GAsyncResult *result, gpointer user_data)
Definition: fl_engine_test.cc:551
remove_view_cb
static void remove_view_cb(GObject *object, GAsyncResult *result, gpointer user_data)
Definition: fl_engine_test.cc:660
result
GAsyncResult * result
Definition: fl_text_input_handler.cc:106
args
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
Definition: fl_event_channel.h:89
error
const uint8_t uint32_t uint32_t GError ** error
Definition: fl_pixel_buffer_texture_test.cc:40
fl_engine_send_pointer_pan_zoom_event
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:908
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:786
on_pre_engine_restart_cb
void on_pre_engine_restart_cb(FlEngine *engine, gpointer user_data)
Definition: fl_engine_test.cc:273
fl_engine_start
gboolean fl_engine_start(FlEngine *self, GError **error)
Definition: fl_engine.cc:509
FL_VALUE_TYPE_FLOAT
@ FL_VALUE_TYPE_FLOAT
Definition: fl_value.h:68
callback
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
Definition: fl_key_channel_responder.cc:120
remove_view_error_cb
static void remove_view_error_cb(GObject *object, GAsyncResult *result, gpointer user_data)
Definition: fl_engine_test.cc:699
fl_engine_send_mouse_pointer_event
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:874
fl_engine_get_switches
GPtrArray * fl_engine_get_switches(FlEngine *self)
Definition: fl_engine.cc:1028
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:754