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_METHOD_CHANNEL_H_ 6 #define FLUTTER_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_FLUTTER_METHOD_CHANNEL_H_ 7 8 #include <iostream> 9 #include <string> 10 11 #include "binary_messenger.h" 12 #include "engine_method_result.h" 13 #include "method_call.h" 14 #include "method_codec.h" 15 #include "method_result.h" 16 17 namespace flutter { 18 19 // A handler for receiving a method call from the Flutter engine. 20 // 21 // Implementations must asynchronously call exactly one of the methods on 22 // |result| to indicate the result of the method call. 23 template <typename T> 24 using MethodCallHandler = 25 std::function<void(const MethodCall<T>& call, 26 std::unique_ptr<MethodResult<T>> result)>; 27 28 // A channel for communicating with the Flutter engine using invocation of 29 // asynchronous methods. 30 template <typename T> 31 class MethodChannel { 32 public: 33 // Creates an instance that sends and receives method calls on the channel 34 // named |name|, encoded with |codec| and dispatched via |messenger|. MethodChannel(BinaryMessenger * messenger,const std::string & name,const MethodCodec<T> * codec)35 MethodChannel(BinaryMessenger* messenger, 36 const std::string& name, 37 const MethodCodec<T>* codec) 38 : messenger_(messenger), name_(name), codec_(codec) {} 39 40 ~MethodChannel() = default; 41 42 // Prevent copying. 43 MethodChannel(MethodChannel const&) = delete; 44 MethodChannel& operator=(MethodChannel const&) = delete; 45 46 // Sends a message to the Flutter engine on this channel. InvokeMethod(const std::string & method,std::unique_ptr<T> arguments)47 void InvokeMethod(const std::string& method, std::unique_ptr<T> arguments) { 48 MethodCall<T> method_call(method, std::move(arguments)); 49 std::unique_ptr<std::vector<uint8_t>> message = 50 codec_->EncodeMethodCall(method_call); 51 messenger_->Send(name_, message->data(), message->size()); 52 } 53 54 // TODO: Add support for a version of InvokeMethod expecting a reply once 55 // https://github.com/flutter/flutter/issues/18852 is fixed. 56 57 // Registers a handler that should be called any time a method call is 58 // received on this channel. SetMethodCallHandler(MethodCallHandler<T> handler)59 void SetMethodCallHandler(MethodCallHandler<T> handler) const { 60 const auto* codec = codec_; 61 std::string channel_name = name_; 62 BinaryMessageHandler binary_handler = [handler, codec, channel_name]( 63 const uint8_t* message, 64 const size_t message_size, 65 BinaryReply reply) { 66 // Use this channel's codec to decode the call and build a result handler. 67 auto result = 68 std::make_unique<EngineMethodResult<T>>(std::move(reply), codec); 69 std::unique_ptr<MethodCall<T>> method_call = 70 codec->DecodeMethodCall(message, message_size); 71 if (!method_call) { 72 std::cerr << "Unable to construct method call from message on channel " 73 << channel_name << std::endl; 74 result->NotImplemented(); 75 return; 76 } 77 handler(*method_call, std::move(result)); 78 }; 79 messenger_->SetMessageHandler(name_, std::move(binary_handler)); 80 } 81 82 private: 83 BinaryMessenger* messenger_; 84 std::string name_; 85 const MethodCodec<T>* codec_; 86 }; 87 88 } // namespace flutter 89 90 #endif // FLUTTER_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_FLUTTER_METHOD_CHANNEL_H_ 91