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 
19 #include "binary_messenger_impl.h"
21 
22 namespace flutter {
23 
24 // ========== binary_messenger_impl.h ==========
25 
26 namespace {
27 // Passes |message| to |user_data|, which must be a BinaryMessageHandler, along
28 // with a BinaryReply that will send a response on |message|'s response handle.
29 //
30 // This serves as an adaptor between the function-pointer-based message callback
31 // interface provided by the C API and the std::function-based message handler
32 // interface of BinaryMessenger.
33 void ForwardToHandler(FlutterDesktopMessengerRef messenger,
34  const FlutterDesktopMessage* message,
35  void* user_data) {
36  auto* response_handle = message->response_handle;
37  BinaryReply reply_handler = [messenger, response_handle](
38  const uint8_t* reply,
39  size_t reply_size) mutable {
40  if (!response_handle) {
41  std::cerr << "Error: Response can be set only once. Ignoring "
42  "duplicate response."
43  << std::endl;
44  return;
45  }
46  FlutterDesktopMessengerSendResponse(messenger, response_handle, reply,
47  reply_size);
48  // The engine frees the response handle once
49  // FlutterDesktopSendMessageResponse is called.
50  response_handle = nullptr;
51  };
52 
53  const BinaryMessageHandler& message_handler =
54  *static_cast<BinaryMessageHandler*>(user_data);
55 
56  message_handler(message->message, message->message_size,
57  std::move(reply_handler));
58 }
59 } // namespace
60 
62  FlutterDesktopMessengerRef core_messenger)
63  : messenger_(core_messenger) {}
64 
66 
67 void BinaryMessengerImpl::Send(const std::string& channel,
68  const uint8_t* message,
69  size_t message_size,
70  BinaryReply reply) const {
71  if (reply == nullptr) {
72  FlutterDesktopMessengerSend(messenger_, channel.c_str(), message,
73  message_size);
74  return;
75  }
76  struct Captures {
77  BinaryReply reply;
78  };
79  auto captures = new Captures();
80  captures->reply = reply;
81 
82  auto message_reply = [](const uint8_t* data, size_t data_size,
83  void* user_data) {
84  auto captures = reinterpret_cast<Captures*>(user_data);
85  captures->reply(data, data_size);
86  delete captures;
87  };
89  messenger_, channel.c_str(), message, message_size, message_reply,
90  captures);
91  if (!result) {
92  delete captures;
93  }
94 }
95 
96 void BinaryMessengerImpl::SetMessageHandler(const std::string& channel,
97  BinaryMessageHandler handler) {
98  if (!handler) {
99  handlers_.erase(channel);
100  FlutterDesktopMessengerSetCallback(messenger_, channel.c_str(), nullptr,
101  nullptr);
102  return;
103  }
104  // Save the handler, to keep it alive.
105  handlers_[channel] = std::move(handler);
106  BinaryMessageHandler* message_handler = &handlers_[channel];
107  // Set an adaptor callback that will invoke the handler.
108  FlutterDesktopMessengerSetCallback(messenger_, channel.c_str(),
109  ForwardToHandler, message_handler);
110 }
111 
112 // ========== engine_method_result.h ==========
113 
114 namespace internal {
115 
116 ReplyManager::ReplyManager(BinaryReply reply_handler)
117  : reply_handler_(std::move(reply_handler)) {
118  assert(reply_handler_);
119 }
120 
122  if (reply_handler_) {
123  // Warn, rather than send a not-implemented response, since the engine may
124  // no longer be valid at this point.
125  std::cerr
126  << "Warning: Failed to respond to a message. This is a memory leak."
127  << std::endl;
128  }
129 }
130 
131 void ReplyManager::SendResponseData(const std::vector<uint8_t>* data) {
132  if (!reply_handler_) {
133  std::cerr
134  << "Error: Only one of Success, Error, or NotImplemented can be "
135  "called,"
136  << " and it can be called exactly once. Ignoring duplicate result."
137  << std::endl;
138  return;
139  }
140 
141  const uint8_t* message = data && !data->empty() ? data->data() : nullptr;
142  size_t message_size = data ? data->size() : 0;
143  reply_handler_(message, message_size);
144  reply_handler_ = nullptr;
145 }
146 
147 } // namespace internal
148 
149 } // namespace flutter
void SetMessageHandler(const std::string &channel, BinaryMessageHandler handler) override
Definition: ref_ptr.h:252
const FlutterDesktopMessageResponseHandle * response_handle
std::function< void(const uint8_t *reply, size_t reply_size)> BinaryReply
bool FlutterDesktopMessengerSendWithReply(FlutterDesktopMessengerRef messenger, const char *channel, const uint8_t *message, const size_t message_size, const FlutterDesktopBinaryReply reply, void *user_data)
void FlutterDesktopMessengerSendResponse(FlutterDesktopMessengerRef messenger, const FlutterDesktopMessageResponseHandle *handle, const uint8_t *data, size_t data_length)
G_BEGIN_DECLS FlMethodCall gpointer user_data
const uint8_t * message
void SendResponseData(const std::vector< uint8_t > *data)
BinaryMessengerImpl(FlutterDesktopMessengerRef core_messenger)
void FlutterDesktopMessengerSetCallback(FlutterDesktopMessengerRef messenger, const char *channel, FlutterDesktopMessageCallback callback, void *user_data)
void Send(const std::string &channel, const uint8_t *message, size_t message_size, BinaryReply reply) const override
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)