• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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