Flutter Engine
mock_engine.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 <cstring>
6 
7 #include "flutter/shell/platform/embedder/embedder.h"
8 #include "flutter/shell/platform/linux/fl_method_codec_private.h"
9 #include "flutter/shell/platform/linux/public/flutter_linux/fl_method_response.h"
10 #include "flutter/shell/platform/linux/public/flutter_linux/fl_standard_method_codec.h"
11 #include "gtest/gtest.h"
12 
14  bool running;
17  void* user_data;
18 
20  FlutterTaskRunnerPostTaskCallback platform_post_task_callback,
21  void* user_data)
22  : running(false),
23  platform_message_callback(platform_message_callback),
24  platform_post_task_callback(platform_post_task_callback),
25  user_data(user_data) {}
26 };
27 
30  void* user_data;
31  std::string channel;
32  bool released;
33 
34  // Constructor for a response handle generated by the engine.
35  explicit _FlutterPlatformMessageResponseHandle(std::string channel)
36  : data_callback(nullptr),
37  user_data(nullptr),
38  channel(channel),
39  released(false) {}
40 
41  // Constructor for a response handle generated by the shell.
43  void* user_data)
44  : data_callback(data_callback), user_data(user_data), released(false) {}
45 };
46 
48  uint64_t task;
49  std::string channel;
51  uint8_t* message;
52  size_t message_size;
53 
55  uint64_t task,
56  const std::string& channel,
57  const FlutterPlatformMessageResponseHandle* response_handle,
58  const uint8_t* message,
59  size_t message_size)
60  : task(task),
61  channel(channel),
62  response_handle(response_handle),
63  message_size(message_size) {
64  if (message_size > 0) {
65  this->message = static_cast<uint8_t*>(malloc(message_size));
66  memcpy(this->message, message, message_size);
67  } else {
68  this->message = nullptr;
69  }
70  }
72  if (response_handle != nullptr) {
73  EXPECT_TRUE(response_handle->released);
74  delete response_handle;
75  }
76  free(message);
77  }
78 };
79 
80 // Send a response from the engine.
81 static void send_response(
83  const std::string& channel,
84  const FlutterPlatformMessageResponseHandle* response_handle,
85  const uint8_t* message,
86  size_t message_size) {
87  if (response_handle == nullptr) {
88  return;
89  }
90 
91  FlutterTask task;
92  task.runner = new _FlutterTaskRunner(1234, channel, response_handle, message,
93  message_size);
94  task.task = task.runner->task;
95  engine->platform_post_task_callback(task, 0, engine->user_data);
96 }
97 
98 // Send a message from the engine.
100  const std::string& channel,
101  const uint8_t* message,
102  size_t message_size) {
103  FlutterTask task;
104  task.runner =
105  new _FlutterTaskRunner(1234, channel, nullptr, message, message_size);
106  task.task = task.runner->task;
107  engine->platform_post_task_callback(task, 0, engine->user_data);
108 }
109 
111  const std::string& channel,
112  const gchar* name,
113  FlValue* args) {
114  g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new();
115  g_autoptr(GError) error = nullptr;
116  g_autoptr(GBytes) message = fl_method_codec_encode_method_call(
117  FL_METHOD_CODEC(codec), name, args, &error);
118  EXPECT_NE(message, nullptr);
119  EXPECT_EQ(error, nullptr);
120 
121  FlutterTask task;
122  task.runner = new _FlutterTaskRunner(
123  1234, channel, nullptr,
124  static_cast<const uint8_t*>(g_bytes_get_data(message, nullptr)),
125  g_bytes_get_size(message));
126  task.task = task.runner->task;
127  engine->platform_post_task_callback(task, 0, engine->user_data);
128 }
129 
131  const FlutterEngineAOTDataSource* source,
132  FlutterEngineAOTData* data_out) {
133  *data_out = nullptr;
134  return kSuccess;
135 }
136 
138  return kSuccess;
139 }
140 
142  const FlutterRendererConfig* config,
143  const FlutterProjectArgs* args,
144  void* user_data,
146  engine_out) {
147  EXPECT_NE(config, nullptr);
148  EXPECT_NE(args, nullptr);
149  EXPECT_NE(user_data, nullptr);
150  EXPECT_NE(engine_out, nullptr);
151 
152  FlutterEngineResult result =
153  FlutterEngineInitialize(version, config, args, user_data, engine_out);
154  if (result != kSuccess) {
155  return result;
156  }
157  return FlutterEngineRunInitialized(*engine_out);
158 }
159 
161  engine) {
162  delete engine;
163  return kSuccess;
164 }
165 
167  const FlutterRendererConfig* config,
168  const FlutterProjectArgs* args,
169  void* user_data,
171  engine_out) {
172  EXPECT_NE(config, nullptr);
173 
174  EXPECT_NE(args, nullptr);
175  EXPECT_NE(args->platform_message_callback, nullptr);
176  EXPECT_NE(args->custom_task_runners, nullptr);
177  EXPECT_NE(args->custom_task_runners->platform_task_runner, nullptr);
179  nullptr);
180 
181  EXPECT_NE(user_data, nullptr);
182 
183  EXPECT_EQ(config->type, kOpenGL);
184 
185  *engine_out = new _FlutterEngine(
188  user_data);
189  return kSuccess;
190 }
191 
193  engine) {
194  return kSuccess;
195 }
196 
199  engine->running = true;
200  return kSuccess;
201 }
202 
206  EXPECT_TRUE(engine->running);
207  return kSuccess;
208 }
209 
212  const FlutterPointerEvent* events,
213  size_t events_count) {
214  return kSuccess;
215 }
216 
220  const FlutterPlatformMessage* message) {
221  EXPECT_TRUE(engine->running);
222 
223  if (strcmp(message->channel, "test/echo") == 0) {
224  // Responds with the same message received.
225  send_response(engine, message->channel, message->response_handle,
226  message->message, message->message_size);
227  } else if (strcmp(message->channel, "test/send-message") == 0) {
228  // Triggers the engine to send a message.
229  send_response(engine, message->channel, message->response_handle, nullptr,
230  0);
231  send_message(engine, "test/messages", message->message,
232  message->message_size);
233  } else if (strcmp(message->channel, "test/standard-method") == 0) {
234  g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new();
235  g_autoptr(GBytes) m = g_bytes_new(message->message, message->message_size);
236  g_autofree gchar* name = nullptr;
237  g_autoptr(FlValue) args = nullptr;
238  g_autoptr(GError) error = nullptr;
239  EXPECT_TRUE(fl_method_codec_decode_method_call(FL_METHOD_CODEC(codec), m,
240  &name, &args, &error));
241  EXPECT_EQ(error, nullptr);
242 
243  g_autoptr(GBytes) response = nullptr;
244  if (strcmp(name, "Echo") == 0) {
245  // Returns args as a success result.
246  response = fl_method_codec_encode_success_envelope(FL_METHOD_CODEC(codec),
247  args, &error);
248  EXPECT_EQ(error, nullptr);
249  } else if (strcmp(name, "Error") == 0) {
250  // Returns an error result.
251  const gchar* code = nullptr;
252  const gchar* message = nullptr;
253  FlValue* details = nullptr;
254  if (fl_value_get_length(args) >= 2) {
255  FlValue* code_value = fl_value_get_list_value(args, 0);
256  EXPECT_EQ(fl_value_get_type(code_value), FL_VALUE_TYPE_STRING);
257  code = fl_value_get_string(code_value);
258  FlValue* message_value = fl_value_get_list_value(args, 1);
259  message = fl_value_get_type(message_value) == FL_VALUE_TYPE_STRING
260  ? fl_value_get_string(message_value)
261  : nullptr;
262  }
263  if (fl_value_get_length(args) >= 3) {
264  details = fl_value_get_list_value(args, 2);
265  }
267  FL_METHOD_CODEC(codec), code, message, details, &error);
268  EXPECT_EQ(error, nullptr);
269  } else if (strcmp(name, "InvokeMethod") == 0) {
270  // Gets the engine to call the shell.
271  if (fl_value_get_length(args) == 3) {
272  FlValue* channel_value = fl_value_get_list_value(args, 0);
273  EXPECT_EQ(fl_value_get_type(channel_value), FL_VALUE_TYPE_STRING);
274  const gchar* channel = fl_value_get_string(channel_value);
275  FlValue* name_value = fl_value_get_list_value(args, 1);
276  EXPECT_EQ(fl_value_get_type(name_value), FL_VALUE_TYPE_STRING);
277  const gchar* name = fl_value_get_string(name_value);
278  FlValue* method_args = fl_value_get_list_value(args, 2);
279  invoke_method(engine, channel, name, method_args);
280  }
281  response = fl_method_codec_encode_success_envelope(FL_METHOD_CODEC(codec),
282  nullptr, &error);
283  EXPECT_EQ(error, nullptr);
284  } else {
285  // Returns "not implemented".
286  response = g_bytes_new(nullptr, 0);
287  }
288 
290  engine, message->channel, message->response_handle,
291  static_cast<const uint8_t*>(g_bytes_get_data(response, nullptr)),
292  g_bytes_get_size(response));
293  } else if (strcmp(message->channel, "test/nullptr-response") == 0) {
294  // Sends a null response.
295  send_response(engine, message->channel, message->response_handle, nullptr,
296  0);
297  } else if (strcmp(message->channel, "test/standard-event") == 0) {
298  // Send a message so the shell can check the events sent.
299  send_message(engine, "test/events", message->message,
300  message->message_size);
301  } else if (strcmp(message->channel, "test/failure") == 0) {
302  // Generates an internal error.
303  return kInternalInconsistency;
304  }
305 
306  return kSuccess;
307 }
308 
311  FlutterDataCallback data_callback,
312  void* user_data,
313  FlutterPlatformMessageResponseHandle** response_out) {
314  EXPECT_TRUE(engine->running);
315  EXPECT_NE(data_callback, nullptr);
316  EXPECT_NE(user_data, nullptr);
317 
319  new _FlutterPlatformMessageResponseHandle(data_callback, user_data);
320 
321  *response_out = handle;
322  return kSuccess;
323 }
324 
328  EXPECT_NE(engine, nullptr);
329  EXPECT_NE(response, nullptr);
330 
331  EXPECT_TRUE(engine->running);
332 
333  EXPECT_FALSE(response->released);
334  response->released = true;
335 
336  return kSuccess;
337 }
338 
342  const uint8_t* data,
343  size_t data_length) {
344  EXPECT_NE(engine, nullptr);
345  EXPECT_NE(handle, nullptr);
346 
347  EXPECT_TRUE(engine->running);
348 
349  // Send a message so the shell can check the responses received.
350  if (handle->channel != "test/responses") {
351  send_message(engine, "test/responses", data, data_length);
352  }
353 
354  EXPECT_FALSE(handle->released);
355 
356  delete handle;
357 
358  return kSuccess;
359 }
360 
362  engine,
363  const FlutterTask* task) {
364  EXPECT_NE(engine, nullptr);
365  EXPECT_NE(task, nullptr);
366  EXPECT_NE(task->runner, nullptr);
367 
368  FlutterTaskRunner runner = task->runner;
369  EXPECT_NE(runner, nullptr);
370  const FlutterPlatformMessageResponseHandle* response_handle =
371  runner->response_handle;
372  if (response_handle != nullptr) {
373  EXPECT_NE(response_handle->data_callback, nullptr);
374  response_handle->data_callback(runner->message, runner->message_size,
375  response_handle->user_data);
376  } else {
379 
380  FlutterPlatformMessage message;
381  message.struct_size = sizeof(FlutterPlatformMessage);
382  message.channel = runner->channel.c_str();
383  message.message = runner->message;
384  message.message_size = runner->message_size;
385  message.response_handle = handle;
386  engine->platform_message_callback(&message, engine->user_data);
387  }
388 
389  delete runner;
390 
391  return kSuccess;
392 }
393 
395  return false;
396 }
397 
399  engine,
400  const FlutterLocale** locales,
401  size_t locales_count) {
402  return kSuccess;
403 }
G_BEGIN_DECLS FlValue * args
_FlutterTaskRunner(uint64_t task, const std::string &channel, const FlutterPlatformMessageResponseHandle *response_handle, const uint8_t *message, size_t message_size)
Definition: mock_engine.cc:54
const char * channel
Definition: embedder.h:567
struct _FlutterEngine * FLUTTER_API_SYMBOL(FlutterEngine)
Definition: embedder.h:220
GBytes * fl_method_codec_encode_method_call(FlMethodCodec *self, const gchar *name, FlValue *args, GError **error)
static void invoke_method(FLUTTER_API_SYMBOL(FlutterEngine) engine, const std::string &channel, const gchar *name, FlValue *args)
Definition: mock_engine.cc:110
FlutterEngineResult FlutterEngineCreateAOTData(const FlutterEngineAOTDataSource *source, FlutterEngineAOTData *data_out)
Creates the necessary data structures to launch a Flutter Dart application in AOT mode...
Definition: mock_engine.cc:130
FlutterEngineResult FlutterPlatformMessageReleaseResponseHandle(FLUTTER_API_SYMBOL(FlutterEngine) engine, FlutterPlatformMessageResponseHandle *response)
Collects the handle created using FlutterPlatformMessageCreateResponseHandle.
Definition: mock_engine.cc:325
FlutterEngineResult FlutterEngineRunInitialized(FLUTTER_API_SYMBOL(FlutterEngine) engine)
Runs an initialized engine instance. An engine can be initialized via FlutterEngineInitialize. An initialized instance can only be run once. During and after this call, custom task runners supplied by the embedder are expected to start servicing tasks.
Definition: mock_engine.cc:197
G_MODULE_EXPORT FlValueType fl_value_get_type(FlValue *self)
Definition: fl_value.cc:395
FlutterEngineResult FlutterEngineUpdateLocales(FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterLocale **locales, size_t locales_count)
Notify a running engine instance that the locale has been updated. The preferred locale must be the f...
Definition: mock_engine.cc:398
FlutterEngineResult FlutterPlatformMessageCreateResponseHandle(FLUTTER_API_SYMBOL(FlutterEngine) engine, FlutterDataCallback data_callback, void *user_data, FlutterPlatformMessageResponseHandle **response_out)
Creates a platform message response handle that allows the embedder to set a native callback for a re...
Definition: mock_engine.cc:309
FlutterEngineResult FlutterEngineSendPlatformMessageResponse(FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterPlatformMessageResponseHandle *handle, const uint8_t *data, size_t data_length)
Send a response from the native side to a platform message from the Dart Flutter application.
Definition: mock_engine.cc:339
static void send_response(FLUTTER_API_SYMBOL(FlutterEngine) engine, const std::string &channel, const FlutterPlatformMessageResponseHandle *response_handle, const uint8_t *message, size_t message_size)
Definition: mock_engine.cc:81
void * user_data
Definition: mock_engine.cc:17
typedefG_BEGIN_DECLS struct _FlValue FlValue
Definition: fl_value.h:39
FlMethodResponse GError ** error
const FlutterPlatformMessageResponseHandle * response_handle
Definition: embedder.h:576
const FlutterCustomTaskRunners * custom_task_runners
Definition: embedder.h:1313
FlutterTaskRunner runner
Definition: embedder.h:707
FlutterEngineResult FlutterEngineDeinitialize(FLUTTER_API_SYMBOL(FlutterEngine) engine)
Stops running the Flutter engine instance. After this call, the embedder is also guaranteed that no m...
Definition: mock_engine.cc:192
FlutterPlatformMessageCallback platform_message_callback
Definition: embedder.h:1222
FlutterEngineResult FlutterEngineCollectAOTData(FlutterEngineAOTData data)
Collects the AOT data.
Definition: mock_engine.cc:137
uint64_t task
Definition: embedder.h:708
FLUTTER_EXPORT FlutterEngineResult FlutterEngineSendPlatformMessage(FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterPlatformMessage *message)
Definition: mock_engine.cc:218
void(* FlutterTaskRunnerPostTaskCallback)(FlutterTask, uint64_t, void *)
Definition: embedder.h:711
FlutterEngineResult FlutterEngineRunTask(FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterTask *task)
Inform the engine to run the specified task. This task has been given to the engine via the FlutterTa...
Definition: mock_engine.cc:361
G_MODULE_EXPORT FlStandardMethodCodec * fl_standard_method_codec_new()
void(* FlutterPlatformMessageCallback)(const FlutterPlatformMessage *, void *)
Definition: embedder.h:579
FlutterPlatformMessageCallback platform_message_callback
Definition: mock_engine.cc:15
FlutterRendererType type
Definition: embedder.h:448
const FlutterPlatformMessageResponseHandle * response_handle
Definition: mock_engine.cc:50
const uint8_t * message
Definition: embedder.h:568
FlutterEngineResult FlutterEngineSendPointerEvent(FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterPointerEvent *events, size_t events_count)
Definition: mock_engine.cc:210
FlutterEngineResult FlutterEngineSendWindowMetricsEvent(FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterWindowMetricsEvent *event)
Definition: mock_engine.cc:203
FlutterEngineResult FlutterEngineShutdown(FLUTTER_API_SYMBOL(FlutterEngine) engine)
Shuts down a Flutter engine instance. The engine handle is no longer valid for any calls in the embed...
Definition: mock_engine.cc:160
G_MODULE_EXPORT FlValue * fl_value_get_list_value(FlValue *self, size_t index)
Definition: fl_value.cc:677
GdkEventButton * event
Definition: fl_view.cc:62
_FlutterEngine(FlutterPlatformMessageCallback platform_message_callback, FlutterTaskRunnerPostTaskCallback platform_post_task_callback, void *user_data)
Definition: mock_engine.cc:19
FlutterEngineResult
Definition: embedder.h:65
FlutterTaskRunnerPostTaskCallback platform_post_task_callback
Definition: mock_engine.cc:16
const char * name
Definition: fuchsia.cc:50
FlutterEngineResult FlutterEngineRun(size_t version, const FlutterRendererConfig *config, const FlutterProjectArgs *args, void *user_data, FLUTTER_API_SYMBOL(FlutterEngine) *engine_out)
Initialize and run a Flutter engine instance and return a handle to it. This is a convenience method ...
Definition: mock_engine.cc:141
_FlutterPlatformMessageResponseHandle(std::string channel)
Definition: mock_engine.cc:35
const FlutterTaskRunnerDescription * platform_task_runner
Definition: embedder.h:752
G_MODULE_EXPORT const gchar * fl_value_get_string(FlValue *self)
Definition: fl_value.cc:596
_FlutterPlatformMessageResponseHandle(FlutterDataCallback data_callback, void *user_data)
Definition: mock_engine.cc:42
FlutterTaskRunnerPostTaskCallback post_task_callback
Definition: embedder.h:739
GBytes * fl_method_codec_encode_error_envelope(FlMethodCodec *self, const gchar *code, const gchar *message, FlValue *details, GError **error)
static void send_message(FLUTTER_API_SYMBOL(FlutterEngine) engine, const std::string &channel, const uint8_t *message, size_t message_size)
Definition: mock_engine.cc:99
GBytes * fl_method_codec_encode_success_envelope(FlMethodCodec *self, FlValue *result, GError **error)
size_t struct_size
The size of this struct. Must be sizeof(FlutterPlatformMessage).
Definition: embedder.h:566
void(* FlutterDataCallback)(const uint8_t *, size_t, void *)
Definition: embedder.h:583
G_MODULE_EXPORT size_t fl_value_get_length(FlValue *self)
Definition: fl_value.cc:631
gboolean fl_method_codec_decode_method_call(FlMethodCodec *self, GBytes *message, gchar **name, FlValue **args, GError **error)
bool FlutterEngineRunsAOTCompiledDartCode()
Returns if the Flutter engine instance will run AOT compiled Dart code. This call has no threading re...
Definition: mock_engine.cc:394
#define FLUTTER_EXPORT
FlutterEngineResult FlutterEngineInitialize(size_t version, const FlutterRendererConfig *config, const FlutterProjectArgs *args, void *user_data, FLUTTER_API_SYMBOL(FlutterEngine) *engine_out)
Initialize a Flutter engine instance. This does not run the Flutter application code till the Flutter...
Definition: mock_engine.cc:166
std::string channel
Definition: mock_engine.cc:49