Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
event_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_EVENT_CHANNEL_H_
6#define FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_EVENT_CHANNEL_H_
7
8#include <iostream>
9#include <memory>
10#include <string>
11
12#include "binary_messenger.h"
14#include "event_sink.h"
16
17namespace flutter {
18
19class EncodableValue;
20
21// A named channel for communicating with the Flutter application using
22// asynchronous event streams. Incoming requests for event stream setup are
23// decoded from binary on receipt, and C++ responses and events are encoded into
24// binary before being transmitted back to Flutter. The MethodCodec used must be
25// compatible with the one used by the Flutter application. This can be achieved
26// by creating an EventChannel
27// ("https://api.flutter.dev/flutter/services/EventChannel-class.html")
28// counterpart of this channel on the Dart side.
29// The C++ type of stream configuration arguments, events, and error details are
30// templated, but only values supported by the specified MethodCodec can be
31// used.
32template <typename T = EncodableValue>
34 public:
35 // Creates an instance that sends and receives event handler on the channel
36 // named |name|, encoded with |codec| and dispatched via |messenger|.
38 const std::string& name,
39 const MethodCodec<T>* codec)
40 : messenger_(messenger), name_(name), codec_(codec) {}
41 ~EventChannel() = default;
42
43 // Prevent copying.
44 EventChannel(EventChannel const&) = delete;
46
47 // Registers a stream handler on this channel.
48 // If no handler has been registered, any incoming stream setup requests will
49 // be handled silently by providing an empty stream.
50 //
51 // Note that the EventChannel does not own the handler and will not
52 // unregister it on destruction. The caller is responsible for unregistering
53 // the handler if it should no longer be called.
54 void SetStreamHandler(std::unique_ptr<StreamHandler<T>> handler) {
55 if (!handler) {
56 messenger_->SetMessageHandler(name_, nullptr);
57 return;
58 }
59
60 // std::function requires a copyable lambda, so convert to a shared pointer.
61 // This is safe since only one copy of the shared_pointer will ever be
62 // accessed.
63 std::shared_ptr<StreamHandler<T>> shared_handler(handler.release());
64 const MethodCodec<T>* codec = codec_;
65 const std::string channel_name = name_;
66 const BinaryMessenger* messenger = messenger_;
67 BinaryMessageHandler binary_handler =
68 [shared_handler, codec, channel_name, messenger,
69 // Mutable state to track the handler's listening status.
70 is_listening = bool(false)](const uint8_t* message,
71 const size_t message_size,
72 const BinaryReply& reply) mutable {
73 constexpr char kOnListenMethod[] = "listen";
74 constexpr char kOnCancelMethod[] = "cancel";
75
76 std::unique_ptr<MethodCall<T>> method_call =
77 codec->DecodeMethodCall(message, message_size);
78 if (!method_call) {
79 std::cerr
80 << "Unable to construct method call from message on channel: "
81 << channel_name << std::endl;
82 reply(nullptr, 0);
83 return;
84 }
85
86 const std::string& method = method_call->method_name();
87 if (method.compare(kOnListenMethod) == 0) {
88 if (is_listening) {
89 std::unique_ptr<StreamHandlerError<T>> error =
90 shared_handler->OnCancel(nullptr);
91 if (error) {
92 std::cerr << "Failed to cancel existing stream: "
93 << (error->error_code) << ", "
94 << (error->error_message) << ", "
95 << (error->error_details);
96 }
97 }
98 is_listening = true;
99
100 std::unique_ptr<std::vector<uint8_t>> result;
101 auto sink = std::make_unique<EventSinkImplementation>(
102 messenger, channel_name, codec);
103 std::unique_ptr<StreamHandlerError<T>> error =
104 shared_handler->OnListen(method_call->arguments(),
105 std::move(sink));
106 if (error) {
107 result = codec->EncodeErrorEnvelope(error->error_code,
108 error->error_message,
109 error->error_details.get());
110 } else {
111 result = codec->EncodeSuccessEnvelope();
112 }
113 reply(result->data(), result->size());
114 } else if (method.compare(kOnCancelMethod) == 0) {
115 std::unique_ptr<std::vector<uint8_t>> result;
116 if (is_listening) {
117 std::unique_ptr<StreamHandlerError<T>> error =
118 shared_handler->OnCancel(method_call->arguments());
119 if (error) {
120 result = codec->EncodeErrorEnvelope(error->error_code,
121 error->error_message,
122 error->error_details.get());
123 } else {
124 result = codec->EncodeSuccessEnvelope();
125 }
126 is_listening = false;
127 } else {
129 "error", "No active stream to cancel", nullptr);
130 }
131 reply(result->data(), result->size());
132 } else {
133 reply(nullptr, 0);
134 }
135 };
136 messenger_->SetMessageHandler(name_, std::move(binary_handler));
137 }
138
139 private:
140 class EventSinkImplementation : public EventSink<T> {
141 public:
142 EventSinkImplementation(const BinaryMessenger* messenger,
143 const std::string& name,
144 const MethodCodec<T>* codec)
145 : messenger_(messenger), name_(name), codec_(codec) {}
146 ~EventSinkImplementation() = default;
147
148 // Prevent copying.
149 EventSinkImplementation(EventSinkImplementation const&) = delete;
150 EventSinkImplementation& operator=(EventSinkImplementation const&) = delete;
151
152 private:
153 const BinaryMessenger* messenger_;
154 const std::string name_;
155 const MethodCodec<T>* codec_;
156
157 protected:
158 void SuccessInternal(const T* event = nullptr) override {
159 auto result = codec_->EncodeSuccessEnvelope(event);
160 messenger_->Send(name_, result->data(), result->size());
161 }
162
163 void ErrorInternal(const std::string& error_code,
164 const std::string& error_message,
165 const T* error_details) override {
166 auto result =
167 codec_->EncodeErrorEnvelope(error_code, error_message, error_details);
168 messenger_->Send(name_, result->data(), result->size());
169 }
170
171 void EndOfStreamInternal() override { messenger_->Send(name_, nullptr, 0); }
172 };
173
174 BinaryMessenger* messenger_;
175 const std::string name_;
176 const MethodCodec<T>* codec_;
177};
178
179} // namespace flutter
180
181#endif // FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_EVENT_CHANNEL_H_
virtual void SetMessageHandler(const std::string &channel, BinaryMessageHandler handler)=0
EventChannel & operator=(EventChannel const &)=delete
void SetStreamHandler(std::unique_ptr< StreamHandler< T > > handler)
EventChannel(EventChannel const &)=delete
EventChannel(BinaryMessenger *messenger, const std::string &name, const MethodCodec< T > *codec)
std::unique_ptr< MethodCall< T > > DecodeMethodCall(const uint8_t *message, size_t message_size) const
std::unique_ptr< std::vector< uint8_t > > EncodeErrorEnvelope(const std::string &error_code, const std::string &error_message="", const T *error_details=nullptr) const
std::unique_ptr< std::vector< uint8_t > > EncodeSuccessEnvelope(const T *result=nullptr) const
FlKeyEvent * event
G_BEGIN_DECLS G_MODULE_EXPORT FlMethodCall * method_call
const uint8_t uint32_t uint32_t GError ** error
GAsyncResult * result
Win32Message message
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
#define T