Flutter Engine
embedder.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 #define FML_USED_ON_EMBEDDER
6 #define RAPIDJSON_HAS_STDSTRING 1
7 
8 #include <cstring>
9 #include <iostream>
10 #include <memory>
11 #include <set>
12 #include <string>
13 #include <vector>
14 
15 #include "flutter/fml/build_config.h"
16 #include "flutter/fml/closure.h"
17 #include "flutter/fml/make_copyable.h"
18 #include "flutter/fml/native_library.h"
19 #include "third_party/dart/runtime/bin/elf_loader.h"
20 #include "third_party/dart/runtime/include/dart_native_api.h"
21 
22 #if !defined(FLUTTER_NO_EXPORT)
23 #if OS_WIN
24 #define FLUTTER_EXPORT __declspec(dllexport)
25 #else // OS_WIN
26 #define FLUTTER_EXPORT __attribute__((visibility("default")))
27 #endif // OS_WIN
28 #endif // !FLUTTER_NO_EXPORT
29 
30 extern "C" {
31 #if FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG
32 // Used for debugging dart:* sources.
33 extern const uint8_t kPlatformStrongDill[];
34 extern const intptr_t kPlatformStrongDillSize;
35 #endif // FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG
36 }
37 
38 #include "flutter/assets/directory_asset_bundle.h"
39 #include "flutter/common/graphics/persistent_cache.h"
40 #include "flutter/common/task_runners.h"
41 #include "flutter/fml/command_line.h"
42 #include "flutter/fml/file.h"
43 #include "flutter/fml/make_copyable.h"
44 #include "flutter/fml/message_loop.h"
45 #include "flutter/fml/paths.h"
46 #include "flutter/fml/trace_event.h"
47 #include "flutter/shell/common/rasterizer.h"
48 #include "flutter/shell/common/switches.h"
49 #include "flutter/shell/platform/embedder/embedder.h"
50 #include "flutter/shell/platform/embedder/embedder_engine.h"
51 #include "flutter/shell/platform/embedder/embedder_external_texture_resolver.h"
52 #include "flutter/shell/platform/embedder/embedder_platform_message_response.h"
53 #include "flutter/shell/platform/embedder/embedder_render_target.h"
54 #include "flutter/shell/platform/embedder/embedder_struct_macros.h"
55 #include "flutter/shell/platform/embedder/embedder_task_runner.h"
56 #include "flutter/shell/platform/embedder/embedder_thread_host.h"
57 #include "flutter/shell/platform/embedder/platform_view_embedder.h"
58 #include "rapidjson/rapidjson.h"
59 #include "rapidjson/writer.h"
60 
61 #ifdef SHELL_ENABLE_GL
62 #include "flutter/shell/platform/embedder/embedder_external_texture_gl.h"
63 #endif
64 
65 #ifdef SHELL_ENABLE_METAL
66 #include "flutter/shell/platform/embedder/embedder_surface_metal.h"
67 #endif
68 
71 
73  const char* reason,
74  const char* code_name,
75  const char* function,
76  const char* file,
77  int line) {
78 #if OS_WIN
79  constexpr char kSeparator = '\\';
80 #else
81  constexpr char kSeparator = '/';
82 #endif
83  const auto file_base =
84  (::strrchr(file, kSeparator) ? strrchr(file, kSeparator) + 1 : file);
85  char error[256] = {};
86  snprintf(error, (sizeof(error) / sizeof(char)),
87  "%s (%d): '%s' returned '%s'. %s", file_base, line, function,
88  code_name, reason);
89  std::cerr << error << std::endl;
90  return code;
91 }
92 
93 #define LOG_EMBEDDER_ERROR(code, reason) \
94  LogEmbedderError(code, reason, #code, __FUNCTION__, __FILE__, __LINE__)
95 
97  if (config->type != kOpenGL) {
98  return false;
99  }
100 
101  const FlutterOpenGLRendererConfig* open_gl_config = &config->open_gl;
102 
103  if (!SAFE_EXISTS(open_gl_config, make_current) ||
104  !SAFE_EXISTS(open_gl_config, clear_current) ||
105  !SAFE_EXISTS_ONE_OF(open_gl_config, fbo_callback,
106  fbo_with_frame_info_callback) ||
107  !SAFE_EXISTS_ONE_OF(open_gl_config, present, present_with_info)) {
108  return false;
109  }
110 
111  return true;
112 }
113 
115  if (config->type != kSoftware) {
116  return false;
117  }
118 
119  const FlutterSoftwareRendererConfig* software_config = &config->software;
120 
121  if (SAFE_ACCESS(software_config, surface_present_callback, nullptr) ==
122  nullptr) {
123  return false;
124  }
125 
126  return true;
127 }
128 
130  if (config->type != kMetal) {
131  return false;
132  }
133 
134  const FlutterMetalRendererConfig* metal_config = &config->metal;
135 
136  bool device = SAFE_ACCESS(metal_config, device, nullptr);
137  bool command_queue =
138  SAFE_ACCESS(metal_config, present_command_queue, nullptr);
139 
140  bool present = SAFE_ACCESS(metal_config, present_drawable_callback, nullptr);
141  bool get_texture =
142  SAFE_ACCESS(metal_config, get_next_drawable_callback, nullptr);
143 
144  return device && command_queue && present && get_texture;
145 }
146 
147 static bool IsRendererValid(const FlutterRendererConfig* config) {
148  if (config == nullptr) {
149  return false;
150  }
151 
152  switch (config->type) {
153  case kOpenGL:
154  return IsOpenGLRendererConfigValid(config);
155  case kSoftware:
156  return IsSoftwareRendererConfigValid(config);
157  case kMetal:
158  return IsMetalRendererConfigValid(config);
159  default:
160  return false;
161  }
162 
163  return false;
164 }
165 
166 #if OS_LINUX || OS_WIN
167 static void* DefaultGLProcResolver(const char* name) {
168  static fml::RefPtr<fml::NativeLibrary> proc_library =
169 #if OS_LINUX
171 #elif OS_WIN // OS_LINUX
172  fml::NativeLibrary::Create("opengl32.dll");
173 #endif // OS_WIN
174  return static_cast<void*>(
175  const_cast<uint8_t*>(proc_library->ResolveSymbol(name)));
176 }
177 #endif // OS_LINUX || OS_WIN
178 
181  const FlutterRendererConfig* config,
182  void* user_data,
184  platform_dispatch_table,
185  std::unique_ptr<flutter::EmbedderExternalViewEmbedder>
186  external_view_embedder) {
187 #ifdef SHELL_ENABLE_GL
188  if (config->type != kOpenGL) {
189  return nullptr;
190  }
191 
192  auto gl_make_current = [ptr = config->open_gl.make_current,
193  user_data]() -> bool { return ptr(user_data); };
194 
195  auto gl_clear_current = [ptr = config->open_gl.clear_current,
196  user_data]() -> bool { return ptr(user_data); };
197 
198  auto gl_present = [present = config->open_gl.present,
199  present_with_info = config->open_gl.present_with_info,
200  user_data](uint32_t fbo_id) -> bool {
201  if (present) {
202  return present(user_data);
203  } else {
204  FlutterPresentInfo present_info = {};
205  present_info.struct_size = sizeof(FlutterPresentInfo);
206  present_info.fbo_id = fbo_id;
207  return present_with_info(user_data, &present_info);
208  }
209  };
210 
211  auto gl_fbo_callback =
212  [fbo_callback = config->open_gl.fbo_callback,
213  fbo_with_frame_info_callback =
215  user_data](flutter::GLFrameInfo gl_frame_info) -> intptr_t {
216  if (fbo_callback) {
217  return fbo_callback(user_data);
218  } else {
219  FlutterFrameInfo frame_info = {};
220  frame_info.struct_size = sizeof(FlutterFrameInfo);
221  frame_info.size = {gl_frame_info.width, gl_frame_info.height};
222  return fbo_with_frame_info_callback(user_data, &frame_info);
223  }
224  };
225 
226  const FlutterOpenGLRendererConfig* open_gl_config = &config->open_gl;
227  std::function<bool()> gl_make_resource_current_callback = nullptr;
228  if (SAFE_ACCESS(open_gl_config, make_resource_current, nullptr) != nullptr) {
229  gl_make_resource_current_callback =
230  [ptr = config->open_gl.make_resource_current, user_data]() {
231  return ptr(user_data);
232  };
233  }
234 
235  std::function<SkMatrix(void)> gl_surface_transformation_callback = nullptr;
236  if (SAFE_ACCESS(open_gl_config, surface_transformation, nullptr) != nullptr) {
237  gl_surface_transformation_callback =
238  [ptr = config->open_gl.surface_transformation, user_data]() {
239  FlutterTransformation transformation = ptr(user_data);
240  return SkMatrix::MakeAll(transformation.scaleX, //
241  transformation.skewX, //
242  transformation.transX, //
243  transformation.skewY, //
244  transformation.scaleY, //
245  transformation.transY, //
246  transformation.pers0, //
247  transformation.pers1, //
248  transformation.pers2 //
249  );
250  };
251 
252  // If there is an external view embedder, ask it to apply the surface
253  // transformation to its surfaces as well.
254  if (external_view_embedder) {
255  external_view_embedder->SetSurfaceTransformationCallback(
256  gl_surface_transformation_callback);
257  }
258  }
259 
260  flutter::GPUSurfaceGLDelegate::GLProcResolver gl_proc_resolver = nullptr;
261  if (SAFE_ACCESS(open_gl_config, gl_proc_resolver, nullptr) != nullptr) {
262  gl_proc_resolver = [ptr = config->open_gl.gl_proc_resolver,
263  user_data](const char* gl_proc_name) {
264  return ptr(user_data, gl_proc_name);
265  };
266  } else {
267 #if OS_LINUX || OS_WIN
268  gl_proc_resolver = DefaultGLProcResolver;
269 #endif
270  }
271 
272  bool fbo_reset_after_present =
273  SAFE_ACCESS(open_gl_config, fbo_reset_after_present, false);
274 
275  flutter::EmbedderSurfaceGL::GLDispatchTable gl_dispatch_table = {
276  gl_make_current, // gl_make_current_callback
277  gl_clear_current, // gl_clear_current_callback
278  gl_present, // gl_present_callback
279  gl_fbo_callback, // gl_fbo_callback
280  gl_make_resource_current_callback, // gl_make_resource_current_callback
281  gl_surface_transformation_callback, // gl_surface_transformation_callback
282  gl_proc_resolver, // gl_proc_resolver
283  };
284 
285  return fml::MakeCopyable(
286  [gl_dispatch_table, fbo_reset_after_present, platform_dispatch_table,
287  external_view_embedder =
288  std::move(external_view_embedder)](flutter::Shell& shell) mutable {
289  return std::make_unique<flutter::PlatformViewEmbedder>(
290  shell, // delegate
291  shell.GetTaskRunners(), // task runners
292  gl_dispatch_table, // embedder GL dispatch table
293  fbo_reset_after_present, // fbo reset after present
294  platform_dispatch_table, // embedder platform dispatch table
295  std::move(external_view_embedder) // external view embedder
296  );
297  });
298 #else
299  return nullptr;
300 #endif
301 }
302 
305  const FlutterRendererConfig* config,
306  void* user_data,
308  platform_dispatch_table,
309  std::unique_ptr<flutter::EmbedderExternalViewEmbedder>
310  external_view_embedder) {
311  if (config->type != kMetal) {
312  return nullptr;
313  }
314 
315 #ifdef SHELL_ENABLE_METAL
316  std::function<bool(flutter::GPUMTLTextureInfo texture)> metal_present =
317  [ptr = config->metal.present_drawable_callback,
319  FlutterMetalTexture embedder_texture;
320  embedder_texture.struct_size = sizeof(FlutterMetalTexture);
321  embedder_texture.texture = texture.texture;
322  embedder_texture.texture_id = texture.texture_id;
323  return ptr(user_data, &embedder_texture);
324  };
325  auto metal_get_texture =
326  [ptr = config->metal.get_next_drawable_callback,
327  user_data](const SkISize& frame_size) -> flutter::GPUMTLTextureInfo {
328  FlutterFrameInfo frame_info = {};
329  frame_info.struct_size = sizeof(FlutterFrameInfo);
330  frame_info.size = {static_cast<uint32_t>(frame_size.width()),
331  static_cast<uint32_t>(frame_size.height())};
332  flutter::GPUMTLTextureInfo texture_info;
333 
334  FlutterMetalTexture metal_texture = ptr(user_data, &frame_info);
335  texture_info.texture_id = metal_texture.texture_id;
336  texture_info.texture = metal_texture.texture;
337  return texture_info;
338  };
339 
341  .present = metal_present,
342  .get_texture = metal_get_texture,
343  };
344 
345  std::shared_ptr<flutter::EmbedderExternalViewEmbedder> view_embedder =
346  std::move(external_view_embedder);
347 
348  std::unique_ptr<flutter::EmbedderSurfaceMetal> embedder_surface =
349  std::make_unique<flutter::EmbedderSurfaceMetal>(
350  const_cast<flutter::GPUMTLDeviceHandle>(config->metal.device),
351  const_cast<flutter::GPUMTLCommandQueueHandle>(
352  config->metal.present_command_queue),
353  metal_dispatch_table, view_embedder);
354 
355  return fml::MakeCopyable(
356  [embedder_surface = std::move(embedder_surface), platform_dispatch_table,
357  external_view_embedder = view_embedder](flutter::Shell& shell) mutable {
358  return std::make_unique<flutter::PlatformViewEmbedder>(
359  shell, // delegate
360  shell.GetTaskRunners(), // task runners
361  std::move(embedder_surface), // embedder surface
362  platform_dispatch_table, // platform dispatch table
363  std::move(external_view_embedder) // external view embedder
364  );
365  });
366 #else
367  return nullptr;
368 #endif
369 }
370 
373  const FlutterRendererConfig* config,
374  void* user_data,
376  platform_dispatch_table,
377  std::unique_ptr<flutter::EmbedderExternalViewEmbedder>
378  external_view_embedder) {
379  if (config->type != kSoftware) {
380  return nullptr;
381  }
382 
383  auto software_present_backing_store =
385  const void* allocation, size_t row_bytes, size_t height) -> bool {
386  return ptr(user_data, allocation, row_bytes, height);
387  };
388 
390  software_dispatch_table = {
391  software_present_backing_store, // required
392  };
393 
394  return fml::MakeCopyable(
395  [software_dispatch_table, platform_dispatch_table,
396  external_view_embedder =
397  std::move(external_view_embedder)](flutter::Shell& shell) mutable {
398  return std::make_unique<flutter::PlatformViewEmbedder>(
399  shell, // delegate
400  shell.GetTaskRunners(), // task runners
401  software_dispatch_table, // software dispatch table
402  platform_dispatch_table, // platform dispatch table
403  std::move(external_view_embedder) // external view embedder
404  );
405  });
406 }
407 
410  const FlutterRendererConfig* config,
411  void* user_data,
413  platform_dispatch_table,
414  std::unique_ptr<flutter::EmbedderExternalViewEmbedder>
415  external_view_embedder) {
416  if (config == nullptr) {
417  return nullptr;
418  }
419 
420  switch (config->type) {
421  case kOpenGL:
423  config, user_data, platform_dispatch_table,
424  std::move(external_view_embedder));
425  case kSoftware:
427  config, user_data, platform_dispatch_table,
428  std::move(external_view_embedder));
429  case kMetal:
431  config, user_data, platform_dispatch_table,
432  std::move(external_view_embedder));
433  default:
434  return nullptr;
435  }
436  return nullptr;
437 }
438 
439 static sk_sp<SkSurface> MakeSkSurfaceFromBackingStore(
440  GrDirectContext* context,
441  const FlutterBackingStoreConfig& config,
442  const FlutterOpenGLTexture* texture) {
443 #ifdef SHELL_ENABLE_GL
444  GrGLTextureInfo texture_info;
445  texture_info.fTarget = texture->target;
446  texture_info.fID = texture->name;
447  texture_info.fFormat = texture->format;
448 
449  GrBackendTexture backend_texture(config.size.width, //
450  config.size.height, //
451  GrMipMapped::kNo, //
452  texture_info //
453  );
454 
455  SkSurfaceProps surface_properties(0, kUnknown_SkPixelGeometry);
456 
457  auto surface = SkSurface::MakeFromBackendTexture(
458  context, // context
459  backend_texture, // back-end texture
460  kBottomLeft_GrSurfaceOrigin, // surface origin
461  1, // sample count
462  kN32_SkColorType, // color type
463  SkColorSpace::MakeSRGB(), // color space
464  &surface_properties, // surface properties
465  static_cast<SkSurface::TextureReleaseProc>(
466  texture->destruction_callback), // release proc
467  texture->user_data // release context
468  );
469 
470  if (!surface) {
471  FML_LOG(ERROR) << "Could not wrap embedder supplied render texture.";
472  return nullptr;
473  }
474 
475  return surface;
476 #else
477  return nullptr;
478 #endif
479 }
480 
481 static sk_sp<SkSurface> MakeSkSurfaceFromBackingStore(
482  GrDirectContext* context,
483  const FlutterBackingStoreConfig& config,
484  const FlutterOpenGLFramebuffer* framebuffer) {
485 #ifdef SHELL_ENABLE_GL
486  GrGLFramebufferInfo framebuffer_info = {};
487  framebuffer_info.fFormat = framebuffer->target;
488  framebuffer_info.fFBOID = framebuffer->name;
489 
490  GrBackendRenderTarget backend_render_target(
491  config.size.width, // width
492  config.size.height, // height
493  1, // sample count
494  0, // stencil bits
495  framebuffer_info // framebuffer info
496  );
497 
498  SkSurfaceProps surface_properties(0, kUnknown_SkPixelGeometry);
499 
500  auto surface = SkSurface::MakeFromBackendRenderTarget(
501  context, // context
502  backend_render_target, // backend render target
503  kBottomLeft_GrSurfaceOrigin, // surface origin
504  kN32_SkColorType, // color type
505  SkColorSpace::MakeSRGB(), // color space
506  &surface_properties, // surface properties
507  static_cast<SkSurface::RenderTargetReleaseProc>(
508  framebuffer->destruction_callback), // release proc
509  framebuffer->user_data // release context
510  );
511 
512  if (!surface) {
513  FML_LOG(ERROR) << "Could not wrap embedder supplied frame-buffer.";
514  return nullptr;
515  }
516  return surface;
517 #else
518  return nullptr;
519 #endif
520 }
521 
522 static sk_sp<SkSurface> MakeSkSurfaceFromBackingStore(
523  GrDirectContext* context,
524  const FlutterBackingStoreConfig& config,
525  const FlutterSoftwareBackingStore* software) {
526  const auto image_info =
527  SkImageInfo::MakeN32Premul(config.size.width, config.size.height);
528 
529  struct Captures {
530  VoidCallback destruction_callback;
531  void* user_data;
532  };
533  auto captures = std::make_unique<Captures>();
534  captures->destruction_callback = software->destruction_callback;
535  captures->user_data = software->user_data;
536  auto release_proc = [](void* pixels, void* context) {
537  auto captures = reinterpret_cast<Captures*>(context);
538  if (captures->destruction_callback) {
539  captures->destruction_callback(captures->user_data);
540  }
541  };
542 
543  auto surface = SkSurface::MakeRasterDirectReleaseProc(
544  image_info, // image info
545  const_cast<void*>(software->allocation), // pixels
546  software->row_bytes, // row bytes
547  release_proc, // release proc
548  captures.release() // release context
549  );
550 
551  if (!surface) {
552  FML_LOG(ERROR)
553  << "Could not wrap embedder supplied software render buffer.";
554  if (software->destruction_callback) {
555  software->destruction_callback(software->user_data);
556  }
557  return nullptr;
558  }
559  return surface;
560 }
561 
562 static sk_sp<SkSurface> MakeSkSurfaceFromBackingStore(
563  GrDirectContext* context,
564  const FlutterBackingStoreConfig& config,
565  const FlutterMetalBackingStore* metal) {
566 #ifdef SHELL_ENABLE_METAL
567  GrMtlTextureInfo texture_info;
568  if (!metal->texture.texture) {
569  FML_LOG(ERROR) << "Embedder supplied null Metal texture.";
570  return nullptr;
571  }
572  sk_cf_obj<FlutterMetalTextureHandle> mtl_texture;
573  mtl_texture.retain(metal->texture.texture);
574  texture_info.fTexture = mtl_texture;
575  GrBackendTexture backend_texture(config.size.width, //
576  config.size.height, //
577  GrMipMapped::kNo, //
578  texture_info //
579  );
580 
581  SkSurfaceProps surface_properties(0, kUnknown_SkPixelGeometry);
582 
583  auto surface = SkSurface::MakeFromBackendTexture(
584  context, // context
585  backend_texture, // back-end texture
586  kTopLeft_GrSurfaceOrigin, // surface origin
587  1, // sample count
588  kBGRA_8888_SkColorType, // color type
589  nullptr, // color space
590  &surface_properties, // surface properties
591  static_cast<SkSurface::TextureReleaseProc>(
592  metal->texture.destruction_callback), // release proc
593  metal->texture.user_data // release context
594  );
595 
596  if (!surface) {
597  FML_LOG(ERROR) << "Could not wrap embedder supplied Metal render texture.";
598  return nullptr;
599  }
600 
601  return surface;
602 #else
603  return nullptr;
604 #endif
605 }
606 
607 static std::unique_ptr<flutter::EmbedderRenderTarget>
609  const FlutterBackingStoreConfig& config,
610  GrDirectContext* context) {
611  FlutterBackingStore backing_store = {};
612  backing_store.struct_size = sizeof(backing_store);
613 
614  // Safe access checks on the compositor struct have been performed in
615  // InferExternalViewEmbedderFromArgs and are not necessary here.
616  auto c_create_callback = compositor->create_backing_store_callback;
617  auto c_collect_callback = compositor->collect_backing_store_callback;
618 
619  {
620  TRACE_EVENT0("flutter", "FlutterCompositorCreateBackingStore");
621  if (!c_create_callback(&config, &backing_store, compositor->user_data)) {
622  FML_LOG(ERROR) << "Could not create the embedder backing store.";
623  return nullptr;
624  }
625  }
626 
627  if (backing_store.struct_size != sizeof(backing_store)) {
628  FML_LOG(ERROR) << "Embedder modified the backing store struct size.";
629  return nullptr;
630  }
631 
632  // In case we return early without creating an embedder render target, the
633  // embedder has still given us ownership of its baton which we must return
634  // back to it. If this method is successful, the closure is released when the
635  // render target is eventually released.
636  fml::ScopedCleanupClosure collect_callback(
637  [c_collect_callback, backing_store, user_data = compositor->user_data]() {
638  TRACE_EVENT0("flutter", "FlutterCompositorCollectBackingStore");
639  c_collect_callback(&backing_store, user_data);
640  });
641 
642  // No safe access checks on the renderer are necessary since we allocated
643  // the struct.
644 
645  sk_sp<SkSurface> render_surface;
646 
647  switch (backing_store.type) {
649  switch (backing_store.open_gl.type) {
651  render_surface = MakeSkSurfaceFromBackingStore(
652  context, config, &backing_store.open_gl.texture);
653  break;
655  render_surface = MakeSkSurfaceFromBackingStore(
656  context, config, &backing_store.open_gl.framebuffer);
657  break;
658  }
659  break;
661  render_surface = MakeSkSurfaceFromBackingStore(context, config,
662  &backing_store.software);
663  break;
665  render_surface =
666  MakeSkSurfaceFromBackingStore(context, config, &backing_store.metal);
667  break;
668  };
669 
670  if (!render_surface) {
671  FML_LOG(ERROR) << "Could not create a surface from an embedder provided "
672  "render target.";
673  return nullptr;
674  }
675 
676  return std::make_unique<flutter::EmbedderRenderTarget>(
677  backing_store, std::move(render_surface), collect_callback.Release());
678 }
679 
680 static std::pair<std::unique_ptr<flutter::EmbedderExternalViewEmbedder>,
681  bool /* halt engine launch if true */>
683  if (compositor == nullptr) {
684  return {nullptr, false};
685  }
686 
687  auto c_create_callback =
688  SAFE_ACCESS(compositor, create_backing_store_callback, nullptr);
689  auto c_collect_callback =
690  SAFE_ACCESS(compositor, collect_backing_store_callback, nullptr);
691  auto c_present_callback =
692  SAFE_ACCESS(compositor, present_layers_callback, nullptr);
693  bool avoid_backing_store_cache =
694  SAFE_ACCESS(compositor, avoid_backing_store_cache, false);
695 
696  // Make sure the required callbacks are present
697  if (!c_create_callback || !c_collect_callback || !c_present_callback) {
698  FML_LOG(ERROR) << "Required compositor callbacks absent.";
699  return {nullptr, true};
700  }
701 
702  FlutterCompositor captured_compositor = *compositor;
703 
705  create_render_target_callback =
706  [captured_compositor](GrDirectContext* context, const auto& config) {
707  return CreateEmbedderRenderTarget(&captured_compositor, config,
708  context);
709  };
710 
712  [c_present_callback,
713  user_data = compositor->user_data](const auto& layers) {
714  TRACE_EVENT0("flutter", "FlutterCompositorPresentLayers");
715  return c_present_callback(
716  const_cast<const FlutterLayer**>(layers.data()), layers.size(),
717  user_data);
718  };
719 
720  return {std::make_unique<flutter::EmbedderExternalViewEmbedder>(
721  avoid_backing_store_cache, create_render_target_callback,
722  present_callback),
723  false};
724 }
725 
727  std::unique_ptr<flutter::PlatformMessage> message;
728 };
729 
731  void operator()(Dart_LoadedElf* elf) {
732  if (elf) {
733  ::Dart_UnloadELF(elf);
734  }
735  }
736 };
737 
738 using UniqueLoadedElf = std::unique_ptr<Dart_LoadedElf, LoadedElfDeleter>;
739 
741  UniqueLoadedElf loaded_elf = nullptr;
742  const uint8_t* vm_snapshot_data = nullptr;
743  const uint8_t* vm_snapshot_instrs = nullptr;
744  const uint8_t* vm_isolate_data = nullptr;
745  const uint8_t* vm_isolate_instrs = nullptr;
746 };
747 
749  const FlutterEngineAOTDataSource* source,
750  FlutterEngineAOTData* data_out) {
753  "AOT data can only be created in AOT mode.");
754  } else if (!source) {
755  return LOG_EMBEDDER_ERROR(kInvalidArguments, "Null source specified.");
756  } else if (!data_out) {
757  return LOG_EMBEDDER_ERROR(kInvalidArguments, "Null data_out specified.");
758  }
759 
760  switch (source->type) {
762  if (!source->elf_path || !fml::IsFile(source->elf_path)) {
764  "Invalid ELF path specified.");
765  }
766 
767  auto aot_data = std::make_unique<_FlutterEngineAOTData>();
768  const char* error = nullptr;
769 
770 #if OS_FUCHSIA
771  // TODO(gw280): https://github.com/flutter/flutter/issues/50285
772  // Dart doesn't implement Dart_LoadELF on Fuchsia
773  Dart_LoadedElf* loaded_elf = nullptr;
774 #else
775  Dart_LoadedElf* loaded_elf = Dart_LoadELF(
776  source->elf_path, // file path
777  0, // file offset
778  &error, // error (out)
779  &aot_data->vm_snapshot_data, // vm snapshot data (out)
780  &aot_data->vm_snapshot_instrs, // vm snapshot instr (out)
781  &aot_data->vm_isolate_data, // vm isolate data (out)
782  &aot_data->vm_isolate_instrs // vm isolate instr (out)
783  );
784 #endif
785 
786  if (loaded_elf == nullptr) {
787  return LOG_EMBEDDER_ERROR(kInvalidArguments, error);
788  }
789 
790  aot_data->loaded_elf.reset(loaded_elf);
791 
792  *data_out = aot_data.release();
793  return kSuccess;
794  }
795  }
796 
797  return LOG_EMBEDDER_ERROR(
799  "Invalid FlutterEngineAOTDataSourceType type specified.");
800 }
801 
803  if (!data) {
804  // Deleting a null object should be a no-op.
805  return kSuccess;
806  }
807 
808  // Created in a unique pointer in `FlutterEngineCreateAOTData`.
809  delete data;
810  return kSuccess;
811 }
812 
814  const FlutterProjectArgs* args,
815  flutter::Settings& settings) { // NOLINT(google-runtime-references)
816  // There are no ownership concerns here as all mappings are owned by the
817  // embedder and not the engine.
818  auto make_mapping_callback = [](const uint8_t* mapping, size_t size) {
819  return [mapping, size]() {
820  return std::make_unique<fml::NonOwnedMapping>(mapping, size);
821  };
822  };
823 
825  if (SAFE_ACCESS(args, aot_data, nullptr) != nullptr) {
826  settings.vm_snapshot_data =
827  make_mapping_callback(args->aot_data->vm_snapshot_data, 0);
828 
829  settings.vm_snapshot_instr =
830  make_mapping_callback(args->aot_data->vm_snapshot_instrs, 0);
831 
832  settings.isolate_snapshot_data =
833  make_mapping_callback(args->aot_data->vm_isolate_data, 0);
834 
835  settings.isolate_snapshot_instr =
836  make_mapping_callback(args->aot_data->vm_isolate_instrs, 0);
837  }
838 
839  if (SAFE_ACCESS(args, vm_snapshot_data, nullptr) != nullptr) {
840  settings.vm_snapshot_data = make_mapping_callback(
841  args->vm_snapshot_data, SAFE_ACCESS(args, vm_snapshot_data_size, 0));
842  }
843 
844  if (SAFE_ACCESS(args, vm_snapshot_instructions, nullptr) != nullptr) {
845  settings.vm_snapshot_instr = make_mapping_callback(
847  SAFE_ACCESS(args, vm_snapshot_instructions_size, 0));
848  }
849 
850  if (SAFE_ACCESS(args, isolate_snapshot_data, nullptr) != nullptr) {
851  settings.isolate_snapshot_data = make_mapping_callback(
852  args->isolate_snapshot_data,
853  SAFE_ACCESS(args, isolate_snapshot_data_size, 0));
854  }
855 
856  if (SAFE_ACCESS(args, isolate_snapshot_instructions, nullptr) != nullptr) {
857  settings.isolate_snapshot_instr = make_mapping_callback(
859  SAFE_ACCESS(args, isolate_snapshot_instructions_size, 0));
860  }
861  }
862 
863 #if !OS_FUCHSIA && (FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG)
864  settings.dart_library_sources_kernel =
865  make_mapping_callback(kPlatformStrongDill, kPlatformStrongDillSize);
866 #endif // !OS_FUCHSIA && (FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG)
867 }
868 
870  const FlutterRendererConfig* config,
871  const FlutterProjectArgs* args,
872  void* user_data,
874  engine_out) {
875  auto result =
876  FlutterEngineInitialize(version, config, args, user_data, engine_out);
877 
878  if (result != kSuccess) {
879  return result;
880  }
881 
882  return FlutterEngineRunInitialized(*engine_out);
883 }
884 
886  const FlutterRendererConfig* config,
887  const FlutterProjectArgs* args,
888  void* user_data,
890  engine_out) {
891  // Step 0: Figure out arguments for shell creation.
892  if (version != FLUTTER_ENGINE_VERSION) {
893  return LOG_EMBEDDER_ERROR(
895  "Flutter embedder version mismatch. There has been a breaking change. "
896  "Please consult the changelog and update the embedder.");
897  }
898 
899  if (engine_out == nullptr) {
901  "The engine out parameter was missing.");
902  }
903 
904  if (args == nullptr) {
906  "The Flutter project arguments were missing.");
907  }
908 
909  if (SAFE_ACCESS(args, assets_path, nullptr) == nullptr) {
910  return LOG_EMBEDDER_ERROR(
912  "The assets path in the Flutter project arguments was missing.");
913  }
914 
915  if (SAFE_ACCESS(args, main_path__unused__, nullptr) != nullptr) {
916  FML_LOG(WARNING)
917  << "FlutterProjectArgs.main_path is deprecated and should be set null.";
918  }
919 
920  if (SAFE_ACCESS(args, packages_path__unused__, nullptr) != nullptr) {
921  FML_LOG(WARNING) << "FlutterProjectArgs.packages_path is deprecated and "
922  "should be set null.";
923  }
924 
925  if (!IsRendererValid(config)) {
927  "The renderer configuration was invalid.");
928  }
929 
930  std::string icu_data_path;
931  if (SAFE_ACCESS(args, icu_data_path, nullptr) != nullptr) {
932  icu_data_path = SAFE_ACCESS(args, icu_data_path, nullptr);
933  }
934 
935  if (SAFE_ACCESS(args, persistent_cache_path, nullptr) != nullptr) {
936  std::string persistent_cache_path =
937  SAFE_ACCESS(args, persistent_cache_path, nullptr);
939  }
940 
941  if (SAFE_ACCESS(args, is_persistent_cache_read_only, false)) {
943  }
944 
945  fml::CommandLine command_line;
946  if (SAFE_ACCESS(args, command_line_argc, 0) != 0 &&
947  SAFE_ACCESS(args, command_line_argv, nullptr) != nullptr) {
948  command_line = fml::CommandLineFromArgcArgv(
949  SAFE_ACCESS(args, command_line_argc, 0),
950  SAFE_ACCESS(args, command_line_argv, nullptr));
951  }
952 
953  flutter::Settings settings = flutter::SettingsFromCommandLine(command_line);
954 
955  if (SAFE_ACCESS(args, aot_data, nullptr)) {
956  if (SAFE_ACCESS(args, vm_snapshot_data, nullptr) ||
957  SAFE_ACCESS(args, vm_snapshot_instructions, nullptr) ||
958  SAFE_ACCESS(args, isolate_snapshot_data, nullptr) ||
959  SAFE_ACCESS(args, isolate_snapshot_instructions, nullptr)) {
960  return LOG_EMBEDDER_ERROR(
962  "Multiple AOT sources specified. Embedders should provide either "
963  "*_snapshot_* buffers or aot_data, not both.");
964  }
965  }
966 
967  PopulateSnapshotMappingCallbacks(args, settings);
968 
969  settings.icu_data_path = icu_data_path;
970  settings.assets_path = args->assets_path;
971  settings.leak_vm = !SAFE_ACCESS(args, shutdown_dart_vm_when_done, false);
972  settings.old_gen_heap_size = SAFE_ACCESS(args, dart_old_gen_heap_size, -1);
973 
975  // Verify the assets path contains Dart 2 kernel assets.
976  const std::string kApplicationKernelSnapshotFileName = "kernel_blob.bin";
977  std::string application_kernel_path = fml::paths::JoinPaths(
978  {settings.assets_path, kApplicationKernelSnapshotFileName});
979  if (!fml::IsFile(application_kernel_path)) {
980  return LOG_EMBEDDER_ERROR(
982  "Not running in AOT mode but could not resolve the kernel binary.");
983  }
985  }
986 
987  settings.task_observer_add = [](intptr_t key, fml::closure callback) {
989  };
990  settings.task_observer_remove = [](intptr_t key) {
992  };
993  if (SAFE_ACCESS(args, root_isolate_create_callback, nullptr) != nullptr) {
995  SAFE_ACCESS(args, root_isolate_create_callback, nullptr);
997  [callback, user_data](const auto& isolate) { callback(user_data); };
998  }
999  if (SAFE_ACCESS(args, log_message_callback, nullptr) != nullptr) {
1001  SAFE_ACCESS(args, log_message_callback, nullptr);
1002  settings.log_message_callback = [callback, user_data](
1003  const std::string& tag,
1004  const std::string& message) {
1005  callback(tag.c_str(), message.c_str(), user_data);
1006  };
1007  }
1008  if (SAFE_ACCESS(args, log_tag, nullptr) != nullptr) {
1009  settings.log_tag = SAFE_ACCESS(args, log_tag, nullptr);
1010  }
1011 
1013  update_semantics_nodes_callback = nullptr;
1014  if (SAFE_ACCESS(args, update_semantics_node_callback, nullptr) != nullptr) {
1015  update_semantics_nodes_callback =
1016  [ptr = args->update_semantics_node_callback,
1018  for (const auto& value : update) {
1019  const auto& node = value.second;
1020  SkMatrix transform = node.transform.asM33();
1021  FlutterTransformation flutter_transform{
1022  transform.get(SkMatrix::kMScaleX),
1023  transform.get(SkMatrix::kMSkewX),
1024  transform.get(SkMatrix::kMTransX),
1025  transform.get(SkMatrix::kMSkewY),
1026  transform.get(SkMatrix::kMScaleY),
1027  transform.get(SkMatrix::kMTransY),
1028  transform.get(SkMatrix::kMPersp0),
1029  transform.get(SkMatrix::kMPersp1),
1030  transform.get(SkMatrix::kMPersp2)};
1031  const FlutterSemanticsNode embedder_node{
1032  sizeof(FlutterSemanticsNode),
1033  node.id,
1034  static_cast<FlutterSemanticsFlag>(node.flags),
1035  static_cast<FlutterSemanticsAction>(node.actions),
1036  node.textSelectionBase,
1037  node.textSelectionExtent,
1038  node.scrollChildren,
1039  node.scrollIndex,
1040  node.scrollPosition,
1041  node.scrollExtentMax,
1042  node.scrollExtentMin,
1043  node.elevation,
1044  node.thickness,
1045  node.label.c_str(),
1046  node.hint.c_str(),
1047  node.value.c_str(),
1048  node.increasedValue.c_str(),
1049  node.decreasedValue.c_str(),
1050  static_cast<FlutterTextDirection>(node.textDirection),
1051  FlutterRect{node.rect.fLeft, node.rect.fTop, node.rect.fRight,
1052  node.rect.fBottom},
1053  flutter_transform,
1054  node.childrenInTraversalOrder.size(),
1055  &node.childrenInTraversalOrder[0],
1056  &node.childrenInHitTestOrder[0],
1057  node.customAccessibilityActions.size(),
1058  &node.customAccessibilityActions[0],
1059  node.platformViewId,
1060  };
1061  ptr(&embedder_node, user_data);
1062  }
1063  const FlutterSemanticsNode batch_end_sentinel = {
1064  sizeof(FlutterSemanticsNode),
1066  };
1067  ptr(&batch_end_sentinel, user_data);
1068  };
1069  }
1070 
1072  update_semantics_custom_actions_callback = nullptr;
1073  if (SAFE_ACCESS(args, update_semantics_custom_action_callback, nullptr) !=
1074  nullptr) {
1075  update_semantics_custom_actions_callback =
1078  for (const auto& value : actions) {
1079  const auto& action = value.second;
1080  const FlutterSemanticsCustomAction embedder_action = {
1082  action.id,
1083  static_cast<FlutterSemanticsAction>(action.overrideId),
1084  action.label.c_str(),
1085  action.hint.c_str(),
1086  };
1087  ptr(&embedder_action, user_data);
1088  }
1089  const FlutterSemanticsCustomAction batch_end_sentinel = {
1092  };
1093  ptr(&batch_end_sentinel, user_data);
1094  };
1095  }
1096 
1098  platform_message_response_callback = nullptr;
1099  if (SAFE_ACCESS(args, platform_message_callback, nullptr) != nullptr) {
1100  platform_message_response_callback =
1101  [ptr = args->platform_message_callback,
1102  user_data](std::unique_ptr<flutter::PlatformMessage> message) {
1103  auto handle = new FlutterPlatformMessageResponseHandle();
1104  const FlutterPlatformMessage incoming_message = {
1105  sizeof(FlutterPlatformMessage), // struct_size
1106  message->channel().c_str(), // channel
1107  message->data().GetMapping(), // message
1108  message->data().GetSize(), // message_size
1109  handle, // response_handle
1110  };
1111  handle->message = std::move(message);
1112  return ptr(&incoming_message, user_data);
1113  };
1114  }
1115 
1116  flutter::VsyncWaiterEmbedder::VsyncCallback vsync_callback = nullptr;
1117  if (SAFE_ACCESS(args, vsync_callback, nullptr) != nullptr) {
1118  vsync_callback = [ptr = args->vsync_callback, user_data](intptr_t baton) {
1119  return ptr(user_data, baton);
1120  };
1121  }
1122 
1124  compute_platform_resolved_locale_callback = nullptr;
1125  if (SAFE_ACCESS(args, compute_platform_resolved_locale_callback, nullptr) !=
1126  nullptr) {
1127  compute_platform_resolved_locale_callback =
1129  const std::vector<std::string>& supported_locales_data) {
1130  const size_t number_of_strings_per_locale = 3;
1131  size_t locale_count =
1132  supported_locales_data.size() / number_of_strings_per_locale;
1133  std::vector<FlutterLocale> supported_locales;
1134  std::vector<const FlutterLocale*> supported_locales_ptr;
1135  for (size_t i = 0; i < locale_count; ++i) {
1136  supported_locales.push_back(
1137  {.struct_size = sizeof(FlutterLocale),
1138  .language_code =
1139  supported_locales_data[i * number_of_strings_per_locale +
1140  0]
1141  .c_str(),
1142  .country_code =
1143  supported_locales_data[i * number_of_strings_per_locale +
1144  1]
1145  .c_str(),
1146  .script_code =
1147  supported_locales_data[i * number_of_strings_per_locale +
1148  2]
1149  .c_str(),
1150  .variant_code = nullptr});
1151  supported_locales_ptr.push_back(&supported_locales[i]);
1152  }
1153 
1154  const FlutterLocale* result =
1155  ptr(supported_locales_ptr.data(), locale_count);
1156 
1157  std::unique_ptr<std::vector<std::string>> out =
1158  std::make_unique<std::vector<std::string>>();
1159  if (result) {
1160  std::string language_code(SAFE_ACCESS(result, language_code, ""));
1161  if (language_code != "") {
1162  out->push_back(language_code);
1163  out->emplace_back(SAFE_ACCESS(result, country_code, ""));
1164  out->emplace_back(SAFE_ACCESS(result, script_code, ""));
1165  }
1166  }
1167  return out;
1168  };
1169  }
1170 
1172  on_pre_engine_restart_callback = nullptr;
1173  if (SAFE_ACCESS(args, on_pre_engine_restart_callback, nullptr) != nullptr) {
1174  on_pre_engine_restart_callback = [ptr =
1176  user_data]() { return ptr(user_data); };
1177  }
1178 
1179  auto external_view_embedder_result =
1180  InferExternalViewEmbedderFromArgs(SAFE_ACCESS(args, compositor, nullptr));
1181  if (external_view_embedder_result.second) {
1183  "Compositor arguments were invalid.");
1184  }
1185 
1187  {
1188  update_semantics_nodes_callback, //
1189  update_semantics_custom_actions_callback, //
1190  platform_message_response_callback, //
1191  vsync_callback, //
1192  compute_platform_resolved_locale_callback, //
1193  on_pre_engine_restart_callback, //
1194  };
1195 
1196  auto on_create_platform_view = InferPlatformViewCreationCallback(
1197  config, user_data, platform_dispatch_table,
1198  std::move(external_view_embedder_result.first));
1199 
1200  if (!on_create_platform_view) {
1201  return LOG_EMBEDDER_ERROR(
1203  "Could not infer platform view creation callback.");
1204  }
1205 
1207  [](flutter::Shell& shell) {
1208  return std::make_unique<flutter::Rasterizer>(shell);
1209  };
1210 
1211  using ExternalTextureResolver = flutter::EmbedderExternalTextureResolver;
1212  std::unique_ptr<ExternalTextureResolver> external_texture_resolver;
1213  external_texture_resolver = std::make_unique<ExternalTextureResolver>();
1214 
1215 #ifdef SHELL_ENABLE_GL
1217  external_texture_callback;
1218  if (config->type == kOpenGL) {
1219  const FlutterOpenGLRendererConfig* open_gl_config = &config->open_gl;
1220  if (SAFE_ACCESS(open_gl_config, gl_external_texture_frame_callback,
1221  nullptr) != nullptr) {
1222  external_texture_callback =
1223  [ptr = open_gl_config->gl_external_texture_frame_callback, user_data](
1224  int64_t texture_identifier, size_t width,
1225  size_t height) -> std::unique_ptr<FlutterOpenGLTexture> {
1226  std::unique_ptr<FlutterOpenGLTexture> texture =
1227  std::make_unique<FlutterOpenGLTexture>();
1228  if (!ptr(user_data, texture_identifier, width, height, texture.get())) {
1229  return nullptr;
1230  }
1231  return texture;
1232  };
1233  external_texture_resolver =
1234  std::make_unique<ExternalTextureResolver>(external_texture_callback);
1235  }
1236  }
1237 #endif
1238 #ifdef SHELL_ENABLE_METAL
1240  external_texture_metal_callback;
1241  if (config->type == kMetal) {
1242  const FlutterMetalRendererConfig* metal_config = &config->metal;
1243  if (SAFE_ACCESS(metal_config, external_texture_frame_callback, nullptr)) {
1244  external_texture_metal_callback =
1245  [ptr = metal_config->external_texture_frame_callback, user_data](
1246  int64_t texture_identifier, size_t width,
1247  size_t height) -> std::unique_ptr<FlutterMetalExternalTexture> {
1248  std::unique_ptr<FlutterMetalExternalTexture> texture =
1249  std::make_unique<FlutterMetalExternalTexture>();
1250  texture->struct_size = sizeof(FlutterMetalExternalTexture);
1251  if (!ptr(user_data, texture_identifier, width, height, texture.get())) {
1252  return nullptr;
1253  }
1254  return texture;
1255  };
1256  external_texture_resolver = std::make_unique<ExternalTextureResolver>(
1257  external_texture_metal_callback);
1258  }
1259  }
1260 #endif
1261 
1262  auto thread_host =
1264  SAFE_ACCESS(args, custom_task_runners, nullptr));
1265 
1266  if (!thread_host || !thread_host->IsValid()) {
1268  "Could not set up or infer thread configuration "
1269  "to run the Flutter engine on.");
1270  }
1271 
1272  auto task_runners = thread_host->GetTaskRunners();
1273 
1274  if (!task_runners.IsValid()) {
1276  "Task runner configuration was invalid.");
1277  }
1278 
1279  auto run_configuration =
1281 
1282  if (SAFE_ACCESS(args, custom_dart_entrypoint, nullptr) != nullptr) {
1283  auto dart_entrypoint = std::string{args->custom_dart_entrypoint};
1284  if (dart_entrypoint.size() != 0) {
1285  run_configuration.SetEntrypoint(std::move(dart_entrypoint));
1286  }
1287  }
1288 
1289  if (SAFE_ACCESS(args, dart_entrypoint_argc, 0) > 0) {
1290  if (SAFE_ACCESS(args, dart_entrypoint_argv, nullptr) == nullptr) {
1292  "Could not determine Dart entrypoint arguments "
1293  "as dart_entrypoint_argc "
1294  "was set, but dart_entrypoint_argv was null.");
1295  }
1296  std::vector<std::string> arguments(args->dart_entrypoint_argc);
1297  for (int i = 0; i < args->dart_entrypoint_argc; ++i) {
1298  arguments[i] = std::string{args->dart_entrypoint_argv[i]};
1299  }
1300  settings.dart_entrypoint_args = std::move(arguments);
1301  }
1302 
1303  if (!run_configuration.IsValid()) {
1304  return LOG_EMBEDDER_ERROR(
1306  "Could not infer the Flutter project to run from given arguments.");
1307  }
1308 
1309  // Create the engine but don't launch the shell or run the root isolate.
1310  auto embedder_engine = std::make_unique<flutter::EmbedderEngine>(
1311  std::move(thread_host), //
1312  std::move(task_runners), //
1313  std::move(settings), //
1314  std::move(run_configuration), //
1315  on_create_platform_view, //
1316  on_create_rasterizer, //
1317  std::move(external_texture_resolver) //
1318  );
1319 
1320  // Release the ownership of the embedder engine to the caller.
1321  *engine_out = reinterpret_cast<FLUTTER_API_SYMBOL(FlutterEngine)>(
1322  embedder_engine.release());
1323  return kSuccess;
1324 }
1325 
1328  if (!engine) {
1329  return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
1330  }
1331 
1332  auto embedder_engine = reinterpret_cast<flutter::EmbedderEngine*>(engine);
1333 
1334  // The engine must not already be running. Initialize may only be called
1335  // once on an engine instance.
1336  if (embedder_engine->IsValid()) {
1337  return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
1338  }
1339 
1340  // Step 1: Launch the shell.
1341  if (!embedder_engine->LaunchShell()) {
1343  "Could not launch the engine using supplied "
1344  "initialization arguments.");
1345  }
1346 
1347  // Step 2: Tell the platform view to initialize itself.
1348  if (!embedder_engine->NotifyCreated()) {
1350  "Could not create platform view components.");
1351  }
1352 
1353  // Step 3: Launch the root isolate.
1354  if (!embedder_engine->RunRootIsolate()) {
1355  return LOG_EMBEDDER_ERROR(
1357  "Could not run the root isolate of the Flutter application using the "
1358  "project arguments specified.");
1359  }
1360 
1361  return kSuccess;
1362 }
1363 
1366  engine) {
1367  if (engine == nullptr) {
1368  return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
1369  }
1370 
1371  auto embedder_engine = reinterpret_cast<flutter::EmbedderEngine*>(engine);
1372  embedder_engine->NotifyDestroyed();
1373  embedder_engine->CollectShell();
1374  return kSuccess;
1375 }
1376 
1378  engine) {
1379  auto result = FlutterEngineDeinitialize(engine);
1380  if (result != kSuccess) {
1381  return result;
1382  }
1383  auto embedder_engine = reinterpret_cast<flutter::EmbedderEngine*>(engine);
1384  delete embedder_engine;
1385  return kSuccess;
1386 }
1387 
1390  const FlutterWindowMetricsEvent* flutter_metrics) {
1391  if (engine == nullptr || flutter_metrics == nullptr) {
1392  return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
1393  }
1394 
1395  flutter::ViewportMetrics metrics;
1396 
1397  metrics.physical_width = SAFE_ACCESS(flutter_metrics, width, 0.0);
1398  metrics.physical_height = SAFE_ACCESS(flutter_metrics, height, 0.0);
1399  metrics.device_pixel_ratio = SAFE_ACCESS(flutter_metrics, pixel_ratio, 1.0);
1400  metrics.physical_view_inset_top =
1401  SAFE_ACCESS(flutter_metrics, physical_view_inset_top, 0.0);
1402  metrics.physical_view_inset_right =
1403  SAFE_ACCESS(flutter_metrics, physical_view_inset_right, 0.0);
1404  metrics.physical_view_inset_bottom =
1405  SAFE_ACCESS(flutter_metrics, physical_view_inset_bottom, 0.0);
1406  metrics.physical_view_inset_left =
1407  SAFE_ACCESS(flutter_metrics, physical_view_inset_left, 0.0);
1408 
1409  if (metrics.device_pixel_ratio <= 0.0) {
1410  return LOG_EMBEDDER_ERROR(
1412  "Device pixel ratio was invalid. It must be greater than zero.");
1413  }
1414 
1415  if (metrics.physical_view_inset_top < 0 ||
1416  metrics.physical_view_inset_right < 0 ||
1417  metrics.physical_view_inset_bottom < 0 ||
1418  metrics.physical_view_inset_left < 0) {
1419  return LOG_EMBEDDER_ERROR(
1421  "Physical view insets are invalid. They must be non-negative.");
1422  }
1423 
1424  if (metrics.physical_view_inset_top > metrics.physical_height ||
1425  metrics.physical_view_inset_right > metrics.physical_width ||
1426  metrics.physical_view_inset_bottom > metrics.physical_height ||
1427  metrics.physical_view_inset_left > metrics.physical_width) {
1429  "Physical view insets are invalid. They cannot "
1430  "be greater than physical height or width.");
1431  }
1432 
1433  return reinterpret_cast<flutter::EmbedderEngine*>(engine)->SetViewportMetrics(
1434  std::move(metrics))
1435  ? kSuccess
1437  "Viewport metrics were invalid.");
1438 }
1439 
1440 // Returns the flutter::PointerData::Change for the given FlutterPointerPhase.
1442  FlutterPointerPhase phase) {
1443  switch (phase) {
1444  case kCancel:
1446  case kUp:
1448  case kDown:
1450  case kMove:
1452  case kAdd:
1454  case kRemove:
1456  case kHover:
1458  }
1460 }
1461 
1462 // Returns the flutter::PointerData::DeviceKind for the given
1463 // FlutterPointerDeviceKind.
1465  FlutterPointerDeviceKind device_kind) {
1466  switch (device_kind) {
1473  }
1475 }
1476 
1477 // Returns the flutter::PointerData::SignalKind for the given
1478 // FlutterPointerSignaKind.
1480  FlutterPointerSignalKind kind) {
1481  switch (kind) {
1486  }
1488 }
1489 
1490 // Returns the buttons to synthesize for a PointerData from a
1491 // FlutterPointerEvent with no type or buttons set.
1494  switch (change) {
1497  // These kinds of change must have a non-zero `buttons`, otherwise
1498  // gesture recognizers will ignore these events.
1505  return 0;
1506  }
1507  return 0;
1508 }
1509 
1512  const FlutterPointerEvent* pointers,
1513  size_t events_count) {
1514  if (engine == nullptr) {
1515  return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
1516  }
1517 
1518  if (pointers == nullptr || events_count == 0) {
1519  return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid pointer events.");
1520  }
1521 
1522  auto packet = std::make_unique<flutter::PointerDataPacket>(events_count);
1523 
1524  const FlutterPointerEvent* current = pointers;
1525 
1526  for (size_t i = 0; i < events_count; ++i) {
1527  flutter::PointerData pointer_data;
1528  pointer_data.Clear();
1529  // this is currely in use only on android embedding.
1530  pointer_data.embedder_id = 0;
1531  pointer_data.time_stamp = SAFE_ACCESS(current, timestamp, 0);
1532  pointer_data.change = ToPointerDataChange(
1533  SAFE_ACCESS(current, phase, FlutterPointerPhase::kCancel));
1534  pointer_data.physical_x = SAFE_ACCESS(current, x, 0.0);
1535  pointer_data.physical_y = SAFE_ACCESS(current, y, 0.0);
1536  // Delta will be generated in pointer_data_packet_converter.cc.
1537  pointer_data.physical_delta_x = 0.0;
1538  pointer_data.physical_delta_y = 0.0;
1539  pointer_data.device = SAFE_ACCESS(current, device, 0);
1540  // Pointer identifier will be generated in
1541  // pointer_data_packet_converter.cc.
1542  pointer_data.pointer_identifier = 0;
1543  pointer_data.signal_kind = ToPointerDataSignalKind(
1544  SAFE_ACCESS(current, signal_kind, kFlutterPointerSignalKindNone));
1545  pointer_data.scroll_delta_x = SAFE_ACCESS(current, scroll_delta_x, 0.0);
1546  pointer_data.scroll_delta_y = SAFE_ACCESS(current, scroll_delta_y, 0.0);
1547  FlutterPointerDeviceKind device_kind = SAFE_ACCESS(current, device_kind, 0);
1548  // For backwards compatibility with embedders written before the device
1549  // kind and buttons were exposed, if the device kind is not set treat it
1550  // as a mouse, with a synthesized primary button state based on the phase.
1551  if (device_kind == 0) {
1553  pointer_data.buttons =
1555 
1556  } else {
1557  pointer_data.kind = ToPointerDataKind(device_kind);
1558  if (pointer_data.kind == flutter::PointerData::DeviceKind::kTouch) {
1559  // For touch events, set the button internally rather than requiring
1560  // it at the API level, since it's a confusing construction to expose.
1561  if (pointer_data.change == flutter::PointerData::Change::kDown ||
1562  pointer_data.change == flutter::PointerData::Change::kMove) {
1564  }
1565  } else {
1566  // Buttons use the same mask values, so pass them through directly.
1567  pointer_data.buttons = SAFE_ACCESS(current, buttons, 0);
1568  }
1569  }
1570  packet->SetPointerData(i, pointer_data);
1571  current = reinterpret_cast<const FlutterPointerEvent*>(
1572  reinterpret_cast<const uint8_t*>(current) + current->struct_size);
1573  }
1574 
1575  return reinterpret_cast<flutter::EmbedderEngine*>(engine)
1576  ->DispatchPointerDataPacket(std::move(packet))
1577  ? kSuccess
1579  "Could not dispatch pointer events to the "
1580  "running Flutter application.");
1581 }
1582 
1584  FlutterKeyEventType event_kind) {
1585  switch (event_kind) {
1592  }
1594 }
1595 
1597  engine,
1598  const FlutterKeyEvent* event,
1600  void* user_data) {
1601  if (engine == nullptr) {
1602  return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
1603  }
1604 
1605  if (event == nullptr) {
1606  return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid key event.");
1607  }
1608 
1609  const char* character = SAFE_ACCESS(event, character, nullptr);
1610 
1611  flutter::KeyData key_data;
1612  key_data.Clear();
1613  key_data.timestamp = static_cast<uint64_t>(SAFE_ACCESS(event, timestamp, 0));
1614  key_data.type = MapKeyEventType(
1616  key_data.physical = SAFE_ACCESS(event, physical, 0);
1617  key_data.logical = SAFE_ACCESS(event, logical, 0);
1618  key_data.synthesized = SAFE_ACCESS(event, synthesized, false);
1619 
1620  auto packet = std::make_unique<flutter::KeyDataPacket>(key_data, character);
1621 
1622  auto response = [callback, user_data](bool handled) {
1623  if (callback != nullptr) {
1624  callback(handled, user_data);
1625  }
1626  };
1627 
1628  return reinterpret_cast<flutter::EmbedderEngine*>(engine)
1629  ->DispatchKeyDataPacket(std::move(packet), response)
1630  ? kSuccess
1632  "Could not dispatch the key event to the "
1633  "running Flutter application.");
1634 }
1635 
1638  const FlutterPlatformMessage* flutter_message) {
1639  if (engine == nullptr) {
1640  return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
1641  }
1642 
1643  if (flutter_message == nullptr) {
1644  return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid message argument.");
1645  }
1646 
1647  if (SAFE_ACCESS(flutter_message, channel, nullptr) == nullptr) {
1648  return LOG_EMBEDDER_ERROR(
1649  kInvalidArguments, "Message argument did not specify a valid channel.");
1650  }
1651 
1652  size_t message_size = SAFE_ACCESS(flutter_message, message_size, 0);
1653  const uint8_t* message_data = SAFE_ACCESS(flutter_message, message, nullptr);
1654 
1655  if (message_size != 0 && message_data == nullptr) {
1656  return LOG_EMBEDDER_ERROR(
1658  "Message size was non-zero but the message data was nullptr.");
1659  }
1660 
1661  const FlutterPlatformMessageResponseHandle* response_handle =
1662  SAFE_ACCESS(flutter_message, response_handle, nullptr);
1663 
1665  if (response_handle && response_handle->message) {
1666  response = response_handle->message->response();
1667  }
1668 
1669  std::unique_ptr<flutter::PlatformMessage> message;
1670  if (message_size == 0) {
1671  message = std::make_unique<flutter::PlatformMessage>(
1672  flutter_message->channel, response);
1673  } else {
1674  message = std::make_unique<flutter::PlatformMessage>(
1675  flutter_message->channel,
1676  fml::MallocMapping::Copy(message_data, message_size), response);
1677  }
1678 
1679  return reinterpret_cast<flutter::EmbedderEngine*>(engine)
1680  ->SendPlatformMessage(std::move(message))
1681  ? kSuccess
1683  "Could not send a message to the running "
1684  "Flutter application.");
1685 }
1686 
1689  FlutterDataCallback data_callback,
1690  void* user_data,
1691  FlutterPlatformMessageResponseHandle** response_out) {
1692  if (engine == nullptr) {
1693  return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
1694  }
1695 
1696  if (data_callback == nullptr || response_out == nullptr) {
1697  return LOG_EMBEDDER_ERROR(
1698  kInvalidArguments, "Data callback or the response handle was invalid.");
1699  }
1700 
1702  [user_data, data_callback](const uint8_t* data, size_t size) {
1703  data_callback(data, size, user_data);
1704  };
1705 
1706  auto platform_task_runner = reinterpret_cast<flutter::EmbedderEngine*>(engine)
1707  ->GetTaskRunners()
1708  .GetPlatformTaskRunner();
1709 
1710  auto handle = new FlutterPlatformMessageResponseHandle();
1711 
1712  handle->message = std::make_unique<flutter::PlatformMessage>(
1713  "", // The channel is empty and unused as the response handle is going
1714  // to referenced directly in the |FlutterEngineSendPlatformMessage|
1715  // with the container message discarded.
1716  fml::MakeRefCounted<flutter::EmbedderPlatformMessageResponse>(
1717  std::move(platform_task_runner), response_callback));
1718  *response_out = handle;
1719  return kSuccess;
1720 }
1721 
1725  if (engine == nullptr) {
1726  return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
1727  }
1728 
1729  if (response == nullptr) {
1730  return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid response handle.");
1731  }
1732  delete response;
1733  return kSuccess;
1734 }
1735 
1739  const uint8_t* data,
1740  size_t data_length) {
1741  if (data_length != 0 && data == nullptr) {
1742  return LOG_EMBEDDER_ERROR(
1744  "Data size was non zero but the pointer to the data was null.");
1745  }
1746 
1747  auto response = handle->message->response();
1748 
1749  if (response) {
1750  if (data_length == 0) {
1751  response->CompleteEmpty();
1752  } else {
1753  response->Complete(std::make_unique<fml::DataMapping>(
1754  std::vector<uint8_t>({data, data + data_length})));
1755  }
1756  }
1757 
1758  delete handle;
1759 
1760  return kSuccess;
1761 }
1762 
1765  return kSuccess;
1766 }
1767 
1770  int64_t texture_identifier) {
1771  if (engine == nullptr) {
1772  return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
1773  }
1774 
1775  if (texture_identifier == 0) {
1777  "Texture identifier was invalid.");
1778  }
1779  if (!reinterpret_cast<flutter::EmbedderEngine*>(engine)->RegisterTexture(
1780  texture_identifier)) {
1782  "Could not register the specified texture.");
1783  }
1784  return kSuccess;
1785 }
1786 
1789  int64_t texture_identifier) {
1790  if (engine == nullptr) {
1791  return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
1792  }
1793 
1794  if (texture_identifier == 0) {
1796  "Texture identifier was invalid.");
1797  }
1798 
1799  if (!reinterpret_cast<flutter::EmbedderEngine*>(engine)->UnregisterTexture(
1800  texture_identifier)) {
1802  "Could not un-register the specified texture.");
1803  }
1804 
1805  return kSuccess;
1806 }
1807 
1810  int64_t texture_identifier) {
1811  if (engine == nullptr) {
1812  return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
1813  }
1814  if (texture_identifier == 0) {
1815  return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid texture identifier.");
1816  }
1817  if (!reinterpret_cast<flutter::EmbedderEngine*>(engine)
1818  ->MarkTextureFrameAvailable(texture_identifier)) {
1819  return LOG_EMBEDDER_ERROR(
1821  "Could not mark the texture frame as being available.");
1822  }
1823  return kSuccess;
1824 }
1825 
1828  bool enabled) {
1829  if (engine == nullptr) {
1830  return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
1831  }
1832  if (!reinterpret_cast<flutter::EmbedderEngine*>(engine)->SetSemanticsEnabled(
1833  enabled)) {
1835  "Could not update semantics state.");
1836  }
1837  return kSuccess;
1838 }
1839 
1843  if (engine == nullptr) {
1844  return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
1845  }
1846  if (!reinterpret_cast<flutter::EmbedderEngine*>(engine)
1847  ->SetAccessibilityFeatures(flags)) {
1849  "Could not update accessibility features.");
1850  }
1851  return kSuccess;
1852 }
1853 
1856  uint64_t id,
1858  const uint8_t* data,
1859  size_t data_length) {
1860  if (engine == nullptr) {
1861  return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
1862  }
1863  auto engine_action = static_cast<flutter::SemanticsAction>(action);
1864  if (!reinterpret_cast<flutter::EmbedderEngine*>(engine)
1865  ->DispatchSemanticsAction(
1866  id, engine_action,
1867  fml::MallocMapping::Copy(data, data_length))) {
1869  "Could not dispatch semantics action.");
1870  }
1871  return kSuccess;
1872 }
1873 
1875  engine,
1876  intptr_t baton,
1877  uint64_t frame_start_time_nanos,
1878  uint64_t frame_target_time_nanos) {
1879  if (engine == nullptr) {
1880  return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
1881  }
1882 
1883  TRACE_EVENT0("flutter", "FlutterEngineOnVsync");
1884 
1885  auto start_time = fml::TimePoint::FromEpochDelta(
1886  fml::TimeDelta::FromNanoseconds(frame_start_time_nanos));
1887 
1888  auto target_time = fml::TimePoint::FromEpochDelta(
1889  fml::TimeDelta::FromNanoseconds(frame_target_time_nanos));
1890 
1891  if (!reinterpret_cast<flutter::EmbedderEngine*>(engine)->OnVsyncEvent(
1892  baton, start_time, target_time)) {
1893  return LOG_EMBEDDER_ERROR(
1895  "Could not notify the running engine instance of a Vsync event.");
1896  }
1897 
1898  return kSuccess;
1899 }
1900 
1903  if (engine == nullptr) {
1904  return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
1905  }
1906 
1907  TRACE_EVENT0("flutter", "FlutterEngineReloadSystemFonts");
1908 
1909  if (!reinterpret_cast<flutter::EmbedderEngine*>(engine)
1910  ->ReloadSystemFonts()) {
1912  "Could not reload system fonts.");
1913  }
1914 
1915  return kSuccess;
1916 }
1917 
1919  fml::tracing::TraceEvent0("flutter", name);
1920 }
1921 
1924 }
1925 
1927  fml::tracing::TraceEventInstant0("flutter", name);
1928 }
1929 
1933  void* baton) {
1934  if (engine == nullptr) {
1935  return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
1936  }
1937 
1938  if (callback == nullptr) {
1940  "Render thread callback was null.");
1941  }
1942 
1943  auto task = [callback, baton]() { callback(baton); };
1944 
1945  return reinterpret_cast<flutter::EmbedderEngine*>(engine)
1946  ->PostRenderThreadTask(task)
1947  ? kSuccess
1949  "Could not post the render thread task.");
1950 }
1951 
1954 }
1955 
1957  engine,
1958  const FlutterTask* task) {
1959  if (engine == nullptr) {
1960  return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
1961  }
1962 
1963  return reinterpret_cast<flutter::EmbedderEngine*>(engine)->RunTask(task)
1964  ? kSuccess
1966  "Could not run the specified task.");
1967 }
1968 
1970  engine,
1971  rapidjson::Document document,
1972  const std::string& channel_name) {
1973  if (channel_name.size() == 0) {
1974  return false;
1975  }
1976 
1977  rapidjson::StringBuffer buffer;
1978  rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
1979 
1980  if (!document.Accept(writer)) {
1981  return false;
1982  }
1983 
1984  const char* message = buffer.GetString();
1985 
1986  if (message == nullptr || buffer.GetSize() == 0) {
1987  return false;
1988  }
1989 
1990  auto platform_message = std::make_unique<flutter::PlatformMessage>(
1991  channel_name.c_str(), // channel
1992  fml::MallocMapping::Copy(message,
1993  buffer.GetSize()), // message
1994  nullptr // response
1995  );
1996 
1997  return reinterpret_cast<flutter::EmbedderEngine*>(engine)
1998  ->SendPlatformMessage(std::move(platform_message));
1999 }
2000 
2002  engine,
2003  const FlutterLocale** locales,
2004  size_t locales_count) {
2005  if (engine == nullptr) {
2006  return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
2007  }
2008 
2009  if (locales_count == 0) {
2010  return kSuccess;
2011  }
2012 
2013  if (locales == nullptr) {
2014  return LOG_EMBEDDER_ERROR(kInvalidArguments, "No locales were specified.");
2015  }
2016 
2017  rapidjson::Document document;
2018  auto& allocator = document.GetAllocator();
2019 
2020  document.SetObject();
2021  document.AddMember("method", "setLocale", allocator);
2022 
2023  rapidjson::Value args(rapidjson::kArrayType);
2024  args.Reserve(locales_count * 4, allocator);
2025  for (size_t i = 0; i < locales_count; ++i) {
2026  const FlutterLocale* locale = locales[i];
2027  const char* language_code_str = SAFE_ACCESS(locale, language_code, nullptr);
2028  if (language_code_str == nullptr || ::strlen(language_code_str) == 0) {
2029  return LOG_EMBEDDER_ERROR(
2031  "Language code is required but not present in FlutterLocale.");
2032  }
2033 
2034  const char* country_code_str = SAFE_ACCESS(locale, country_code, "");
2035  const char* script_code_str = SAFE_ACCESS(locale, script_code, "");
2036  const char* variant_code_str = SAFE_ACCESS(locale, variant_code, "");
2037 
2038  rapidjson::Value language_code, country_code, script_code, variant_code;
2039 
2040  language_code.SetString(language_code_str, allocator);
2041  country_code.SetString(country_code_str ? country_code_str : "", allocator);
2042  script_code.SetString(script_code_str ? script_code_str : "", allocator);
2043  variant_code.SetString(variant_code_str ? variant_code_str : "", allocator);
2044 
2045  // Required.
2046  args.PushBack(language_code, allocator);
2047  args.PushBack(country_code, allocator);
2048  args.PushBack(script_code, allocator);
2049  args.PushBack(variant_code, allocator);
2050  }
2051  document.AddMember("args", args, allocator);
2052 
2053  return DispatchJSONPlatformMessage(engine, std::move(document),
2054  "flutter/localization")
2055  ? kSuccess
2057  "Could not send message to update locale of "
2058  "a running Flutter application.");
2059 }
2060 
2063 }
2064 
2068  const FlutterEngineDartObject* object) {
2069  if (engine == nullptr) {
2070  return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
2071  }
2072 
2073  if (!reinterpret_cast<flutter::EmbedderEngine*>(engine)->IsValid()) {
2074  return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine not running.");
2075  }
2076 
2077  if (port == ILLEGAL_PORT) {
2079  "Attempted to post to an illegal port.");
2080  }
2081 
2082  if (object == nullptr) {
2084  "Invalid Dart object to post.");
2085  }
2086 
2087  Dart_CObject dart_object = {};
2088  fml::ScopedCleanupClosure typed_data_finalizer;
2089 
2090  switch (object->type) {
2092  dart_object.type = Dart_CObject_kNull;
2093  break;
2095  dart_object.type = Dart_CObject_kBool;
2096  dart_object.value.as_bool = object->bool_value;
2097  break;
2099  dart_object.type = Dart_CObject_kInt32;
2100  dart_object.value.as_int32 = object->int32_value;
2101  break;
2103  dart_object.type = Dart_CObject_kInt64;
2104  dart_object.value.as_int64 = object->int64_value;
2105  break;
2107  dart_object.type = Dart_CObject_kDouble;
2108  dart_object.value.as_double = object->double_value;
2109  break;
2111  if (object->string_value == nullptr) {
2113  "kFlutterEngineDartObjectTypeString must be "
2114  "a null terminated string but was null.");
2115  }
2116  dart_object.type = Dart_CObject_kString;
2117  dart_object.value.as_string = const_cast<char*>(object->string_value);
2118  break;
2120  auto* buffer = SAFE_ACCESS(object->buffer_value, buffer, nullptr);
2121  if (buffer == nullptr) {
2123  "kFlutterEngineDartObjectTypeBuffer must "
2124  "specify a buffer but found nullptr.");
2125  }
2126  auto buffer_size = SAFE_ACCESS(object->buffer_value, buffer_size, 0);
2127  auto callback =
2128  SAFE_ACCESS(object->buffer_value, buffer_collect_callback, nullptr);
2129  auto user_data = SAFE_ACCESS(object->buffer_value, user_data, nullptr);
2130 
2131  // The user has provided a callback, let them manage the lifecycle of
2132  // the underlying data. If not, copy it out from the provided buffer.
2133 
2134  if (callback == nullptr) {
2135  dart_object.type = Dart_CObject_kTypedData;
2136  dart_object.value.as_typed_data.type = Dart_TypedData_kUint8;
2137  dart_object.value.as_typed_data.length = buffer_size;
2138  dart_object.value.as_typed_data.values = buffer;
2139  } else {
2140  struct ExternalTypedDataPeer {
2141  void* user_data = nullptr;
2142  VoidCallback trampoline = nullptr;
2143  };
2144  auto peer = new ExternalTypedDataPeer();
2145  peer->user_data = user_data;
2146  peer->trampoline = callback;
2147  // This finalizer is set so that in case of failure of the
2148  // Dart_PostCObject below, we collect the peer. The embedder is still
2149  // responsible for collecting the buffer in case of non-kSuccess
2150  // returns from this method. This finalizer must be released in case
2151  // of kSuccess returns from this method.
2152  typed_data_finalizer.SetClosure([peer]() {
2153  // This is the tiny object we use as the peer to the Dart call so
2154  // that we can attach the a trampoline to the embedder supplied
2155  // callback. In case of error, we need to collect this object lest
2156  // we introduce a tiny leak.
2157  delete peer;
2158  });
2159  dart_object.type = Dart_CObject_kExternalTypedData;
2160  dart_object.value.as_external_typed_data.type = Dart_TypedData_kUint8;
2161  dart_object.value.as_external_typed_data.length = buffer_size;
2162  dart_object.value.as_external_typed_data.data = buffer;
2163  dart_object.value.as_external_typed_data.peer = peer;
2164  dart_object.value.as_external_typed_data.callback =
2165  +[](void* unused_isolate_callback_data, void* peer) {
2166  auto typed_peer = reinterpret_cast<ExternalTypedDataPeer*>(peer);
2167  typed_peer->trampoline(typed_peer->user_data);
2168  delete typed_peer;
2169  };
2170  }
2171  } break;
2172  default:
2173  return LOG_EMBEDDER_ERROR(
2175  "Invalid FlutterEngineDartObjectType type specified.");
2176  }
2177 
2178  if (!Dart_PostCObject(port, &dart_object)) {
2180  "Could not post the object to the Dart VM.");
2181  }
2182 
2183  // On a successful call, the VM takes ownership of and is responsible for
2184  // invoking the finalizer.
2185  typed_data_finalizer.Release();
2186  return kSuccess;
2187 }
2188 
2190  FLUTTER_API_SYMBOL(FlutterEngine) raw_engine) {
2191  auto engine = reinterpret_cast<flutter::EmbedderEngine*>(raw_engine);
2192  if (engine == nullptr || !engine->IsValid()) {
2193  return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine was invalid.");
2194  }
2195 
2196  engine->GetShell().NotifyLowMemoryWarning();
2197 
2198  rapidjson::Document document;
2199  auto& allocator = document.GetAllocator();
2200 
2201  document.SetObject();
2202  document.AddMember("type", "memoryPressure", allocator);
2203 
2204  return DispatchJSONPlatformMessage(raw_engine, std::move(document),
2205  "flutter/system")
2206  ? kSuccess
2209  "Could not dispatch the low memory notification message.");
2210 }
2211 
2215  void* user_data) {
2216  if (engine == nullptr) {
2217  return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
2218  }
2219 
2220  if (callback == nullptr) {
2222  "Invalid native thread callback.");
2223  }
2224 
2225  return reinterpret_cast<flutter::EmbedderEngine*>(engine)
2226  ->PostTaskOnEngineManagedNativeThreads(
2227  [callback, user_data](FlutterNativeThreadType type) {
2228  callback(type, user_data);
2229  })
2230  ? kSuccess
2232  "Internal error while attempting to post "
2233  "tasks to all threads.");
2234 }
2235 
2236 namespace {
2237 static bool ValidDisplayConfiguration(const FlutterEngineDisplay* displays,
2238  size_t display_count) {
2239  std::set<FlutterEngineDisplayId> display_ids;
2240  for (size_t i = 0; i < display_count; i++) {
2241  if (displays[i].single_display && display_count != 1) {
2242  return false;
2243  }
2244  display_ids.insert(displays[i].display_id);
2245  }
2246 
2247  return display_ids.size() == display_count;
2248 }
2249 } // namespace
2250 
2252  FLUTTER_API_SYMBOL(FlutterEngine) raw_engine,
2253  const FlutterEngineDisplaysUpdateType update_type,
2254  const FlutterEngineDisplay* embedder_displays,
2255  size_t display_count) {
2256  if (raw_engine == nullptr) {
2257  return LOG_EMBEDDER_ERROR(kInvalidArguments, "Invalid engine handle.");
2258  }
2259 
2260  if (!ValidDisplayConfiguration(embedder_displays, display_count)) {
2261  return LOG_EMBEDDER_ERROR(
2263  "Invalid FlutterEngineDisplay configuration specified.");
2264  }
2265 
2266  auto engine = reinterpret_cast<flutter::EmbedderEngine*>(raw_engine);
2267 
2268  switch (update_type) {
2270  std::vector<flutter::Display> displays;
2271  for (size_t i = 0; i < display_count; i++) {
2272  flutter::Display display =
2273  flutter::Display(embedder_displays[i].refresh_rate);
2274  if (!embedder_displays[i].single_display) {
2275  display = flutter::Display(embedder_displays[i].display_id,
2276  embedder_displays[i].refresh_rate);
2277  }
2278  displays.push_back(display);
2279  }
2280  engine->GetShell().OnDisplayUpdates(flutter::DisplayUpdateType::kStartup,
2281  displays);
2282  return kSuccess;
2283  }
2284  default:
2285  return LOG_EMBEDDER_ERROR(
2287  "Invalid FlutterEngineDisplaysUpdateType type specified.");
2288  }
2289 }
2290 
2292  FlutterEngineProcTable* table) {
2293  if (!table) {
2294  return LOG_EMBEDDER_ERROR(kInvalidArguments, "Null table specified.");
2295  }
2296 #define SET_PROC(member, function) \
2297  if (STRUCT_HAS_MEMBER(table, member)) { \
2298  table->member = &function; \
2299  }
2300 
2301  SET_PROC(CreateAOTData, FlutterEngineCreateAOTData);
2302  SET_PROC(CollectAOTData, FlutterEngineCollectAOTData);
2303  SET_PROC(Run, FlutterEngineRun);
2304  SET_PROC(Shutdown, FlutterEngineShutdown);
2306  SET_PROC(Deinitialize, FlutterEngineDeinitialize);
2307  SET_PROC(RunInitialized, FlutterEngineRunInitialized);
2308  SET_PROC(SendWindowMetricsEvent, FlutterEngineSendWindowMetricsEvent);
2309  SET_PROC(SendPointerEvent, FlutterEngineSendPointerEvent);
2310  SET_PROC(SendKeyEvent, FlutterEngineSendKeyEvent);
2311  SET_PROC(SendPlatformMessage, FlutterEngineSendPlatformMessage);
2312  SET_PROC(PlatformMessageCreateResponseHandle,
2314  SET_PROC(PlatformMessageReleaseResponseHandle,
2316  SET_PROC(SendPlatformMessageResponse,
2318  SET_PROC(RegisterExternalTexture, FlutterEngineRegisterExternalTexture);
2319  SET_PROC(UnregisterExternalTexture, FlutterEngineUnregisterExternalTexture);
2320  SET_PROC(MarkExternalTextureFrameAvailable,
2322  SET_PROC(UpdateSemanticsEnabled, FlutterEngineUpdateSemanticsEnabled);
2323  SET_PROC(UpdateAccessibilityFeatures,
2326  SET_PROC(OnVsync, FlutterEngineOnVsync);
2327  SET_PROC(ReloadSystemFonts, FlutterEngineReloadSystemFonts);
2328  SET_PROC(TraceEventDurationBegin, FlutterEngineTraceEventDurationBegin);
2329  SET_PROC(TraceEventDurationEnd, FlutterEngineTraceEventDurationEnd);
2330  SET_PROC(TraceEventInstant, FlutterEngineTraceEventInstant);
2331  SET_PROC(PostRenderThreadTask, FlutterEnginePostRenderThreadTask);
2333  SET_PROC(RunTask, FlutterEngineRunTask);
2334  SET_PROC(UpdateLocales, FlutterEngineUpdateLocales);
2335  SET_PROC(RunsAOTCompiledDartCode, FlutterEngineRunsAOTCompiledDartCode);
2336  SET_PROC(PostDartObject, FlutterEnginePostDartObject);
2338  SET_PROC(PostCallbackOnAllNativeThreads,
2340  SET_PROC(NotifyDisplayUpdate, FlutterEngineNotifyDisplayUpdate);
2341 #undef SET_PROC
2342 
2343  return kSuccess;
2344 }
double skewY
vertical skew factor
Definition: embedder.h:238
FlutterEngineResult FlutterEngineNotifyDisplayUpdate(FLUTTER_API_SYMBOL(FlutterEngine) raw_engine, const FlutterEngineDisplaysUpdateType update_type, const FlutterEngineDisplay *embedder_displays, size_t display_count)
Posts updates corresponding to display changes to a running engine instance.
Definition: embedder.cc:2251
uint64_t timestamp
Definition: key_data.h:33
uint32_t fbo_id
Id of the fbo backing the surface that was presented.
Definition: embedder.h:378
MappingCallback isolate_snapshot_instr
Definition: settings.h:108
FlutterAccessibilityFeature
Definition: embedder.h:83
G_BEGIN_DECLS FlValue * args
uint64_t synthesized
Definition: key_data.h:40
static flutter::Shell::CreateCallback< flutter::PlatformView > InferSoftwarePlatformViewCreationCallback(const FlutterRendererConfig *config, void *user_data, flutter::PlatformViewEmbedder::PlatformDispatchTable platform_dispatch_table, std::unique_ptr< flutter::EmbedderExternalViewEmbedder > external_view_embedder)
Definition: embedder.cc:372
FlutterSoftwareRendererConfig software
Definition: embedder.h:558
std::function< void()> OnPreEngineRestartCallback
TransformationCallback surface_transformation
Definition: embedder.h:423
Definition: embedder.h:595
KeyCallType type
Specified an software allocation for Flutter to render into using the CPU.
Definition: embedder.h:1048
flutter::PointerData::SignalKind ToPointerDataSignalKind(FlutterPointerSignalKind kind)
Definition: embedder.cc:1479
std::function< std::unique_ptr< FlutterMetalExternalTexture >(int64_t, size_t, size_t)> ExternalTextureCallback
const char * channel
Definition: embedder.h:758
double skewX
horizontal skew factor
Definition: embedder.h:234
double pers1
input y-axis perspective factor
Definition: embedder.h:246
struct _FlutterEngine * FLUTTER_API_SYMBOL(FlutterEngine)
Definition: embedder.h:228
LogMessageCallback log_message_callback
Definition: settings.h:247
int64_t texture_id
Definition: embedder.h:499
G_BEGIN_DECLS FlTexture * texture
const uint8_t * isolate_snapshot_data
Definition: embedder.h:1423
double pers2
perspective scale factor
Definition: embedder.h:248
std::function< std::unique_ptr< T >(Shell &)> CreateCallback
Definition: shell.h:114
const uint8_t uint32_t uint32_t GError ** error
static void SetSemanticsEnabled(JNIEnv *env, jobject jcaller, jlong shell_holder, jboolean enabled)
size_t struct_size
The size of this struct. Must be sizeof(FlutterMetalTexture).
Definition: embedder.h:494
#define TRACE_EVENT0(category_group, name)
Definition: trace_event.h:90
FlutterComputePlatformResolvedLocaleCallback compute_platform_resolved_locale_callback
Definition: embedder.h:1554
uint32_t width
Definition: embedder.h:328
static void DispatchSemanticsAction(JNIEnv *env, jobject jcaller, jlong shell_holder, jint id, jint action, jobject args, jint args_position)
FLUTTER_EXPORT 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: embedder.cc:1365
FlutterEngineResult FlutterPlatformMessageReleaseResponseHandle(FLUTTER_API_SYMBOL(FlutterEngine) engine, FlutterPlatformMessageResponseHandle *response)
Collects the handle created using FlutterPlatformMessageCreateResponseHandle.
Definition: embedder.cc:1722
static constexpr TimeDelta FromNanoseconds(int64_t nanos)
Definition: time_delta.h:40
FlutterMetalTextureFrameCallback external_texture_frame_callback
Definition: embedder.h:541
#define FLUTTER_EXPORT
Definition: embedder.cc:26
flutter::PointerData::DeviceKind ToPointerDataKind(FlutterPointerDeviceKind device_kind)
Definition: embedder.cc:1464
const uint8_t kPlatformStrongDill[]
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: embedder.cc:1956
std::vector< std::string > dart_entrypoint_args
Definition: settings.h:126
std::function< void(const DartIsolate &)> root_isolate_create_callback
Definition: settings.h:216
uint64_t logical
Definition: key_data.h:36
static fml::RefPtr< NativeLibrary > CreateForCurrentProcess()
int64_t FlutterEngineDartPort
Definition: embedder.h:1220
FlutterKeyEventType
Definition: embedder.h:677
std::string application_kernel_asset
Definition: settings.h:119
FlutterOpenGLFramebuffer framebuffer
Definition: embedder.h:960
static bool DispatchJSONPlatformMessage(FLUTTER_API_SYMBOL(FlutterEngine) engine, rapidjson::Document document, const std::string &channel_name)
Definition: embedder.cc:1969
void TraceEventEnd(TraceArg name)
Definition: trace_event.cc:331
void AddTaskObserver(intptr_t key, const fml::closure &callback)
Definition: message_loop.cc:64
FlutterMetalCommandQueueHandle present_command_queue
Alias for id<MTLCommandQueue>.
Definition: embedder.h:530
SignalKind signal_kind
Definition: pointer_data.h:65
CommandLine CommandLineFromArgcArgv(int argc, const char *const *argv)
Definition: command_line.h:222
void FlutterEngineTraceEventDurationEnd(const char *name)
A profiling utility. Logs a trace duration end event to the timeline. If the timeline is unavailable ...
Definition: embedder.cc:1922
FlutterEngineResult FlutterEnginePostRenderThreadTask(FLUTTER_API_SYMBOL(FlutterEngine) engine, VoidCallback callback, void *baton)
Posts a task onto the Flutter render thread. Typically, this may be called from any thread as long as...
Definition: embedder.cc:1930
static void UnregisterTexture(JNIEnv *env, jobject jcaller, jlong shell_holder, jlong texture_id)
int64_t pointer_identifier
Definition: pointer_data.h:67
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: embedder.cc:1736
const uint8_t * vm_isolate_data
Definition: embedder.cc:744
void operator()(Dart_LoadedElf *elf)
Definition: embedder.cc:731
FlutterEngineDisplaysUpdateType
Definition: embedder.h:1210
const uint8_t * ResolveSymbol(const char *symbol)
const TaskRunners & GetTaskRunners() const override
If callers wish to interact directly with any shell subcomponents, they must (on the platform thread)...
Definition: shell.cc:674
const intptr_t kPlatformStrongDillSize
FlutterPointerPhase
The phase of the pointer event.
Definition: embedder.h:587
FlutterEngineResult FlutterEngineDispatchSemanticsAction(FLUTTER_API_SYMBOL(FlutterEngine) engine, uint64_t id, FlutterSemanticsAction action, const uint8_t *data, size_t data_length)
Dispatch a semantics action to the specified semantics node.
Definition: embedder.cc:1854
FlutterRect rect
The bounding box for this node in its coordinate system.
Definition: embedder.h:839
Function-pointer-based versions of the APIs above.
Definition: embedder.h:2372
static bool IsMetalRendererConfigValid(const FlutterRendererConfig *config)
Definition: embedder.cc:129
MappingCallback vm_snapshot_data
Definition: settings.h:101
OnPreEngineRestartCallback on_pre_engine_restart_callback
Definition: embedder.h:1591
#define LOG_EMBEDDER_ERROR(code, reason)
Definition: embedder.cc:93
double pers0
input x-axis perspective factor
Definition: embedder.h:244
int64_t old_gen_heap_size
Definition: settings.h:283
void(* FlutterLogMessageCallback)(const char *, const char *, void *)
Definition: embedder.h:1340
void * user_data
std::function< void(const uint8_t *data, size_t size)> Callback
static bool IsRendererValid(const FlutterRendererConfig *config)
Definition: embedder.cc:147
FlutterEngineResult FlutterEngineUpdateAccessibilityFeatures(FLUTTER_API_SYMBOL(FlutterEngine) engine, FlutterAccessibilityFeature flags)
Sets additional accessibility features.
Definition: embedder.cc:1840
static FML_EMBEDDER_ONLY MessageLoop & GetCurrent()
Definition: message_loop.cc:19
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: embedder.cc:1377
char32_t character
BoolPresentInfoCallback present_with_info
Definition: embedder.h:443
std::unordered_map< int32_t, SemanticsNode > SemanticsNodeUpdates
GAsyncResult * result
constexpr std::size_t size(T(&array)[N])
Definition: size.h:13
DEF_SWITCHES_START snapshot asset Path to the directory containing the four files specified by VmSnapshotInstructions and IsolateSnapshotInstructions vm snapshot The VM instructions snapshot that will be memory mapped as read and executable SnapshotAssetPath must be present isolate snapshot The isolate instructions snapshot that will be memory mapped as read and executable SnapshotAssetPath must be present icu symbol Prefix for the symbols representing ICU data linked into the Flutter library dart Flags passed directly to the Dart VM without being interpreted by the Flutter shell observatory port
Definition: switches.h:75
Specifies a Metal backing store. This is backed by a Metal texture.
Definition: embedder.h:1050
Settings SettingsFromCommandLine(const fml::CommandLine &command_line)
Definition: switches.cc:228
TimeDelta ToEpochDelta() const
Definition: time_point.h:47
FlutterEngineResult FlutterEnginePostDartObject(FLUTTER_API_SYMBOL(FlutterEngine) engine, FlutterEngineDartPort port, const FlutterEngineDartObject *object)
Posts a Dart object to specified send port. The corresponding receive port for send port can be in an...
Definition: embedder.cc:2065
#define FML_LOG(severity)
Definition: logging.h:65
FlutterEngineResult FlutterEngineMarkExternalTextureFrameAvailable(FLUTTER_API_SYMBOL(FlutterEngine) engine, int64_t texture_identifier)
Mark that a new texture frame is available for a given texture identifier.
Definition: embedder.cc:1808
static constexpr TimePoint FromEpochDelta(TimeDelta ticks)
Definition: time_point.h:38
FlutterPointerDeviceKind
The device type that created a pointer event.
Definition: embedder.h:623
UIntFrameInfoCallback fbo_with_frame_info_callback
Definition: embedder.h:437
FlutterPlatformMessageCallback platform_message_callback
Definition: embedder.h:1402
std::function< void *(const char *)> GLProcResolver
A structure to represent a rectangle.
Definition: embedder.h:333
FlutterEngineResult FlutterEngineNotifyLowMemoryWarning(FLUTTER_API_SYMBOL(FlutterEngine) raw_engine)
Posts a low memory notification to a running engine instance. The engine will do its best to release ...
Definition: embedder.cc:2189
FlutterMetalPresentCallback present_drawable_callback
Definition: embedder.h:536
FlKeyEvent FlKeyResponderAsyncCallback callback
FlutterSemanticsFlag flags
static const char * kApplicationKernelSnapshotFileName
#define SAFE_ACCESS(pointer, member, default_value)
FlutterSemanticsAction
Definition: embedder.h:101
void FlutterEngineTraceEventDurationBegin(const char *name)
A profiling utility. Logs a trace duration begin event to the timeline. If the timeline is unavailabl...
Definition: embedder.cc:1918
FlKeyEvent * event
const uint8_t * vm_snapshot_instrs
Definition: embedder.cc:743
FlutterEngineResult FlutterEngineReloadSystemFonts(FLUTTER_API_SYMBOL(FlutterEngine) engine)
Reloads the system fonts in engine.
Definition: embedder.cc:1901
const char *const * dart_entrypoint_argv
Definition: embedder.h:1566
VsyncCallback vsync_callback
Definition: embedder.h:1479
double scaleY
vertical scale factor
Definition: embedder.h:240
FlutterUIntSize size
The size of the surface that will be backed by the fbo.
Definition: embedder.h:363
const char * string_value
Definition: embedder.h:1288
static bool IsSoftwareRendererConfigValid(const FlutterRendererConfig *config)
Definition: embedder.cc:114
void FlutterEngineTraceEventInstant(const char *name)
A profiling utility. Logs a trace duration instant event to the timeline. If the timeline is unavaila...
Definition: embedder.cc:1926
std::function< bool(const std::vector< const FlutterLayer * > &layers)> PresentCallback
static void NotifyLowMemoryWarning(JNIEnv *env, jobject obj, jlong shell_holder)
VoidCallback destruction_callback
Definition: embedder.h:978
Wraps a closure that is invoked in the destructor unless released by the caller.
Definition: closure.h:32
FlutterOpenGLTargetType type
Definition: embedder.h:954
void TraceEventInstant0(TraceArg category_group, TraceArg name)
Definition: trace_event.cc:358
FlutterMetalTexture texture
Definition: embedder.h:988
static bool IsValid(double value)
VoidCallback destruction_callback
Definition: embedder.h:299
std::function< void()> closure
Definition: closure.h:14
FlutterEngineResult FlutterEngineUpdateSemanticsEnabled(FLUTTER_API_SYMBOL(FlutterEngine) engine, bool enabled)
Enable or disable accessibility semantics.
Definition: embedder.cc:1826
VoidCallback destruction_callback
Definition: embedder.h:509
internal::CopyableLambda< T > MakeCopyable(T lambda)
Definition: make_copyable.h:57
std::string JoinPaths(std::initializer_list< std::string > components)
Definition: paths.cc:14
FlutterSemanticsFlag flags
The set of semantics flags associated with this node.
Definition: embedder.h:800
std::unique_ptr< Dart_LoadedElf, LoadedElfDeleter > UniqueLoadedElf
Definition: embedder.cc:738
static RunConfiguration InferFromSettings(const Settings &settings, fml::RefPtr< fml::TaskRunner > io_worker=nullptr)
Attempts to infer a run configuration from the settings object. This tries to create a run configurat...
size_t struct_size
The size of this struct. Must be sizeof(FlutterFrameInfo).
Definition: embedder.h:361
#define FLUTTER_ENGINE_VERSION
Definition: embedder.h:63
static FlutterEngineResult LogEmbedderError(FlutterEngineResult code, const char *reason, const char *code_name, const char *function, const char *file, int line)
Definition: embedder.cc:72
FlutterSoftwareBackingStore software
The description of the software backing store.
Definition: embedder.h:1069
FlutterRendererType type
Definition: embedder.h:555
static flutter::KeyEventType MapKeyEventType(FlutterKeyEventType event_kind)
Definition: embedder.cc:1583
uint8_t value
double transX
horizontal translation
Definition: embedder.h:236
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: embedder.cc:869
VoidCallback destruction_callback
Definition: embedder.h:274
static void SetCacheDirectoryPath(std::string path)
double thickness
Describes how much space the semantics node takes up along the z-axis.
Definition: embedder.h:822
FlutterEngineResult FlutterEngineCollectAOTData(FlutterEngineAOTData data)
Collects the AOT data.
Definition: embedder.cc:802
const FlutterSemanticsNode * node
Definition: fl_view.cc:83
size_t row_bytes
The number of bytes in a single row of the allocation.
Definition: embedder.h:969
flutter::PointerData::Change ToPointerDataChange(FlutterPointerPhase phase)
Definition: embedder.cc:1441
static flutter::Shell::CreateCallback< flutter::PlatformView > InferMetalPlatformViewCreationCallback(const FlutterRendererConfig *config, void *user_data, flutter::PlatformViewEmbedder::PlatformDispatchTable platform_dispatch_table, std::unique_ptr< flutter::EmbedderExternalViewEmbedder > external_view_embedder)
Definition: embedder.cc:304
void Initialize(fidl::InterfaceHandle< fuchsia::sys::Environment > environment, zx::channel directory_request, std::optional< zx::eventpair > view_ref)
Initializes Dart bindings for the Fuchsia application model.
Definition: fuchsia.cc:103
FlutterUpdateSemanticsNodeCallback update_semantics_node_callback
Definition: embedder.h:1446
void(* FlutterNativeThreadCallback)(FlutterNativeThreadType type, void *user_data)
Definition: embedder.h:1315
static fml::RefPtr< NativeLibrary > Create(const char *path)
KeyEventType type
Definition: key_data.h:34
std::function< void(flutter::CustomAccessibilityActionUpdates actions)> UpdateSemanticsCustomActionsCallback
FlutterOpenGLBackingStore open_gl
The description of the OpenGL backing store.
Definition: embedder.h:1067
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: embedder.cc:2001
SemanticsAction action
The pointer moved while up.
Definition: embedder.h:619
int32_t id
The unique identifier for this node.
Definition: embedder.h:798
#define SET_PROC(member, function)
constexpr int64_t ToNanoseconds() const
Definition: time_delta.h:61
FlutterUpdateSemanticsCustomActionCallback update_semantics_custom_action_callback
Definition: embedder.h:1457
FlutterTransformation transform
Definition: embedder.h:842
static bool IsRunningPrecompiledCode()
Checks if VM instances in the process can run precompiled code. This call can be made at any time and...
Definition: dart_vm.cc:202
BoolCallback make_resource_current
Definition: embedder.h:407
const uint8_t * vm_snapshot_data
Definition: embedder.h:1407
BoolCallback clear_current
Definition: embedder.h:390
TextureFrameCallback gl_external_texture_frame_callback
Definition: embedder.h:429
const char * hint
A brief description of the result of performing an action on the node.
Definition: embedder.h:826
double width
Definition: embedder.h:320
static std::unique_ptr< flutter::EmbedderRenderTarget > CreateEmbedderRenderTarget(const FlutterCompositor *compositor, const FlutterBackingStoreConfig &config, GrDirectContext *context)
Definition: embedder.cc:608
size_t struct_size
The size of this struct. Must be sizeof(FlutterBackingStore).
Definition: embedder.h:1055
const uint8_t * vm_snapshot_instructions
Definition: embedder.h:1415
FlutterEngineResult FlutterEngineSendKeyEvent(FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterKeyEvent *event, FlutterKeyEventCallback callback, void *user_data)
Sends a key event to the engine. The framework will decide whether to handle this event in a synchron...
Definition: embedder.cc:1596
int32_t width
FlutterEngineResult FlutterEngineRegisterExternalTexture(FLUTTER_API_SYMBOL(FlutterEngine) engine, int64_t texture_identifier)
Register an external texture with a unique (per engine) identifier. Only rendering backends that supp...
Definition: embedder.cc:1768
static std::pair< std::unique_ptr< flutter::EmbedderExternalViewEmbedder >, bool > InferExternalViewEmbedderFromArgs(const FlutterCompositor *compositor)
Definition: embedder.cc:682
static void SetAccessibilityFeatures(JNIEnv *env, jobject jcaller, jlong shell_holder, jint flags)
TaskObserverAdd task_observer_add
Definition: settings.h:212
FlutterMetalTextureCallback get_next_drawable_callback
Definition: embedder.h:533
FlutterEngineResult FlutterEngineGetProcAddresses(FlutterEngineProcTable *table)
Gets the table of engine function pointers.
Definition: embedder.cc:2291
fml::closure SetClosure(const fml::closure &closure)
Definition: closure.h:44
Definition: embedder.h:612
FlutterEngineResult FlutterEnginePostCallbackOnAllNativeThreads(FLUTTER_API_SYMBOL(FlutterEngine) engine, FlutterNativeThreadCallback callback, void *user_data)
Schedule a callback to be run on all engine managed threads. The engine will attempt to service this ...
Definition: embedder.cc:2212
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: embedder.cc:885
void PopulateSnapshotMappingCallbacks(const FlutterProjectArgs *args, flutter::Settings &settings)
Definition: embedder.cc:813
static std::unique_ptr< EmbedderThreadHost > CreateEmbedderOrEngineManagedThreadHost(const FlutterCustomTaskRunners *custom_task_runners)
std::string icu_data_path
Definition: settings.h:258
int32_t height
const char * custom_dart_entrypoint
Definition: embedder.h:1488
FlutterBackingStoreCollectCallback collect_backing_store_callback
Definition: embedder.h:1142
static MallocMapping Copy(const T *begin, const T *end)
Definition: mapping.h:147
const char * assets_path
Definition: embedder.h:1354
BoolCallback make_current
Definition: embedder.h:389
fml::closure Release()
Definition: closure.h:50
FlutterPointerSignalKind
The type of a pointer signal.
Definition: embedder.h:642
MappingCallback isolate_snapshot_data
Definition: settings.h:106
void RunExpiredTasksNow()
Definition: message_loop.cc:72
const uint8_t * vm_isolate_instrs
Definition: embedder.cc:745
FlutterOpenGLRendererConfig open_gl
Definition: embedder.h:557
std::function< void(std::unique_ptr< PlatformMessage >)> PlatformMessageResponseCallback
static bool IsOpenGLRendererConfigValid(const FlutterRendererConfig *config)
Definition: embedder.cc:96
FlutterBackingStoreType type
Specifies the type of backing store.
Definition: embedder.h:1061
const int32_t kFlutterSemanticsNodeIdBatchEnd
Definition: embedder.cc:69
FlutterEngineResult
Definition: embedder.h:65
size_t struct_size
The size of this struct. Must be sizeof(FlutterFrameInfo).
Definition: embedder.h:376
const char * value
A textual description of the current value of the node.
Definition: embedder.h:828
MappingCallback dart_library_sources_kernel
Definition: settings.h:112
const char * name
Definition: fuchsia.cc:50
bool IsFile(const std::string &path)
Definition: file_posix.cc:145
std::function< void(flutter::SemanticsNodeUpdates update)> UpdateSemanticsNodesCallback
UIntCallback fbo_callback
Definition: embedder.h:400
const char * label
A textual description of the node.
Definition: embedder.h:824
FlutterEngineResult FlutterEngineUnregisterExternalTexture(FLUTTER_API_SYMBOL(FlutterEngine) engine, int64_t texture_identifier)
Unregister a previous texture registration.
Definition: embedder.cc:1787
static flutter::Shell::CreateCallback< flutter::PlatformView > InferOpenGLPlatformViewCreationCallback(const FlutterRendererConfig *config, void *user_data, flutter::PlatformViewEmbedder::PlatformDispatchTable platform_dispatch_table, std::unique_ptr< flutter::EmbedderExternalViewEmbedder > external_view_embedder)
Definition: embedder.cc:180
void RemoveTaskObserver(intptr_t key)
Definition: message_loop.cc:68
int64_t PointerDataButtonsForLegacyEvent(flutter::PointerData::Change change)
Definition: embedder.cc:1492
double transY
vertical translation
Definition: embedder.h:242
std::function< void(intptr_t)> VsyncCallback
static const uint8_t buffer[]
FlutterMetalTextureHandle texture
Definition: embedder.h:502
#define GetCurrentTime()
FlutterSemanticsAction actions
The set of semantics actions applicable to this node.
Definition: embedder.h:802
double height
Definition: embedder.h:321
void(* VoidCallback)(void *)
Definition: embedder.h:251
struct _FlutterPlatformMessageResponseHandle FlutterPlatformMessageResponseHandle
Definition: embedder.h:752
FlutterNativeThreadType
Definition: embedder.h:1296
uint64_t physical
Definition: key_data.h:35
MappingCallback vm_snapshot_instr
Definition: settings.h:103
FlutterEngineAOTDataSourceType type
Definition: embedder.h:1326
static void RegisterTexture(JNIEnv *env, jobject jcaller, jlong shell_holder, jlong texture_id, jobject surface_texture)
FlutterMetalRendererConfig metal
Definition: embedder.h:559
FlutterMetalBackingStore metal
Definition: embedder.h:1071
#define SAFE_EXISTS(pointer, member)
Checks if the member exists and is non-null.
FlutterEngineResult FlutterEngineSendPointerEvent(FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterPointerEvent *pointers, size_t events_count)
Definition: embedder.cc:1510
const FlutterEngineDartBuffer * buffer_value
Definition: embedder.h:1289
uint32_t name
The name of the texture.
Definition: embedder.h:267
void(* FlutterKeyEventCallback)(bool, void *)
Definition: embedder.h:748
FlutterEngineAOTData aot_data
Definition: embedder.h:1543
FlutterEngineResult __FlutterEngineFlushPendingTasksNow()
This API is only meant to be used by platforms that need to flush tasks on a message loop not control...
Definition: embedder.cc:1763
std::function< std::unique_ptr< FlutterOpenGLTexture >(int64_t, size_t, size_t)> ExternalTextureCallback
std::function< std::unique_ptr< EmbedderRenderTarget >(GrDirectContext *context, const FlutterBackingStoreConfig &config)> CreateRenderTargetCallback
FlutterSize size
The size of the render target the engine expects to render into.
Definition: embedder.h:1079
FlutterTextDirection
Definition: embedder.h:219
const uint8_t * isolate_snapshot_instructions
Definition: embedder.h:1431
#define SAFE_EXISTS_ONE_OF(pointer, member1, member2)
Checks if exactly one of member1 or member2 exists and is non-null.
static sk_sp< SkSurface > MakeSkSurfaceFromBackingStore(GrDirectContext *context, const FlutterBackingStoreConfig &config, const FlutterOpenGLTexture *texture)
Definition: embedder.cc:439
std::unordered_map< int32_t, CustomAccessibilityAction > CustomAccessibilityActionUpdates
FlutterMetalDeviceHandle device
Alias for id<MTLDevice>.
Definition: embedder.h:528
TaskObserverRemove task_observer_remove
Definition: settings.h:213
void * user_data
User data to be returned on the invocation of the destruction callback.
Definition: embedder.h:295
static void SetViewportMetrics(JNIEnv *env, jobject jcaller, jlong shell_holder, jfloat devicePixelRatio, jint physicalWidth, jint physicalHeight, jint physicalPaddingTop, jint physicalPaddingRight, jint physicalPaddingBottom, jint physicalPaddingLeft, jint physicalViewInsetTop, jint physicalViewInsetRight, jint physicalViewInsetBottom, jint physicalViewInsetLeft, jint systemGestureInsetTop, jint systemGestureInsetRight, jint systemGestureInsetBottom, jint systemGestureInsetLeft, jint physicalTouchSlop)
ProcResolver gl_proc_resolver
Definition: embedder.h:424
void * user_data
User data to be returned on the invocation of the destruction callback.
Definition: embedder.h:271
void(* FlutterDataCallback)(const uint8_t *, size_t, void *)
Definition: embedder.h:774
FlutterEngineResult FlutterEngineSendWindowMetricsEvent(FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterWindowMetricsEvent *flutter_metrics)
Definition: embedder.cc:1388
std::string assets_path
Definition: settings.h:264
static void DispatchPointerDataPacket(JNIEnv *env, jobject jcaller, jlong shell_holder, jobject buffer, jint position)
FlutterEngineResult FlutterEngineOnVsync(FLUTTER_API_SYMBOL(FlutterEngine) engine, intptr_t baton, uint64_t frame_start_time_nanos, uint64_t frame_target_time_nanos)
Notify the engine that a vsync event occurred. A baton passed to the platform via the vsync callback ...
Definition: embedder.cc:1874
double scaleX
horizontal scale factor
Definition: embedder.h:232
const uint8_t * vm_snapshot_data
Definition: embedder.cc:742
void TraceEvent0(TraceArg category_group, TraceArg name)
Definition: trace_event.cc:317
std::unique_ptr< flutter::PlatformMessage > message
Definition: embedder.cc:727
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: embedder.cc:1326
bool FlutterEngineRunsAOTCompiledDartCode(void)
Returns if the Flutter engine instance will run AOT compiled Dart code. This call has no threading re...
Definition: embedder.cc:2061
uint32_t format
The texture format (example GL_RGBA8).
Definition: embedder.h:269
std::function< bool(GPUMTLTextureInfo texture)> present
std::string log_tag
Definition: settings.h:251
uint64_t FlutterEngineGetCurrentTime()
Get the current time in nanoseconds from the clock used by the flutter engine. This is the system mon...
Definition: embedder.cc:1952
const char * elf_path
Absolute path to an ELF library file.
Definition: embedder.h:1329
static TimePoint Now()
Definition: time_point.cc:39
uint32_t name
The name of the framebuffer.
Definition: embedder.h:292
FlutterEngineResult FlutterEngineSendPlatformMessage(FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterPlatformMessage *flutter_message)
Definition: embedder.cc:1636
const int32_t kFlutterSemanticsCustomActionIdBatchEnd
Definition: embedder.cc:70
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: embedder.cc:1687
SoftwareSurfacePresentCallback surface_present_callback
Definition: embedder.h:551
static flutter::Shell::CreateCallback< flutter::PlatformView > InferPlatformViewCreationCallback(const FlutterRendererConfig *config, void *user_data, flutter::PlatformViewEmbedder::PlatformDispatchTable platform_dispatch_table, std::unique_ptr< flutter::EmbedderExternalViewEmbedder > external_view_embedder)
Definition: embedder.cc:409
std::function< std::unique_ptr< std::vector< std::string > >(const std::vector< std::string > &supported_locale_data)> ComputePlatformResolvedLocaleCallback
FlutterEngineDartObjectType type
Definition: embedder.h:1279
FlutterOpenGLTexture texture
A texture for Flutter to render into.
Definition: embedder.h:957
static void MarkTextureFrameAvailable(JNIEnv *env, jobject jcaller, jlong shell_holder, jlong texture_id)
KeyEventType
Definition: key_data.h:19
FlutterBackingStoreCreateCallback create_backing_store_callback
Definition: embedder.h:1139
FlutterEngineResult FlutterEngineCreateAOTData(const FlutterEngineAOTDataSource *source, FlutterEngineAOTData *data_out)
Creates the necessary data structures to launch a Flutter Dart application in AOT mode...
Definition: embedder.cc:748