Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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
12#include "binary_messenger.h"
14#include "method_call.h"
15#include "method_codec.h"
16#include "method_result.h"
17
18namespace flutter {
19
20class 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.
26template <typename T>
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.
33template <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;
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_
virtual void Send(const std::string &channel, const uint8_t *message, size_t message_size, BinaryReply reply=nullptr) const =0
virtual void SetMessageHandler(const std::string &channel, BinaryMessageHandler handler)=0
void SetMethodCallHandler(MethodCallHandler< T > handler) const
MethodChannel & operator=(MethodChannel const &)=delete
void Resize(int new_size)
MethodChannel(BinaryMessenger *messenger, const std::string &name, const MethodCodec< T > *codec)
void InvokeMethod(const std::string &method, std::unique_ptr< T > arguments, std::unique_ptr< MethodResult< T > > result=nullptr)
void SetWarnsOnOverflow(bool warns)
MethodChannel(MethodChannel const &)=delete
G_BEGIN_DECLS G_MODULE_EXPORT FlMethodCall * method_call
GAsyncResult * result
Win32Message message
void SetChannelWarnsOnOverflow(BinaryMessenger *messenger, std::string name, bool warns)
void ResizeChannel(BinaryMessenger *messenger, std::string name, int new_size)
std::function< void(const uint8_t *message, size_t message_size, BinaryReply reply)> BinaryMessageHandler
std::function< void(const uint8_t *reply, size_t reply_size)> BinaryReply
DEF_SWITCHES_START aot vmservice shared library name
Definition switches.h:32
std::function< void(const MethodCall< T > &call, std::unique_ptr< MethodResult< T > > result)> MethodCallHandler