Flutter Engine
flutter_runner::PlatformView Class Referenceabstract

#include <platform_view.h>

Inheritance diagram for flutter_runner::PlatformView:
flutter::PlatformView flutter_runner::FlatlandPlatformView flutter_runner::GfxPlatformView

Public Member Functions

 PlatformView (flutter::PlatformView::Delegate &delegate, flutter::TaskRunners task_runners, fuchsia::ui::views::ViewRef view_ref, std::shared_ptr< flutter::ExternalViewEmbedder > external_view_embedder, fuchsia::ui::input::ImeServiceHandle ime_service, fuchsia::ui::input3::KeyboardHandle keyboard, fuchsia::ui::pointer::TouchSourceHandle touch_source, fuchsia::ui::pointer::MouseSourceHandle mouse_source, fuchsia::ui::views::FocuserHandle focuser, fuchsia::ui::views::ViewRefFocusedHandle view_ref_focused, OnEnableWireframe wireframe_enabled_callback, OnUpdateView on_update_view_callback, OnCreateSurface on_create_surface_callback, OnSemanticsNodeUpdate on_semantics_node_update_callback, OnRequestAnnounce on_request_announce_callback, OnShaderWarmup on_shader_warmup, AwaitVsyncCallback await_vsync_callback, AwaitVsyncForSecondaryCallbackCallback await_vsync_for_secondary_callback_callback)
 
 ~PlatformView () override
 Destroys the platform view. The platform view is owned by the shell and will be destroyed by the same on the platform tasks runner. More...
 
void SetSemanticsEnabled (bool enabled) override
 Used by embedder to notify the running isolate hosted by the engine on the UI thread that the accessibility tree needs to be generated. More...
 
std::shared_ptr< flutter::ExternalViewEmbedderCreateExternalViewEmbedder () override
 
- Public Member Functions inherited from flutter::PlatformView
 PlatformView (Delegate &delegate, TaskRunners task_runners)
 Creates a platform view with the specified delegate and task runner. The base class by itself does not do much but is suitable for use in test environments where full platform integration may not be necessary. The platform view may only be created, accessed and destroyed on the platform task runner. More...
 
void DispatchPlatformMessage (std::unique_ptr< PlatformMessage > message)
 Used by embedders to dispatch a platform message to a running root isolate hosted by the engine. If an isolate is not running, the message is dropped. If there is no one on the other side listening on the channel, the message is dropped. When a platform message is dropped, any response handles associated with that message will be dropped as well. All users of platform messages must assume that message may not be delivered and/or their response handles may not be invoked. Platform messages are not buffered. More...
 
virtual void HandlePlatformMessage (std::unique_ptr< PlatformMessage > message)
 Overridden by embedders to perform actions in response to platform messages sent from the framework to the embedder. Default implementation of this method simply returns an empty response. More...
 
void DispatchSemanticsAction (int32_t id, SemanticsAction action, fml::MallocMapping args)
 Used by embedders to dispatch an accessibility action to a running isolate hosted by the engine. More...
 
virtual void SetAccessibilityFeatures (int32_t flags)
 Used by the embedder to specify the features to enable in the accessibility tree generated by the isolate. This information is forwarded to the root isolate hosted by the engine on the UI thread. More...
 
void SetViewportMetrics (const ViewportMetrics &metrics)
 Used by embedders to specify the updated viewport metrics. In response to this call, on the raster thread, the rasterizer may need to be reconfigured to the updated viewport dimensions. On the UI thread, the framework may need to start generating a new frame for the updated viewport metrics as well. More...
 
void NotifyCreated ()
 Used by embedders to notify the shell that a platform view has been created. This notification is used to create a rendering surface and pick the client rendering API to use to render into this surface. No frames will be scheduled or rendered before this call. The surface must remain valid till the corresponding call to NotifyDestroyed. More...
 
virtual void NotifyDestroyed ()
 Used by embedders to notify the shell that the platform view has been destroyed. This notification used to collect the rendering surface and all associated resources. Frame scheduling is also suspended. More...
 
virtual sk_sp< GrDirectContext > CreateResourceContext () const
 Used by the shell to obtain a Skia GPU context that is capable of operating on the IO thread. The context must be in the same share-group as the Skia GPU context used on the render thread. This context will always be used on the IO thread. Because it is in the same share-group as the separate render thread context, any GPU resources uploaded in this context will be visible to the render thread context (synchronization of GPU resources is managed by Skia). More...
 
virtual void ReleaseResourceContext () const
 Used by the shell to notify the embedder that the resource context previously obtained via a call to CreateResourceContext() is being collected. The embedder is free to collect an platform specific resources associated with this context. More...
 
virtual PointerDataDispatcherMaker GetDispatcherMaker ()
 Returns a platform-specific PointerDataDispatcherMaker so the Engine can construct the PointerDataPacketDispatcher based on platforms. More...
 
fml::WeakPtr< PlatformViewGetWeakPtr () const
 Returns a weak pointer to the platform view. Since the platform view may only be created, accessed and destroyed on the platform thread, any access to the platform view from a non-platform task runner needs a weak pointer to the platform view along with a reference to the platform task runner. A task must be posted to the platform task runner with the weak pointer captured in the same. The platform view method may only be called in the posted task once the weak pointer validity has been checked. This method is used by callers to obtain that weak pointer. More...
 
virtual void OnPreEngineRestart () const
 Gives embedders a chance to react to a "cold restart" of the running isolate. The default implementation of this method does nothing. More...
 
void SetNextFrameCallback (const fml::closure &closure)
 Sets a callback that gets executed when the rasterizer renders the next frame. Due to the asynchronous nature of rendering in Flutter, embedders usually add a placeholder over the contents in which Flutter is going to render when Flutter is first initialized. This callback may be used as a signal to remove that placeholder. The callback is executed on the render task runner and not the platform task runner. It is the embedder's responsibility to re-thread as necessary. More...
 
void DispatchPointerDataPacket (std::unique_ptr< PointerDataPacket > packet)
 Dispatches pointer events from the embedder to the framework. Each pointer data packet may contain multiple pointer input events. Each call to this method wakes up the UI thread. More...
 
void DispatchKeyDataPacket (std::unique_ptr< KeyDataPacket > packet, Delegate::KeyDataResponse callback)
 Dispatches key events from the embedder to the framework. Each key data packet contains one physical event and multiple logical key events. Each call to this method wakes up the UI thread. More...
 
void RegisterTexture (std::shared_ptr< flutter::Texture > texture)
 Used by the embedder to specify a texture that it wants the rasterizer to composite within the Flutter layer tree. All textures must have a unique identifier. When the rasterizer encounters an external texture within its hierarchy, it gives the embedder a chance to update that texture on the raster thread before it composites the same on-screen. More...
 
void UnregisterTexture (int64_t texture_id)
 Used by the embedder to notify the rasterizer that it will no longer attempt to composite the specified texture within the layer tree. This allows the rasterizer to collect associated resources. More...
 
void MarkTextureFrameAvailable (int64_t texture_id)
 Used by the embedder to notify the rasterizer that the context of the previously registered texture have been updated. Typically, Flutter will only render a frame if there is an updated layer tree. However, in cases where the layer tree is static but one of the externally composited textures has been updated by the embedder, the embedder needs to notify the rasterizer to render a new frame. In such cases, the existing layer tree may be reused with the frame re-composited with all updated external textures. Unlike the calls to register and unregister the texture, this call must be made each time a new texture frame is available. More...
 
virtual std::unique_ptr< std::vector< std::string > > ComputePlatformResolvedLocales (const std::vector< std::string > &supported_locale_data)
 Directly invokes platform-specific APIs to compute the locale the platform would have natively resolved to. More...
 
virtual void RequestDartDeferredLibrary (intptr_t loading_unit_id)
 Invoked when the dart VM requests that a deferred library be loaded. Notifies the engine that the deferred library identified by the specified loading unit id should be downloaded and loaded into the Dart VM via LoadDartDeferredLibrary More...
 
virtual void LoadDartDeferredLibrary (intptr_t loading_unit_id, std::unique_ptr< const fml::Mapping > snapshot_data, std::unique_ptr< const fml::Mapping > snapshot_instructions)
 Loads the Dart shared library into the Dart VM. When the Dart library is loaded successfully, the Dart future returned by the originating loadLibrary() call completes. More...
 
virtual void LoadDartDeferredLibraryError (intptr_t loading_unit_id, const std::string error_message, bool transient)
 Indicates to the dart VM that the request to load a deferred library with the specified loading unit id has failed. More...
 
virtual void UpdateAssetResolverByType (std::unique_ptr< AssetResolver > updated_asset_resolver, AssetResolver::AssetResolverType type)
 Replaces the asset resolver handled by the engine's AssetManager of the specified type with updated_asset_resolver. The matching AssetResolver is removed and replaced with updated_asset_resolvers. More...
 
