Flutter Engine
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 // Passes |message| to |user_data|, which must be a BinaryMessageHandler, along
30 // with a BinaryReply that will send a response on |message|'s response handle.
31 //
32 // This serves as an adaptor between the function-pointer-based message callback
33 // interface provided by the C API and the std::function-based message handler
34 // interface of BinaryMessenger.
35 void ForwardToHandler(FlutterDesktopMessengerRef messenger,
36  const FlutterDesktopMessage* message,
37  void* user_data) {
38  auto* response_handle = message->response_handle;
39  BinaryReply reply_handler = [messenger, response_handle](
40  const uint8_t* reply,
41  size_t reply_size) mutable {
42  if (!response_handle) {
43  std::cerr << "Error: Response can be set only once. Ignoring "
44  "duplicate response."
45  << std::endl;
46  return;
47  }
48  FlutterDesktopMessengerSendResponse(messenger, response_handle, reply,
49  reply_size);
50  // The engine frees the response handle once
51  // FlutterDesktopSendMessageResponse is called.
52  response_handle = nullptr;
53  };
54 
55  const BinaryMessageHandler& message_handler =
56  *static_cast<BinaryMessageHandler*>(user_data);
57 
58  message_handler(message->message, message->message_size,
59  std::move(reply_handler));
60 }
61 } // namespace
62 
64  FlutterDesktopMessengerRef core_messenger)
65  : messenger_(core_messenger) {}
66 
68 
69 void BinaryMessengerImpl::Send(const std::string& channel,
70  const uint8_t* message,
71  size_t message_size,
72  BinaryReply reply) const {
73  if (reply == nullptr) {
74  FlutterDesktopMessengerSend(messenger_, channel.c_str(), message,
75  message_size);
76  return;
77  }
78  struct Captures {
79  BinaryReply reply;
80  };
81  auto captures = new Captures();
82  captures->reply = reply;
83 
84  auto message_reply = [](const uint8_t* data, size_t data_size,
85  void* user_data) {
86  auto captures = reinterpret_cast<Captures*>(user_data);
87  captures->reply(data, data_size);
88  delete captures;
89  };
91  messenger_, channel.c_str(), message, message_size, message_reply,
92  captures);
93  if (!result) {
94  delete captures;
95  }
96 }
97 
98 void BinaryMessengerImpl::SetMessageHandler(const std::string& channel,
99  BinaryMessageHandler handler) {
100  if (!handler) {
101  handlers_.erase(channel);
102  FlutterDesktopMessengerSetCallback(messenger_, channel.c_str(), nullptr,
103  nullptr);
104  return;
105  }
106  // Save the handler, to keep it alive.
107  handlers_[channel] = std::move(handler);
108  BinaryMessageHandler* message_handler = &handlers_[channel];
109  // Set an adaptor callback that will invoke the handler.
110  FlutterDesktopMessengerSetCallback(messenger_, channel.c_str(),
111  ForwardToHandler, message_handler);
112 }
113 
114 // ========== engine_method_result.h ==========
115 
116 namespace internal {
117 
118 ReplyManager::ReplyManager(BinaryReply reply_handler)
119  : reply_handler_(std::move(reply_handler)) {
120  assert(reply_handler_);
121 }
122 
124  if (reply_handler_) {
125  // Warn, rather than send a not-implemented response, since the engine may
126  // no longer be valid at this point.
127  std::cerr
128  << "Warning: Failed to respond to a message. This is a memory leak."
129  << std::endl;
130  }
131 }
132 
133 void ReplyManager::SendResponseData(const std::vector<uint8_t>* data) {
134  if (!reply_handler_) {
135  std::cerr
136  << "Error: Only one of Success, Error, or NotImplemented can be "
137  "called,"
138  << " and it can be called exactly once. Ignoring duplicate result."
139  << std::endl;
140  return;
141  }
142 
143  const uint8_t* message = data && !data->empty() ? data->data() : nullptr;
144  size_t message_size = data ? data->size() : 0;
145  reply_handler_(message, message_size);
146  reply_handler_ = nullptr;
147 }
148 
149 } // namespace internal
150 
151 // ========== texture_registrar_impl.h ==========
152 
154  FlutterDesktopTextureRegistrarRef texture_registrar_ref)
155  : texture_registrar_ref_(texture_registrar_ref) {}
156 
158 
160  if (auto pixel_buffer_texture = std::get_if<PixelBufferTexture>(texture)) {
161  FlutterDesktopTextureInfo info = {};
163  info.pixel_buffer_config.user_data = pixel_buffer_texture;
165  [](size_t width, size_t height,
166  void* user_data) -> const FlutterDesktopPixelBuffer* {
167  auto texture = static_cast<PixelBufferTexture*>(user_data);
168  auto buffer = texture->CopyPixelBuffer(width, height);
169  return buffer;
170  };
171 
173  texture_registrar_ref_, &info);
174  return texture_id;
175  }
176 
177  std::cerr << "Attempting to register unknown texture variant." << std::endl;
178  return -1;
179 } // namespace flutter
180 
183  texture_registrar_ref_, texture_id);
184 }
185 
188  texture_registrar_ref_, texture_id);
189 }
190 
191 } // namespace flutter
int64_t FlutterDesktopTextureRegistrarRegisterExternalTexture(FlutterDesktopTextureRegistrarRef texture_registrar, const FlutterDesktopTextureInfo *info)
G_BEGIN_DECLS FlTexture * texture
FlutterDesktopPixelBufferTextureConfig pixel_buffer_config
int64_t RegisterTexture(TextureVariant *texture) override
bool FlutterDesktopTextureRegistrarUnregisterExternalTexture(FlutterDesktopTextureRegistrarRef texture_registrar, int64_t texture_id)
void SetMessageHandler(const std::string &channel, BinaryMessageHandler handler) override
void * user_data
Definition: ref_ptr.h:252
int64_t texture_id
GAsyncResult * result
bool UnregisterTexture(int64_t texture_id) override
const FlutterDesktopMessageResponseHandle * response_handle
std::function< void(const uint8_t *reply, size_t reply_size)> BinaryReply
struct FlutterDesktopTextureRegistrar * FlutterDesktopTextureRegistrarRef
bool FlutterDesktopMessengerSendWithReply(FlutterDesktopMessengerRef messenger, const char *channel, const uint8_t *message, const size_t message_size, const FlutterDesktopBinaryReply reply, void *user_data)
FlutterDesktopTextureType type
FlutterDesktopPixelBufferTextureCallback callback
TextureRegistrarImpl(FlutterDesktopTextureRegistrarRef texture_registrar_ref)
int32_t width
void FlutterDesktopMessengerSendResponse(FlutterDesktopMessengerRef messenger, const FlutterDesktopMessageResponseHandle *handle, const uint8_t *data, size_t data_length)
const uint8_t * message
void SendResponseData(const std::vector< uint8_t > *data)
int32_t height
static const uint8_t buffer[]
bool MarkTextureFrameAvailable(int64_t texture_id) override
BinaryMessengerImpl(FlutterDesktopMessengerRef core_messenger)
void FlutterDesktopMessengerSetCallback(FlutterDesktopMessengerRef messenger, const char *channel, FlutterDesktopMessageCallback callback, void *user_data)
std::variant< PixelBufferTexture > TextureVariant
void Send(const std::string &channel, const uint8_t *message, size_t message_size, BinaryReply reply) const override
bool FlutterDesktopTextureRegistrarMarkExternalTextureFrameAvailable(FlutterDesktopTextureRegistrarRef texture_registrar, int64_t texture_id)
std::function< void(const uint8_t *message, size_t message_size, BinaryReply reply)> BinaryMessageHandler
bool FlutterDesktopMessengerSend(FlutterDesktopMessengerRef messenger, const char *channel, const uint8_t *message, const size_t message_size)