Flutter Windows Embedder
flutter::FlutterWindowsEngine Class Reference

#include <flutter_windows_engine.h>

Public Member Functions

 FlutterWindowsEngine (const FlutterProjectBundle &project, std::shared_ptr< WindowsProcTable > windows_proc_table=nullptr)
 
virtual ~FlutterWindowsEngine ()
 
bool Run ()
 
bool Run (std::string_view entrypoint)
 
virtual bool running () const
 
virtual bool Stop ()
 
std::unique_ptr< FlutterWindowsViewCreateView (std::unique_ptr< WindowBindingHandler > window)
 
virtual void RemoveView (FlutterViewId view_id)
 
FlutterWindowsViewview (FlutterViewId view_id) const
 
FlutterDesktopPluginRegistrarRef GetRegistrar ()
 
void AddPluginRegistrarDestructionCallback (FlutterDesktopOnPluginRegistrarDestroyed callback, FlutterDesktopPluginRegistrarRef registrar)
 
void SetSwitches (const std::vector< std::string > &switches)
 
FlutterDesktopMessengerRef messenger ()
 
IncomingMessageDispatchermessage_dispatcher ()
 
TaskRunnertask_runner ()
 
BinaryMessengermessenger_wrapper ()
 
FlutterWindowsTextureRegistrartexture_registrar ()
 
egl::Manageregl_manager () const
 
WindowProcDelegateManagerwindow_proc_delegate_manager ()
 
void SendWindowMetricsEvent (const FlutterWindowMetricsEvent &event)
 
void SendPointerEvent (const FlutterPointerEvent &event)
 
void SendKeyEvent (const FlutterKeyEvent &event, FlutterKeyEventCallback callback, void *user_data)
 
KeyboardHandlerBasekeyboard_key_handler ()
 
TextInputPlugintext_input_plugin ()
 
bool SendPlatformMessage (const char *channel, const uint8_t *message, const size_t message_size, const FlutterDesktopBinaryReply reply, void *user_data)
 
void SendPlatformMessageResponse (const FlutterDesktopMessageResponseHandle *handle, const uint8_t *data, size_t data_length)
 
void HandlePlatformMessage (const FlutterPlatformMessage *)
 
void ReloadSystemFonts ()
 
void ScheduleFrame ()
 
void SetNextFrameCallback (fml::closure callback)
 
bool RegisterExternalTexture (int64_t texture_id)
 
bool UnregisterExternalTexture (int64_t texture_id)
 
bool MarkExternalTextureFrameAvailable (int64_t texture_id)
 
virtual bool PostRasterThreadTask (fml::closure callback) const
 
void OnVsync (intptr_t baton)
 
bool DispatchSemanticsAction (uint64_t id, FlutterSemanticsAction action, fml::MallocMapping data)
 
void UpdateSemanticsEnabled (bool enabled)
 
bool semantics_enabled () const
 
void UpdateAccessibilityFeatures ()
 
void UpdateHighContrastMode ()
 
bool high_contrast_enabled () const
 
void SetRootIsolateCreateCallback (const fml::closure &callback)
 
std::string GetExecutableName () const
 
void OnQuit (std::optional< HWND > hwnd, std::optional< WPARAM > wparam, std::optional< LPARAM > lparam, UINT exit_code)
 
void RequestApplicationQuit (HWND hwnd, WPARAM wparam, LPARAM lparam, AppExitType exit_type)
 
void OnDwmCompositionChanged ()
 
void OnWindowStateEvent (HWND hwnd, WindowStateEvent event)
 