virtual std::unique_ptr< SnapshotSurfaceProducerCreateSnapshotSurfaceProducer ()
 Creates an object that produces surfaces suitable for raster snapshotting. The rasterizer will request this surface if no on screen surface is currently available when an application requests a snapshot, e.g. if Scene.toImage or Picture.toImage are called while the application is in the background. More...
 
virtual std::shared_ptr< PlatformMessageHandlerGetPlatformMessageHandler () const
 Specifies a delegate that will receive PlatformMessages from Flutter to the host platform. More...
 

Protected Member Functions

void RegisterPlatformMessageHandlers ()
 
void OnKeyEvent (fuchsia::ui::input3::KeyEvent key_event, fuchsia::ui::input3::KeyboardListener::OnKeyEventCallback callback) override
 
void DidUpdateState (fuchsia::ui::input::TextInputState state, std::unique_ptr< fuchsia::ui::input::InputEvent > event) override
 
void OnAction (fuchsia::ui::input::InputMethodAction action) override
 
bool OnHandlePointerEvent (const fuchsia::ui::input::PointerEvent &pointer)
 
bool OnHandleFocusEvent (const fuchsia::ui::input::FocusEvent &focus)
 
void ActivateIme ()
 
void DeactivateIme ()
 
std::unique_ptr< flutter::VsyncWaiterCreateVSyncWaiter () override
 Invoked by the shell to obtain a platform specific vsync waiter. It is optional for platforms to override this method and provide a custom vsync waiter because a timer based fall-back waiter is used by default. However, it is highly recommended that platform provide their own Vsync waiter as the timer based fall-back will not render frames aligned with vsync boundaries. More...
 
std::unique_ptr< flutter::SurfaceCreateRenderingSurface () override
 
void HandlePlatformMessage (std::unique_ptr< flutter::PlatformMessage > message) override
 
void UpdateSemantics (flutter::SemanticsNodeUpdates update, flutter::CustomAccessibilityActionUpdates actions) override
 Used by the framework to tell the embedder to apply the specified semantics node updates. The default implementation of this method does nothing. More...
 
bool HandleAccessibilityChannelPlatformMessage (std::unique_ptr< flutter::PlatformMessage > message)
 
bool HandleFlutterPlatformChannelPlatformMessage (std::unique_ptr< flutter::PlatformMessage > message)
 
bool HandleFlutterTextInputChannelPlatformMessage (std::unique_ptr< flutter::PlatformMessage > message)
 
bool HandleFlutterPlatformViewsChannelPlatformMessage (std::unique_ptr< flutter::PlatformMessage > message)
 
virtual void OnCreateView (ViewCallback on_view_created, int64_t view_id_raw, bool hit_testable, bool focusable)=0
 
virtual void OnDisposeView (int64_t view_id_raw)=0
 
std::array< float, 2 > ClampToViewSpace (const float x, const float y) const
 
 FML_DISALLOW_COPY_AND_ASSIGN (PlatformView)
 

Static Protected Member Functions

static bool HandleFuchsiaShaderWarmupChannelPlatformMessage (OnShaderWarmup on_shader_warmup, std::unique_ptr< flutter::PlatformMessage > message)
 

Protected Attributes

std::optional< std::array< float, 2 > > view_logical_size_
 
std::optional< std::array< float, 2 > > view_logical_origin_
 
std::optional< float > view_pixel_ratio_
 
std::shared_ptr< flutter::ExternalViewEmbedderexternal_view_embedder_
 
std::shared_ptr< FocusDelegatefocus_delegate_
 
std::shared_ptr< PointerDelegatepointer_delegate_
 
fidl::Binding< fuchsia::ui::input::InputMethodEditorClient > ime_client_
 
fuchsia::ui::input::InputMethodEditorPtr ime_
 
fuchsia::ui::input::ImeServicePtr text_sync_service_
 
int current_text_input_client_ = 0
 
fidl::Binding< fuchsia::ui::input3::KeyboardListener > keyboard_listener_binding_
 
fuchsia::ui::input3::KeyboardPtr keyboard_
 
Keyboard keyboard_translator_
 
std::unique_ptr< fuchsia::ui::input::TextInputState > last_text_state_
 
std::set< int > down_pointers_
 
std::map< std::string, std::function< bool(std::unique_ptr< flutter::PlatformMessage >)> > platform_message_handlers_
 
std::set< std::string > unregistered_channels_
 
OnEnableWireframe wireframe_enabled_callback_
 
OnUpdateView on_update_view_callback_
 
OnCreateSurface on_create_surface_callback_
 
OnSemanticsNodeUpdate on_semantics_node_update_callback_
 
OnRequestAnnounce on_request_announce_callback_
 
OnShaderWarmup on_shader_warmup_
 
AwaitVsyncCallback await_vsync_callback_
 
AwaitVsyncForSecondaryCallbackCallback await_vsync_for_secondary_callback_callback_
 
fml::WeakPtrFactory< PlatformViewweak_factory_
 
- Protected Attributes inherited from flutter::PlatformView
PlatformView::Delegatedelegate_
 
const TaskRunners task_runners_
 
PointerDataPacketConverter pointer_data_packet_converter_
 
SkISize size_
 
fml::WeakPtrFactory< PlatformViewweak_factory_
 

Detailed Description

Definition at line 62 of file platform_view.h.

Constructor & Destructor Documentation

◆ PlatformView()

flutter_runner::PlatformView::PlatformView ( flutter::PlatformView::Delegate delegate,
flutter::TaskRunners  task_runners,
fuchsia::ui::views::ViewRef  view_ref,
std::shared_ptr< flutter::ExternalViewEmbedder external_view_embedder,
fuchsia::ui::input::ImeServiceHandle  ime_service,
fuchsia::ui::input3::KeyboardHandle  keyboard,
fuchsia::ui::pointer::TouchSourceHandle  touch_source,
fuchsia::ui::pointer::MouseSourceHandle  mouse_source,
fuchsia::ui::views::FocuserHandle  focuser,
fuchsia::ui::views::ViewRefFocusedHandle  view_ref_focused,
OnEnableWireframe  wireframe_enabled_callback,
OnUpdateView  on_update_view_callback,
OnCreateSurface  on_create_surface_callback,
OnSemanticsNodeUpdate  on_semantics_node_update_callback,
OnRequestAnnounce  on_request_announce_callback,
OnShaderWarmup  on_shader_warmup,
AwaitVsyncCallback  await_vsync_callback,
AwaitVsyncForSecondaryCallbackCallback  await_vsync_for_secondary_callback_callback 
)

Definition at line 53 of file platform_view.cc.

