From c9464edaa2865c22466b9efbc080a6aade5111e9 Mon Sep 17 00:00:00 2001 From: Bruno Leroux Date: Fri, 20 Oct 2023 16:10:07 +0200 Subject: [PATCH 1/6] [Windows] Expose channel buffers 'resize' and 'overflow' control commands --- .../basic_message_channel_unittests.cc | 72 ++++++++++++++++++- .../include/flutter/basic_message_channel.h | 38 +++++++++- .../include/flutter/method_channel.h | 40 +++++++++++ .../method_channel_unittests.cc | 64 +++++++++++++++++ 4 files changed, 212 insertions(+), 2 deletions(-) diff --git a/shell/platform/common/client_wrapper/basic_message_channel_unittests.cc b/shell/platform/common/client_wrapper/basic_message_channel_unittests.cc index f38595c8c165a..837d9d169ad14 100644 --- a/shell/platform/common/client_wrapper/basic_message_channel_unittests.cc +++ b/shell/platform/common/client_wrapper/basic_message_channel_unittests.cc @@ -9,6 +9,7 @@ #include "flutter/shell/platform/common/client_wrapper/include/flutter/binary_messenger.h" #include "flutter/shell/platform/common/client_wrapper/include/flutter/standard_message_codec.h" +#include "flutter/shell/platform/common/client_wrapper/include/flutter/standard_method_codec.h" #include "gtest/gtest.h" namespace flutter { @@ -20,7 +21,14 @@ class TestBinaryMessenger : public BinaryMessenger { void Send(const std::string& channel, const uint8_t* message, const size_t message_size, - BinaryReply reply) const override {} + BinaryReply reply) const override { + send_called_ = true; + int length = static_cast(message_size); + last_message_size_ = length; + std::vector last_message(length); + memcpy(&last_message[0], &message[0], length * sizeof(uint8_t)); + last_message_ = last_message; + } void SetMessageHandler(const std::string& channel, BinaryMessageHandler handler) override { @@ -28,15 +36,24 @@ class TestBinaryMessenger : public BinaryMessenger { last_message_handler_ = handler; } + bool send_called() { return send_called_; } + std::string last_message_handler_channel() { return last_message_handler_channel_; } BinaryMessageHandler last_message_handler() { return last_message_handler_; } + std::vector last_message() { return last_message_; } + + int last_message_size() { return last_message_size_; } + private: + mutable bool send_called_ = false; std::string last_message_handler_channel_; BinaryMessageHandler last_message_handler_; + mutable std::vector last_message_; + mutable int last_message_size_; }; } // namespace @@ -86,4 +103,57 @@ TEST(BasicMessageChannelTest, Unregistration) { EXPECT_EQ(messenger.last_message_handler(), nullptr); } +// Tests that calling Resize generates the binary message expected by the Dart +// implementation. +TEST(BasicMessageChannelTest, Resize) { + TestBinaryMessenger messenger; + const std::string channel_name("flutter/test"); + BasicMessageChannel channel(&messenger, channel_name, + &flutter::StandardMessageCodec::GetInstance()); + + channel.Resize(3); + + // The expected content was created from the following Dart code: + // MethodCall call = MethodCall('resize', ['flutter/test',3]); + // StandardMethodCodec().encodeMethodCall(call).buffer.asUint8List(); + const int expected_message_size = 29; + + EXPECT_EQ(messenger.send_called(), true); + EXPECT_EQ(messenger.last_message_size(), expected_message_size); + + int expected[expected_message_size] = { + 7, 6, 114, 101, 115, 105, 122, 101, 12, 2, 7, 12, 102, 108, 117, + 116, 116, 101, 114, 47, 116, 101, 115, 116, 3, 3, 0, 0, 0}; + for (int i = 0; i < expected_message_size; i++) { + EXPECT_EQ(messenger.last_message()[i], expected[i]); + } +} + +// Tests that calling SetWarnsOnOverflow generates the binary message expected +// by the Dart implementation. +TEST(BasicMessageChannelTest, SetWarnsOnOverflow) { + TestBinaryMessenger messenger; + + const std::string channel_name("flutter/test"); + BasicMessageChannel channel(&messenger, channel_name, + &flutter::StandardMessageCodec::GetInstance()); + + channel.SetWarnsOnOverflow(false); + + // The expected content was created from the following Dart code: + // MethodCall call = MethodCall('overflow',['flutter/test', true]); + // StandardMethodCodec().encodeMethodCall(call).buffer.asUint8List(); + const int expected_message_size = 27; + + EXPECT_EQ(messenger.send_called(), true); + EXPECT_EQ(messenger.last_message_size(), expected_message_size); + + int expected[expected_message_size] = { + 7, 8, 111, 118, 101, 114, 102, 108, 111, 119, 12, 2, 7, 12, + 102, 108, 117, 116, 116, 101, 114, 47, 116, 101, 115, 116, 1}; + for (int i = 0; i < expected_message_size; i++) { + EXPECT_EQ(messenger.last_message()[i], expected[i]); + } +} + } // namespace flutter diff --git a/shell/platform/common/client_wrapper/include/flutter/basic_message_channel.h b/shell/platform/common/client_wrapper/include/flutter/basic_message_channel.h index 4109c59a0a615..7b98c50c53b1f 100644 --- a/shell/platform/common/client_wrapper/include/flutter/basic_message_channel.h +++ b/shell/platform/common/client_wrapper/include/flutter/basic_message_channel.h @@ -11,7 +11,8 @@ #include "binary_messenger.h" #include "message_codec.h" - +#include "method_channel.h" +#include "standard_method_codec.h" namespace flutter { class EncodableValue; @@ -101,6 +102,41 @@ class BasicMessageChannel { messenger_->SetMessageHandler(name_, std::move(binary_handler)); } + // Adjusts the number of messages that will get buffered when sending messages + // to channels that aren't fully set up yet. For example, the engine isn't + // running yet or the channel's message handler isn't set up on the Dart side + // yet. + // + // |new_size] is an int because the deserialization logic handles only 32 bits + // values, see + // https://github.com/flutter/engine/blob/93e8901490e78c7ba7e319cce4470d9c6478c6dc/lib/ui/channel_buffers.dart#L495. + void Resize(int new_size) { + auto control_channel = std::make_unique>( + messenger_, kControlChannelName, &StandardMethodCodec::GetInstance()); + + control_channel->InvokeMethod( + kResizeMethod, std::make_unique(EncodableList{ + EncodableValue(name_), + EncodableValue(new_size), + })); + } + + // Defines whether the channel should show warning messages when discarding + // messages due to overflow. + // + // When |warns| is false, the channel is expected to overflow and warning + // messages will not be shown. + void SetWarnsOnOverflow(bool warns) { + auto control_channel = std::make_unique>( + messenger_, kControlChannelName, &StandardMethodCodec::GetInstance()); + + control_channel->InvokeMethod( + kOverflowMethod, std::make_unique(EncodableList{ + EncodableValue(name_), + EncodableValue(!warns), + })); + } + private: BinaryMessenger* messenger_; std::string name_; diff --git a/shell/platform/common/client_wrapper/include/flutter/method_channel.h b/shell/platform/common/client_wrapper/include/flutter/method_channel.h index 6e39a644f6e08..fedef91b4a001 100644 --- a/shell/platform/common/client_wrapper/include/flutter/method_channel.h +++ b/shell/platform/common/client_wrapper/include/flutter/method_channel.h @@ -13,6 +13,11 @@ #include "method_call.h" #include "method_codec.h" #include "method_result.h" +#include "standard_method_codec.h" + +static constexpr char kControlChannelName[] = "dev.flutter/channel-buffers"; +static constexpr char kResizeMethod[] = "resize"; +static constexpr char kOverflowMethod[] = "overflow"; namespace flutter { @@ -122,6 +127,41 @@ class MethodChannel { messenger_->SetMessageHandler(name_, std::move(binary_handler)); } + // Adjusts the number of messages that will get buffered when sending messages + // to channels that aren't fully set up yet. For example, the engine isn't + // running yet or the channel's message handler isn't set up on the Dart side + // yet. + // + // |new_size] is an int because the deserialization logic handles only 32 bits + // values, see + // https://github.com/flutter/engine/blob/93e8901490e78c7ba7e319cce4470d9c6478c6dc/lib/ui/channel_buffers.dart#L495. + void Resize(int new_size) { + auto control_channel = std::make_unique>( + messenger_, kControlChannelName, &StandardMethodCodec::GetInstance()); + + control_channel->InvokeMethod( + kResizeMethod, std::make_unique(EncodableList{ + EncodableValue(name_), + EncodableValue(new_size), + })); + } + + // Defines whether the channel should show warning messages when discarding + // messages due to overflow. + // + // When |warns| is false, the channel is expected to overflow and warning + // messages will not be shown. + void SetWarnsOnOverflow(bool warns) { + auto control_channel = std::make_unique>( + messenger_, kControlChannelName, &StandardMethodCodec::GetInstance()); + + control_channel->InvokeMethod( + kOverflowMethod, std::make_unique(EncodableList{ + EncodableValue(name_), + EncodableValue(!warns), + })); + } + private: BinaryMessenger* messenger_; std::string name_; diff --git a/shell/platform/common/client_wrapper/method_channel_unittests.cc b/shell/platform/common/client_wrapper/method_channel_unittests.cc index 55c4529edd581..42b88a49c229c 100644 --- a/shell/platform/common/client_wrapper/method_channel_unittests.cc +++ b/shell/platform/common/client_wrapper/method_channel_unittests.cc @@ -24,6 +24,11 @@ class TestBinaryMessenger : public BinaryMessenger { BinaryReply reply) const override { send_called_ = true; last_reply_handler_ = reply; + int length = static_cast(message_size); + last_message_size_ = length; + std::vector last_message(length); + memcpy(&last_message[0], &message[0], length * sizeof(uint8_t)); + last_message_ = last_message; } void SetMessageHandler(const std::string& channel, @@ -42,11 +47,17 @@ class TestBinaryMessenger : public BinaryMessenger { BinaryMessageHandler last_message_handler() { return last_message_handler_; } + std::vector last_message() { return last_message_; } + + int last_message_size() { return last_message_size_; } + private: mutable bool send_called_ = false; mutable BinaryReply last_reply_handler_; std::string last_message_handler_channel_; BinaryMessageHandler last_message_handler_; + mutable std::vector last_message_; + mutable int last_message_size_; }; } // namespace @@ -156,4 +167,57 @@ TEST(MethodChannelTest, InvokeNotImplemented) { EXPECT_TRUE(received_not_implemented); } +// Tests that calling Resize generates the binary message expected by the Dart +// implementation. +TEST(MethodChannelTest, Resize) { + TestBinaryMessenger messenger; + const std::string channel_name("flutter/test"); + MethodChannel channel(&messenger, channel_name, + &StandardMethodCodec::GetInstance()); + + channel.Resize(3); + + // The expected content was created from the following Dart code: + // MethodCall call = MethodCall('resize', ['flutter/test',3]); + // StandardMethodCodec().encodeMethodCall(call).buffer.asUint8List(); + const int expected_message_size = 29; + + EXPECT_EQ(messenger.send_called(), true); + EXPECT_EQ(messenger.last_message_size(), expected_message_size); + + int expected[expected_message_size] = { + 7, 6, 114, 101, 115, 105, 122, 101, 12, 2, 7, 12, 102, 108, 117, + 116, 116, 101, 114, 47, 116, 101, 115, 116, 3, 3, 0, 0, 0}; + for (int i = 0; i < expected_message_size; i++) { + EXPECT_EQ(messenger.last_message()[i], expected[i]); + } +} + +// Tests that calling SetWarnsOnOverflow generates the binary message expected +// by the Dart implementation. +TEST(MethodChannelTest, SetWarnsOnOverflow) { + TestBinaryMessenger messenger; + + const std::string channel_name("flutter/test"); + MethodChannel channel(&messenger, channel_name, + &StandardMethodCodec::GetInstance()); + + channel.SetWarnsOnOverflow(false); + + // The expected content was created from the following Dart code: + // MethodCall call = MethodCall('overflow',['flutter/test', true]); + // StandardMethodCodec().encodeMethodCall(call).buffer.asUint8List(); + const int expected_message_size = 27; + + EXPECT_EQ(messenger.send_called(), true); + EXPECT_EQ(messenger.last_message_size(), expected_message_size); + + int expected[expected_message_size] = { + 7, 8, 111, 118, 101, 114, 102, 108, 111, 119, 12, 2, 7, 12, + 102, 108, 117, 116, 116, 101, 114, 47, 116, 101, 115, 116, 1}; + for (int i = 0; i < expected_message_size; i++) { + EXPECT_EQ(messenger.last_message()[i], expected[i]); + } +} + } // namespace flutter From c60194030055e44a12005577af3f32c13c4c705f Mon Sep 17 00:00:00 2001 From: Bruno Leroux Date: Thu, 2 Nov 2023 12:19:45 +0100 Subject: [PATCH 2/6] Address review comments --- .../common/client_wrapper/basic_message_channel_unittests.cc | 5 ++--- .../client_wrapper/include/flutter/basic_message_channel.h | 2 +- .../common/client_wrapper/include/flutter/method_channel.h | 4 ++-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/shell/platform/common/client_wrapper/basic_message_channel_unittests.cc b/shell/platform/common/client_wrapper/basic_message_channel_unittests.cc index 837d9d169ad14..33bb2e749b5d9 100644 --- a/shell/platform/common/client_wrapper/basic_message_channel_unittests.cc +++ b/shell/platform/common/client_wrapper/basic_message_channel_unittests.cc @@ -25,9 +25,8 @@ class TestBinaryMessenger : public BinaryMessenger { send_called_ = true; int length = static_cast(message_size); last_message_size_ = length; - std::vector last_message(length); - memcpy(&last_message[0], &message[0], length * sizeof(uint8_t)); - last_message_ = last_message; + last_message_ = + std::vector(message, message + length * sizeof(uint8_t)); } void SetMessageHandler(const std::string& channel, diff --git a/shell/platform/common/client_wrapper/include/flutter/basic_message_channel.h b/shell/platform/common/client_wrapper/include/flutter/basic_message_channel.h index 7b98c50c53b1f..eeb4febac3c45 100644 --- a/shell/platform/common/client_wrapper/include/flutter/basic_message_channel.h +++ b/shell/platform/common/client_wrapper/include/flutter/basic_message_channel.h @@ -12,7 +12,7 @@ #include "binary_messenger.h" #include "message_codec.h" #include "method_channel.h" -#include "standard_method_codec.h" + namespace flutter { class EncodableValue; diff --git a/shell/platform/common/client_wrapper/include/flutter/method_channel.h b/shell/platform/common/client_wrapper/include/flutter/method_channel.h index fedef91b4a001..4e0457ed5dcc1 100644 --- a/shell/platform/common/client_wrapper/include/flutter/method_channel.h +++ b/shell/platform/common/client_wrapper/include/flutter/method_channel.h @@ -15,12 +15,12 @@ #include "method_result.h" #include "standard_method_codec.h" +namespace flutter { + static constexpr char kControlChannelName[] = "dev.flutter/channel-buffers"; static constexpr char kResizeMethod[] = "resize"; static constexpr char kOverflowMethod[] = "overflow"; -namespace flutter { - class EncodableValue; // A handler for receiving a method call from the Flutter engine. From 6df13f8e75ac1f842e81242d2426ec6a99c05125 Mon Sep 17 00:00:00 2001 From: Bruno Leroux Date: Fri, 3 Nov 2023 14:21:37 +0100 Subject: [PATCH 3/6] Add a comment to explain why the test relies on bytes array comparaison --- .../client_wrapper/basic_message_channel_unittests.cc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/shell/platform/common/client_wrapper/basic_message_channel_unittests.cc b/shell/platform/common/client_wrapper/basic_message_channel_unittests.cc index 33bb2e749b5d9..638465dedfdc5 100644 --- a/shell/platform/common/client_wrapper/basic_message_channel_unittests.cc +++ b/shell/platform/common/client_wrapper/basic_message_channel_unittests.cc @@ -112,6 +112,11 @@ TEST(BasicMessageChannelTest, Resize) { channel.Resize(3); + // Because the Dart implementation for the control channel implements its own + // custom deserialization logic, this test compares the generated bytes array + // to the expected one (for instance, the deserialization logic expects the + // size parameter of the resize method call to be an uint32). + // // The expected content was created from the following Dart code: // MethodCall call = MethodCall('resize', ['flutter/test',3]); // StandardMethodCodec().encodeMethodCall(call).buffer.asUint8List(); @@ -139,6 +144,10 @@ TEST(BasicMessageChannelTest, SetWarnsOnOverflow) { channel.SetWarnsOnOverflow(false); + // Because the Dart implementation for the control channel implements its own + // custom deserialization logic, this test compares the generated bytes array + // to the expected one. + // // The expected content was created from the following Dart code: // MethodCall call = MethodCall('overflow',['flutter/test', true]); // StandardMethodCodec().encodeMethodCall(call).buffer.asUint8List(); From 7be16573b4d8849d2d5bafd79f747955c0b4a67f Mon Sep 17 00:00:00 2001 From: Bruno Leroux Date: Thu, 9 Nov 2023 11:35:39 +0100 Subject: [PATCH 4/6] Update int truncation comment + remove last_message_size in tests --- .../basic_message_channel_unittests.cc | 10 ++++------ .../include/flutter/basic_message_channel.h | 8 +++----- .../client_wrapper/method_channel_unittests.cc | 15 ++++++--------- 3 files changed, 13 insertions(+), 20 deletions(-) diff --git a/shell/platform/common/client_wrapper/basic_message_channel_unittests.cc b/shell/platform/common/client_wrapper/basic_message_channel_unittests.cc index 638465dedfdc5..ba24f60b00f1c 100644 --- a/shell/platform/common/client_wrapper/basic_message_channel_unittests.cc +++ b/shell/platform/common/client_wrapper/basic_message_channel_unittests.cc @@ -24,7 +24,6 @@ class TestBinaryMessenger : public BinaryMessenger { BinaryReply reply) const override { send_called_ = true; int length = static_cast(message_size); - last_message_size_ = length; last_message_ = std::vector(message, message + length * sizeof(uint8_t)); } @@ -45,14 +44,11 @@ class TestBinaryMessenger : public BinaryMessenger { std::vector last_message() { return last_message_; } - int last_message_size() { return last_message_size_; } - private: mutable bool send_called_ = false; std::string last_message_handler_channel_; BinaryMessageHandler last_message_handler_; mutable std::vector last_message_; - mutable int last_message_size_; }; } // namespace @@ -123,7 +119,8 @@ TEST(BasicMessageChannelTest, Resize) { const int expected_message_size = 29; EXPECT_EQ(messenger.send_called(), true); - EXPECT_EQ(messenger.last_message_size(), expected_message_size); + EXPECT_EQ(static_cast(messenger.last_message().size()), + expected_message_size); int expected[expected_message_size] = { 7, 6, 114, 101, 115, 105, 122, 101, 12, 2, 7, 12, 102, 108, 117, @@ -154,7 +151,8 @@ TEST(BasicMessageChannelTest, SetWarnsOnOverflow) { const int expected_message_size = 27; EXPECT_EQ(messenger.send_called(), true); - EXPECT_EQ(messenger.last_message_size(), expected_message_size); + EXPECT_EQ(static_cast(messenger.last_message().size()), + expected_message_size); int expected[expected_message_size] = { 7, 8, 111, 118, 101, 114, 102, 108, 111, 119, 12, 2, 7, 12, diff --git a/shell/platform/common/client_wrapper/include/flutter/basic_message_channel.h b/shell/platform/common/client_wrapper/include/flutter/basic_message_channel.h index eeb4febac3c45..25b805fd08aa2 100644 --- a/shell/platform/common/client_wrapper/include/flutter/basic_message_channel.h +++ b/shell/platform/common/client_wrapper/include/flutter/basic_message_channel.h @@ -106,18 +106,16 @@ class BasicMessageChannel { // to channels that aren't fully set up yet. For example, the engine isn't // running yet or the channel's message handler isn't set up on the Dart side // yet. - // - // |new_size] is an int because the deserialization logic handles only 32 bits - // values, see - // https://github.com/flutter/engine/blob/93e8901490e78c7ba7e319cce4470d9c6478c6dc/lib/ui/channel_buffers.dart#L495. void Resize(int new_size) { auto control_channel = std::make_unique>( messenger_, kControlChannelName, &StandardMethodCodec::GetInstance()); + // The deserialization logic handles only 32 bits values, see + // https://github.com/flutter/engine/blob/93e8901490e78c7ba7e319cce4470d9c6478c6dc/lib/ui/channel_buffers.dart#L495. control_channel->InvokeMethod( kResizeMethod, std::make_unique(EncodableList{ EncodableValue(name_), - EncodableValue(new_size), + EncodableValue(static_cast(new_size)), })); } diff --git a/shell/platform/common/client_wrapper/method_channel_unittests.cc b/shell/platform/common/client_wrapper/method_channel_unittests.cc index 42b88a49c229c..b9dcb91e9a064 100644 --- a/shell/platform/common/client_wrapper/method_channel_unittests.cc +++ b/shell/platform/common/client_wrapper/method_channel_unittests.cc @@ -25,10 +25,8 @@ class TestBinaryMessenger : public BinaryMessenger { send_called_ = true; last_reply_handler_ = reply; int length = static_cast(message_size); - last_message_size_ = length; - std::vector last_message(length); - memcpy(&last_message[0], &message[0], length * sizeof(uint8_t)); - last_message_ = last_message; + last_message_ = + std::vector(message, message + length * sizeof(uint8_t)); } void SetMessageHandler(const std::string& channel, @@ -49,15 +47,12 @@ class TestBinaryMessenger : public BinaryMessenger { std::vector last_message() { return last_message_; } - int last_message_size() { return last_message_size_; } - private: mutable bool send_called_ = false; mutable BinaryReply last_reply_handler_; std::string last_message_handler_channel_; BinaryMessageHandler last_message_handler_; mutable std::vector last_message_; - mutable int last_message_size_; }; } // namespace @@ -183,7 +178,8 @@ TEST(MethodChannelTest, Resize) { const int expected_message_size = 29; EXPECT_EQ(messenger.send_called(), true); - EXPECT_EQ(messenger.last_message_size(), expected_message_size); + EXPECT_EQ(static_cast(messenger.last_message().size()), + expected_message_size); int expected[expected_message_size] = { 7, 6, 114, 101, 115, 105, 122, 101, 12, 2, 7, 12, 102, 108, 117, @@ -210,7 +206,8 @@ TEST(MethodChannelTest, SetWarnsOnOverflow) { const int expected_message_size = 27; EXPECT_EQ(messenger.send_called(), true); - EXPECT_EQ(messenger.last_message_size(), expected_message_size); + EXPECT_EQ(static_cast(messenger.last_message().size()), + expected_message_size); int expected[expected_message_size] = { 7, 8, 111, 118, 101, 114, 102, 108, 111, 119, 12, 2, 7, 12, From 308cda288cddeee8bac7dcac354ded13c9acf510 Mon Sep 17 00:00:00 2001 From: Bruno Leroux Date: Thu, 9 Nov 2023 14:46:07 +0100 Subject: [PATCH 5/6] Move control channel logic to a private namespace --- .../include/flutter/basic_message_channel.h | 22 +----- .../include/flutter/method_channel.h | 79 +++++++++++++------ .../method_channel_unittests.cc | 5 ++ 3 files changed, 61 insertions(+), 45 deletions(-) diff --git a/shell/platform/common/client_wrapper/include/flutter/basic_message_channel.h b/shell/platform/common/client_wrapper/include/flutter/basic_message_channel.h index 25b805fd08aa2..2e1f42e9d10f1 100644 --- a/shell/platform/common/client_wrapper/include/flutter/basic_message_channel.h +++ b/shell/platform/common/client_wrapper/include/flutter/basic_message_channel.h @@ -106,18 +106,7 @@ class BasicMessageChannel { // to channels that aren't fully set up yet. For example, the engine isn't // running yet or the channel's message handler isn't set up on the Dart side // yet. - void Resize(int new_size) { - auto control_channel = std::make_unique>( - messenger_, kControlChannelName, &StandardMethodCodec::GetInstance()); - - // The deserialization logic handles only 32 bits values, see - // https://github.com/flutter/engine/blob/93e8901490e78c7ba7e319cce4470d9c6478c6dc/lib/ui/channel_buffers.dart#L495. - control_channel->InvokeMethod( - kResizeMethod, std::make_unique(EncodableList{ - EncodableValue(name_), - EncodableValue(static_cast(new_size)), - })); - } + void Resize(int new_size) { ResizeChannel(messenger_, name_, new_size); } // Defines whether the channel should show warning messages when discarding // messages due to overflow. @@ -125,14 +114,7 @@ class BasicMessageChannel { // When |warns| is false, the channel is expected to overflow and warning // messages will not be shown. void SetWarnsOnOverflow(bool warns) { - auto control_channel = std::make_unique>( - messenger_, kControlChannelName, &StandardMethodCodec::GetInstance()); - - control_channel->InvokeMethod( - kOverflowMethod, std::make_unique(EncodableList{ - EncodableValue(name_), - EncodableValue(!warns), - })); + SetChannelWarnsOnOverflow(messenger_, name_, warns); } private: diff --git a/shell/platform/common/client_wrapper/include/flutter/method_channel.h b/shell/platform/common/client_wrapper/include/flutter/method_channel.h index 4e0457ed5dcc1..899af6ca0b129 100644 --- a/shell/platform/common/client_wrapper/include/flutter/method_channel.h +++ b/shell/platform/common/client_wrapper/include/flutter/method_channel.h @@ -17,9 +17,15 @@ namespace flutter { -static constexpr char kControlChannelName[] = "dev.flutter/channel-buffers"; -static constexpr char kResizeMethod[] = "resize"; -static constexpr char kOverflowMethod[] = "overflow"; +namespace { + +void ResizeChannel(BinaryMessenger* messenger, std::string name, int new_size); + +void SetChannelWarnsOnOverflow(BinaryMessenger* messenger, + std::string name, + bool warns); + +} // namespace class EncodableValue; @@ -131,20 +137,7 @@ class MethodChannel { // to channels that aren't fully set up yet. For example, the engine isn't // running yet or the channel's message handler isn't set up on the Dart side // yet. - // - // |new_size] is an int because the deserialization logic handles only 32 bits - // values, see - // https://github.com/flutter/engine/blob/93e8901490e78c7ba7e319cce4470d9c6478c6dc/lib/ui/channel_buffers.dart#L495. - void Resize(int new_size) { - auto control_channel = std::make_unique>( - messenger_, kControlChannelName, &StandardMethodCodec::GetInstance()); - - control_channel->InvokeMethod( - kResizeMethod, std::make_unique(EncodableList{ - EncodableValue(name_), - EncodableValue(new_size), - })); - } + void Resize(int new_size) { ResizeChannel(messenger_, name_, new_size); } // Defines whether the channel should show warning messages when discarding // messages due to overflow. @@ -152,14 +145,7 @@ class MethodChannel { // When |warns| is false, the channel is expected to overflow and warning // messages will not be shown. void SetWarnsOnOverflow(bool warns) { - auto control_channel = std::make_unique>( - messenger_, kControlChannelName, &StandardMethodCodec::GetInstance()); - - control_channel->InvokeMethod( - kOverflowMethod, std::make_unique(EncodableList{ - EncodableValue(name_), - EncodableValue(!warns), - })); + SetChannelWarnsOnOverflow(messenger_, name_, warns); } private: @@ -168,6 +154,49 @@ class MethodChannel { const MethodCodec* codec_; }; +namespace { + +static constexpr char kControlChannelName[] = "dev.flutter/channel-buffers"; +static constexpr char kResizeMethod[] = "resize"; +static constexpr char kOverflowMethod[] = "overflow"; + +// Adjusts the number of messages that will get buffered when sending messages +// to channels that aren't fully set up yet. For example, the engine isn't +// running yet or the channel's message handler isn't set up on the Dart side +// yet. +void ResizeChannel(BinaryMessenger* messenger, std::string name, int new_size) { + auto control_channel = std::make_unique>( + messenger, kControlChannelName, &StandardMethodCodec::GetInstance()); + + // The deserialization logic handles only 32 bits values, see + // https://github.com/flutter/engine/blob/93e8901490e78c7ba7e319cce4470d9c6478c6dc/lib/ui/channel_buffers.dart#L495. + control_channel->InvokeMethod( + kResizeMethod, std::make_unique(EncodableList{ + EncodableValue(name), + EncodableValue(static_cast(new_size)), + })); +} + +// Defines whether the channel should show warning messages when discarding +// messages due to overflow. +// +// When |warns| is false, the channel is expected to overflow and warning +// messages will not be shown. +void SetChannelWarnsOnOverflow(BinaryMessenger* messenger, + std::string name, + bool warns) { + auto control_channel = std::make_unique>( + messenger, kControlChannelName, &StandardMethodCodec::GetInstance()); + + control_channel->InvokeMethod(kOverflowMethod, + std::make_unique(EncodableList{ + EncodableValue(name), + EncodableValue(!warns), + })); +} + +} // namespace + } // namespace flutter #endif // FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_METHOD_CHANNEL_H_ diff --git a/shell/platform/common/client_wrapper/method_channel_unittests.cc b/shell/platform/common/client_wrapper/method_channel_unittests.cc index b9dcb91e9a064..2edce72a566c6 100644 --- a/shell/platform/common/client_wrapper/method_channel_unittests.cc +++ b/shell/platform/common/client_wrapper/method_channel_unittests.cc @@ -172,6 +172,11 @@ TEST(MethodChannelTest, Resize) { channel.Resize(3); + // Because the Dart implementation for the control channel implements its own + // custom deserialization logic, this test compares the generated bytes array + // to the expected one (for instance, the deserialization logic expects the + // size parameter of the resize method call to be an uint32). + // // The expected content was created from the following Dart code: // MethodCall call = MethodCall('resize', ['flutter/test',3]); // StandardMethodCodec().encodeMethodCall(call).buffer.asUint8List(); From c6e9fe9de3a6f728bb87def6987a493a33e5d8d5 Mon Sep 17 00:00:00 2001 From: Bruno Leroux Date: Thu, 14 Dec 2023 09:10:15 +0100 Subject: [PATCH 6/6] Move helper functions to core_implementations.cc --- .../client_wrapper/core_implementations.cc | 42 +++++++++++++ .../include/flutter/basic_message_channel.h | 27 +++++++- .../include/flutter/method_channel.h | 61 ++----------------- 3 files changed, 71 insertions(+), 59 deletions(-) diff --git a/shell/platform/common/client_wrapper/core_implementations.cc b/shell/platform/common/client_wrapper/core_implementations.cc index 1eb5a5898117d..f682f1b22994e 100644 --- a/shell/platform/common/client_wrapper/core_implementations.cc +++ b/shell/platform/common/client_wrapper/core_implementations.cc @@ -19,6 +19,8 @@ #include "binary_messenger_impl.h" #include "include/flutter/engine_method_result.h" +#include "include/flutter/method_channel.h" +#include "include/flutter/standard_method_codec.h" #include "texture_registrar_impl.h" namespace flutter { @@ -164,6 +166,46 @@ void ReplyManager::SendResponseData(const std::vector* data) { } // namespace internal +// ========== method_channel.h ========== + +namespace { + +constexpr char kControlChannelName[] = "dev.flutter/channel-buffers"; +constexpr char kResizeMethod[] = "resize"; +constexpr char kOverflowMethod[] = "overflow"; + +} // namespace + +namespace internal { + +void ResizeChannel(BinaryMessenger* messenger, std::string name, int new_size) { + auto control_channel = std::make_unique>( + messenger, kControlChannelName, &StandardMethodCodec::GetInstance()); + + // The deserialization logic handles only 32 bits values, see + // https://github.com/flutter/engine/blob/93e8901490e78c7ba7e319cce4470d9c6478c6dc/lib/ui/channel_buffers.dart#L495. + control_channel->InvokeMethod( + kResizeMethod, std::make_unique(EncodableList{ + EncodableValue(name), + EncodableValue(static_cast(new_size)), + })); +} + +void SetChannelWarnsOnOverflow(BinaryMessenger* messenger, + std::string name, + bool warns) { + auto control_channel = std::make_unique>( + messenger, kControlChannelName, &StandardMethodCodec::GetInstance()); + + control_channel->InvokeMethod(kOverflowMethod, + std::make_unique(EncodableList{ + EncodableValue(name), + EncodableValue(!warns), + })); +} + +} // namespace internal + // ========== texture_registrar_impl.h ========== TextureRegistrarImpl::TextureRegistrarImpl( diff --git a/shell/platform/common/client_wrapper/include/flutter/basic_message_channel.h b/shell/platform/common/client_wrapper/include/flutter/basic_message_channel.h index 2e1f42e9d10f1..27c6cc93d6f50 100644 --- a/shell/platform/common/client_wrapper/include/flutter/basic_message_channel.h +++ b/shell/platform/common/client_wrapper/include/flutter/basic_message_channel.h @@ -11,10 +11,29 @@ #include "binary_messenger.h" #include "message_codec.h" -#include "method_channel.h" namespace flutter { +namespace internal { +// Internal helper functions used by BasicMessageChannel and MethodChannel. + +// Adjusts the number of messages that will get buffered when sending messages +// to channels that aren't fully set up yet. For example, the engine isn't +// running yet or the channel's message handler isn't set up on the Dart side +// yet. +void ResizeChannel(BinaryMessenger* messenger, std::string name, int new_size); + +// Defines whether the channel should show warning messages when discarding +// messages due to overflow. +// +// When |warns| is false, the channel is expected to overflow and warning +// messages will not be shown. +void SetChannelWarnsOnOverflow(BinaryMessenger* messenger, + std::string name, + bool warns); + +} // namespace internal + class EncodableValue; // A message reply callback. @@ -106,7 +125,9 @@ class BasicMessageChannel { // to channels that aren't fully set up yet. For example, the engine isn't // running yet or the channel's message handler isn't set up on the Dart side // yet. - void Resize(int new_size) { ResizeChannel(messenger_, name_, new_size); } + void Resize(int new_size) { + internal::ResizeChannel(messenger_, name_, new_size); + } // Defines whether the channel should show warning messages when discarding // messages due to overflow. @@ -114,7 +135,7 @@ class BasicMessageChannel { // When |warns| is false, the channel is expected to overflow and warning // messages will not be shown. void SetWarnsOnOverflow(bool warns) { - SetChannelWarnsOnOverflow(messenger_, name_, warns); + internal::SetChannelWarnsOnOverflow(messenger_, name_, warns); } private: diff --git a/shell/platform/common/client_wrapper/include/flutter/method_channel.h b/shell/platform/common/client_wrapper/include/flutter/method_channel.h index 899af6ca0b129..a4029fccf7a5c 100644 --- a/shell/platform/common/client_wrapper/include/flutter/method_channel.h +++ b/shell/platform/common/client_wrapper/include/flutter/method_channel.h @@ -8,25 +8,15 @@ #include #include +#include "basic_message_channel.h" #include "binary_messenger.h" #include "engine_method_result.h" #include "method_call.h" #include "method_codec.h" #include "method_result.h" -#include "standard_method_codec.h" namespace flutter { -namespace { - -void ResizeChannel(BinaryMessenger* messenger, std::string name, int new_size); - -void SetChannelWarnsOnOverflow(BinaryMessenger* messenger, - std::string name, - bool warns); - -} // namespace - class EncodableValue; // A handler for receiving a method call from the Flutter engine. @@ -137,7 +127,9 @@ class MethodChannel { // to channels that aren't fully set up yet. For example, the engine isn't // running yet or the channel's message handler isn't set up on the Dart side // yet. - void Resize(int new_size) { ResizeChannel(messenger_, name_, new_size); } + void Resize(int new_size) { + internal::ResizeChannel(messenger_, name_, new_size); + } // Defines whether the channel should show warning messages when discarding // messages due to overflow. @@ -145,7 +137,7 @@ class MethodChannel { // When |warns| is false, the channel is expected to overflow and warning // messages will not be shown. void SetWarnsOnOverflow(bool warns) { - SetChannelWarnsOnOverflow(messenger_, name_, warns); + internal::SetChannelWarnsOnOverflow(messenger_, name_, warns); } private: @@ -154,49 +146,6 @@ class MethodChannel { const MethodCodec* codec_; }; -namespace { - -static constexpr char kControlChannelName[] = "dev.flutter/channel-buffers"; -static constexpr char kResizeMethod[] = "resize"; -static constexpr char kOverflowMethod[] = "overflow"; - -// Adjusts the number of messages that will get buffered when sending messages -// to channels that aren't fully set up yet. For example, the engine isn't -// running yet or the channel's message handler isn't set up on the Dart side -// yet. -void ResizeChannel(BinaryMessenger* messenger, std::string name, int new_size) { - auto control_channel = std::make_unique>( - messenger, kControlChannelName, &StandardMethodCodec::GetInstance()); - - // The deserialization logic handles only 32 bits values, see - // https://github.com/flutter/engine/blob/93e8901490e78c7ba7e319cce4470d9c6478c6dc/lib/ui/channel_buffers.dart#L495. - control_channel->InvokeMethod( - kResizeMethod, std::make_unique(EncodableList{ - EncodableValue(name), - EncodableValue(static_cast(new_size)), - })); -} - -// Defines whether the channel should show warning messages when discarding -// messages due to overflow. -// -// When |warns| is false, the channel is expected to overflow and warning -// messages will not be shown. -void SetChannelWarnsOnOverflow(BinaryMessenger* messenger, - std::string name, - bool warns) { - auto control_channel = std::make_unique>( - messenger, kControlChannelName, &StandardMethodCodec::GetInstance()); - - control_channel->InvokeMethod(kOverflowMethod, - std::make_unique(EncodableList{ - EncodableValue(name), - EncodableValue(!warns), - })); -} - -} // namespace - } // namespace flutter #endif // FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_METHOD_CHANNEL_H_