Flutter Linux Embedder
method_channel.h
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 #ifndef FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_METHOD_CHANNEL_H_
6 #define FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_METHOD_CHANNEL_H_
7 
8 #include <iostream>
9 #include <string>
10 
11 #include "basic_message_channel.h"
12 #include "binary_messenger.h"
13 #include "engine_method_result.h"
14 #include "method_call.h"
15 #include "method_codec.h"
16 #include "method_result.h"
17 
18 namespace flutter {
19 
20 class EncodableValue;
21 
22 // A handler for receiving a method call from the Flutter engine.
23 //
24 // Implementations must asynchronously call exactly one of the methods on
25 // |result| to indicate the result of the method call.
26 template <typename T>
27 using MethodCallHandler =
28  std::function<void(const MethodCall<T>& call,
29  std::unique_ptr<MethodResult<T>> result)>;
30 
31 // A channel for communicating with the Flutter engine using invocation of
32 // asynchronous methods.
33 template <typename T = EncodableValue>
35  public:
36  // Creates an instance that sends and receives method calls on the channel
37  // named |name|, encoded with |codec| and dispatched via |messenger|.
39  const std::string& name,
40  const MethodCodec<T>* codec)
41  : messenger_(messenger), name_(name), codec_(codec) {}
42 
43  ~MethodChannel() = default;
44 
45  // Prevent copying.
46  MethodChannel(MethodChannel const&) = delete;
47  MethodChannel& operator=(MethodChannel const&) = delete;
48 
49  // Sends a message to the Flutter engine on this channel.
50  //
51  // If |result| is provided, one of its methods will be invoked with the
52  // response from the engine.
53  void InvokeMethod(const std::string& method,
54  std::unique_ptr<T> arguments,
55  std::unique_ptr<MethodResult<T>> result = nullptr) {
56  MethodCall<T> method_call(method, std::move(arguments));
57  std::unique_ptr<std::vector<uint8_t>> message =
58  codec_->EncodeMethodCall(method_call);
59  if (!result) {
60  messenger_->Send(name_, message->data(), message->size(), nullptr);
61  return;
62  }
63 
64  // std::function requires a copyable lambda, so convert to a shared pointer.
65  // This is safe since only one copy of the shared_pointer will ever be
66  // accessed.
67  std::shared_ptr<MethodResult<T>> shared_result(result.release());
68  const auto* codec = codec_;
69  std::string channel_name = name_;
70  BinaryReply reply_handler = [shared_result, codec, channel_name](
71  const uint8_t* reply, size_t reply_size) {
72  if (reply_size == 0) {
73  shared_result->NotImplemented();
74  return;
75  }
76  // Use this channel's codec to decode and handle the
77  // reply.
78  bool decoded = codec->DecodeAndProcessResponseEnvelope(
79  reply, reply_size, shared_result.get());
80  if (!decoded) {
81  std::cerr << "Unable to decode reply to method "
82  "invocation on channel "
83  << channel_name << std::endl;
84  shared_result->NotImplemented();
85  }
86  };
87 
88  messenger_->Send(name_, message->data(), message->size(),
89  std::move(reply_handler));
90  }
91 
92  // Registers a handler that should be called any time a method call is
93  // received on this channel. A null handler will remove any previous handler.
94  //
95  // The handler will be owned by the underlying BinaryMessageHandler.
96  // Destroying the MethodChannel will not unregister the handler, so
97  // the caller is responsible for unregistering explicitly if the handler
98  // stops being valid before the engine is destroyed.
100  if (!handler) {
101  messenger_->SetMessageHandler(name_, nullptr);
102  return;
103  }
104  const auto* codec = codec_;
105  std::string channel_name = name_;
106  BinaryMessageHandler binary_handler = [handler, codec, channel_name](
107  const uint8_t* message,
108  size_t message_size,
109  BinaryReply reply) {
110  // Use this channel's codec to decode the call and build a result handler.
111  auto result =
112  std::make_unique<EngineMethodResult<T>>(std::move(reply), codec);
113  std::unique_ptr<MethodCall<T>> method_call =
114  codec->DecodeMethodCall(message, message_size);
115  if (!method_call) {
116  std::cerr << "Unable to construct method call from message on channel "
117  << channel_name << std::endl;
118  result->NotImplemented();
119  return;
120  }
121  handler(*method_call, std::move(result));
122  };
123  messenger_->SetMessageHandler(name_, std::move(binary_handler));
124  }
125 
126  // Adjusts the number of messages that will get buffered when sending messages
127  // to channels that aren't fully set up yet. For example, the engine isn't
128  // running yet or the channel's message handler isn't set up on the Dart side
129  // yet.
130  void Resize(int new_size) {
131  internal::ResizeChannel(messenger_, name_, new_size);
132  }
133 
134  // Defines whether the channel should show warning messages when discarding
135  // messages due to overflow.
136  //
137  // When |warns| is false, the channel is expected to overflow and warning
138  // messages will not be shown.
139  void SetWarnsOnOverflow(bool warns) {
140  internal::SetChannelWarnsOnOverflow(messenger_, name_, warns);
141  }
142 
143  private:
144  BinaryMessenger* messenger_;
145  std::string name_;
146  const MethodCodec<T>* codec_;
147 };
148 
149 } // namespace flutter
150 
151 #endif // FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_METHOD_CHANNEL_H_
engine_method_result.h
flutter::MethodChannel
Definition: method_channel.h:34
flutter::MethodChannel::~MethodChannel
~MethodChannel()=default
method_codec.h
flutter::MethodChannel::operator=
MethodChannel & operator=(MethodChannel const &)=delete
flutter::MethodChannel::InvokeMethod
void InvokeMethod(const std::string &method, std::unique_ptr< T > arguments, std::unique_ptr< MethodResult< T >> result=nullptr)
Definition: method_channel.h:53
flutter::MethodCallHandler
std::function< void(const MethodCall< T > &call, std::unique_ptr< MethodResult< T > > result)> MethodCallHandler
Definition: method_channel.h:29
binary_messenger.h
method_result.h
flutter::BinaryMessenger
Definition: binary_messenger.h:28
flutter::BinaryMessenger::SetMessageHandler
virtual void SetMessageHandler(const std::string &channel, BinaryMessageHandler handler)=0
flutter::MethodChannel::SetMethodCallHandler
void SetMethodCallHandler(MethodCallHandler< T > handler) const
Definition: method_channel.h:99
flutter::MethodCall
Definition: method_call.h:18
method_call
G_BEGIN_DECLS G_MODULE_EXPORT FlMethodCall * method_call
Definition: fl_method_channel.h:120
flutter::BinaryReply
std::function< void(const uint8_t *reply, size_t reply_size)> BinaryReply
Definition: binary_messenger.h:17
flutter::internal::ResizeChannel
void ResizeChannel(BinaryMessenger *messenger, std::string name, int new_size)
Definition: core_implementations.cc:181
flutter
Definition: accessibility_bridge.cc:14
flutter::MethodChannel::SetWarnsOnOverflow
void SetWarnsOnOverflow(bool warns)
Definition: method_channel.h:139
flutter::MethodChannel::Resize
void Resize(int new_size)
Definition: method_channel.h:130
basic_message_channel.h
flutter::internal::SetChannelWarnsOnOverflow
void SetChannelWarnsOnOverflow(BinaryMessenger *messenger, std::string name, bool warns)
Definition: core_implementations.cc:194
result
GAsyncResult * result
Definition: fl_text_input_plugin.cc:106
flutter::MethodChannel::MethodChannel
MethodChannel(BinaryMessenger *messenger, const std::string &name, const MethodCodec< T > *codec)
Definition: method_channel.h:38
flutter::MethodResult
Definition: method_result.h:17
flutter::MethodCodec
Definition: method_codec.h:20
flutter::BinaryMessenger::Send
virtual void Send(const std::string &channel, const uint8_t *message, size_t message_size, BinaryReply reply=nullptr) const =0
flutter::BinaryMessageHandler
std::function< void(const uint8_t *message, size_t message_size, BinaryReply reply)> BinaryMessageHandler
Definition: binary_messenger.h:24
method_call.h