73  : flutter::PlatformView(delegate, std::move(task_runners)),
74  external_view_embedder_(external_view_embedder),
76  std::make_shared<FocusDelegate>(std::move(view_ref_focused),
77  std::move(focuser))),
79  std::make_shared<PointerDelegate>(std::move(touch_source),
80  std::move(mouse_source))),
81  ime_client_(this),
82  text_sync_service_(ime_service.Bind()),
84  keyboard_(keyboard.Bind()),
85  wireframe_enabled_callback_(std::move(wireframe_enabled_callback)),
86  on_update_view_callback_(std::move(on_update_view_callback)),
87  on_create_surface_callback_(std::move(on_create_surface_callback)),
89  std::move(on_semantics_node_update_callback)),
90  on_request_announce_callback_(std::move(on_request_announce_callback)),
91  on_shader_warmup_(std::move(on_shader_warmup)),
92  await_vsync_callback_(await_vsync_callback),
94  await_vsync_for_secondary_callback_callback),
95  weak_factory_(this) {
96  // Register all error handlers.
97  SetInterfaceErrorHandler(ime_, "Input Method Editor");
99  SetInterfaceErrorHandler(text_sync_service_, "Text Sync Service");
101  SetInterfaceErrorHandler(keyboard_, "Keyboard");
102 
103  // Configure keyboard listener.
104  keyboard_->AddListener(std::move(view_ref),
105  keyboard_listener_binding_.NewBinding(), [] {});
106 
107  // Begin watching for focus changes.
108  focus_delegate_->WatchLoop([weak = weak_factory_.GetWeakPtr()](bool focused) {
109  if (!weak) {
110  FML_LOG(WARNING) << "PlatformView use-after-free attempted. Ignoring.";
111  return;
112  }
113 
114  // Ensure last_text_state_ is set to make sure Flutter actually wants
115  // an IME.
116  if (focused && weak->last_text_state_) {
117  weak->ActivateIme();
118  } else if (!focused) {
119  weak->DeactivateIme();
120  }
121  });
122 
123  // Begin watching for pointer events.
124  pointer_delegate_->WatchLoop([weak = weak_factory_.GetWeakPtr()](
125  std::vector<flutter::PointerData> events) {
126  if (!weak) {
127  FML_LOG(WARNING) << "PlatformView use-after-free attempted. Ignoring.";
128  return;
129  }
130 
131  if (events.size() == 0) {
132  return; // No work, bounce out.
133  }
134 
135  // If pixel ratio hasn't been set, use a default value of 1.
136  const float pixel_ratio = weak->view_pixel_ratio_.value_or(1.f);
137  auto packet = std::make_unique<flutter::PointerDataPacket>(events.size());
138  for (size_t i = 0; i < events.size(); ++i) {
139  auto& event = events[i];
140  // Translate logical to physical coordinates, as per flutter::PointerData
141  // contract. Done here because pixel ratio comes from the graphics API.
142  event.physical_x = event.physical_x * pixel_ratio;
143  event.physical_y = event.physical_y * pixel_ratio;
144  packet->SetPointerData(i, event);
145  }
146  weak->DispatchPointerDataPacket(std::move(packet));
147  });
148 
149  // Finally! Register the native platform message handlers.
151 }
void SetInterfaceErrorHandler(fidl::InterfacePtr< T > &interface, std::string name)
std::shared_ptr< FocusDelegate > focus_delegate_
fuchsia::ui::input::InputMethodEditorPtr ime_
std::shared_ptr< flutter::ExternalViewEmbedder > external_view_embedder_
OnCreateSurface on_create_surface_callback_
OnSemanticsNodeUpdate on_semantics_node_update_callback_
AwaitVsyncCallback await_vsync_callback_
#define FML_LOG(severity)
Definition: logging.h:65
Platform views are created by the shell on the platform task runner. Unless explicitly specified...
Definition: platform_view.h:47
AwaitVsyncForSecondaryCallbackCallback await_vsync_for_secondary_callback_callback_
FlKeyEvent * event
fidl::Binding< fuchsia::ui::input3::KeyboardListener > keyboard_listener_binding_
fidl::Binding< fuchsia::ui::input::InputMethodEditorClient > ime_client_
OnEnableWireframe wireframe_enabled_callback_
OnRequestAnnounce on_request_announce_callback_
fuchsia::ui::input::ImeServicePtr text_sync_service_
OnUpdateView on_update_view_callback_
std::shared_ptr< PointerDelegate > pointer_delegate_
fuchsia::ui::input3::KeyboardPtr keyboard_
fml::WeakPtrFactory< PlatformView > weak_factory_
OnShaderWarmup on_shader_warmup_

◆ ~PlatformView()

flutter_runner::PlatformView::~PlatformView ( )
overridevirtualdefault

Destroys the platform view. The platform view is owned by the shell and will be destroyed by the same on the platform tasks runner.

Reimplemented from flutter::PlatformView.

Member Function Documentation

◆ ActivateIme()

void flutter_runner::PlatformView::ActivateIme ( )
protected

Definition at line 438 of file platform_view.cc.

References DEBUG_CHECK, ime_, ime_client_, last_text_state_, LOG_TAG, and text_sync_service_.

Referenced by HandleFlutterTextInputChannelPlatformMessage().

438  {
440 
441  text_sync_service_->GetInputMethodEditor(
442  fuchsia::ui::input::KeyboardType::TEXT, // keyboard type
443  fuchsia::ui::input::InputMethodAction::DONE, // input method action
444  *last_text_state_, // initial state
445  ime_client_.NewBinding(), // client
446  ime_.NewRequest() // editor
447  );
448 }
fuchsia::ui::input::InputMethodEditorPtr ime_
#define DEBUG_CHECK(condition, tag, message)
Definition: inlines.h:19
std::unique_ptr< fuchsia::ui::input::TextInputState > last_text_state_
fidl::Binding< fuchsia::ui::input::InputMethodEditorClient > ime_client_
#define LOG_TAG
Definition: logging.h:11
fuchsia::ui::input::ImeServicePtr text_sync_service_

◆ ClampToViewSpace()

std::array< float, 2 > flutter_runner::PlatformView::ClampToViewSpace ( const float  x,
const float  y 
) const
protected

Definition at line 296 of file platform_view.cc.

References FML_LOG, fml::size(), view_logical_origin_, and view_logical_size_.

Referenced by OnHandlePointerEvent().

297  {
298  if (!view_logical_size_.has_value() || !view_logical_origin_.has_value()) {
299  return {x, y}; // If we can't do anything, return the original values.
300  }
301 
302  const auto origin = view_logical_origin_.value();
303  const auto size = view_logical_size_.value();
304  const float min_x = origin[0];
305  const float max_x = origin[0] + size[0];
306  const float min_y = origin[1];
307  const float max_y = origin[1] + size[1];
308  if (min_x <= x && x < max_x && min_y <= y && y < max_y) {
309  return {x, y}; // No clamping to perform.
310  }
311 
312  // View boundary is [min_x, max_x) x [min_y, max_y). Note that min is
313  // inclusive, but max is exclusive - so we subtract epsilon.
314  const float max_x_inclusive = max_x - std::numeric_limits<float>::epsilon();
315  const float max_y_inclusive = max_y - std::numeric_limits<float>::epsilon();
316  const float& clamped_x = std::clamp(x, min_x, max_x_inclusive);
317  const float& clamped_y = std::clamp(y, min_y, max_y_inclusive);
318  FML_LOG(INFO) << "Clamped (" << x << ", " << y << ") to (" << clamped_x
319  << ", " << clamped_y << ").";
320  return {clamped_x, clamped_y};
321 }
constexpr std::size_t size(T(&array)[N])
Definition: size.h:13
std::optional< std::array< float, 2 > > view_logical_origin_
#define FML_LOG(severity)
Definition: logging.h:65
std::optional< std::array< float, 2 > > view_logical_size_

◆ CreateExternalViewEmbedder()

std::shared_ptr< flutter::ExternalViewEmbedder > flutter_runner::PlatformView::CreateExternalViewEmbedder ( )
overridevirtual

Reimplemented from flutter::PlatformView.

Definition at line 474 of file platform_view.cc.

References external_view_embedder_.

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

474  {
476 }
std::shared_ptr< flutter::ExternalViewEmbedder > external_view_embedder_

◆ CreateRenderingSurface()

std::unique_ptr< flutter::Surface > flutter_runner::PlatformView::CreateRenderingSurface ( )
overrideprotectedvirtual

Reimplemented from flutter::PlatformView.

Definition at line 468 of file platform_view.cc.

References on_create_surface_callback_.

468  {
470 }
OnCreateSurface on_create_surface_callback_

◆ CreateVSyncWaiter()

std::unique_ptr< flutter::VsyncWaiter > flutter_runner::PlatformView::CreateVSyncWaiter ( )
overrideprotectedvirtual

Invoked by the shell to obtain a platform specific vsync waiter. It is optional for platforms to override this method and provide a custom vsync waiter because a timer based fall-back waiter is used by default. However, it is highly recommended that platform provide their own Vsync waiter as the timer based fall-back will not render frames aligned with vsync boundaries.

Attention
If a timer based fall-back is used, a warning is logged to the console. In case this method is overridden in a subclass, it must return a valid vsync waiter. Returning null will lead to internal errors. If a valid vsync waiter cannot be returned, subclasses should just call the based class method instead.
Returns
A vsync waiter. If is an internal error to return a null waiter.

Reimplemented from flutter::PlatformView.

Definition at line 461 of file platform_view.cc.

References await_vsync_callback_, await_vsync_for_secondary_callback_callback_, and flutter::PlatformView::task_runners_.

461  {
462  return std::make_unique<flutter_runner::VsyncWaiter>(
464  task_runners_);
465 }
const TaskRunners task_runners_
AwaitVsyncCallback await_vsync_callback_
AwaitVsyncForSecondaryCallbackCallback await_vsync_for_secondary_callback_callback_

◆ DeactivateIme()

void flutter_runner::PlatformView::DeactivateIme ( )
protected

Definition at line 450 of file platform_view.cc.

References ime_, ime_client_, and text_sync_service_.

Referenced by HandleFlutterTextInputChannelPlatformMessage().

450  {
451  if (ime_) {
452  text_sync_service_->HideKeyboard();
453  ime_ = nullptr;
454  }
455  if (ime_client_.is_bound()) {
456  ime_client_.Unbind();
457  }
458 }
fuchsia::ui::input::InputMethodEditorPtr ime_
fidl::Binding< fuchsia::ui::input::InputMethodEditorClient > ime_client_
fuchsia::ui::input::ImeServicePtr text_sync_service_

◆ DidUpdateState()

