Flutter Engine
flutter_runner::Engine Class Referencefinal

#include <engine.h>

Classes

class  Delegate
 

Public Member Functions

 Engine (Delegate &delegate, std::string thread_label, std::shared_ptr< sys::ServiceDirectory > svc, std::shared_ptr< sys::ServiceDirectory > runner_services, flutter::Settings settings, fml::RefPtr< const flutter::DartSnapshot > isolate_snapshot, fuchsia::ui::views::ViewToken view_token, scenic::ViewRefPair view_ref_pair, UniqueFDIONS fdio_ns, fidl::InterfaceRequest< fuchsia::io::Directory > directory_request, FlutterRunnerProductConfiguration product_config)
 
 ~Engine ()
 
std::optional< uint32_t > GetEngineReturnCode () const
 
void WriteProfileToTrace () const
 

Detailed Description

Definition at line 39 of file engine.h.

Constructor & Destructor Documentation

◆ Engine()

flutter_runner::Engine::Engine ( Delegate delegate,
std::string  thread_label,
std::shared_ptr< sys::ServiceDirectory >  svc,
std::shared_ptr< sys::ServiceDirectory >  runner_services,
flutter::Settings  settings,
fml::RefPtr< const flutter::DartSnapshot isolate_snapshot,
fuchsia::ui::views::ViewToken  view_token,
scenic::ViewRefPair  view_ref_pair,
UniqueFDIONS  fdio_ns,
fidl::InterfaceRequest< fuchsia::io::Directory >  directory_request,
FlutterRunnerProductConfiguration  product_config 
)

Definition at line 62 of file engine.cc.

References flutter::DartVMRef::Create(), flutter::Shell::Create(), flutter_runner::CreateFMLTaskRunner(), engine, flutter::Engine::Failure, FML_DCHECK, FML_DLOG, FML_LOG, FML_VLOG, flutter_runner::FlutterRunnerProductConfiguration::get_max_frames_in_flight(), flutter_runner::FlutterRunnerProductConfiguration::get_vsync_offset(), flutter::TaskRunners::GetPlatformTaskRunner(), flutter::TaskRunners::GetRasterTaskRunner(), flutter::RunConfiguration::InferFromSettings(), fml::MakeCopyable(), fml::TaskRunner::PostTask(), flutter::Settings::root_isolate_create_callback, flutter::Settings::root_isolate_shutdown_callback, fml::AutoResetWaitableEvent::Signal(), TRACE_EVENT0, and fml::AutoResetWaitableEvent::Wait().

