Flutter Linux Embedder
fl_view_test.cc File Reference
#include "flutter/shell/platform/linux/public/flutter_linux/fl_view.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/fl_view_private.h"
#include "flutter/shell/platform/linux/testing/fl_test.h"
#include "flutter/shell/platform/linux/testing/fl_test_gtk_logs.h"
#include "flutter/shell/platform/linux/testing/mock_gtk.h"
#include "gtest/gtest.h"

Go to the source code of this file.

Functions

static void first_frame_cb (FlView *view, gboolean *first_frame_emitted)
 
 TEST (FlViewTest, GetEngine)
 
 TEST (FlViewTest, StateUpdateDoesNotHappenInInit)
 
 TEST (FlViewTest, FirstFrameSignal)
 
 TEST (FlViewTest, SemanticsUpdate)
 
 TEST (FlViewTest, SemanticsUpdateOtherView)
 
 TEST (FlViewTest, SecondaryView)
 
 TEST (FlViewTest, SecondaryViewError)
 
 TEST (FlViewTest, ViewDestroy)
 
 TEST (FlViewTest, ViewDestroyError)
 

Function Documentation

◆ first_frame_cb()

static void first_frame_cb ( FlView *  view,
gboolean *  first_frame_emitted 
)
static

Definition at line 15 of file fl_view_test.cc.

15  {
16  *first_frame_emitted = TRUE;
17 }

References TRUE.

Referenced by TEST().

◆ TEST() [1/9]

TEST ( FlViewTest  ,
FirstFrameSignal   
)

Definition at line 43 of file fl_view_test.cc.

43  {
44  flutter::testing::fl_ensure_gtk_init();
45 
46  g_autoptr(FlDartProject) project = fl_dart_project_new();
47  FlView* view = fl_view_new(project);
48  gboolean first_frame_emitted = FALSE;
49  g_signal_connect(view, "first-frame", G_CALLBACK(first_frame_cb),
50  &first_frame_emitted);
51 
52  EXPECT_FALSE(first_frame_emitted);
53 
54  fl_renderable_redraw(FL_RENDERABLE(view));
55 
56  // Signal is emitted in idle, clear the main loop.
57  while (g_main_context_iteration(g_main_context_default(), FALSE)) {
58  // Repeat until nothing to iterate on.
59  }
60 
61  // Check view has detected frame.
62  EXPECT_TRUE(first_frame_emitted);
63 }
FlView * view
G_MODULE_EXPORT FlDartProject * fl_dart_project_new()
void fl_renderable_redraw(FlRenderable *self)
G_MODULE_EXPORT FlView * fl_view_new(FlDartProject *project)
Definition: fl_view.cc:751
static void first_frame_cb(FlView *view, gboolean *first_frame_emitted)
Definition: fl_view_test.cc:15

References first_frame_cb(), fl_dart_project_new(), fl_renderable_redraw(), fl_view_new(), and view.

◆ TEST() [2/9]

TEST ( FlViewTest  ,
GetEngine   
)

Definition at line 19 of file fl_view_test.cc.

19  {
20  flutter::testing::fl_ensure_gtk_init();
21  g_autoptr(FlDartProject) project = fl_dart_project_new();
22  FlView* view = fl_view_new(project);
23 
24  // Check the engine is immediately available (i.e. before the widget is
25  // realized).
26  FlEngine* engine = fl_view_get_engine(view);
27  EXPECT_NE(engine, nullptr);
28 }
G_MODULE_EXPORT FlEngine * fl_view_get_engine(FlView *self)
Definition: fl_view.cc:787

References fl_dart_project_new(), fl_view_get_engine(), fl_view_new(), and view.

◆ TEST() [3/9]

TEST ( FlViewTest  ,
SecondaryView   
)

Definition at line 117 of file fl_view_test.cc.

