|  | 
|  | 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_CPP_CLIENT_WRAPPER_INCLUDE_FLUTTER_BASIC_MESSAGE_CHANNEL_H_ | 
|  | 6 | +#define FLUTTER_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_FLUTTER_BASIC_MESSAGE_CHANNEL_H_ | 
|  | 7 | + | 
|  | 8 | +#include <iostream> | 
|  | 9 | +#include <string> | 
|  | 10 | + | 
|  | 11 | +#include "binary_messenger.h" | 
|  | 12 | +#include "message_codec.h" | 
|  | 13 | + | 
|  | 14 | +namespace flutter { | 
|  | 15 | + | 
|  | 16 | +// A message reply callback. | 
|  | 17 | +// | 
|  | 18 | +// Used for submitting a reply back to a Flutter message sender. | 
|  | 19 | +template <typename T> | 
|  | 20 | +using MessageReply = std::function<void(const T& reply)>; | 
|  | 21 | + | 
|  | 22 | +// A handler for receiving a message from the Flutter engine. | 
|  | 23 | +// | 
|  | 24 | +// Implementations must asynchronously call reply exactly once with the reply | 
|  | 25 | +// to the message. | 
|  | 26 | +template <typename T> | 
|  | 27 | +using MessageHandler = | 
|  | 28 | +    std::function<void(const T& message, MessageReply<T> reply)>; | 
|  | 29 | + | 
|  | 30 | +// A channel for communicating with the Flutter engine by sending asynchronous | 
|  | 31 | +// messages. | 
|  | 32 | +template <typename T> | 
|  | 33 | +class BasicMessageChannel { | 
|  | 34 | + public: | 
|  | 35 | +  // Creates an instance that sends and receives method calls on the channel | 
|  | 36 | +  // named |name|, encoded with |codec| and dispatched via |messenger|. | 
|  | 37 | +  BasicMessageChannel(BinaryMessenger* messenger, | 
|  | 38 | +                      const std::string& name, | 
|  | 39 | +                      const MessageCodec<T>* codec) | 
|  | 40 | +      : messenger_(messenger), name_(name), codec_(codec) {} | 
|  | 41 | + | 
|  | 42 | +  ~BasicMessageChannel() = default; | 
|  | 43 | + | 
|  | 44 | +  // Prevent copying. | 
|  | 45 | +  BasicMessageChannel(BasicMessageChannel const&) = delete; | 
|  | 46 | +  BasicMessageChannel& operator=(BasicMessageChannel const&) = delete; | 
|  | 47 | + | 
|  | 48 | +  // Sends a message to the Flutter engine on this channel. | 
|  | 49 | +  void Send(const T& message) { | 
|  | 50 | +    std::unique_ptr<std::vector<uint8_t>> raw_message = | 
|  | 51 | +        codec_->EncodeMessage(message); | 
|  | 52 | +    messenger_->Send(name_, raw_message->data(), raw_message->size()); | 
|  | 53 | +  } | 
|  | 54 | + | 
|  | 55 | +  // TODO: Add support for a version of Send expecting a reply once | 
|  | 56 | +  // https://github.com/flutter/flutter/issues/18852 is fixed. | 
|  | 57 | + | 
|  | 58 | +  // Registers a handler that should be called any time a message is | 
|  | 59 | +  // received on this channel. | 
|  | 60 | +  void SetMessageHandler(MessageHandler<T> handler) const { | 
|  | 61 | +    const auto* codec = codec_; | 
|  | 62 | +    std::string channel_name = name_; | 
|  | 63 | +    BinaryMessageHandler binary_handler = [handler, codec, channel_name]( | 
|  | 64 | +                                              const uint8_t* binary_message, | 
|  | 65 | +                                              const size_t binary_message_size, | 
|  | 66 | +                                              BinaryReply binary_reply) { | 
|  | 67 | +      // Use this channel's codec to decode the message and build a reply | 
|  | 68 | +      // handler. | 
|  | 69 | +      std::unique_ptr<T> message = | 
|  | 70 | +          codec->DecodeMessage(binary_message, binary_message_size); | 
|  | 71 | +      if (!message) { | 
|  | 72 | +        std::cerr << "Unable to decode message on channel " << channel_name | 
|  | 73 | +                  << std::endl; | 
|  | 74 | +        binary_reply(nullptr, 0); | 
|  | 75 | +        return; | 
|  | 76 | +      } | 
|  | 77 | + | 
|  | 78 | +      MessageReply<T> unencoded_reply = [binary_reply, | 
|  | 79 | +                                         codec](const T& unencoded_response) { | 
|  | 80 | +        auto binary_response = codec->EncodeMessage(unencoded_response); | 
|  | 81 | +        binary_reply(binary_response->data(), binary_response->size()); | 
|  | 82 | +      }; | 
|  | 83 | +      handler(*message, std::move(unencoded_reply)); | 
|  | 84 | +    }; | 
|  | 85 | +    messenger_->SetMessageHandler(name_, std::move(binary_handler)); | 
|  | 86 | +  } | 
|  | 87 | + | 
|  | 88 | + private: | 
|  | 89 | +  BinaryMessenger* messenger_; | 
|  | 90 | +  std::string name_; | 
|  | 91 | +  const MessageCodec<T>* codec_; | 
|  | 92 | +}; | 
|  | 93 | + | 
|  | 94 | +}  // namespace flutter | 
|  | 95 | + | 
|  | 96 | +#endif  // FLUTTER_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_FLUTTER_BASIC_MESSAGE_CHANNEL_H_ | 
0 commit comments