void flutter_runner::PlatformView::DidUpdateState ( fuchsia::ui::input::TextInputState  state,
std::unique_ptr< fuchsia::ui::input::InputEvent >  event 
)
overrideprotected

Definition at line 174 of file platform_view.cc.

References args, buffer, fml::MallocMapping::Copy(), current_text_input_client_, flutter::PlatformView::DispatchPlatformMessage(), last_text_state_, and state.

176  {
177  rapidjson::Document document;
178  auto& allocator = document.GetAllocator();
179  rapidjson::Value encoded_state(rapidjson::kObjectType);
180  encoded_state.AddMember("text", state.text, allocator);
181  encoded_state.AddMember("selectionBase", state.selection.base, allocator);
182  encoded_state.AddMember("selectionExtent", state.selection.extent, allocator);
183  switch (state.selection.affinity) {
184  case fuchsia::ui::input::TextAffinity::UPSTREAM:
185  encoded_state.AddMember("selectionAffinity",
186  rapidjson::Value("TextAffinity.upstream"),
187  allocator);
188  break;
189  case fuchsia::ui::input::TextAffinity::DOWNSTREAM:
190  encoded_state.AddMember("selectionAffinity",
191  rapidjson::Value("TextAffinity.downstream"),
192  allocator);
193  break;
194  }
195  encoded_state.AddMember("selectionIsDirectional", true, allocator);
196  encoded_state.AddMember("composingBase", state.composing.start, allocator);
197  encoded_state.AddMember("composingExtent", state.composing.end, allocator);
198 
199  rapidjson::Value args(rapidjson::kArrayType);
200  args.PushBack(current_text_input_client_, allocator);
201  args.PushBack(encoded_state, allocator);
202 
203  document.SetObject();
204  document.AddMember("method",
205  rapidjson::Value("TextInputClient.updateEditingState"),
206  allocator);
207  document.AddMember("args", args, allocator);
208 
209  rapidjson::StringBuffer buffer;
210  rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
211  document.Accept(writer);
212 
213  const uint8_t* data = reinterpret_cast<const uint8_t*>(buffer.GetString());
214  DispatchPlatformMessage(std::make_unique<flutter::PlatformMessage>(
215  kTextInputChannel, // channel
216  fml::MallocMapping::Copy(data, buffer.GetSize()), // message
217  nullptr) // response
218  );
220  std::make_unique<fuchsia::ui::input::TextInputState>(state);
221 }
G_BEGIN_DECLS FlValue * args
static constexpr char kTextInputChannel[]
std::unique_ptr< fuchsia::ui::input::TextInputState > last_text_state_
void DispatchPlatformMessage(std::unique_ptr< PlatformMessage > message)
Used by embedders to dispatch a platform message to a running root isolate hosted by the engine...
static MallocMapping Copy(const T *begin, const T *end)
Definition: mapping.h:147
static const uint8_t buffer[]
AtkStateType state

◆ FML_DISALLOW_COPY_AND_ASSIGN()

flutter_runner::PlatformView::FML_DISALLOW_COPY_AND_ASSIGN ( PlatformView  )
protected

◆ HandleAccessibilityChannelPlatformMessage()

bool flutter_runner::PlatformView::HandleAccessibilityChannelPlatformMessage ( std::unique_ptr< flutter::PlatformMessage message)
protected

Definition at line 532 of file platform_view.cc.

References FML_DCHECK, flutter::StandardMessageCodec::GetInstance(), flutter_runner::kAccessibilityChannel, on_request_announce_callback_, text, and type.

Referenced by RegisterPlatformMessageHandlers().

533  {
534  FML_DCHECK(message->channel() == kAccessibilityChannel);
535 
536  const flutter::StandardMessageCodec& standard_message_codec =
538  std::unique_ptr<flutter::EncodableValue> decoded =
539  standard_message_codec.DecodeMessage(message->data().GetMapping(),
540  message->data().GetSize());
541 
542  flutter::EncodableMap map = std::get<flutter::EncodableMap>(*decoded);
543  std::string type =
544  std::get<std::string>(map.at(flutter::EncodableValue("type")));
545  if (type == "announce") {
546  flutter::EncodableMap data_map = std::get<flutter::EncodableMap>(
547  map.at(flutter::EncodableValue("data")));
548  std::string text =
549  std::get<std::string>(data_map.at(flutter::EncodableValue("message")));
550 
552  }
553 
554  // Complete with an empty response.
555  return false;
556 }
KeyCallType type
#define FML_DCHECK(condition)
Definition: logging.h:86
static constexpr char kAccessibilityChannel[]
static const StandardMessageCodec & GetInstance(const StandardCodecSerializer *serializer=nullptr)
OnRequestAnnounce on_request_announce_callback_
std::u16string text
std::map< EncodableValue, EncodableValue > EncodableMap

◆ HandleFlutterPlatformChannelPlatformMessage()

bool flutter_runner::PlatformView::HandleFlutterPlatformChannelPlatformMessage ( std::unique_ptr< flutter::PlatformMessage message)
protected

Definition at line 559 of file platform_view.cc.

References FML_DCHECK, and flutter_runner::kFlutterPlatformChannel.

Referenced by RegisterPlatformMessageHandlers().

560  {
561  FML_DCHECK(message->channel() == kFlutterPlatformChannel);
562 
563  // Fuchsia does not handle any platform messages at this time.
564 
565  // Complete with an empty response.
566  return false;
567 }
static constexpr char kFlutterPlatformChannel[]
#define FML_DCHECK(condition)
Definition: logging.h:86

◆ HandleFlutterPlatformViewsChannelPlatformMessage()

bool flutter_runner::PlatformView::HandleFlutterPlatformViewsChannelPlatformMessage ( std::unique_ptr< flutter::PlatformMessage message)
protected

Definition at line 663 of file platform_view.cc.

References args, FML_DCHECK, FML_DLOG, FML_LOG, focus_delegate_, flutter::TaskRunners::GetPlatformTaskRunner(), flutter_runner::kFlutterPlatformViewsChannel, fml::MakeCopyable(), on_update_view_callback_, OnCreateView(), OnDisposeView(), flutter::PlatformView::task_runners_, and wireframe_enabled_callback_.

Referenced by RegisterPlatformMessageHandlers().