117  {
118  flutter::testing::fl_ensure_gtk_init();
119 
120  g_autoptr(FlDartProject) project = fl_dart_project_new();
121  FlView* implicit_view = fl_view_new(project);
122 
123  FlEngine* engine = fl_view_get_engine(implicit_view);
124 
125  FlutterViewId view_id = -1;
126  fl_engine_get_embedder_api(engine)->AddView = MOCK_ENGINE_PROC(
127  AddView, ([&view_id](auto engine, const FlutterAddViewInfo* info) {
128  view_id = info->view_id;
129  FlutterAddViewResult result = {
130  .struct_size = sizeof(FlutterAddViewResult),
131  .added = true,
132  .user_data = info->user_data};
133  info->add_view_callback(&result);
134  return kSuccess;
135  }));
136 
137  g_autoptr(GError) error = nullptr;
138  EXPECT_TRUE(fl_engine_start(engine, &error));
139 
140  FlView* secondary_view = fl_view_new_for_engine(engine);
141  EXPECT_EQ(view_id, fl_view_get_id(secondary_view));
142 }
FlutterEngineProcTable * fl_engine_get_embedder_api(FlEngine *self)
Definition: fl_engine.cc:726
gboolean fl_engine_start(FlEngine *self, GError **error)
Definition: fl_engine.cc:613
G_BEGIN_DECLS G_MODULE_EXPORT FlValue gpointer user_data
const uint8_t uint32_t uint32_t GError ** error
G_MODULE_EXPORT FlView * fl_view_new_for_engine(FlEngine *engine)
Definition: fl_view.cc:772
G_MODULE_EXPORT int64_t fl_view_get_id(FlView *self)
Definition: fl_view.cc:793
G_BEGIN_DECLS FlutterViewId view_id

References error, fl_dart_project_new(), fl_engine_get_embedder_api(), fl_engine_start(), fl_view_get_engine(), fl_view_get_id(), fl_view_new(), fl_view_new_for_engine(), user_data, and view_id.

◆ TEST() [4/9]

TEST ( FlViewTest  ,
SecondaryViewError   
)

Definition at line 145 of file fl_view_test.cc.

145  {
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 
153  FlutterViewId view_id = -1;
154  fl_engine_get_embedder_api(engine)->AddView = MOCK_ENGINE_PROC(
155  AddView, ([&view_id](auto engine, const FlutterAddViewInfo* info) {
156  view_id = info->view_id;
157  return kInvalidArguments;
158  }));
159 
160  g_autoptr(GError) error = nullptr;
161  EXPECT_TRUE(fl_engine_start(engine, &error));
162 
163  FlView* secondary_view = fl_view_new_for_engine(engine);
164  EXPECT_EQ(view_id, fl_view_get_id(secondary_view));
165 }

References error, fl_dart_project_new(), fl_engine_get_embedder_api(), fl_engine_start(), fl_view_get_engine(), fl_view_get_id(), fl_view_new(), fl_view_new_for_engine(), and view_id.

◆ TEST() [5/9]

TEST ( FlViewTest  ,
SemanticsUpdate   
)

Definition at line 66 of file fl_view_test.cc.

66  {
67  flutter::testing::fl_ensure_gtk_init();
68 
69  g_autoptr(FlDartProject) project = fl_dart_project_new();
70  FlView* view = fl_view_new(project);
71 
72  FlEngine* engine = fl_view_get_engine(view);
73  g_autoptr(GError) error = nullptr;
74  EXPECT_TRUE(fl_engine_start(engine, &error));
75 
76  FlutterSemanticsNode2 root_node = {
77  .id = 0,
78  .label = "root",
79  };
80  FlutterSemanticsNode2* nodes[1] = {&root_node};
81  FlutterSemanticsUpdate2 update = {
82  .node_count = 1, .nodes = nodes, .view_id = 0};
83  g_signal_emit_by_name(engine, "update-semantics", &update);
84 
85  FlViewAccessible* accessible = fl_view_get_accessible(view);
86  EXPECT_EQ(atk_object_get_n_accessible_children(ATK_OBJECT(accessible)), 1);
87  AtkObject* root_object =
88  atk_object_ref_accessible_child(ATK_OBJECT(accessible), 0);
89  EXPECT_STREQ(atk_object_get_name(root_object), "root");
90 }
FlViewAccessible * fl_view_get_accessible(FlView *self)
Definition: fl_view.cc:805

References error, fl_dart_project_new(), fl_engine_start(), fl_view_get_accessible(), fl_view_get_engine(), fl_view_new(), and view.

◆ TEST() [6/9]

TEST ( FlViewTest  ,
SemanticsUpdateOtherView   
)

Definition at line 93 of file fl_view_test.cc.

93  {
94  flutter::testing::fl_ensure_gtk_init();
95 
96  g_autoptr(FlDartProject) project = fl_dart_project_new();
97  FlView* view = fl_view_new(project);
98 
99  FlEngine* engine = fl_view_get_engine(view);
100  g_autoptr(GError) error = nullptr;
101  EXPECT_TRUE(fl_engine_start(engine, &error));
102 
103  FlutterSemanticsNode2 root_node = {
104  .id = 0,
105  .label = "root",
106  };
107  FlutterSemanticsNode2* nodes[1] = {&root_node};
108  FlutterSemanticsUpdate2 update = {
109  .node_count = 1, .nodes = nodes, .view_id = 99};
110  g_signal_emit_by_name(engine, "update-semantics", &update);
111 
112  FlViewAccessible* accessible = fl_view_get_accessible(view);
113  EXPECT_EQ(atk_object_get_n_accessible_children(ATK_OBJECT(accessible)), 0);
114 }