73  : delegate_(delegate),
74  thread_label_(std::move(thread_label)),
75 #if defined(LEGACY_FUCHSIA_EMBEDDER)
76  use_legacy_renderer_(product_config.use_legacy_renderer()),
77 #endif
78  weak_factory_(this) {
79  if (zx::event::create(0, &vsync_event_) != ZX_OK) {
80  FML_DLOG(ERROR) << "Could not create the vsync event.";
81  return;
82  }
83 
84  // Get the task runners from the managed threads. The current thread will be
85  // used as the "platform" thread.
86  const flutter::TaskRunners task_runners(
87  thread_label_, // Dart thread labels
88  CreateFMLTaskRunner(async_get_default_dispatcher()), // platform
89  CreateFMLTaskRunner(threads_[0].dispatcher()), // raster
90  CreateFMLTaskRunner(threads_[1].dispatcher()), // ui
91  CreateFMLTaskRunner(threads_[2].dispatcher()) // io
92  );
93  UpdateNativeThreadLabelNames(thread_label_, task_runners);
94 
95  // Connect to Scenic.
96  auto scenic = svc->Connect<fuchsia::ui::scenic::Scenic>();
97  fidl::InterfaceHandle<fuchsia::ui::scenic::Session> session;
98  fidl::InterfaceHandle<fuchsia::ui::scenic::SessionListener> session_listener;
99  auto session_listener_request = session_listener.NewRequest();
100  fidl::InterfaceHandle<fuchsia::ui::views::Focuser> focuser;
101  scenic->CreateSession2(session.NewRequest(), session_listener.Bind(),
102  focuser.NewRequest());
103 
104  // Make clones of the `ViewRef` before sending it down to Scenic.
105  fuchsia::ui::views::ViewRef platform_view_ref, isolate_view_ref;
106  view_ref_pair.view_ref.Clone(&platform_view_ref);
107  view_ref_pair.view_ref.Clone(&isolate_view_ref);
108 
109  // Session is terminated on the raster thread, but we must terminate ourselves
110  // on the platform thread.
111  //
112  // This handles the fidl error callback when the Session connection is
113  // broken. The SessionListener interface also has an OnError method, which is
114  // invoked on the platform thread (in PlatformView).
115  fml::closure session_error_callback = [dispatcher =
116  async_get_default_dispatcher(),
117  weak = weak_factory_.GetWeakPtr()]() {
118  async::PostTask(dispatcher, [weak]() {
119  if (weak) {
120  weak->Terminate();
121  }
122  });
123  };
124 
125  // Set up the session connection and other Scenic helpers on the raster
126  // thread. We also need to wait for the external view embedder to be setup
127  // before creating the shell.
128  fml::AutoResetWaitableEvent view_embedder_latch;
129  task_runners.GetRasterTaskRunner()->PostTask(fml::MakeCopyable(
130  [this, session = std::move(session),
131  session_error_callback = std::move(session_error_callback),
132  view_token = std::move(view_token),
133  view_ref_pair = std::move(view_ref_pair),
134  max_frames_in_flight = product_config.get_max_frames_in_flight(),
135  vsync_handle = vsync_event_.get(), &view_embedder_latch]() mutable {
136  session_connection_.emplace(
137  thread_label_, std::move(session),
138  std::move(session_error_callback), [](auto) {}, vsync_handle,
139  max_frames_in_flight);
140  surface_producer_.emplace(session_connection_->get());
141 #if defined(LEGACY_FUCHSIA_EMBEDDER)
142  if (use_legacy_renderer_) {
143  legacy_external_view_embedder_ =
144  std::make_shared<flutter::SceneUpdateContext>(
145  thread_label_, std::move(view_token),
146  std::move(view_ref_pair), session_connection_.value());
147  } else
148 #endif
149  {
150  external_view_embedder_ =
151  std::make_shared<FuchsiaExternalViewEmbedder>(
152  thread_label_, std::move(view_token),
153  std::move(view_ref_pair), session_connection_.value(),
154  surface_producer_.value());
155  }
156  view_embedder_latch.Signal();
157  }));
158  view_embedder_latch.Wait();
159 
160  // Grab the parent environment services. The platform view may want to
161  // access some of these services.
162  fuchsia::sys::EnvironmentPtr environment;
163  svc->Connect(environment.NewRequest());
164  fidl::InterfaceHandle<fuchsia::sys::ServiceProvider>
165  parent_environment_service_provider;
166  environment->GetServices(parent_environment_service_provider.NewRequest());
167  environment.Unbind();
168 
169  OnEnableWireframe on_enable_wireframe_callback = std::bind(
170  &Engine::DebugWireframeSettingsChanged, this, std::placeholders::_1);
171 
172  OnCreateView on_create_view_callback =
173  std::bind(&Engine::CreateView, this, std::placeholders::_1,
174  std::placeholders::_2, std::placeholders::_3);
175 
176  OnUpdateView on_update_view_callback =
177  std::bind(&Engine::UpdateView, this, std::placeholders::_1,
178  std::placeholders::_2, std::placeholders::_3);
179 
180  OnDestroyView on_destroy_view_callback =
181  std::bind(&Engine::DestroyView, this, std::placeholders::_1);
182 
183  OnCreateSurface on_create_surface_callback =
184  std::bind(&Engine::CreateSurface, this);
185 
186  // SessionListener has a OnScenicError method; invoke this callback on the
187  // platform thread when that happens. The Session itself should also be
188  // disconnected when this happens, and it will also attempt to terminate.
189  fit::closure on_session_listener_error_callback =
190  [dispatcher = async_get_default_dispatcher(),
191  weak = weak_factory_.GetWeakPtr()]() {
192  async::PostTask(dispatcher, [weak]() {
193  if (weak) {
194  weak->Terminate();
195  }
196  });
197  };
198 
199  // Setup the callback that will instantiate the platform view.
201  on_create_platform_view = fml::MakeCopyable(
202  [debug_label = thread_label_, view_ref = std::move(platform_view_ref),
203  runner_services,
204  parent_environment_service_provider =
205  std::move(parent_environment_service_provider),
206  session_listener_request = std::move(session_listener_request),
207  focuser = std::move(focuser),
208  on_session_listener_error_callback =
209  std::move(on_session_listener_error_callback),
210  on_enable_wireframe_callback =
211  std::move(on_enable_wireframe_callback),
212  on_create_view_callback = std::move(on_create_view_callback),
213  on_update_view_callback = std::move(on_update_view_callback),
214  on_destroy_view_callback = std::move(on_destroy_view_callback),
215  on_create_surface_callback = std::move(on_create_surface_callback),
216  external_view_embedder = GetExternalViewEmbedder(),
217  vsync_offset = product_config.get_vsync_offset(),
218  vsync_handle = vsync_event_.get()](flutter::Shell& shell) mutable {
219  return std::make_unique<flutter_runner::PlatformView>(
220  shell, // delegate
221  debug_label, // debug label
222  std::move(view_ref), // view ref
223  shell.GetTaskRunners(), // task runners
224  std::move(runner_services),
225  std::move(parent_environment_service_provider), // services
226  std::move(session_listener_request), // session listener
227  std::move(focuser),
228  std::move(on_session_listener_error_callback),
229  std::move(on_enable_wireframe_callback),
230  std::move(on_create_view_callback),
231  std::move(on_update_view_callback),
232  std::move(on_destroy_view_callback),
233  std::move(on_create_surface_callback),
234  external_view_embedder, // external view embedder
235  std::move(vsync_offset), // vsync offset
236  vsync_handle);
237  });
238 
239  // Setup the callback that will instantiate the rasterizer.
241 #if defined(LEGACY_FUCHSIA_EMBEDDER)
242  on_create_rasterizer = [this](flutter::Shell& shell) {
243  if (use_legacy_renderer_) {
244  FML_DCHECK(session_connection_);
245  FML_DCHECK(surface_producer_);
246  FML_DCHECK(legacy_external_view_embedder_);
247 
248  auto compositor_context =
249  std::make_unique<flutter_runner::CompositorContext>(
250  session_connection_.value(), surface_producer_.value(),
251  legacy_external_view_embedder_);
252  return std::make_unique<flutter::Rasterizer>(
253  shell, std::move(compositor_context));
254  } else {
255  return std::make_unique<flutter::Rasterizer>(shell);
256  }
257  };
258 #else
259  on_create_rasterizer = [](flutter::Shell& shell) {
260  return std::make_unique<flutter::Rasterizer>(shell);
261  };
262 #endif
263 
265  std::bind(&Engine::OnMainIsolateStart, this);
267  std::bind([weak = weak_factory_.GetWeakPtr(),
268  runner = task_runners.GetPlatformTaskRunner()]() {
269  runner->PostTask([weak = std::move(weak)] {
270  if (weak) {
271  weak->OnMainIsolateShutdown();
272  }
273  });
274  });
275 
276  auto vm = flutter::DartVMRef::Create(settings);
277 
278  if (!isolate_snapshot) {
279  isolate_snapshot = vm->GetVMData()->GetIsolateSnapshot();
280  }
281 
282  {
283  TRACE_EVENT0("flutter", "CreateShell");
284  shell_ = flutter::Shell::Create(
285  std::move(task_runners), // host task runners
286  flutter::PlatformData(), // default window data
287  std::move(settings), // shell launch settings
288  std::move(isolate_snapshot), // isolate snapshot
289  std::move(on_create_platform_view), // platform view create callback
290  std::move(on_create_rasterizer), // rasterizer create callback
291  std::move(vm) // vm reference
292  );
293  }
294 
295  if (!shell_) {
296  FML_LOG(ERROR) << "Could not launch the shell.";
297  return;
298  }
299 
300  // Shell has been created. Before we run the engine, setup the isolate
301  // configurator.
302  {
303  fuchsia::sys::EnvironmentPtr environment;
304  svc->Connect(environment.NewRequest());
305 
306  isolate_configurator_ = std::make_unique<IsolateConfigurator>(
307  std::move(fdio_ns), //
308  std::move(environment), //
309  directory_request.TakeChannel(), //
310  std::move(isolate_view_ref.reference) //
311  );
312  }
313 
314  // This platform does not get a separate surface platform view creation
315  // notification. Fire one eagerly.
316  shell_->GetPlatformView()->NotifyCreated();
317 
318  // Connect to the intl property provider. If the connection fails, the
319  // initialization of the engine will simply proceed, printing a warning
320  // message. The engine will be fully functional, except that the user's
321  // locale preferences would not be communicated to flutter engine.
322  {
323  intl_property_provider_.set_error_handler([](zx_status_t status) {
324  FML_LOG(WARNING) << "Failed to connect to "
325  << fuchsia::intl::PropertyProvider::Name_ << ": "
326  << zx_status_get_string(status)
327  << " This is not a fatal error, but the user locale "
328  << " preferences will not be forwarded to flutter apps";
329  });
330 
331  // Note that we're using the runner's services, not the component's.
332  // Flutter locales should be updated regardless of whether the component has
333  // direct access to the fuchsia.intl.PropertyProvider service.
334  ZX_ASSERT(runner_services->Connect(intl_property_provider_.NewRequest()) ==
335  ZX_OK);
336 
337  auto get_profile_callback = [flutter_runner_engine =
338  weak_factory_.GetWeakPtr()](
339  const fuchsia::intl::Profile& profile) {
340  if (!flutter_runner_engine) {
341  return;
342  }
343  if (!profile.has_locales()) {
344  FML_LOG(WARNING) << "Got intl Profile without locales";
345  }
346  auto message = MakeLocalizationPlatformMessage(profile);
347  FML_VLOG(-1) << "Sending LocalizationPlatformMessage";
348  flutter_runner_engine->shell_->GetPlatformView()->DispatchPlatformMessage(
349  message);
350  };
351 
352  FML_VLOG(-1) << "Requesting intl Profile";
353 
354  // Make the initial request
355  intl_property_provider_->GetProfile(get_profile_callback);
356 
357  // And register for changes
358  intl_property_provider_.events().OnChange = [this, runner_services,
359  get_profile_callback]() {
360  FML_VLOG(-1) << fuchsia::intl::PropertyProvider::Name_ << ": OnChange";
361  runner_services->Connect(intl_property_provider_.NewRequest());
362  intl_property_provider_->GetProfile(get_profile_callback);
363  };
364  }
365 
366  // Launch the engine in the appropriate configuration.
367  auto run_configuration = flutter::RunConfiguration::InferFromSettings(
368  shell_->GetSettings(), shell_->GetTaskRunners().GetIOTaskRunner());
369 
370  auto on_run_failure = [weak = weak_factory_.GetWeakPtr()]() {
371  // The engine could have been killed by the caller right after the
372  // constructor was called but before it could run on the UI thread.
373  if (weak) {
374  weak->Terminate();
375  }
376  };
377 
378  // Connect to the system font provider.
379  fuchsia::fonts::ProviderSyncPtr sync_font_provider;
380  svc->Connect(sync_font_provider.NewRequest());
381 
382  shell_->GetTaskRunners().GetUITaskRunner()->PostTask(
383  fml::MakeCopyable([engine = shell_->GetEngine(), //
384  run_configuration = std::move(run_configuration), //
385  sync_font_provider = std::move(sync_font_provider), //
386  on_run_failure //
387  ]() mutable {
388  if (!engine) {
389  return;
390  }
391 
392  // Set default font manager.
393  engine->GetFontCollection().GetFontCollection()->SetDefaultFontManager(
394  SkFontMgr_New_Fuchsia(std::move(sync_font_provider)));
395 
396  if (engine->Run(std::move(run_configuration)) ==
398  on_run_failure();
399  }
400  }));
401 }
std::function< std::unique_ptr< T >(Shell &)> CreateCallback
Definition: shell.h:99
fml::RefPtr< fml::TaskRunner > CreateFMLTaskRunner(async_dispatcher_t *dispatcher)
#define TRACE_EVENT0(category_group, name)
Definition: trace_event.h:75
#define FML_DCHECK(condition)
Definition: logging.h:86
std::function< void(const DartIsolate &)> root_isolate_create_callback
Definition: settings.h:174
fit::function< std::unique_ptr< flutter::Surface >()> OnCreateSurface
Definition: platform_view.h:31
#define FML_LOG(severity)
Definition: logging.h:65
static DartVMRef Create(Settings settings, fml::RefPtr< DartSnapshot > vm_snapshot=nullptr, fml::RefPtr< DartSnapshot > isolate_snapshot=nullptr)
fit::function< void(int64_t)> OnDestroyView
Definition: platform_view.h:30
MockDelegate delegate_
std::function< void()> closure
Definition: closure.h:14
internal::CopyableLambda< T > MakeCopyable(T lambda)
Definition: make_copyable.h:57
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...
fml::closure root_isolate_shutdown_callback
Definition: settings.h:180
fit::function< void(int64_t, bool, bool)> OnUpdateView
Definition: platform_view.h:29
fit::function< void(int64_t, bool, bool)> OnCreateView
Definition: platform_view.h:28
#define FML_DLOG(severity)
Definition: logging.h:85
#define FML_VLOG(verbose_level)
Definition: logging.h:81
fit::function< void(bool)> OnEnableWireframe
Definition: platform_view.h:27
static std::unique_ptr< Shell > Create(TaskRunners task_runners, Settings settings, const CreateCallback< PlatformView > &on_create_platform_view, const CreateCallback< Rasterizer > &on_create_rasterizer)
Creates a shell instance using the provided settings. The callbacks to create the various shell subco...
Definition: shell.cc:239