664  {
665  FML_DCHECK(message->channel() == kFlutterPlatformViewsChannel);
666  const auto& data = message->data();
667  rapidjson::Document document;
668  document.Parse(reinterpret_cast<const char*>(data.GetMapping()),
669  data.GetSize());
670  if (document.HasParseError() || !document.IsObject()) {
671  FML_LOG(ERROR) << "Could not parse document";
672  return false;
673  }
674  auto root = document.GetObject();
675  auto method_member = root.FindMember("method");
676  if (method_member == root.MemberEnd() || !method_member->value.IsString()) {
677  return false;
678  }
679  std::string method(method_member->value.GetString());
680 
681  if (method == "View.enableWireframe") {
682  auto args_it = root.FindMember("args");
683  if (args_it == root.MemberEnd() || !args_it->value.IsObject()) {
684  FML_LOG(ERROR) << "No arguments found.";
685  return false;
686  }
687  const auto& args = args_it->value;
688 
689  auto enable = args.FindMember("enable");
690  if (!enable->value.IsBool()) {
691  FML_LOG(ERROR) << "Argument 'enable' is not a bool";
692  return false;
693  }
694 
695  wireframe_enabled_callback_(enable->value.GetBool());
696  } else if (method == "View.create") {
697  auto args_it = root.FindMember("args");
698  if (args_it == root.MemberEnd() || !args_it->value.IsObject()) {
699  FML_LOG(ERROR) << "No arguments found.";
700  return false;
701  }
702  const auto& args = args_it->value;
703 
704  auto view_id = args.FindMember("viewId");
705  if (!view_id->value.IsUint64()) {
706  FML_LOG(ERROR) << "Argument 'viewId' is not a int64";
707  return false;
708  }
709 
710  auto hit_testable = args.FindMember("hitTestable");
711  if (!hit_testable->value.IsBool()) {
712  FML_LOG(ERROR) << "Argument 'hitTestable' is not a bool";
713  return false;
714  }
715 
716  auto focusable = args.FindMember("focusable");
717  if (!focusable->value.IsBool()) {
718  FML_LOG(ERROR) << "Argument 'focusable' is not a bool";
719  return false;
720  }
721 
722  auto on_view_created = fml::MakeCopyable(
723  [platform_task_runner = task_runners_.GetPlatformTaskRunner(),
724  message = std::move(message)]() {
725  // The client is waiting for view creation. Send an empty response
726  // back to signal the view was created.
727  if (message->response()) {
728  message->response()->Complete(std::make_unique<fml::DataMapping>(
729  std::vector<uint8_t>({'[', '0', ']'})));
730  }
731  });
732  OnCreateView(std::move(on_view_created), view_id->value.GetUint64(),
733  hit_testable->value.GetBool(), focusable->value.GetBool());
734  return true;
735  } else if (method == "View.update") {
736  auto args_it = root.FindMember("args");
737  if (args_it == root.MemberEnd() || !args_it->value.IsObject()) {
738  FML_LOG(ERROR) << "No arguments found.";
739  return false;
740  }
741  const auto& args = args_it->value;
742 
743  auto view_id = args.FindMember("viewId");
744  if (!view_id->value.IsUint64()) {
745  FML_LOG(ERROR) << "Argument 'viewId' is not a int64";
746  return false;
747  }
748 
749  auto hit_testable = args.FindMember("hitTestable");
750  if (!hit_testable->value.IsBool()) {
751  FML_LOG(ERROR) << "Argument 'hitTestable' is not a bool";
752  return false;
753  }
754 
755  auto focusable = args.FindMember("focusable");
756  if (!focusable->value.IsBool()) {
757  FML_LOG(ERROR) << "Argument 'focusable' is not a bool";
758  return false;
759  }
760 
761  SkRect view_occlusion_hint_raw = SkRect::MakeEmpty();
762  auto view_occlusion_hint = args.FindMember("viewOcclusionHintLTRB");
763  if (view_occlusion_hint != args.MemberEnd()) {
764  if (view_occlusion_hint->value.IsArray()) {
765  const auto& view_occlusion_hint_array =
766  view_occlusion_hint->value.GetArray();
767  if (view_occlusion_hint_array.Size() == 4) {
768  bool parse_error = false;
769  for (int i = 0; i < 4; i++) {
770  auto& array_val = view_occlusion_hint_array[i];
771  if (!array_val.IsDouble()) {
772  FML_LOG(ERROR) << "Argument 'viewOcclusionHintLTRB' element " << i
773  << " is not a double";
774  parse_error = true;
775  break;
776  }
777  }
778 
779  if (!parse_error) {
780  view_occlusion_hint_raw =
781  SkRect::MakeLTRB(view_occlusion_hint_array[0].GetDouble(),
782  view_occlusion_hint_array[1].GetDouble(),
783  view_occlusion_hint_array[2].GetDouble(),
784  view_occlusion_hint_array[3].GetDouble());
785  }
786  } else {
787  FML_LOG(ERROR)
788  << "Argument 'viewOcclusionHintLTRB' expected size 4; got "
789  << view_occlusion_hint_array.Size();
790  }
791  } else {
792  FML_LOG(ERROR)
793  << "Argument 'viewOcclusionHintLTRB' is not a double array";
794  }
795  } else {
796  FML_LOG(WARNING) << "Argument 'viewOcclusionHintLTRB' is missing";
797  }
798 
800  view_id->value.GetUint64(), view_occlusion_hint_raw,
801  hit_testable->value.GetBool(), focusable->value.GetBool());
802  if (message->response()) {
803  message->response()->Complete(std::make_unique<fml::DataMapping>(
804  std::vector<uint8_t>({'[', '0', ']'})));
805  return true;
806  }
807  } else if (method == "View.dispose") {
808  auto args_it = root.FindMember("args");
809  if (args_it == root.MemberEnd() || !args_it->value.IsObject()) {
810  FML_LOG(ERROR) << "No arguments found.";
811  return false;
812  }
813  const auto& args = args_it->value;
814 
815  auto view_id = args.FindMember("viewId");
816  if (!view_id->value.IsUint64()) {
817  FML_LOG(ERROR) << "Argument 'viewId' is not a int64";
818  return false;
819  }
820 
821  OnDisposeView(view_id->value.GetUint64());
822  if (message->response()) {
823  message->response()->Complete(std::make_unique<fml::DataMapping>(
824  std::vector<uint8_t>({'[', '0', ']'})));
825  return true;
826  }
827  } else if (method.rfind("View.focus", 0) == 0) {
828  return focus_delegate_->HandlePlatformMessage(root, message->response());
829  } else {
830  FML_DLOG(ERROR) << "Unknown " << message->channel() << " method " << method;
831  }
832  // Complete with an empty response by default.
833  return false;
834 }
G_BEGIN_DECLS FlValue * args
std::shared_ptr< FocusDelegate > focus_delegate_
#define FML_DCHECK(condition)
Definition: logging.h:86
const TaskRunners task_runners_
fml::RefPtr< fml::TaskRunner > GetPlatformTaskRunner() const
Definition: task_runners.cc:30
#define FML_LOG(severity)
Definition: logging.h:65
virtual void OnCreateView(ViewCallback on_view_created, int64_t view_id_raw, bool hit_testable, bool focusable)=0
internal::CopyableLambda< T > MakeCopyable(T lambda)
Definition: make_copyable.h:57
OnEnableWireframe wireframe_enabled_callback_
static constexpr char kFlutterPlatformViewsChannel[]
OnUpdateView on_update_view_callback_
#define FML_DLOG(severity)
Definition: logging.h:85
virtual void OnDisposeView(int64_t view_id_raw)=0

◆ HandleFlutterTextInputChannelPlatformMessage()

bool flutter_runner::PlatformView::HandleFlutterTextInputChannelPlatformMessage ( std::unique_ptr< flutter::PlatformMessage message)
protected

Definition at line 570 of file platform_view.cc.

References ActivateIme(), args, current_text_input_client_, DeactivateIme(), FML_DCHECK, FML_DLOG, ime_, flutter_runner::kTextInputChannel, last_text_state_, state, text, and text_sync_service_.

Referenced by RegisterPlatformMessageHandlers().

571  {
572  FML_DCHECK(message->channel() == kTextInputChannel);
573  const auto& data = message->data();
574  rapidjson::Document document;
575  document.Parse(reinterpret_cast<const char*>(data.GetMapping()),
576  data.GetSize());
577  if (document.HasParseError() || !document.IsObject()) {
578  return false;
579  }
580  auto root = document.GetObject();
581  auto method = root.FindMember("method");
582  if (method == root.MemberEnd() || !method->value.IsString()) {
583  return false;
584  }
585 
586  if (method->value == "TextInput.show") {
587  if (ime_) {
588  text_sync_service_->ShowKeyboard();
589  }
590  } else if (method->value == "TextInput.hide") {
591  if (ime_) {
592  text_sync_service_->HideKeyboard();
593  }
594  } else if (method->value == "TextInput.setClient") {
596  DeactivateIme();
597  auto args = root.FindMember("args");
598  if (args == root.MemberEnd() || !args->value.IsArray() ||
599  args->value.Size() != 2)
600  return false;
601  const auto& configuration = args->value[1];
602  if (!configuration.IsObject()) {
603  return false;
604  }
605  // TODO(abarth): Read the keyboard type from the configuration.
606  current_text_input_client_ = args->value[0].GetInt();
607 
608  auto initial_text_input_state = fuchsia::ui::input::TextInputState{};
609  initial_text_input_state.text = "";
610  last_text_state_ = std::make_unique<fuchsia::ui::input::TextInputState>(
611  initial_text_input_state);
612  ActivateIme();
613  } else if (method->value == "TextInput.setEditingState") {
614  if (ime_) {
615  auto args_it = root.FindMember("args");
616  if (args_it == root.MemberEnd() || !args_it->value.IsObject()) {
617  return false;
618  }
619  const auto& args = args_it->value;
620  fuchsia::ui::input::TextInputState state;
621  state.text = "";
622  // TODO(abarth): Deserialize state.
623  auto text = args.FindMember("text");
624  if (text != args.MemberEnd() && text->value.IsString())
625  state.text = text->value.GetString();
626  auto selection_base = args.FindMember("selectionBase");
627  if (selection_base != args.MemberEnd() && selection_base->value.IsInt())
628  state.selection.base = selection_base->value.GetInt();
629  auto selection_extent = args.FindMember("selectionExtent");
630  if (selection_extent != args.MemberEnd() &&
631  selection_extent->value.IsInt())
632  state.selection.extent = selection_extent->value.GetInt();
633  auto selection_affinity = args.FindMember("selectionAffinity");
634  if (selection_affinity != args.MemberEnd() &&
635  selection_affinity->value.IsString() &&
636  selection_affinity->value == "TextAffinity.upstream")
637  state.selection.affinity = fuchsia::ui::input::TextAffinity::UPSTREAM;
638  else
639  state.selection.affinity = fuchsia::ui::input::TextAffinity::DOWNSTREAM;
640  // We ignore selectionIsDirectional because that concept doesn't exist on
641  // Fuchsia.
642  auto composing_base = args.FindMember("composingBase");
643  if (composing_base != args.MemberEnd() && composing_base->value.IsInt())
644  state.composing.start = composing_base->value.GetInt();
645  auto composing_extent = args.FindMember("composingExtent");
646  if (composing_extent != args.MemberEnd() &&
647  composing_extent->value.IsInt())
648  state.composing.end = composing_extent->value.GetInt();
649  ime_->SetState(std::move(state));
650  }
651  } else if (method->value == "TextInput.clearClient") {
653  last_text_state_ = nullptr;
654  DeactivateIme();
655  } else {
656  FML_DLOG(ERROR) << "Unknown " << message->channel() << " method "
657  << method->value.GetString();
658  }
659  // Complete with an empty response.
660  return false;
661 }
G_BEGIN_DECLS FlValue * args
fuchsia::ui::input::InputMethodEditorPtr ime_
#define FML_DCHECK(condition)
Definition: logging.h:86
static constexpr char kTextInputChannel[]
std::unique_ptr< fuchsia::ui::input::TextInputState > last_text_state_
fuchsia::ui::input::ImeServicePtr text_sync_service_
std::u16string text
#define FML_DLOG(severity)
Definition: logging.h:85
AtkStateType state

◆ HandleFuchsiaShaderWarmupChannelPlatformMessage()

bool flutter_runner::PlatformView::HandleFuchsiaShaderWarmupChannelPlatformMessage ( OnShaderWarmup  on_shader_warmup,
std::unique_ptr< flutter::PlatformMessage message 
)
staticprotected

Definition at line 836 of file platform_view.cc.

References FML_DCHECK, FML_LOG, height, flutter_runner::kFuchsiaShaderWarmupChannel, result, and width.

Referenced by RegisterPlatformMessageHandlers().

838  {
839  FML_DCHECK(message->channel() == kFuchsiaShaderWarmupChannel);
840 
841  if (!on_shader_warmup) {
842  FML_LOG(ERROR) << "No shader warmup callback set!";
843  std::string result = "[0]";
844  message->response()->Complete(
845  std::make_unique<fml::DataMapping>(std::vector<uint8_t>(
846  (const uint8_t*)result.c_str(),
847  (const uint8_t*)result.c_str() + result.length())));
848  return true;
849  }
850 
851  const auto& data = message->data();
852  rapidjson::Document document;
853  document.Parse(reinterpret_cast<const char*>(data.GetMapping()),
854  data.GetSize());
855  if (document.HasParseError() || !document.IsObject()) {
856  FML_LOG(ERROR) << "Could not parse document";
857  return false;
858  }
859  auto root = document.GetObject();
860  auto method = root.FindMember("method");
861  if (method == root.MemberEnd() || !method->value.IsString() ||
862  method->value != "WarmupSkps") {
863  FML_LOG(ERROR) << "Invalid method name";
864  return false;
865  }
866 
867  auto args_it = root.FindMember("args");
868  if (args_it == root.MemberEnd() || !args_it->value.IsObject()) {
869  FML_LOG(ERROR) << "No arguments found.";
870  return false;
871  }
872 
873  auto shaders_it = root["args"].FindMember("shaders");
874  if (shaders_it == root["args"].MemberEnd() || !shaders_it->value.IsArray()) {
875  FML_LOG(ERROR) << "No shaders found.";
876  return false;
877  }
878 
879  auto width_it = root["args"].FindMember("width");
880  auto height_it = root["args"].FindMember("height");
881  if (width_it == root["args"].MemberEnd() || !width_it->value.IsNumber()) {
882  FML_LOG(ERROR) << "Invalid width";
883  return false;
884  }
885  if (height_it == root["args"].MemberEnd() || !height_it->value.IsNumber()) {
886  FML_LOG(ERROR) << "Invalid height";
887  return false;
888  }
889  auto width = width_it->value.GetUint64();
890  auto height = height_it->value.GetUint64();
891 
892  std::vector<std::string> skp_paths;
893  const auto& shaders = shaders_it->value;
894  for (rapidjson::Value::ConstValueIterator itr = shaders.Begin();
895  itr != shaders.End(); ++itr) {
896  skp_paths.push_back((*itr).GetString());
897  }
898 
899  auto completion_callback = [response =
900  message->response()](uint num_successes) {
901  std::ostringstream result_stream;
902  result_stream << "[" << num_successes << "]";
903 
904  std::string result(result_stream.str());
905 
906  response->Complete(std::make_unique<fml::DataMapping>(std::vector<uint8_t>(
907  (const uint8_t*)result.c_str(),
908  (const uint8_t*)result.c_str() + result.length())));
909  };
910 
911  on_shader_warmup(skp_paths, completion_callback, width, height);
912  // The response has already been completed by us.
913  return true;
914 }
#define FML_DCHECK(condition)
Definition: logging.h:86
GAsyncResult * result
#define FML_LOG(severity)
Definition: logging.h:65
static constexpr char kFuchsiaShaderWarmupChannel[]
int32_t width
int32_t height

◆ HandlePlatformMessage()

void flutter_runner::PlatformView::HandlePlatformMessage ( std::unique_ptr< flutter::PlatformMessage message)
overrideprotected

Definition at line 479 of file platform_view.cc.

References FML_DCHECK, FML_LOG, flutter::PlatformView::HandlePlatformMessage(), platform_message_handlers_, and unregistered_channels_.

480  {
481  if (!message) {
482  return;
483  }
484  const std::string channel = message->channel();
485  auto found = platform_message_handlers_.find(channel);
486  if (found == platform_message_handlers_.end()) {
487  const bool already_errored = unregistered_channels_.count(channel);
488  if (!already_errored) {
489  FML_LOG(INFO)
490  << "Platform view received message on channel '" << message->channel()
491  << "' with no registered handler. And empty response will be "
492  "generated. Please implement the native message handler. This "
493  "message will appear only once per channel.";
494  unregistered_channels_.insert(channel);
495  }
497  return;
498  }
499  auto response = message->response();
500  bool response_handled = found->second(std::move(message));
501 
502  // Ensure all responses are completed.
503  if (response && !response_handled) {
504  // response_handled should be true if the response was completed.
505  FML_DCHECK(!response->is_complete());
506  response->CompleteEmpty();
507  }
508 }
#define FML_DCHECK(condition)
Definition: logging.h:86
#define FML_LOG(severity)
Definition: logging.h:65
std::map< std::string, std::function< bool(std::unique_ptr< flutter::PlatformMessage >)> > platform_message_handlers_
std::set< std::string > unregistered_channels_
virtual void HandlePlatformMessage(std::unique_ptr< PlatformMessage > message)
Overridden by embedders to perform actions in response to platform messages sent from the framework t...

◆ OnAction()

void flutter_runner::PlatformView::OnAction ( fuchsia::ui::input::InputMethodAction  action)
overrideprotected

Definition at line 224 of file platform_view.cc.

References args, buffer, fml::MallocMapping::Copy(), current_text_input_client_, and flutter::PlatformView::DispatchPlatformMessage().

224  {
225  rapidjson::Document document;
226  auto& allocator = document.GetAllocator();
227 
228  rapidjson::Value args(rapidjson::kArrayType);
229  args.PushBack(current_text_input_client_, allocator);
230 
231  // Done is currently the only text input action defined by Flutter.
232  args.PushBack("TextInputAction.done", allocator);
233 
234  document.SetObject();
235  document.AddMember(
236  "method", rapidjson::Value("TextInputClient.performAction"), allocator);
237  document.AddMember("args", args, allocator);
238 
239  rapidjson::StringBuffer buffer;
240  rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
241  document.Accept(writer);
242 
243  const uint8_t* data = reinterpret_cast<const uint8_t*>(buffer.GetString());
244  DispatchPlatformMessage(std::make_unique<flutter::PlatformMessage>(
245  kTextInputChannel, // channel
246  fml::MallocMapping::Copy(data, buffer.GetSize()), // message
247  nullptr) // response
248  );
249 }
G_BEGIN_DECLS FlValue * args
static constexpr char kTextInputChannel[]
void DispatchPlatformMessage(std::unique_ptr< PlatformMessage > message)
Used by embedders to dispatch a platform message to a running root isolate hosted by the engine...
static MallocMapping Copy(const T *begin, const T *end)
Definition: mapping.h:147
static const uint8_t buffer[]

◆ OnCreateView()

virtual void flutter_runner::PlatformView::OnCreateView ( ViewCallback  on_view_created,
int64_t  view_id_raw,
bool  hit_testable,
bool  focusable 
)
protectedpure virtual

◆ OnDisposeView()

virtual void flutter_runner::PlatformView::OnDisposeView ( int64_t  view_id_raw)
protectedpure virtual

◆ OnHandleFocusEvent()

bool flutter_runner::PlatformView::OnHandleFocusEvent ( const fuchsia::ui::input::FocusEvent &  focus)
protected

◆ OnHandlePointerEvent()

bool flutter_runner::PlatformView::OnHandlePointerEvent ( const fuchsia::ui::input::PointerEvent &  pointer)
protected

Definition at line 323 of file platform_view.cc.

References flutter::PointerData::buttons, flutter::PointerData::change, ClampToViewSpace(), flutter::PointerData::Clear(), flutter::PointerData::device, flutter::PlatformView::DispatchPointerDataPacket(), down_pointers_, FML_DLOG, flutter_runner::GetChangeFromPointerEventPhase(), flutter_runner::GetKindFromPointerType(), flutter::PointerData::kAdd, flutter::PointerData::kCancel, flutter::PointerData::kDown, flutter::PointerData::kHover, flutter::PointerData::kind, flutter::PointerData::kMove, flutter::PointerData::kRemove, flutter::PointerData::kUp, flutter::PointerData::physical_x, flutter::PointerData::physical_y, flutter_runner::PointerTraceHACK(), flutter::PointerData::time_stamp, TRACE_EVENT0, TRACE_FLOW_END, and view_pixel_ratio_.

324  {
325  TRACE_EVENT0("flutter", "PlatformView::OnHandlePointerEvent");
326 
327  // TODO(SCN-1278): Use proper trace_id for tracing flow.
328  trace_flow_id_t trace_id =
329  PointerTraceHACK(pointer.radius_major, pointer.radius_minor);
330  TRACE_FLOW_END("input", "dispatch_event_to_client", trace_id);
331 
332  const float pixel_ratio =
333  view_pixel_ratio_.has_value() ? *view_pixel_ratio_ : 0.f;
334 
335  flutter::PointerData pointer_data;
336  pointer_data.Clear();
337  pointer_data.time_stamp = pointer.event_time / 1000;
338  pointer_data.change = GetChangeFromPointerEventPhase(pointer.phase);
339  pointer_data.kind = GetKindFromPointerType(pointer.type);
340  pointer_data.device = pointer.pointer_id;
341  // Pointer events are in logical pixels, so scale to physical.
342  pointer_data.physical_x = pointer.x * pixel_ratio;
343  pointer_data.physical_y = pointer.y * pixel_ratio;
344  // Buttons are single bit values starting with kMousePrimaryButton = 1.
345  pointer_data.buttons = static_cast<uint64_t>(pointer.buttons);
346 
347  switch (pointer_data.change) {
349  // Make the pointer start in the view space, despite numerical drift.
350  auto clamped_pointer = ClampToViewSpace(pointer.x, pointer.y);
351  pointer_data.physical_x = clamped_pointer[0] * pixel_ratio;
352  pointer_data.physical_y = clamped_pointer[1] * pixel_ratio;
353 
354  down_pointers_.insert(pointer_data.device);
355  break;
356  }
359  down_pointers_.erase(pointer_data.device);
360  break;
362  if (down_pointers_.count(pointer_data.device) == 0) {
364  }
365  break;
367  if (down_pointers_.count(pointer_data.device) != 0) {
368  FML_DLOG(ERROR) << "Received add event for down pointer.";
369  }
370  break;
372  if (down_pointers_.count(pointer_data.device) != 0) {
373  FML_DLOG(ERROR) << "Received remove event for down pointer.";
374  }
375  break;
377  if (down_pointers_.count(pointer_data.device) != 0) {
378  FML_DLOG(ERROR) << "Received hover event for down pointer.";
379  }
380  break;
381  }
382 
383  auto packet = std::make_unique<flutter::PointerDataPacket>(1);
384  packet->SetPointerData(0, pointer_data);
385  DispatchPointerDataPacket(std::move(packet));
386  return true;
387 }
std::optional< float > view_pixel_ratio_
#define TRACE_EVENT0(category_group, name)
Definition: trace_event.h:90
static flutter::PointerData::Change GetChangeFromPointerEventPhase(fuchsia::ui::input::PointerEventPhase phase)
#define TRACE_FLOW_END(category, name, id)
Definition: trace_event.h:136
static flutter::PointerData::DeviceKind GetKindFromPointerType(fuchsia::ui::input::PointerEventType type)
void DispatchPointerDataPacket(std::unique_ptr< PointerDataPacket > packet)
Dispatches pointer events from the embedder to the framework. Each pointer data packet may contain mu...
std::set< int > down_pointers_
static trace_flow_id_t PointerTraceHACK(float fa, float fb)
std::array< float, 2 > ClampToViewSpace(const float x, const float y) const
#define FML_DLOG(severity)
Definition: logging.h:85

◆ OnKeyEvent()

void flutter_runner::PlatformView::OnKeyEvent ( fuchsia::ui::input3::KeyEvent  key_event,
fuchsia::ui::input3::KeyboardListener::OnKeyEventCallback  callback 
)
overrideprotected

Definition at line 390 of file platform_view.cc.

References buffer, callback, flutter_runner::Keyboard::ConsumeEvent(), fml::MallocMapping::Copy(), flutter::PlatformView::DispatchPlatformMessage(), FML_DLOG, keyboard_translator_, flutter_runner::Keyboard::LastCodePoint(), flutter_runner::Keyboard::LastHIDUsage(), flutter_runner::Keyboard::Modifiers(), and type.

392  {
393  const char* type = nullptr;
394  switch (key_event.type()) {
395  case fuchsia::ui::input3::KeyEventType::PRESSED:
396  type = "keydown";
397  break;
398  case fuchsia::ui::input3::KeyEventType::RELEASED:
399  type = "keyup";
400  break;
401  case fuchsia::ui::input3::KeyEventType::SYNC:
402  // What, if anything, should happen here?
403  case fuchsia::ui::input3::KeyEventType::CANCEL:
404  // What, if anything, should happen here?
405  default:
406  break;
407  }
408  if (type == nullptr) {
409  FML_DLOG(ERROR) << "Unknown key event phase.";
410  callback(fuchsia::ui::input3::KeyEventStatus::NOT_HANDLED);
411  return;
412  }
414 
415  rapidjson::Document document;
416  auto& allocator = document.GetAllocator();
417  document.SetObject();
418  document.AddMember("type", rapidjson::Value(type, strlen(type)), allocator);
419  document.AddMember("keymap", rapidjson::Value("fuchsia"), allocator);
420  document.AddMember("hidUsage", keyboard_translator_.LastHIDUsage(),
421  allocator);
422  document.AddMember("codePoint", keyboard_translator_.LastCodePoint(),
423  allocator);
424  document.AddMember("modifiers", keyboard_translator_.Modifiers(), allocator);
425  rapidjson::StringBuffer buffer;
426  rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
427  document.Accept(writer);
428 
429  const uint8_t* data = reinterpret_cast<const uint8_t*>(buffer.GetString());
430  DispatchPlatformMessage(std::make_unique<flutter::PlatformMessage>(
431  kKeyEventChannel, // channel
432  fml::MallocMapping::Copy(data, buffer.GetSize()), // data
433  nullptr) // response
434  );
435  callback(fuchsia::ui::input3::KeyEventStatus::HANDLED);
436 }
static constexpr char kKeyEventChannel[]
KeyCallType type
uint32_t LastCodePoint()
Definition: keyboard.cc:300
FlutterKeyEvent key_event
FlKeyEvent FlKeyResponderAsyncCallback callback
void DispatchPlatformMessage(std::unique_ptr< PlatformMessage > message)
Used by embedders to dispatch a platform message to a running root isolate hosted by the engine...
FlutterKeyEventType type
The event kind.
Definition: embedder.h:713
static MallocMapping Copy(const T *begin, const T *end)
Definition: mapping.h:147
static const uint8_t buffer[]
#define FML_DLOG(severity)
Definition: logging.h:85
bool ConsumeEvent(fuchsia::ui::input3::KeyEvent event)
Definition: keyboard.cc:174

◆ RegisterPlatformMessageHandlers()

void flutter_runner::PlatformView::RegisterPlatformMessageHandlers ( )
protected

Definition at line 155 of file platform_view.cc.

References HandleAccessibilityChannelPlatformMessage(), HandleFlutterPlatformChannelPlatformMessage(), HandleFlutterPlatformViewsChannelPlatformMessage(), HandleFlutterTextInputChannelPlatformMessage(), HandleFuchsiaShaderWarmupChannelPlatformMessage(), flutter_runner::kAccessibilityChannel, flutter_runner::kFlutterPlatformChannel, flutter_runner::kFlutterPlatformViewsChannel, flutter_runner::kFuchsiaShaderWarmupChannel, flutter_runner::kTextInputChannel, on_shader_warmup_, and platform_message_handlers_.

155  {
158  this, std::placeholders::_1);
161  this, std::placeholders::_1);
164  std::placeholders::_1);
167  this, std::placeholders::_1);
170  on_shader_warmup_, std::placeholders::_1);
171 }
bool HandleFlutterTextInputChannelPlatformMessage(std::unique_ptr< flutter::PlatformMessage > message)
static constexpr char kFlutterPlatformChannel[]
bool HandleAccessibilityChannelPlatformMessage(std::unique_ptr< flutter::PlatformMessage > message)
static constexpr char kAccessibilityChannel[]
bool HandleFlutterPlatformChannelPlatformMessage(std::unique_ptr< flutter::PlatformMessage > message)
static constexpr char kTextInputChannel[]
static constexpr char kFuchsiaShaderWarmupChannel[]
std::map< std::string, std::function< bool(std::unique_ptr< flutter::PlatformMessage >)> > platform_message_handlers_
static bool HandleFuchsiaShaderWarmupChannelPlatformMessage(OnShaderWarmup on_shader_warmup, std::unique_ptr< flutter::PlatformMessage > message)
static constexpr char kFlutterPlatformViewsChannel[]
bool HandleFlutterPlatformViewsChannelPlatformMessage(std::unique_ptr< flutter::PlatformMessage > message)
OnShaderWarmup on_shader_warmup_

◆ SetSemanticsEnabled()

void flutter_runner::PlatformView::SetSemanticsEnabled ( bool  enabled)
overridevirtual

Used by embedder to notify the running isolate hosted by the engine on the UI thread that the accessibility tree needs to be generated.

Attention
Subclasses may choose to override this method to perform platform specific functions. However, they must call the base class method at some point in their implementation.
Parameters
[in]enabledWhether the accessibility tree needs to be generated.

Reimplemented from flutter::PlatformView.

Definition at line 511 of file platform_view.cc.

References flutter::kAccessibleNavigation, flutter::PlatformView::SetAccessibilityFeatures(), and flutter::PlatformView::SetSemanticsEnabled().

511  {
513  if (enabled) {
514  SetAccessibilityFeatures(static_cast<int32_t>(
516  } else {
518  }
519 }
virtual void SetAccessibilityFeatures(int32_t flags)
Used by the embedder to specify the features to enable in the accessibility tree generated by the iso...
virtual void SetSemanticsEnabled(bool enabled)
Used by embedder to notify the running isolate hosted by the engine on the UI thread that the accessi...

◆ UpdateSemantics()

void flutter_runner::PlatformView::UpdateSemantics ( flutter::SemanticsNodeUpdates  updates,
flutter::CustomAccessibilityActionUpdates  actions 
)
overrideprotectedvirtual

Used by the framework to tell the embedder to apply the specified semantics node updates. The default implementation of this method does nothing.

See also
SemanticsNode, SemticsNodeUpdates, CustomAccessibilityActionUpdates
Parameters
[in]updatesA map with the stable semantics node identifier as key and the node properties as the value.
[in]actionsA map with the stable semantics node identifier as key and the custom node action as the value.

Reimplemented from flutter::PlatformView.

Definition at line 522 of file platform_view.cc.

References on_semantics_node_update_callback_, and view_pixel_ratio_.

524  {
525  const float pixel_ratio =
526  view_pixel_ratio_.has_value() ? *view_pixel_ratio_ : 0.f;
527 
528  on_semantics_node_update_callback_(update, pixel_ratio);
529 }
std::optional< float > view_pixel_ratio_
OnSemanticsNodeUpdate on_semantics_node_update_callback_

Member Data Documentation

◆ await_vsync_callback_

AwaitVsyncCallback flutter_runner::PlatformView::await_vsync_callback_
protected

Definition at line 222 of file platform_view.h.

Referenced by CreateVSyncWaiter().

◆ await_vsync_for_secondary_callback_callback_

AwaitVsyncForSecondaryCallbackCallback flutter_runner::PlatformView::await_vsync_for_secondary_callback_callback_
protected

Definition at line 224 of file platform_view.h.

Referenced by CreateVSyncWaiter().

◆ current_text_input_client_

int flutter_runner::PlatformView::current_text_input_client_ = 0
protected

◆ down_pointers_

std::set<int> flutter_runner::PlatformView::down_pointers_
protected

Definition at line 205 of file platform_view.h.

Referenced by OnHandlePointerEvent().

◆ external_view_embedder_

std::shared_ptr<flutter::ExternalViewEmbedder> flutter_runner::PlatformView::external_view_embedder_
protected

Definition at line 185 of file platform_view.h.

Referenced by CreateExternalViewEmbedder().

◆ focus_delegate_

std::shared_ptr<FocusDelegate> flutter_runner::PlatformView::focus_delegate_
protected

Definition at line 187 of file platform_view.h.

Referenced by HandleFlutterPlatformViewsChannelPlatformMessage().

◆ ime_

fuchsia::ui::input::InputMethodEditorPtr flutter_runner::PlatformView::ime_
protected

◆ ime_client_

fidl::Binding<fuchsia::ui::input::InputMethodEditorClient> flutter_runner::PlatformView::ime_client_
protected

Definition at line 190 of file platform_view.h.

Referenced by ActivateIme(), and DeactivateIme().

◆ keyboard_

fuchsia::ui::input3::KeyboardPtr flutter_runner::PlatformView::keyboard_
protected

Definition at line 197 of file platform_view.h.

◆ keyboard_listener_binding_

fidl::Binding<fuchsia::ui::input3::KeyboardListener> flutter_runner::PlatformView::keyboard_listener_binding_
protected

Definition at line 196 of file platform_view.h.

◆ keyboard_translator_

Keyboard flutter_runner::PlatformView::keyboard_translator_
protected

Definition at line 198 of file platform_view.h.

Referenced by OnKeyEvent().

◆ last_text_state_

std::unique_ptr<fuchsia::ui::input::TextInputState> flutter_runner::PlatformView::last_text_state_
protected

◆ on_create_surface_callback_

OnCreateSurface flutter_runner::PlatformView::on_create_surface_callback_
protected

Definition at line 218 of file platform_view.h.

Referenced by CreateRenderingSurface().

◆ on_request_announce_callback_

OnRequestAnnounce flutter_runner::PlatformView::on_request_announce_callback_
protected

Definition at line 220 of file platform_view.h.

Referenced by HandleAccessibilityChannelPlatformMessage().

◆ on_semantics_node_update_callback_

OnSemanticsNodeUpdate flutter_runner::PlatformView::on_semantics_node_update_callback_
protected

Definition at line 219 of file platform_view.h.

Referenced by UpdateSemantics().

◆ on_shader_warmup_

OnShaderWarmup flutter_runner::PlatformView::on_shader_warmup_
protected

Definition at line 221 of file platform_view.h.

Referenced by RegisterPlatformMessageHandlers().

◆ on_update_view_callback_

OnUpdateView flutter_runner::PlatformView::on_update_view_callback_
protected

Definition at line 217 of file platform_view.h.

Referenced by HandleFlutterPlatformViewsChannelPlatformMessage().

◆ platform_message_handlers_

std::map<std::string , std::function<bool ( std::unique_ptr< flutter::PlatformMessage> )> > flutter_runner::PlatformView::platform_message_handlers_
protected

Definition at line 210 of file platform_view.h.

Referenced by HandlePlatformMessage(), and RegisterPlatformMessageHandlers().

◆ pointer_delegate_

std::shared_ptr<PointerDelegate> flutter_runner::PlatformView::pointer_delegate_
protected

Definition at line 188 of file platform_view.h.

◆ text_sync_service_

fuchsia::ui::input::ImeServicePtr flutter_runner::PlatformView::text_sync_service_
protected

◆ unregistered_channels_

std::set<std::string > flutter_runner::PlatformView::unregistered_channels_
protected

Definition at line 214 of file platform_view.h.

Referenced by HandlePlatformMessage().

◆ view_logical_origin_

std::optional<std::array<float, 2> > flutter_runner::PlatformView::view_logical_origin_
protected

Definition at line 182 of file platform_view.h.

Referenced by ClampToViewSpace().

◆ view_logical_size_

std::optional<std::array<float, 2> > flutter_runner::PlatformView::view_logical_size_
protected

◆ view_pixel_ratio_

std::optional<float> flutter_runner::PlatformView::view_pixel_ratio_
protected

Definition at line 183 of file platform_view.h.

Referenced by OnHandlePointerEvent(), and UpdateSemantics().

◆ weak_factory_

fml::WeakPtrFactory<PlatformView> flutter_runner::PlatformView::weak_factory_
protected

Definition at line 226 of file platform_view.h.

◆ wireframe_enabled_callback_

OnEnableWireframe flutter_runner::PlatformView::wireframe_enabled_callback_
protected

Definition at line 216 of file platform_view.h.

Referenced by HandleFlutterPlatformViewsChannelPlatformMessage().


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