Flutter Linux Embedder
core_implementations.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // This file contains the implementations of any class in the wrapper that
6 // - is not fully inline, and
7 // - is necessary for all clients of the wrapper (either app or plugin).
8 // It exists instead of the usual structure of having some_class_name.cc files
9 // so that changes to the set of things that need non-header implementations
10 // are not breaking changes for the template.
11 //
12 // If https://github.com/flutter/flutter/issues/57146 is fixed, this can be
13 // removed in favor of the normal structure since templates will no longer
14 // manually include files.
15 
16 #include <cassert>
17 #include <iostream>
18 #include <variant>
19 
20 #include "binary_messenger_impl.h"
22 #include "texture_registrar_impl.h"
23 
24 namespace flutter {
25 
26 // ========== binary_messenger_impl.h ==========
27 
28 namespace {
29 
30 using FlutterDesktopMessengerScopedLock =
31  std::unique_ptr<FlutterDesktopMessenger,
33 
34 // Passes |message| to |user_data|, which must be a BinaryMessageHandler, along
35 // with a BinaryReply that will send a response on |message|'s response handle.
36 //
37 // This serves as an adaptor between the function-pointer-based message callback
38 // interface provided by the C API and the std::function-based message handler
39 // interface of BinaryMessenger.
40 void ForwardToHandler(FlutterDesktopMessengerRef messenger,
41  const FlutterDesktopMessage* message,
42  void* user_data) {
43  auto* response_handle = message->response_handle;
44  auto messenger_ptr = std::shared_ptr<FlutterDesktopMessenger>(
47  BinaryReply reply_handler = [messenger_ptr, response_handle](
48  const uint8_t* reply,
49  size_t reply_size) mutable {
50  // Note: This lambda can be called on any thread.
51  auto lock = FlutterDesktopMessengerScopedLock(
52  FlutterDesktopMessengerLock(messenger_ptr.get()),
54  if (!FlutterDesktopMessengerIsAvailable(messenger_ptr.get())) {
55  // Drop reply if it comes in after the engine is destroyed.
56  return;
57  }
58  if (!response_handle) {
59  std::cerr << "Error: Response can be set only once. Ignoring "
60  "duplicate response."
61  << std::endl;
62  return;
63  }
64  FlutterDesktopMessengerSendResponse(messenger_ptr.get(), response_handle,
65  reply, reply_size);
66  // The engine frees the response handle once
67  // FlutterDesktopSendMessageResponse is called.
68  response_handle = nullptr;
69  };
70 
71  const BinaryMessageHandler& message_handler =
72  *static_cast<BinaryMessageHandler*>(user_data);
73 
74  message_handler(message->message, message->message_size,
75  std::move(reply_handler));
76 }
77 } // namespace
78 
80  FlutterDesktopMessengerRef core_messenger)
81  : messenger_(core_messenger) {}
82 
84 
85 void BinaryMessengerImpl::Send(const std::string& channel,
86  const uint8_t* message,
87  size_t message_size,
88  BinaryReply reply) const {
89  if (reply == nullptr) {
90  FlutterDesktopMessengerSend(messenger_, channel.c_str(), message,
91  message_size);
92  return;
93  }
94  struct Captures {
95  BinaryReply reply;
96  };
97  auto captures = new Captures();
98  captures->reply = reply;
99 
100  auto message_reply = [](const uint8_t* data, size_t data_size,
101  void* user_data) {
102  auto captures = reinterpret_cast<Captures*>(user_data);
103  captures->reply(data, data_size);
104  delete captures;
105  };
107  messenger_, channel.c_str(), message, message_size, message_reply,
108  captures);
109  if (!result) {
110  delete captures;
111  }
112 }
113 
114 void BinaryMessengerImpl::SetMessageHandler(const std::string& channel,
115  BinaryMessageHandler handler) {
116  if (!handler) {
117  handlers_.erase(channel);
118  FlutterDesktopMessengerSetCallback(messenger_, channel.c_str(), nullptr,
119  nullptr);
120  return;
121  }
122  // Save the handler, to keep it alive.
123  handlers_[channel] = std::move(handler);
124  BinaryMessageHandler* message_handler = &handlers_[channel];
125  // Set an adaptor callback that will invoke the handler.
126  FlutterDesktopMessengerSetCallback(messenger_, channel.c_str(),
127  ForwardToHandler, message_handler);
128 }
129 
130 // ========== engine_method_result.h ==========
131 
132 namespace internal {
133 
135  : reply_handler_(std::move(reply_handler)) {
136  assert(reply_handler_);
137 }
138 
140  if (reply_handler_) {
141  // Warn, rather than send a not-implemented response, since the engine may
142  // no longer be valid at this point.
143  std::cerr
144  << "Warning: Failed to respond to a message. This is a memory leak."
145  << std::endl;
146  }
147 }
148 
149 void ReplyManager::SendResponseData(const std::vector<uint8_t>* data) {
150  if (!reply_handler_) {
151  std::cerr
152  << "Error: Only one of Success, Error, or NotImplemented can be "
153  "called,"
154  << " and it can be called exactly once. Ignoring duplicate result."
155  << std::endl;
156  return;
157  }
158 
159  const uint8_t* message = data && !data->empty() ? data->data() : nullptr;
160  size_t message_size = data ? data->size() : 0;
161  reply_handler_(message, message_size);
162  reply_handler_ = nullptr;
163 }
164 
165 } // namespace internal
166 
167 // ========== texture_registrar_impl.h ==========
168 
170  FlutterDesktopTextureRegistrarRef texture_registrar_ref)
171  : texture_registrar_ref_(texture_registrar_ref) {}
172 
174 
176  FlutterDesktopTextureInfo info = {};
177  if (auto pixel_buffer_texture = std::get_if<PixelBufferTexture>(texture)) {
179  info.pixel_buffer_config.user_data = pixel_buffer_texture;
181  [](size_t width, size_t height,
182  void* user_data) -> const FlutterDesktopPixelBuffer* {
183  auto texture = static_cast<PixelBufferTexture*>(user_data);
184  return texture->CopyPixelBuffer(width, height);
185  };
186  } else if (auto gpu_surface_texture =
187  std::get_if<GpuSurfaceTexture>(texture)) {
191  info.gpu_surface_config.type = gpu_surface_texture->surface_type();
192  info.gpu_surface_config.user_data = gpu_surface_texture;
194  [](size_t width, size_t height,
196  auto texture = static_cast<GpuSurfaceTexture*>(user_data);
197  return texture->ObtainDescriptor(width, height);
198  };
199  } else {
200  std::cerr << "Attempting to register unknown texture variant." << std::endl;
201  return -1;
202  }
203 
205  texture_registrar_ref_, &info);
206  return texture_id;
207 } // namespace flutter
208 
211  texture_registrar_ref_, texture_id);
212 }
213 
215  std::function<void()> callback) {
216  if (callback == nullptr) {
218  texture_registrar_ref_, texture_id, nullptr, nullptr);
219  return;
220  }
221 
222  struct Captures {
223  std::function<void()> callback;
224  };
225  auto captures = new Captures();
226  captures->callback = std::move(callback);
228  texture_registrar_ref_, texture_id,
229  [](void* opaque) {
230  auto captures = reinterpret_cast<Captures*>(opaque);
231  captures->callback();
232  delete captures;
233  },
234  captures);
235 }
236 
238  UnregisterTexture(texture_id, nullptr);
239  return true;
240 }
241 
242 } // namespace flutter
flutter::internal::ReplyManager::ReplyManager
ReplyManager(BinaryReply reply_handler_)
Definition: core_implementations.cc:134
flutter::TextureRegistrarImpl::TextureRegistrarImpl
TextureRegistrarImpl(FlutterDesktopTextureRegistrarRef texture_registrar_ref)
Definition: core_implementations.cc:169
engine_method_result.h
FlutterDesktopMessengerAddRef
FLUTTER_EXPORT FlutterDesktopMessengerRef FlutterDesktopMessengerAddRef(FlutterDesktopMessengerRef messenger)
FlutterDesktopMessengerUnlock
FLUTTER_EXPORT void FlutterDesktopMessengerUnlock(FlutterDesktopMessengerRef messenger)
flutter::BinaryMessengerImpl::BinaryMessengerImpl
BinaryMessengerImpl(FlutterDesktopMessengerRef core_messenger)
Definition: core_implementations.cc:79
kFlutterDesktopGpuSurfaceTexture
@ kFlutterDesktopGpuSurfaceTexture
Definition: flutter_texture_registrar.h:28
FlutterDesktopTextureRegistrarRegisterExternalTexture
FLUTTER_EXPORT int64_t FlutterDesktopTextureRegistrarRegisterExternalTexture(FlutterDesktopTextureRegistrarRef texture_registrar, const FlutterDesktopTextureInfo *info)
FlutterDesktopPixelBuffer
Definition: flutter_texture_registrar.h:56
flutter::TextureRegistrarImpl::MarkTextureFrameAvailable
bool MarkTextureFrameAvailable(int64_t texture_id) override
Definition: core_implementations.cc:209
FlutterDesktopMessengerSendWithReply
FLUTTER_EXPORT bool FlutterDesktopMessengerSendWithReply(FlutterDesktopMessengerRef messenger, const char *channel, const uint8_t *message, const size_t message_size, const FlutterDesktopBinaryReply reply, void *user_data)
FlutterDesktopPixelBufferTextureConfig::user_data
void * user_data
Definition: flutter_texture_registrar.h:134
user_data
FlKeyEvent uint64_t FlKeyResponderAsyncCallback gpointer user_data
Definition: fl_key_channel_responder.cc:121
height
G_BEGIN_DECLS int height
Definition: fl_backing_store_provider.h:37
FlutterDesktopGpuSurfaceTextureConfig::user_data
void * user_data
Definition: flutter_texture_registrar.h:148
flutter::BinaryMessengerImpl::~BinaryMessengerImpl
virtual ~BinaryMessengerImpl()
FlutterDesktopPixelBufferTextureConfig::callback
FlutterDesktopPixelBufferTextureCallback callback
Definition: flutter_texture_registrar.h:132
flutter::GpuSurfaceTexture
Definition: texture_registrar.h:47
FlutterDesktopTextureInfo::type
FlutterDesktopTextureType type
Definition: flutter_texture_registrar.h:152
FlutterDesktopMessengerSetCallback
FLUTTER_EXPORT void FlutterDesktopMessengerSetCallback(FlutterDesktopMessengerRef messenger, const char *channel, FlutterDesktopMessageCallback callback, void *user_data)
FlutterDesktopMessage::message_size
size_t message_size
Definition: flutter_messenger.h:39
FlutterDesktopTextureRegistrarRef
struct FlutterDesktopTextureRegistrar * FlutterDesktopTextureRegistrarRef
Definition: flutter_texture_registrar.h:19
FlutterDesktopGpuSurfaceTextureConfig::struct_size
size_t struct_size
Definition: flutter_texture_registrar.h:141
FlutterDesktopTextureInfo::pixel_buffer_config
FlutterDesktopPixelBufferTextureConfig pixel_buffer_config
Definition: flutter_texture_registrar.h:154
flutter::BinaryReply
std::function< void(const uint8_t *reply, size_t reply_size)> BinaryReply
Definition: binary_messenger.h:17
FlutterDesktopGpuSurfaceTextureConfig::type
FlutterDesktopGpuSurfaceType type
Definition: flutter_texture_registrar.h:144
flutter::PixelBufferTexture::CopyPixelBuffer
const FlutterDesktopPixelBuffer * CopyPixelBuffer(size_t width, size_t height) const
Definition: texture_registrar.h:37
FlutterDesktopTextureInfo
Definition: flutter_texture_registrar.h:151
FlutterDesktopMessengerRelease
FLUTTER_EXPORT void FlutterDesktopMessengerRelease(FlutterDesktopMessengerRef messenger)
FlutterDesktopGpuSurfaceTextureConfig::callback
FlutterDesktopGpuSurfaceTextureCallback callback
Definition: flutter_texture_registrar.h:146
flutter::TextureVariant
std::variant< PixelBufferTexture, GpuSurfaceTexture > TextureVariant
Definition: texture_registrar.h:79
FlutterDesktopMessengerSendResponse
FLUTTER_EXPORT void FlutterDesktopMessengerSendResponse(FlutterDesktopMessengerRef messenger, const FlutterDesktopMessageResponseHandle *handle, const uint8_t *data, size_t data_length)
binary_messenger_impl.h
flutter::internal::ReplyManager::~ReplyManager
~ReplyManager()
Definition: core_implementations.cc:139
flutter
Definition: accessibility_bridge.cc:14
FlutterDesktopGpuSurfaceDescriptor
Definition: flutter_texture_registrar.h:70
flutter::TextureRegistrarImpl::~TextureRegistrarImpl
virtual ~TextureRegistrarImpl()
flutter::PixelBufferTexture
Definition: texture_registrar.h:19
flutter::TextureRegistrarImpl::UnregisterTexture
void UnregisterTexture(int64_t texture_id, std::function< void()> callback) override
Definition: core_implementations.cc:214
FlutterDesktopTextureInfo::gpu_surface_config
FlutterDesktopGpuSurfaceTextureConfig gpu_surface_config
Definition: flutter_texture_registrar.h:155
FlutterDesktopMessengerLock
FLUTTER_EXPORT FlutterDesktopMessengerRef FlutterDesktopMessengerLock(FlutterDesktopMessengerRef messenger)
flutter::BinaryMessengerImpl::SetMessageHandler
void SetMessageHandler(const std::string &channel, BinaryMessageHandler handler) override
Definition: core_implementations.cc:114
result
GAsyncResult * result
Definition: fl_text_input_plugin.cc:106
FlutterDesktopMessengerSend
FLUTTER_EXPORT bool FlutterDesktopMessengerSend(FlutterDesktopMessengerRef messenger, const char *channel, const uint8_t *message, const size_t message_size)
FlutterDesktopTextureRegistrarUnregisterExternalTexture
FLUTTER_EXPORT void FlutterDesktopTextureRegistrarUnregisterExternalTexture(FlutterDesktopTextureRegistrarRef texture_registrar, int64_t texture_id, void(*callback)(void *user_data), void *user_data)
FlutterDesktopMessengerRef
struct FlutterDesktopMessenger * FlutterDesktopMessengerRef
Definition: flutter_messenger.h:19
FlutterDesktopMessage
Definition: flutter_messenger.h:31
FlutterDesktopGpuSurfaceTextureConfig
Definition: flutter_texture_registrar.h:138
flutter::internal::ReplyManager::SendResponseData
void SendResponseData(const std::vector< uint8_t > *data)
Definition: core_implementations.cc:149
FlutterDesktopTextureRegistrarMarkExternalTextureFrameAvailable
FLUTTER_EXPORT bool FlutterDesktopTextureRegistrarMarkExternalTextureFrameAvailable(FlutterDesktopTextureRegistrarRef texture_registrar, int64_t texture_id)
flutter::TextureRegistrarImpl::RegisterTexture
int64_t RegisterTexture(TextureVariant *texture) override
Definition: core_implementations.cc:175
texture_registrar_impl.h
flutter::BinaryMessageHandler
std::function< void(const uint8_t *message, size_t message_size, BinaryReply reply)> BinaryMessageHandler
Definition: binary_messenger.h:24
flutter::GpuSurfaceTexture::ObtainDescriptor
const FlutterDesktopGpuSurfaceDescriptor * ObtainDescriptor(size_t width, size_t height) const
Definition: texture_registrar.h:62
callback
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
Definition: fl_key_channel_responder.cc:120
FlutterDesktopMessage::response_handle
const FlutterDesktopMessageResponseHandle * response_handle
Definition: flutter_messenger.h:42
FlutterDesktopMessengerIsAvailable
FLUTTER_EXPORT bool FlutterDesktopMessengerIsAvailable(FlutterDesktopMessengerRef messenger)
FlutterDesktopMessage::message
const uint8_t * message
Definition: flutter_messenger.h:37
texture_id
int64_t texture_id
Definition: texture_registrar_unittests.cc:24
width
const uint8_t uint32_t * width
Definition: fl_pixel_buffer_texture_test.cc:38
kFlutterDesktopPixelBufferTexture
@ kFlutterDesktopPixelBufferTexture
Definition: flutter_texture_registrar.h:26
flutter::BinaryMessengerImpl::Send
void Send(const std::string &channel, const uint8_t *message, size_t message_size, BinaryReply reply) const override
Definition: core_implementations.cc:85