◆ ~Engine()

flutter_runner::Engine::~Engine ( )

Definition at line 403 of file engine.cc.

403  {
404  shell_.reset();
405  for (auto& thread : threads_) {
406  thread.Quit();
407  }
408  for (auto& thread : threads_) {
409  thread.Join();
410  }
411 }

Member Function Documentation

◆ GetEngineReturnCode()

std::optional< uint32_t > flutter_runner::Engine::GetEngineReturnCode ( ) const

Definition at line 413 of file engine.cc.

References engine, fml::TaskRunner::RunNowOrPostTask(), fml::AutoResetWaitableEvent::Signal(), and fml::AutoResetWaitableEvent::Wait().

Referenced by flutter_runner::CreateWithContentsOfFile().

413  {
414  if (!shell_) {
415  return std::nullopt;
416  }
417  std::optional<uint32_t> code;
420  shell_->GetTaskRunners().GetUITaskRunner(),
421  [&latch, &code, engine = shell_->GetEngine()]() {
422  if (engine) {
423  code = engine->GetUIIsolateReturnCode();
424  }
425  latch.Signal();
426  });
427  latch.Wait();
428  return code;
429 }
static void RunNowOrPostTask(fml::RefPtr< fml::TaskRunner > runner, const fml::closure &task)
Definition: task_runner.cc:55

◆ WriteProfileToTrace()

void flutter_runner::Engine::WriteProfileToTrace ( ) const

Definition at line 615 of file engine.cc.

References error, and FML_LOG.

615  {
616  Dart_Port main_port = shell_->GetEngine()->GetUIIsolateMainPort();
617  char* error = NULL;
618  bool success = Dart_WriteProfileToTimeline(main_port, &error);
619  if (!success) {
620  FML_LOG(ERROR) << "Failed to write Dart profile to trace: " << error;
621  free(error);
622  }
623 }
FlMethodResponse GError ** error
#define FML_LOG(severity)
Definition: logging.h:65

The documentation for this class was generated from the following files: