Flutter macOS Embedder
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"
13 #include "engine_method_result.h"
14 #include "event_sink.h"
15 #include "event_stream_handler.h"
16 
17 namespace flutter {
18 
19 class 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-io.cn/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.
32 template <typename T = EncodableValue>
33 class EventChannel {
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;
45  EventChannel& operator=(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 {
128  result = codec->EncodeErrorEnvelope(
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_
event_sink.h
engine_method_result.h
flutter::EventSink
Definition: event_sink.h:15
flutter::EventChannel::~EventChannel
~EventChannel()=default
event_stream_handler.h
binary_messenger.h
flutter::EventChannel::EventChannel
EventChannel(BinaryMessenger *messenger, const std::string &name, const MethodCodec< T > *codec)
Definition: event_channel.h:37
flutter::BinaryMessenger
Definition: binary_messenger.h:28
flutter::BinaryMessenger::SetMessageHandler
virtual void SetMessageHandler(const std::string &channel, BinaryMessageHandler handler)=0
flutter::BinaryReply
std::function< void(const uint8_t *reply, size_t reply_size)> BinaryReply
Definition: binary_messenger.h:17
flutter
Definition: AccessibilityBridgeMac.h:16
flutter::EventChannel::SetStreamHandler
void SetStreamHandler(std::unique_ptr< StreamHandler< T >> handler)
Definition: event_channel.h:54
flutter::MethodCodec
Definition: method_codec.h:20
flutter::StreamHandler
Definition: event_stream_handler.h:38
flutter::BinaryMessageHandler
std::function< void(const uint8_t *message, size_t message_size, BinaryReply reply)> BinaryMessageHandler
Definition: binary_messenger.h:24
flutter::EventChannel::operator=
EventChannel & operator=(EventChannel const &)=delete
flutter::EventChannel
Definition: event_channel.h:33