std::optional< LRESULT > ProcessExternalWindowMessage (HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
 
WindowsLifecycleManagerlifecycle_manager ()
 
std::shared_ptr< WindowsProcTablewindows_proc_table ()
 

Protected Member Functions

virtual std::unique_ptr< KeyboardHandlerBaseCreateKeyboardKeyHandler (BinaryMessenger *messenger, KeyboardKeyEmbedderHandler::GetKeyStateHandler get_key_state, KeyboardKeyEmbedderHandler::MapVirtualKeyToScanCode map_vk_to_scan)
 
virtual std::unique_ptr< TextInputPluginCreateTextInputPlugin (BinaryMessenger *messenger)
 
void OnPreEngineRestart ()
 
virtual void OnChannelUpdate (std::string name, bool listening)
 

Friends

class EngineModifier
 

Detailed Description

Definition at line 90 of file flutter_windows_engine.h.

Constructor & Destructor Documentation

◆ FlutterWindowsEngine()

flutter::FlutterWindowsEngine::FlutterWindowsEngine ( const FlutterProjectBundle project,
std::shared_ptr< WindowsProcTable windows_proc_table = nullptr 
)

Definition at line 147 of file flutter_windows_engine.cc.

150  : project_(std::make_unique<FlutterProjectBundle>(project)),
151  windows_proc_table_(std::move(windows_proc_table)),
152  aot_data_(nullptr, nullptr),
153  views_mutex_(fml::SharedMutex::Create()),
154  lifecycle_manager_(std::make_unique<WindowsLifecycleManager>(this)) {
155  if (windows_proc_table_ == nullptr) {
156  windows_proc_table_ = std::make_shared<WindowsProcTable>();
157  }
158 
159  gl_ = egl::ProcTable::Create();
160 
161  embedder_api_.struct_size = sizeof(FlutterEngineProcTable);
162  FlutterEngineGetProcAddresses(&embedder_api_);
163 
164  task_runner_ =
165  std::make_unique<TaskRunner>(
166  embedder_api_.GetCurrentTime, [this](const auto* task) {
167  if (!engine_) {
168  FML_LOG(ERROR)
169  << "Cannot post an engine task when engine is not running.";
170  return;
171  }
172  if (embedder_api_.RunTask(engine_, task) != kSuccess) {
173  FML_LOG(ERROR) << "Failed to post an engine task.";
174  }
175  });
176 
177  // Set up the legacy structs backing the API handles.
178  messenger_ =
179  fml::RefPtr<FlutterDesktopMessenger>(new FlutterDesktopMessenger());
180  messenger_->SetEngine(this);
181  plugin_registrar_ = std::make_unique<FlutterDesktopPluginRegistrar>();
182  plugin_registrar_->engine = this;
183 
184  messenger_wrapper_ =
185  std::make_unique<BinaryMessengerImpl>(messenger_->ToRef());
186  message_dispatcher_ =
187  std::make_unique<IncomingMessageDispatcher>(messenger_->ToRef());
188 
189  texture_registrar_ =
190  std::make_unique<FlutterWindowsTextureRegistrar>(this, gl_);
191 
192  // Check for impeller support.
193  auto& switches = project_->GetSwitches();
194  enable_impeller_ = std::find(switches.begin(), switches.end(),
195  "--enable-impeller=true") != switches.end();
196 
197  egl_manager_ = egl::Manager::Create(enable_impeller_);
198  window_proc_delegate_manager_ = std::make_unique<WindowProcDelegateManager>();
199  window_proc_delegate_manager_->RegisterTopLevelWindowProcDelegate(
200  [](HWND hwnd, UINT msg, WPARAM wpar, LPARAM lpar, void* user_data,
201  LRESULT* result) {
202  BASE_DCHECK(user_data);
203  FlutterWindowsEngine* that =
204  static_cast<FlutterWindowsEngine*>(user_data);
205  BASE_DCHECK(that->lifecycle_manager_);
206  return that->lifecycle_manager_->WindowProc(hwnd, msg, wpar, lpar,
207  result);
208  },
209  static_cast<void*>(this));
210 
211  // Set up internal channels.
212  // TODO: Replace this with an embedder.h API. See
213  // https://github.com/flutter/flutter/issues/71099
214  internal_plugin_registrar_ =
215  std::make_unique<PluginRegistrar>(plugin_registrar_.get());
216 
217  accessibility_plugin_ = std::make_unique<AccessibilityPlugin>(this);
218  AccessibilityPlugin::SetUp(messenger_wrapper_.get(),
219  accessibility_plugin_.get());
220 
221  cursor_handler_ =
222  std::make_unique<CursorHandler>(messenger_wrapper_.get(), this);
223  platform_handler_ =
224  std::make_unique<PlatformHandler>(messenger_wrapper_.get(), this);
225  settings_plugin_ = std::make_unique<SettingsPlugin>(messenger_wrapper_.get(),
226  task_runner_.get());
227 }

References flutter::egl::ProcTable::Create().

◆ ~FlutterWindowsEngine()

flutter::FlutterWindowsEngine::~FlutterWindowsEngine ( )
virtual

Definition at line 229 of file flutter_windows_engine.cc.

229  {
230  messenger_->SetEngine(nullptr);
231  Stop();
232 }

Member Function Documentation

◆ AddPluginRegistrarDestructionCallback()

void flutter::FlutterWindowsEngine::AddPluginRegistrarDestructionCallback ( FlutterDesktopOnPluginRegistrarDestroyed  callback,
FlutterDesktopPluginRegistrarRef  registrar 
)

Definition at line 672 of file flutter_windows_engine.cc.

674  {
675  plugin_registrar_destruction_callbacks_[callback] = registrar;
676 }

References callback.

Referenced by FlutterDesktopPluginRegistrarSetDestructionHandler().

◆ CreateKeyboardKeyHandler()

std::unique_ptr< KeyboardHandlerBase > flutter::FlutterWindowsEngine::CreateKeyboardKeyHandler ( BinaryMessenger messenger,
KeyboardKeyEmbedderHandler::GetKeyStateHandler  get_key_state,
KeyboardKeyEmbedderHandler::MapVirtualKeyToScanCode  map_vk_to_scan 
)
protectedvirtual

Definition at line 817 of file flutter_windows_engine.cc.

820  {
821  auto keyboard_key_handler = std::make_unique<KeyboardKeyHandler>(messenger);
822  keyboard_key_handler->AddDelegate(
823  std::make_unique<KeyboardKeyEmbedderHandler>(
824  [this](const FlutterKeyEvent& event, FlutterKeyEventCallback callback,
825  void* user_data) {
826  return SendKeyEvent(event, callback, user_data);
827  },
828  get_key_state, map_vk_to_scan));
829  keyboard_key_handler->AddDelegate(
830  std::make_unique<KeyboardKeyChannelHandler>(messenger));
831  keyboard_key_handler->InitKeyboardChannel();
832  return keyboard_key_handler;
833 }

References callback, and user_data.

◆ CreateTextInputPlugin()

std::unique_ptr< TextInputPlugin > flutter::FlutterWindowsEngine::CreateTextInputPlugin ( BinaryMessenger messenger)
protectedvirtual

Definition at line 835 of file flutter_windows_engine.cc.

836  {
837  return std::make_unique<TextInputPlugin>(messenger, this);
838 }

◆ CreateView()

std::unique_ptr< FlutterWindowsView > flutter::FlutterWindowsEngine::CreateView ( std::unique_ptr< WindowBindingHandler window)

Definition at line 495 of file flutter_windows_engine.cc.

496  {
497  auto view_id = next_view_id_;
498  auto view = std::make_unique<FlutterWindowsView>(
499  view_id, this, std::move(window), windows_proc_table_);
500 
502 
503  next_view_id_++;
504 
505  {
506  // Add the view to the embedder. This must happen before the engine
507  // is notified the view exists and starts presenting to it.
508  fml::UniqueLock write_lock{*views_mutex_};
509  FML_DCHECK(views_.find(view_id) == views_.end());
510  views_[view_id] = view.get();
511  }
512 
513  if (!view->IsImplicitView()) {
514  FML_DCHECK(running());
515 
516  struct Captures {
517  fml::AutoResetWaitableEvent latch;
518  bool added;
519  };
520  Captures captures = {};
521 
522  FlutterWindowMetricsEvent metrics = view->CreateWindowMetricsEvent();
523 
524  FlutterAddViewInfo info = {};
525  info.struct_size = sizeof(FlutterAddViewInfo);
526  info.view_id = view_id;
527  info.view_metrics = &metrics;
528  info.user_data = &captures;
529  info.add_view_callback = [](const FlutterAddViewResult* result) {
530  Captures* captures = reinterpret_cast<Captures*>(result->user_data);
531  captures->added = result->added;
532  captures->latch.Signal();
533  };
534 
535  FlutterEngineResult result = embedder_api_.AddView(engine_, &info);
536  if (result != kSuccess) {
537  FML_LOG(ERROR)
538  << "Starting the add view operation failed. FlutterEngineAddView "
539  "returned an unexpected result: "
540  << result << ". This indicates a bug in the Windows embedder.";
541  FML_DCHECK(false);
542  return nullptr;
543  }
544 
545  // Block the platform thread until the engine has added the view.
546  // TODO(loicsharma): This blocks the platform thread eagerly and can
547  // cause unnecessary delay in input processing. Instead, this should block
548  // lazily only when the app does an operation which needs the view.
549  // https://github.com/flutter/flutter/issues/146248
550  captures.latch.Wait();
551 
552  if (!captures.added) {
553  // Adding the view failed. Update the embedder's state to match the
554  // engine's state. This is unexpected and indicates a bug in the Windows
555  // embedder.
556  FML_LOG(ERROR) << "FlutterEngineAddView failed to add view";
557  fml::UniqueLock write_lock{*views_mutex_};
558  views_.erase(view_id);
559  return nullptr;
560  }
561  }
562 
563  return std::move(view);
564 }

Referenced by CreateViewController().

◆ DispatchSemanticsAction()

bool flutter::FlutterWindowsEngine::DispatchSemanticsAction ( uint64_t  id,
FlutterSemanticsAction  action,
fml::MallocMapping  data 
)

Definition at line 876 of file flutter_windows_engine.cc.

879  {
880  return (embedder_api_.DispatchSemanticsAction(engine_, target, action,
881  data.GetMapping(),
882  data.GetSize()) == kSuccess);
883 }

Referenced by flutter::AccessibilityBridgeWindows::DispatchAccessibilityAction().

◆ egl_manager()

◆ GetExecutableName()

std::string flutter::FlutterWindowsEngine::GetExecutableName ( ) const

Definition at line 902 of file flutter_windows_engine.cc.

902  {
903  std::pair<bool, std::string> result = fml::paths::GetExecutablePath();
904  if (result.first) {
905  const std::string& executable_path = result.second;
906  size_t last_separator = executable_path.find_last_of("/\\");
907  if (last_separator == std::string::npos ||
908  last_separator == executable_path.size() - 1) {
909  return executable_path;
910  }
911  return executable_path.substr(last_separator + 1);
912  }
913  return "Flutter";
914 }

◆ GetRegistrar()

FlutterDesktopPluginRegistrarRef flutter::FlutterWindowsEngine::GetRegistrar ( )

Definition at line 668 of file flutter_windows_engine.cc.

668  {
669  return plugin_registrar_.get();
670 }

Referenced by FlutterDesktopEngineGetPluginRegistrar().

◆ HandlePlatformMessage()

void flutter::FlutterWindowsEngine::HandlePlatformMessage ( const FlutterPlatformMessage *  engine_message)

Definition at line 740 of file flutter_windows_engine.cc.

741  {
742  if (engine_message->struct_size != sizeof(FlutterPlatformMessage)) {
743  FML_LOG(ERROR) << "Invalid message size received. Expected: "
744  << sizeof(FlutterPlatformMessage) << " but received "
745  << engine_message->struct_size;
746  return;
747  }
748 
749  auto message = ConvertToDesktopMessage(*engine_message);
750 
751  message_dispatcher_->HandleMessage(message, [this] {}, [this] {});
752 }

References message.

Referenced by Run().

◆ high_contrast_enabled()

bool flutter::FlutterWindowsEngine::high_contrast_enabled ( ) const
inline

Definition at line 248 of file flutter_windows_engine.h.

248 { return high_contrast_enabled_; }

◆ keyboard_key_handler()

KeyboardHandlerBase* flutter::FlutterWindowsEngine::keyboard_key_handler ( )
inline

Definition at line 182 of file flutter_windows_engine.h.

182  {
183  return keyboard_key_handler_.get();
184  }

Referenced by flutter::FlutterWindowsView::OnPointerMove().

◆ lifecycle_manager()

WindowsLifecycleManager* flutter::FlutterWindowsEngine::lifecycle_manager ( )
inline

Definition at line 293 of file flutter_windows_engine.h.

293  {
294  return lifecycle_manager_.get();
295  }

◆ MarkExternalTextureFrameAvailable()

bool flutter::FlutterWindowsEngine::MarkExternalTextureFrameAvailable ( int64_t  texture_id)

Definition at line 850 of file flutter_windows_engine.cc.

851  {
852  return (embedder_api_.MarkExternalTextureFrameAvailable(
853  engine_, texture_id) == kSuccess);
854 }

◆ message_dispatcher()

IncomingMessageDispatcher* flutter::FlutterWindowsEngine::message_dispatcher ( )
inline

Definition at line 151 of file flutter_windows_engine.h.

151  {
152  return message_dispatcher_.get();
153  }

Referenced by FlutterDesktopMessengerSetCallback().

◆ messenger()

FlutterDesktopMessengerRef flutter::FlutterWindowsEngine::messenger ( )
inline

Definition at line 149 of file flutter_windows_engine.h.

149 { return messenger_->ToRef(); }

Referenced by FlutterDesktopEngineGetMessenger(), and FlutterDesktopPluginRegistrarGetMessenger().

◆ messenger_wrapper()

BinaryMessenger* flutter::FlutterWindowsEngine::messenger_wrapper ( )
inline

Definition at line 157 of file flutter_windows_engine.h.

157 { return messenger_wrapper_.get(); }

◆ OnChannelUpdate()

void flutter::FlutterWindowsEngine::OnChannelUpdate ( std::string  name,
bool  listening 
)
protectedvirtual

Definition at line 978 of file flutter_windows_engine.cc.

978  {
979  if (name == "flutter/platform" && listening) {
980  lifecycle_manager_->BeginProcessingExit();
981  } else if (name == "flutter/lifecycle" && listening) {
982  lifecycle_manager_->BeginProcessingLifecycle();
983  }
984 }

◆ OnDwmCompositionChanged()

void flutter::FlutterWindowsEngine::OnDwmCompositionChanged ( )

Definition at line 953 of file flutter_windows_engine.cc.

953  {
954  fml::SharedLock read_lock{*views_mutex_};
955 
956  for (auto iterator = views_.begin(); iterator != views_.end(); iterator++) {
957  iterator->second->OnDwmCompositionChanged();
958  }
959 }

Referenced by flutter::WindowsLifecycleManager::WindowProc().

◆ OnPreEngineRestart()

void flutter::FlutterWindowsEngine::OnPreEngineRestart ( )
protected

Definition at line 897 of file flutter_windows_engine.cc.

897  {
898  // Reset the keyboard's state on hot restart.
899  InitializeKeyboard();
900 }

Referenced by Run().

◆ OnQuit()

void flutter::FlutterWindowsEngine::OnQuit ( std::optional< HWND >  hwnd,
std::optional< WPARAM >  wparam,
std::optional< LPARAM >  lparam,
UINT  exit_code 
)

Definition at line 946 of file flutter_windows_engine.cc.

949  {
950  lifecycle_manager_->Quit(hwnd, wparam, lparam, exit_code);
951 }

Referenced by flutter::PlatformHandler::QuitApplication().

◆ OnVsync()

void flutter::FlutterWindowsEngine::OnVsync ( intptr_t  baton)

Definition at line 628 of file flutter_windows_engine.cc.

628  {
629  std::chrono::nanoseconds current_time =
630  std::chrono::nanoseconds(embedder_api_.GetCurrentTime());
631  std::chrono::nanoseconds frame_interval = FrameInterval();
632  auto next = SnapToNextTick(current_time, start_time_, frame_interval);
633  embedder_api_.OnVsync(engine_, baton, next.count(),
634  (next + frame_interval).count());
635 }

Referenced by Run().

◆ OnWindowStateEvent()

void flutter::FlutterWindowsEngine::OnWindowStateEvent ( HWND  hwnd,
WindowStateEvent  event 
)

Definition at line 961 of file flutter_windows_engine.cc.

962  {
963  lifecycle_manager_->OnWindowStateEvent(hwnd, event);
964 }

Referenced by flutter::FlutterWindowsView::OnWindowStateEvent(), and flutter::FlutterWindowsView::~FlutterWindowsView().

◆ PostRasterThreadTask()

bool flutter::FlutterWindowsEngine::PostRasterThreadTask ( fml::closure  callback) const
virtual

Definition at line 856 of file flutter_windows_engine.cc.

856  {
857  struct Captures {
858  fml::closure callback;
859  };
860  auto captures = new Captures();
861  captures->callback = std::move(callback);
862  if (embedder_api_.PostRenderThreadTask(
863  engine_,
864  [](void* opaque) {
865  auto captures = reinterpret_cast<Captures*>(opaque);
866  captures->callback();
867  delete captures;
868  },
869  captures) == kSuccess) {
870  return true;
871  }
872  delete captures;
873  return false;
874 }

References callback.

Referenced by flutter::FlutterWindowsTextureRegistrar::UnregisterTexture().

◆ ProcessExternalWindowMessage()

std::optional< LRESULT > flutter::FlutterWindowsEngine::ProcessExternalWindowMessage ( HWND  hwnd,
UINT  message,
WPARAM  wparam,
LPARAM  lparam 
)

Definition at line 966 of file flutter_windows_engine.cc.

970  {
971  if (lifecycle_manager_) {
972  return lifecycle_manager_->ExternalWindowMessage(hwnd, message, wparam,
973  lparam);
974  }
975  return std::nullopt;
976 }

References message.

Referenced by FlutterDesktopEngineProcessExternalWindowMessage().

◆ RegisterExternalTexture()

bool flutter::FlutterWindowsEngine::RegisterExternalTexture ( int64_t  texture_id)

Definition at line 840 of file flutter_windows_engine.cc.

840  {
841  return (embedder_api_.RegisterExternalTexture(engine_, texture_id) ==
842  kSuccess);
843 }

◆ ReloadSystemFonts()

void flutter::FlutterWindowsEngine::ReloadSystemFonts ( )

Definition at line 754 of file flutter_windows_engine.cc.

754  {
755  embedder_api_.ReloadSystemFonts(engine_);
756 }

Referenced by FlutterDesktopEngineReloadSystemFonts().

◆ RemoveView()

void flutter::FlutterWindowsEngine::RemoveView ( FlutterViewId  view_id)
virtual

Definition at line 566 of file flutter_windows_engine.cc.

566  {
567  FML_DCHECK(running());
568 
569  // Notify the engine to stop rendering to the view if it isn't the implicit
570  // view. The engine and framework assume the implicit view always exists and
571  // can continue presenting.
572  if (view_id != kImplicitViewId) {
573  struct Captures {
574  fml::AutoResetWaitableEvent latch;
575  bool removed;
576  };
577  Captures captures = {};
578 
579  FlutterRemoveViewInfo info = {};
580  info.struct_size = sizeof(FlutterRemoveViewInfo);
581  info.view_id = view_id;
582  info.user_data = &captures;
583  info.remove_view_callback = [](const FlutterRemoveViewResult* result) {
584  // This is invoked on an engine thread. If
585  // |FlutterRemoveViewResult.removed| is `true`, the engine guarantees the
586  // view won't be presented.
587  Captures* captures = reinterpret_cast<Captures*>(result->user_data);
588  captures->removed = result->removed;
589  captures->latch.Signal();
590  };
591 
592  FlutterEngineResult result = embedder_api_.RemoveView(engine_, &info);
593  if (result != kSuccess) {
594  FML_LOG(ERROR) << "Starting the remove view operation failed. "
595  "FlutterEngineRemoveView "
596  "returned an unexpected result: "
597  << result
598  << ". This indicates a bug in the Windows embedder.";
599  FML_DCHECK(false);
600  return;
601  }
602 
603  // Block the platform thread until the engine has removed the view.
604  // TODO(loicsharma): This blocks the platform thread eagerly and can
605  // cause unnecessary delay in input processing. Instead, this should block
606  // lazily only when an operation needs the view.
607  // https://github.com/flutter/flutter/issues/146248
608  captures.latch.Wait();
609 
610  if (!captures.removed) {
611  // Removing the view failed. This is unexpected and indicates a bug in the
612  // Windows embedder.
613  FML_LOG(ERROR) << "FlutterEngineRemoveView failed to remove view";
614  return;
615  }
616  }
617 
618  {
619  // The engine no longer presents to the view. Remove the view from the
620  // embedder.
621  fml::UniqueLock write_lock{*views_mutex_};
622 
623  FML_DCHECK(views_.find(view_id) != views_.end());
624  views_.erase(view_id);
625  }
626 }

References flutter::kImplicitViewId.

◆ RequestApplicationQuit()

void flutter::FlutterWindowsEngine::RequestApplicationQuit ( HWND  hwnd,
WPARAM  wparam,
LPARAM  lparam,
AppExitType  exit_type 
)

Definition at line 939 of file flutter_windows_engine.cc.

942  {
943  platform_handler_->RequestAppExit(hwnd, wparam, lparam, exit_type, 0);
944 }

◆ Run() [1/2]

bool flutter::FlutterWindowsEngine::Run ( )

Definition at line 239 of file flutter_windows_engine.cc.

239  {
240  return Run("");
241 }

Referenced by FlutterDesktopEngineRun().

◆ Run() [2/2]

bool flutter::FlutterWindowsEngine::Run ( std::string_view  entrypoint)

Definition at line 243 of file flutter_windows_engine.cc.

243  {
244  if (!project_->HasValidPaths()) {
245  FML_LOG(ERROR) << "Missing or unresolvable paths to assets.";
246  return false;
247  }
248  std::string assets_path_string = project_->assets_path().u8string();
249  std::string icu_path_string = project_->icu_path().u8string();
250  if (embedder_api_.RunsAOTCompiledDartCode()) {
251  aot_data_ = project_->LoadAotData(embedder_api_);
252  if (!aot_data_) {
253  FML_LOG(ERROR) << "Unable to start engine without AOT data.";
254  return false;
255  }
256  }
257 
258  // FlutterProjectArgs is expecting a full argv, so when processing it for
259  // flags the first item is treated as the executable and ignored. Add a dummy
260  // value so that all provided arguments are used.
261  std::string executable_name = GetExecutableName();
262  std::vector<const char*> argv = {executable_name.c_str()};
263  std::vector<std::string> switches = project_->GetSwitches();
264  std::transform(
265  switches.begin(), switches.end(), std::back_inserter(argv),
266  [](const std::string& arg) -> const char* { return arg.c_str(); });
267 
268  const std::vector<std::string>& entrypoint_args =
269  project_->dart_entrypoint_arguments();
270  std::vector<const char*> entrypoint_argv;
271  std::transform(
272  entrypoint_args.begin(), entrypoint_args.end(),
273  std::back_inserter(entrypoint_argv),
274  [](const std::string& arg) -> const char* { return arg.c_str(); });
275 
276  // Configure task runners.
277  FlutterTaskRunnerDescription platform_task_runner = {};
278  platform_task_runner.struct_size = sizeof(FlutterTaskRunnerDescription);
279  platform_task_runner.user_data = task_runner_.get();
280  platform_task_runner.runs_task_on_current_thread_callback =
281  [](void* user_data) -> bool {
282  return static_cast<TaskRunner*>(user_data)->RunsTasksOnCurrentThread();
283  };
284  platform_task_runner.post_task_callback = [](FlutterTask task,
285  uint64_t target_time_nanos,
286  void* user_data) -> void {
287  static_cast<TaskRunner*>(user_data)->PostFlutterTask(task,
288  target_time_nanos);
289  };
290  FlutterCustomTaskRunners custom_task_runners = {};
291  custom_task_runners.struct_size = sizeof(FlutterCustomTaskRunners);
292  custom_task_runners.platform_task_runner = &platform_task_runner;
293  custom_task_runners.thread_priority_setter =
295 
296  FlutterProjectArgs args = {};
297  args.struct_size = sizeof(FlutterProjectArgs);
298  args.shutdown_dart_vm_when_done = true;
299  args.assets_path = assets_path_string.c_str();
300  args.icu_data_path = icu_path_string.c_str();
301  args.command_line_argc = static_cast<int>(argv.size());
302  args.command_line_argv = argv.empty() ? nullptr : argv.data();
303 
304  // Fail if conflicting non-default entrypoints are specified in the method
305  // argument and the project.
306  //
307  // TODO(cbracken): https://github.com/flutter/flutter/issues/109285
308  // The entrypoint method parameter should eventually be removed from this
309  // method and only the entrypoint specified in project_ should be used.
310  if (!project_->dart_entrypoint().empty() && !entrypoint.empty() &&
311  project_->dart_entrypoint() != entrypoint) {
312  FML_LOG(ERROR) << "Conflicting entrypoints were specified in "
313  "FlutterDesktopEngineProperties.dart_entrypoint and "
314  "FlutterDesktopEngineRun(engine, entry_point). ";
315  return false;
316  }
317  if (!entrypoint.empty()) {
318  args.custom_dart_entrypoint = entrypoint.data();
319  } else if (!project_->dart_entrypoint().empty()) {
320  args.custom_dart_entrypoint = project_->dart_entrypoint().c_str();
321  }
322  args.dart_entrypoint_argc = static_cast<int>(entrypoint_argv.size());
323  args.dart_entrypoint_argv =
324  entrypoint_argv.empty() ? nullptr : entrypoint_argv.data();
325  args.platform_message_callback =
326  [](const FlutterPlatformMessage* engine_message,
327  void* user_data) -> void {
328  auto host = static_cast<FlutterWindowsEngine*>(user_data);
329  return host->HandlePlatformMessage(engine_message);
330  };
331  args.vsync_callback = [](void* user_data, intptr_t baton) -> void {
332  auto host = static_cast<FlutterWindowsEngine*>(user_data);
333  host->OnVsync(baton);
334  };
335  args.on_pre_engine_restart_callback = [](void* user_data) {
336  auto host = static_cast<FlutterWindowsEngine*>(user_data);
337  host->OnPreEngineRestart();
338  };
339  args.update_semantics_callback2 = [](const FlutterSemanticsUpdate2* update,
340  void* user_data) {
341  auto host = static_cast<FlutterWindowsEngine*>(user_data);
342 
343  // TODO(loicsharma): Remove implicit view assumption.
344  // https://github.com/flutter/flutter/issues/142845
345  auto view = host->view(kImplicitViewId);
346  if (!view) {
347  return;
348  }
349 
350  auto accessibility_bridge = view->accessibility_bridge().lock();
351  if (!accessibility_bridge) {
352  return;
353  }
354 
355  for (size_t i = 0; i < update->node_count; i++) {
356  const FlutterSemanticsNode2* node = update->nodes[i];
357  accessibility_bridge->AddFlutterSemanticsNodeUpdate(*node);
358  }
359 
360  for (size_t i = 0; i < update->custom_action_count; i++) {
361  const FlutterSemanticsCustomAction2* action = update->custom_actions[i];
362  accessibility_bridge->AddFlutterSemanticsCustomActionUpdate(*action);
363  }
364 
365  accessibility_bridge->CommitUpdates();
366  };
367  args.root_isolate_create_callback = [](void* user_data) {
368  auto host = static_cast<FlutterWindowsEngine*>(user_data);
369  if (host->root_isolate_create_callback_) {
370  host->root_isolate_create_callback_();
371  }
372  };
373  args.channel_update_callback = [](const FlutterChannelUpdate* update,
374  void* user_data) {
375  auto host = static_cast<FlutterWindowsEngine*>(user_data);
376  if (SAFE_ACCESS(update, channel, nullptr) != nullptr) {
377  std::string channel_name(update->channel);
378  host->OnChannelUpdate(std::move(channel_name),
379  SAFE_ACCESS(update, listening, false));
380  }
381  };
382 
383  args.custom_task_runners = &custom_task_runners;
384 
385  if (!platform_view_plugin_) {
386  platform_view_plugin_ = std::make_unique<PlatformViewPlugin>(
387  messenger_wrapper_.get(), task_runner_.get());
388  }
389  if (egl_manager_) {
390  auto resolver = [](const char* name) -> void* {
391  return reinterpret_cast<void*>(::eglGetProcAddress(name));
392  };
393 
394  // TODO(schectman) Pass the platform view manager to the compositor
395  // constructors: https://github.com/flutter/flutter/issues/143375
396  compositor_ = std::make_unique<CompositorOpenGL>(this, resolver);
397  } else {
398  compositor_ = std::make_unique<CompositorSoftware>();
399  }
400 
401  FlutterCompositor compositor = {};
402  compositor.struct_size = sizeof(FlutterCompositor);
403  compositor.user_data = this;
404  compositor.create_backing_store_callback =
405  [](const FlutterBackingStoreConfig* config,
406  FlutterBackingStore* backing_store_out, void* user_data) -> bool {
407  auto host = static_cast<FlutterWindowsEngine*>(user_data);
408 
409  return host->compositor_->CreateBackingStore(*config, backing_store_out);
410  };
411 
412  compositor.collect_backing_store_callback =
413  [](const FlutterBackingStore* backing_store, void* user_data) -> bool {
414  auto host = static_cast<FlutterWindowsEngine*>(user_data);
415 
416  return host->compositor_->CollectBackingStore(backing_store);
417  };
418 
419  compositor.present_view_callback =
420  [](const FlutterPresentViewInfo* info) -> bool {
421  auto host = static_cast<FlutterWindowsEngine*>(info->user_data);
422 
423  return host->Present(info);
424  };
425  args.compositor = &compositor;
426 
427  if (aot_data_) {
428  args.aot_data = aot_data_.get();
429  }
430 
431  // The platform thread creates OpenGL contexts. These
432  // must be released to be used by the engine's threads.
433  FML_DCHECK(!egl_manager_ || !egl_manager_->HasContextCurrent());
434 
435  FlutterRendererConfig renderer_config;
436 
437  if (enable_impeller_) {
438  // Impeller does not support a Software backend. Avoid falling back and
439  // confusing the engine on which renderer is selected.
440  if (!egl_manager_) {
441  FML_LOG(ERROR) << "Could not create surface manager. Impeller backend "
442  "does not support software rendering.";
443  return false;
444  }
445  renderer_config = GetOpenGLRendererConfig();
446  } else {
447  renderer_config =
448  egl_manager_ ? GetOpenGLRendererConfig() : GetSoftwareRendererConfig();
449  }
450 
451  auto result = embedder_api_.Run(FLUTTER_ENGINE_VERSION, &renderer_config,
452  &args, this, &engine_);
453  if (result != kSuccess || engine_ == nullptr) {
454  FML_LOG(ERROR) << "Failed to start Flutter engine: error " << result;
455  return false;
456  }
457 
458  // Configure device frame rate displayed via devtools.
459  FlutterEngineDisplay display = {};
460  display.struct_size = sizeof(FlutterEngineDisplay);
461  display.display_id = 0;
462  display.single_display = true;
463  display.refresh_rate =
464  1.0 / (static_cast<double>(FrameInterval().count()) / 1000000000.0);
465 
466  std::vector<FlutterEngineDisplay> displays = {display};
467  embedder_api_.NotifyDisplayUpdate(engine_,
468  kFlutterEngineDisplaysUpdateTypeStartup,
469  displays.data(), displays.size());
470 
471  SendSystemLocales();
472  SetLifecycleState(flutter::AppLifecycleState::kResumed);
473 
474  settings_plugin_->StartWatching();
475  settings_plugin_->SendSettings();
476 
477  InitializeKeyboard();
478 
479  return true;
480 }

References flutter::FlutterWindowsView::accessibility_bridge(), action, HandlePlatformMessage(), flutter::kImplicitViewId, OnPreEngineRestart(), OnVsync(), user_data, view(), and flutter::WindowsPlatformThreadPrioritySetter().

◆ running()

virtual bool flutter::FlutterWindowsEngine::running ( ) const
inlinevirtual

Definition at line 117 of file flutter_windows_engine.h.

117 { return engine_ != nullptr; }

Referenced by FlutterDesktopEngineDestroy().

◆ ScheduleFrame()

void flutter::FlutterWindowsEngine::ScheduleFrame ( )

Definition at line 758 of file flutter_windows_engine.cc.

758  {
759  embedder_api_.ScheduleFrame(engine_);
760 }

Referenced by flutter::FlutterWindowsView::ForceRedraw().

◆ semantics_enabled()

bool flutter::FlutterWindowsEngine::semantics_enabled ( ) const
inline

Definition at line 239 of file flutter_windows_engine.h.

239 { return semantics_enabled_; }

Referenced by flutter::AccessibilityPlugin::Announce().

◆ SendKeyEvent()

void flutter::FlutterWindowsEngine::SendKeyEvent ( const FlutterKeyEvent &  event,
FlutterKeyEventCallback  callback,
void *  user_data 
)

Definition at line 691 of file flutter_windows_engine.cc.

693  {
694  if (engine_) {
695  embedder_api_.SendKeyEvent(engine_, &event, callback, user_data);
696  }
697 }

◆ SendPlatformMessage()

bool flutter::FlutterWindowsEngine::SendPlatformMessage ( const char *  channel,
const uint8_t *  message,
const size_t  message_size,
const FlutterDesktopBinaryReply  reply,
void *  user_data 
)

Definition at line 699 of file flutter_windows_engine.cc.

704  {
705  FlutterPlatformMessageResponseHandle* response_handle = nullptr;
706  if (reply != nullptr && user_data != nullptr) {
707  FlutterEngineResult result =
708  embedder_api_.PlatformMessageCreateResponseHandle(
709  engine_, reply, user_data, &response_handle);
710  if (result != kSuccess) {
711  FML_LOG(ERROR) << "Failed to create response handle";
712  return false;
713  }
714  }
715 
716  FlutterPlatformMessage platform_message = {
717  sizeof(FlutterPlatformMessage),
718  channel,
719  message,
720  message_size,
721  response_handle,
722  };
723 
724  FlutterEngineResult message_result =
725  embedder_api_.SendPlatformMessage(engine_, &platform_message);
726  if (response_handle != nullptr) {
727  embedder_api_.PlatformMessageReleaseResponseHandle(engine_,
728  response_handle);
729  }
730  return message_result == kSuccess;
731 }

References user_data.

Referenced by FlutterDesktopMessengerSendWithReply().

◆ SendPlatformMessageResponse()

void flutter::FlutterWindowsEngine::SendPlatformMessageResponse ( const FlutterDesktopMessageResponseHandle handle,
const uint8_t *  data,
size_t  data_length 
)

Definition at line 733 of file flutter_windows_engine.cc.

736  {
737  embedder_api_.SendPlatformMessageResponse(engine_, handle, data, data_length);
738 }

Referenced by FlutterDesktopMessengerSendResponse().

◆ SendPointerEvent()

void flutter::FlutterWindowsEngine::SendPointerEvent ( const FlutterPointerEvent &  event)

Definition at line 685 of file flutter_windows_engine.cc.

685  {
686  if (engine_) {
687  embedder_api_.SendPointerEvent(engine_, &event, 1);
688  }
689 }

◆ SendWindowMetricsEvent()

void flutter::FlutterWindowsEngine::SendWindowMetricsEvent ( const FlutterWindowMetricsEvent &  event)

Definition at line 678 of file flutter_windows_engine.cc.

679  {
680  if (engine_) {
681  embedder_api_.SendWindowMetricsEvent(engine_, &event);
682  }
683 }

Referenced by flutter::FlutterWindowsView::SendInitialBounds().

◆ SetNextFrameCallback()

void flutter::FlutterWindowsEngine::SetNextFrameCallback ( fml::closure  callback)

Definition at line 762 of file flutter_windows_engine.cc.

762  {
763  next_frame_callback_ = std::move(callback);
764 
765  embedder_api_.SetNextFrameCallback(
766  engine_,
767  [](void* user_data) {
768  // Embedder callback runs on raster thread. Switch back to platform
769  // thread.
770  FlutterWindowsEngine* self =
771  static_cast<FlutterWindowsEngine*>(user_data);
772 
773  self->task_runner_->PostTask(std::move(self->next_frame_callback_));
774  },
775  this);
776 }

Referenced by FlutterDesktopEngineSetNextFrameCallback().

◆ SetRootIsolateCreateCallback()

void flutter::FlutterWindowsEngine::SetRootIsolateCreateCallback ( const fml::closure &  callback)
inline

Definition at line 259 of file flutter_windows_engine.h.

259  {
260  root_isolate_create_callback_ = callback;
261  }

References callback.

◆ SetSwitches()

void flutter::FlutterWindowsEngine::SetSwitches ( const std::vector< std::string > &  switches)

Definition at line 234 of file flutter_windows_engine.cc.

235  {
236  project_->SetSwitches(switches);
237 }

◆ Stop()

bool flutter::FlutterWindowsEngine::Stop ( )
virtual

Definition at line 482 of file flutter_windows_engine.cc.

482  {
483  if (engine_) {
484  for (const auto& [callback, registrar] :
485  plugin_registrar_destruction_callbacks_) {
486  callback(registrar);
487  }
488  FlutterEngineResult result = embedder_api_.Shutdown(engine_);
489  engine_ = nullptr;
490  return (result == kSuccess);
491  }
492  return false;
493 }

Referenced by FlutterDesktopEngineDestroy().

◆ task_runner()

TaskRunner* flutter::FlutterWindowsEngine::task_runner ( )
inline

◆ text_input_plugin()

TextInputPlugin* flutter::FlutterWindowsEngine::text_input_plugin ( )
inline

Definition at line 185 of file flutter_windows_engine.h.

185 { return text_input_plugin_.get(); }

◆ texture_registrar()

FlutterWindowsTextureRegistrar* flutter::FlutterWindowsEngine::texture_registrar ( )
inline

Definition at line 159 of file flutter_windows_engine.h.

159  {
160  return texture_registrar_.get();
161  }

Referenced by FlutterDesktopRegistrarGetTextureRegistrar().

◆ UnregisterExternalTexture()

bool flutter::FlutterWindowsEngine::UnregisterExternalTexture ( int64_t  texture_id)

Definition at line 845 of file flutter_windows_engine.cc.

845  {
846  return (embedder_api_.UnregisterExternalTexture(engine_, texture_id) ==
847  kSuccess);
848 }

◆ UpdateAccessibilityFeatures()

void flutter::FlutterWindowsEngine::UpdateAccessibilityFeatures ( )

Definition at line 916 of file flutter_windows_engine.cc.

916  {
918 }

Referenced by flutter::testing::TEST_F().

◆ UpdateHighContrastMode()

void flutter::FlutterWindowsEngine::UpdateHighContrastMode ( )

Definition at line 920 of file flutter_windows_engine.cc.

920  {
921  high_contrast_enabled_ = windows_proc_table_->GetHighContrastEnabled();
922 
923  SendAccessibilityFeatures();
924  settings_plugin_->UpdateHighContrastMode(high_contrast_enabled_);
925 }

Referenced by flutter::FlutterWindowsView::OnHighContrastChanged().

◆ UpdateSemanticsEnabled()

void flutter::FlutterWindowsEngine::UpdateSemanticsEnabled ( bool  enabled)

Definition at line 885 of file flutter_windows_engine.cc.

885  {
886  if (engine_ && semantics_enabled_ != enabled) {
887  fml::SharedLock read_lock{*views_mutex_};
888 
889  semantics_enabled_ = enabled;
890  embedder_api_.UpdateSemanticsEnabled(engine_, enabled);
891  for (auto iterator = views_.begin(); iterator != views_.end(); iterator++) {
892  iterator->second->UpdateSemanticsEnabled(enabled);
893  }
894  }
895 }

Referenced by flutter::FlutterWindowsView::OnUpdateSemanticsEnabled(), and flutter::testing::TEST_F().

◆ view()

FlutterWindowsView * flutter::FlutterWindowsEngine::view ( FlutterViewId  view_id) const

Definition at line 656 of file flutter_windows_engine.cc.

656  {
657  fml::SharedLock read_lock{*views_mutex_};
658 
659  auto iterator = views_.find(view_id);
660  if (iterator == views_.end()) {
661  return nullptr;
662  }
663 
664  return iterator->second;
665 }

Referenced by flutter::AccessibilityPlugin::Announce(), FlutterDesktopPluginRegistrarGetView(), FlutterDesktopPluginRegistrarGetViewById(), flutter::PlatformHandler::GetHasStrings(), flutter::PlatformHandler::GetPlainText(), Run(), and flutter::PlatformHandler::SetPlainText().

◆ window_proc_delegate_manager()

WindowProcDelegateManager* flutter::FlutterWindowsEngine::window_proc_delegate_manager ( )
inline

Definition at line 167 of file flutter_windows_engine.h.

167  {
168  return window_proc_delegate_manager_.get();
169  }

Referenced by FlutterDesktopPluginRegistrarRegisterTopLevelWindowProcDelegate(), and FlutterDesktopPluginRegistrarUnregisterTopLevelWindowProcDelegate().

◆ windows_proc_table()

std::shared_ptr<WindowsProcTable> flutter::FlutterWindowsEngine::windows_proc_table ( )
inline

Definition at line 297 of file flutter_windows_engine.h.

297  {
298  return windows_proc_table_;
299  }

Referenced by CreateViewController().

Friends And Related Function Documentation

◆ EngineModifier

friend class EngineModifier
friend

Definition at line 330 of file flutter_windows_engine.h.


The documentation for this class was generated from the following files:
flutter::kImplicitViewId
constexpr FlutterViewId kImplicitViewId
Definition: flutter_windows_engine.h:55
flutter::FlutterWindowsView::CreateRenderSurface
void CreateRenderSurface()
Definition: flutter_windows_view.cc:697
flutter::FlutterWindowsEngine::view
FlutterWindowsView * view(FlutterViewId view_id) const
Definition: flutter_windows_engine.cc:656
user_data
void * user_data
Definition: flutter_windows_view_unittests.cc:53
flutter::FlutterWindowsView::accessibility_bridge
std::weak_ptr< AccessibilityBridgeWindows > accessibility_bridge()
Definition: flutter_windows_view.h:242
flutter::FlutterWindowsEngine::running
virtual bool running() const
Definition: flutter_windows_engine.h:117
flutter::FlutterWindowsEngine::FlutterWindowsEngine
FlutterWindowsEngine(const FlutterProjectBundle &project, std::shared_ptr< WindowsProcTable > windows_proc_table=nullptr)
Definition: flutter_windows_engine.cc:147
flutter::FlutterWindowsView::IsImplicitView
bool IsImplicitView() const
Definition: flutter_windows_view.cc:693
flutter::FlutterWindowsEngine::windows_proc_table
std::shared_ptr< WindowsProcTable > windows_proc_table()
Definition: flutter_windows_engine.h:297
flutter::FlutterWindowsEngine::Stop
virtual bool Stop()
Definition: flutter_windows_engine.cc:482
flutter::FlutterWindowsEngine::messenger
FlutterDesktopMessengerRef messenger()
Definition: flutter_windows_engine.h:149
flutter::FlutterWindowsEngine::keyboard_key_handler
KeyboardHandlerBase * keyboard_key_handler()
Definition: flutter_windows_engine.h:182
flutter::FlutterWindowsEngine::SendKeyEvent
void SendKeyEvent(const FlutterKeyEvent &event, FlutterKeyEventCallback callback, void *user_data)
Definition: flutter_windows_engine.cc:691
flutter::egl::ProcTable::Create
static std::shared_ptr< ProcTable > Create()
Definition: proc_table.cc:12
flutter::FlutterWindowsEngine::UpdateHighContrastMode
void UpdateHighContrastMode()
Definition: flutter_windows_engine.cc:920
flutter::AppLifecycleState::kResumed
@ kResumed
message
Win32Message message
Definition: keyboard_unittests.cc:137
action
int action
Definition: keyboard_key_handler_unittests.cc:116
flutter::egl::Manager::Create
static std::unique_ptr< Manager > Create(bool enable_impeller)
Definition: manager.cc:17
flutter::FlutterWindowsView::CreateWindowMetricsEvent
FlutterWindowMetricsEvent CreateWindowMetricsEvent() const
Definition: flutter_windows_view.cc:375
flutter::FlutterWindowsEngine::Run
bool Run()
Definition: flutter_windows_engine.cc:239
flutter::WindowsPlatformThreadPrioritySetter
static void WindowsPlatformThreadPrioritySetter(FlutterThreadPriority priority)
Definition: flutter_windows_engine.h:60
texture_id
uint32_t texture_id
Definition: compositor_opengl.cc:20
flutter::AccessibilityPlugin::SetUp
static void SetUp(BinaryMessenger *binary_messenger, AccessibilityPlugin *plugin)
Definition: accessibility_plugin.cc:76
flutter::FlutterWindowsEngine::GetExecutableName
std::string GetExecutableName() const
Definition: flutter_windows_engine.cc:902
callback
FlutterDesktopBinaryReply callback
Definition: flutter_windows_view_unittests.cc:52