References error, fl_dart_project_new(), fl_engine_start(), fl_view_get_accessible(), fl_view_get_engine(), fl_view_new(), and view.

◆ TEST() [7/9]

TEST ( FlViewTest  ,
StateUpdateDoesNotHappenInInit   
)

Definition at line 30 of file fl_view_test.cc.

30  {
31  flutter::testing::fl_ensure_gtk_init();
32  g_autoptr(FlDartProject) project = fl_dart_project_new();
33  FlView* view = fl_view_new(project);
34  // Check that creating a view doesn't try to query the window state in
35  // initialization, causing a critical log to be issued.
36  EXPECT_EQ(
37  flutter::testing::fl_get_received_gtk_log_levels() & G_LOG_LEVEL_CRITICAL,
38  (GLogLevelFlags)0x0);
39 
40  (void)view;
41 }

References fl_dart_project_new(), fl_view_new(), and view.

◆ TEST() [8/9]

TEST ( FlViewTest  ,
ViewDestroy   
)

Definition at line 168 of file fl_view_test.cc.

168  {
169  flutter::testing::fl_ensure_gtk_init();
170 
171  g_autoptr(FlDartProject) project = fl_dart_project_new();
172  FlView* implicit_view = fl_view_new(project);
173 
174  FlEngine* engine = fl_view_get_engine(implicit_view);
175 
176  g_autoptr(GPtrArray) removed_views = g_ptr_array_new();
177  fl_engine_get_embedder_api(engine)->RemoveView = MOCK_ENGINE_PROC(
178  RemoveView,
179  ([removed_views](auto engine, const FlutterRemoveViewInfo* info) {
180  g_ptr_array_add(removed_views, GINT_TO_POINTER(info->view_id));
181  return kSuccess;
182  }));
183 
184  g_autoptr(GError) error = nullptr;
185  EXPECT_TRUE(fl_engine_start(engine, &error));
186 
187  FlView* secondary_view = fl_view_new_for_engine(engine);
188 
189  int64_t implicit_view_id = fl_view_get_id(implicit_view);
190  int64_t secondary_view_id = fl_view_get_id(secondary_view);
191 
192  fl_gtk_widget_destroy(GTK_WIDGET(secondary_view));
193  fl_gtk_widget_destroy(GTK_WIDGET(implicit_view));
194 
195  EXPECT_EQ(removed_views->len, 2u);
196  EXPECT_EQ(GPOINTER_TO_INT(g_ptr_array_index(removed_views, 0)),
197  secondary_view_id);
198  EXPECT_EQ(GPOINTER_TO_INT(g_ptr_array_index(removed_views, 1)),
199  implicit_view_id);
200 }

References error, fl_dart_project_new(), fl_engine_get_embedder_api(), fl_engine_start(), fl_view_get_engine(), fl_view_get_id(), fl_view_new(), and fl_view_new_for_engine().

◆ TEST() [9/9]

TEST ( FlViewTest  ,
ViewDestroyError   
)

Definition at line 203 of file fl_view_test.cc.

203  {
204  flutter::testing::fl_ensure_gtk_init();
205 
206  g_autoptr(FlDartProject) project = fl_dart_project_new();
207  FlView* implicit_view = fl_view_new(project);
208 
209  FlEngine* engine = fl_view_get_engine(implicit_view);
210 
211  fl_engine_get_embedder_api(engine)->RemoveView = MOCK_ENGINE_PROC(
212  RemoveView, ([](auto engine, const FlutterRemoveViewInfo* info) {
213  return kInvalidArguments;
214  }));
215 
216  g_autoptr(GError) error = nullptr;
217  EXPECT_TRUE(fl_engine_start(engine, &error));
218 
219  FlView* secondary_view = fl_view_new_for_engine(engine);
220 
221  fl_gtk_widget_destroy(GTK_WIDGET(secondary_view));
222  fl_gtk_widget_destroy(GTK_WIDGET(implicit_view));
223 }

References error, fl_dart_project_new(), fl_engine_get_embedder_api(), fl_engine_start(), fl_view_get_engine(), fl_view_new(), and fl_view_new_for_engine().