| Flutter iOS 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"
21 #include "include/flutter/engine_method_result.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,
32 decltype(&FlutterDesktopMessengerUnlock)>;
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>(
45 FlutterDesktopMessengerAddRef(messenger),
46 &FlutterDesktopMessengerRelease);
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()),
53 &FlutterDesktopMessengerUnlock);
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
79 BinaryMessengerImpl::BinaryMessengerImpl(
80 FlutterDesktopMessengerRef core_messenger)
81 : messenger_(core_messenger) {}
82
83 BinaryMessengerImpl::~BinaryMessengerImpl() = default;
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 };
106 bool result = FlutterDesktopMessengerSendWithReply(
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
134 ReplyManager::ReplyManager(BinaryReply reply_handler)
135 : reply_handler_(std::move(reply_handler)) {
136 assert(reply_handler_);
137 }
138
139 ReplyManager::~ReplyManager() {
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
169 TextureRegistrarImpl::TextureRegistrarImpl(
170 FlutterDesktopTextureRegistrarRef texture_registrar_ref)
171 : texture_registrar_ref_(texture_registrar_ref) {}
172
173 TextureRegistrarImpl::~TextureRegistrarImpl() = default;
174
175 int64_t TextureRegistrarImpl::RegisterTexture(TextureVariant* texture) {
176 FlutterDesktopTextureInfo info = {};
177 if (auto pixel_buffer_texture = std::get_if<PixelBufferTexture>(texture)) {
178 info.type = kFlutterDesktopPixelBufferTexture;
179 info.pixel_buffer_config.user_data = pixel_buffer_texture;
180 info.pixel_buffer_config.callback =
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)) {
188 info.type = kFlutterDesktopGpuSurfaceTexture;
189 info.gpu_surface_config.struct_size =
190 sizeof(FlutterDesktopGpuSurfaceTextureConfig);
191 info.gpu_surface_config.type = gpu_surface_texture->surface_type();
192 info.gpu_surface_config.user_data = gpu_surface_texture;
193 info.gpu_surface_config.callback =
194 [](size_t width, size_t height,
195 void* user_data) -> const FlutterDesktopGpuSurfaceDescriptor* {
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
204 int64_t texture_id = FlutterDesktopTextureRegistrarRegisterExternalTexture(
205 texture_registrar_ref_, &info);
206 return texture_id;
207 } // namespace flutter
208
209 bool TextureRegistrarImpl::MarkTextureFrameAvailable(int64_t texture_id) {
210 return FlutterDesktopTextureRegistrarMarkExternalTextureFrameAvailable(
211 texture_registrar_ref_, texture_id);
212 }
213
214 void TextureRegistrarImpl::UnregisterTexture(int64_t texture_id,
215 std::function<void()> callback) {
216 if (callback == nullptr) {
217 FlutterDesktopTextureRegistrarUnregisterExternalTexture(
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);
227 FlutterDesktopTextureRegistrarUnregisterExternalTexture(
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
237 bool TextureRegistrarImpl::UnregisterTexture(int64_t texture_id) {
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)
user_data
void * user_data
Definition: texture_registrar_unittests.cc:27
FlutterDesktopPixelBufferTextureConfig::user_data
void * user_data
Definition: flutter_texture_registrar.h:134
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.h:28
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
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
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
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