| Flutter Linux Embedder |

fl_view_test.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "flutter/shell/platform/linux/public/flutter_linux/fl_view.h"
6 #include "flutter/shell/platform/embedder/test_utils/proc_table_replacement.h"
7 #include "flutter/shell/platform/linux/fl_engine_private.h"
8 #include "flutter/shell/platform/linux/fl_view_private.h"
9 #include "flutter/shell/platform/linux/testing/fl_test.h"
10 #include "flutter/shell/platform/linux/testing/fl_test_gtk_logs.h"
11
12 #include "gtest/gtest.h"
13
14 static void first_frame_cb(FlView* view, gboolean* first_frame_emitted) {
15 *first_frame_emitted = TRUE;
16 }
17
18 TEST(FlViewTest, GetEngine) {
19 flutter::testing::fl_ensure_gtk_init();
20 g_autoptr(FlDartProject) project = fl_dart_project_new();
21 FlView* view = fl_view_new(project);
22
23 // Check the engine is immediately available (i.e. before the widget is
24 // realized).
25 FlEngine* engine = fl_view_get_engine(view);
26 EXPECT_NE(engine, nullptr);
27 }
28
29 TEST(FlViewTest, StateUpdateDoesNotHappenInInit) {
30 flutter::testing::fl_ensure_gtk_init();
31 g_autoptr(FlDartProject) project = fl_dart_project_new();
32 FlView* view = fl_view_new(project);
33 // Check that creating a view doesn't try to query the window state in
34 // initialization, causing a critical log to be issued.
35 EXPECT_EQ(
36 flutter::testing::fl_get_received_gtk_log_levels() & G_LOG_LEVEL_CRITICAL,
37 (GLogLevelFlags)0x0);
38
39 (void)view;
40 }
41
42 TEST(FlViewTest, FirstFrameSignal) {
43 flutter::testing::fl_ensure_gtk_init();
44
45 g_autoptr(FlDartProject) project = fl_dart_project_new();
46 FlView* view = fl_view_new(project);
47 gboolean first_frame_emitted = FALSE;
48 g_signal_connect(view, "first-frame", G_CALLBACK(first_frame_cb),
49 &first_frame_emitted);
50
51 EXPECT_FALSE(first_frame_emitted);
52
53 fl_view_redraw(view);
54
55 // Signal is emitted in idle, clear the main loop.
56 while (g_main_context_iteration(g_main_context_default(), FALSE)) {
57 // Repeat until nothing to iterate on.
58 }
59
60 // Check view has detected frame.
61 EXPECT_TRUE(first_frame_emitted);
62 }
63
64 // Check secondary view is registered with engine.
65 TEST(FlViewTest, SecondaryView) {
66 flutter::testing::fl_ensure_gtk_init();
67
68 g_autoptr(FlDartProject) project = fl_dart_project_new();
69 FlView* implicit_view = fl_view_new(project);
70
71 FlEngine* engine = fl_view_get_engine(implicit_view);
72 FlutterEngineProcTable* embedder_api = fl_engine_get_embedder_api(engine);
73
74 FlutterViewId view_id = -1;
75 embedder_api->AddView = MOCK_ENGINE_PROC(
76 AddView, ([&view_id](auto engine, const FlutterAddViewInfo* info) {
77 view_id = info->view_id;
78 FlutterAddViewResult result = {
79 .struct_size = sizeof(FlutterAddViewResult),
80 .added = true,
81 .user_data = info->user_data};
82 info->add_view_callback(&result);
83 return kSuccess;
84 }));
85
86 FlView* secondary_view = fl_view_new_for_engine(engine);
87 EXPECT_EQ(view_id, fl_view_get_id(secondary_view));
88 }
89
90 // Check secondary view that fails registration.
91 TEST(FlViewTest, SecondaryViewError) {
92 flutter::testing::fl_ensure_gtk_init();
93
94 g_autoptr(FlDartProject) project = fl_dart_project_new();
95 FlView* implicit_view = fl_view_new(project);
96
97 FlEngine* engine = fl_view_get_engine(implicit_view);
98 FlutterEngineProcTable* embedder_api = fl_engine_get_embedder_api(engine);
99
100 FlutterViewId view_id = -1;
101 embedder_api->AddView = MOCK_ENGINE_PROC(
102 AddView, ([&view_id](auto engine, const FlutterAddViewInfo* info) {
103 view_id = info->view_id;
104 return kInvalidArguments;
105 }));
106
107 FlView* secondary_view = fl_view_new_for_engine(engine);
108 EXPECT_EQ(view_id, fl_view_get_id(secondary_view));
109 }
110
111 // Check views are deregistered on destruction.
112 TEST(FlViewTest, ViewDestroy) {
113 flutter::testing::fl_ensure_gtk_init();
114
115 g_autoptr(FlDartProject) project = fl_dart_project_new();
116 FlView* implicit_view = fl_view_new(project);
117
118 FlEngine* engine = fl_view_get_engine(implicit_view);
119 FlutterEngineProcTable* embedder_api = fl_engine_get_embedder_api(engine);
120
121 g_autoptr(GPtrArray) removed_views = g_ptr_array_new();
122 embedder_api->RemoveView = MOCK_ENGINE_PROC(
123 RemoveView,
124 ([removed_views](auto engine, const FlutterRemoveViewInfo* info) {
125 g_ptr_array_add(removed_views, GINT_TO_POINTER(info->view_id));
126 return kSuccess;
127 }));
128
129 FlView* secondary_view = fl_view_new_for_engine(engine);
130
131 int64_t implicit_view_id = fl_view_get_id(implicit_view);
132 int64_t secondary_view_id = fl_view_get_id(secondary_view);
133
134 gtk_widget_destroy(GTK_WIDGET(secondary_view));
135 gtk_widget_destroy(GTK_WIDGET(implicit_view));
136
137 EXPECT_EQ(removed_views->len, 2u);
138 EXPECT_EQ(GPOINTER_TO_INT(g_ptr_array_index(removed_views, 0)),
139 secondary_view_id);
140 EXPECT_EQ(GPOINTER_TO_INT(g_ptr_array_index(removed_views, 1)),
141 implicit_view_id);
142 }
143
144 // Check views deregistered with errors works.
145 TEST(FlViewTest, ViewDestroyError) {
146 flutter::testing::fl_ensure_gtk_init();
147
148 g_autoptr(FlDartProject) project = fl_dart_project_new();
149 FlView* implicit_view = fl_view_new(project);
150
151 FlEngine* engine = fl_view_get_engine(implicit_view);
152 FlutterEngineProcTable* embedder_api = fl_engine_get_embedder_api(engine);
153
154 embedder_api->RemoveView = MOCK_ENGINE_PROC(
155 RemoveView, ([](auto engine, const FlutterRemoveViewInfo* info) {
156 return kInvalidArguments;
157 }));
158
159 FlView* secondary_view = fl_view_new_for_engine(engine);
160
161 gtk_widget_destroy(GTK_WIDGET(secondary_view));
162 gtk_widget_destroy(GTK_WIDGET(implicit_view));
163 }
fl_engine_get_embedder_api
FlutterEngineProcTable * fl_engine_get_embedder_api(FlEngine *self)
Definition: fl_engine.cc:637
fl_view_get_id
G_MODULE_EXPORT int64_t fl_view_get_id(FlView *self)
Definition: fl_view.cc:880
fl_view_new_for_engine
G_MODULE_EXPORT FlView * fl_view_new_for_engine(FlEngine *engine)
Definition: fl_view.cc:855
user_data
FlKeyEvent uint64_t FlKeyResponderAsyncCallback gpointer user_data
Definition: fl_key_channel_responder.cc:121
fl_dart_project_new
G_MODULE_EXPORT FlDartProject * fl_dart_project_new()
Definition: fl_dart_project.cc:50
fl_view_private.h
fl_view_new
G_MODULE_EXPORT FlView * fl_view_new(FlDartProject *project)
Definition: fl_view.cc:829
fl_engine_private.h
TRUE
return TRUE
Definition: fl_pixel_buffer_texture_test.cc:53
fl_view_get_engine
G_MODULE_EXPORT FlEngine * fl_view_get_engine(FlView *self)
Definition: fl_view.cc:874
fl_view_redraw
void fl_view_redraw(FlView *self)
Definition: fl_view.cc:892
fl_view.h
result
GAsyncResult * result
Definition: fl_text_input_handler.cc:106
view
FlView * view
Definition: fl_application.cc:35
TEST
TEST(FlViewTest, GetEngine)
Definition: fl_view_test.cc:18
first_frame_cb
static void first_frame_cb(FlView *view, gboolean *first_frame_emitted)
Definition: fl_view_test.cc:14