Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit a565cea

Browse files
authored
[Windows] Expose channel buffers 'resize' and 'overflow' control commands exposed by the control channel. (#47158)
## Description This PR adds two helper functions to invoke the 'resize' and 'overflow' commands exposed by the control channel. See: https://github.com/flutter/engine/blob/93e8901490e78c7ba7e319cce4470d9c6478c6dc/lib/ui/channel_buffers.dart#L302-L309 Implementation based on the discussion from #46998. ## Related Issue Windows implementation for flutter/flutter#132386 ## Tests Adds 4 tests.
1 parent caf3327 commit a565cea

File tree

5 files changed

+240
-1
lines changed

5 files changed

+240
-1
lines changed

shell/platform/common/client_wrapper/basic_message_channel_unittests.cc

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#include "flutter/shell/platform/common/client_wrapper/include/flutter/binary_messenger.h"
1111
#include "flutter/shell/platform/common/client_wrapper/include/flutter/standard_message_codec.h"
12+
#include "flutter/shell/platform/common/client_wrapper/include/flutter/standard_method_codec.h"
1213
#include "gtest/gtest.h"
1314

1415
namespace flutter {
@@ -20,23 +21,34 @@ class TestBinaryMessenger : public BinaryMessenger {
2021
void Send(const std::string& channel,
2122
const uint8_t* message,
2223
const size_t message_size,
23-
BinaryReply reply) const override {}
24+
BinaryReply reply) const override {
25+
send_called_ = true;
26+
int length = static_cast<int>(message_size);
27+
last_message_ =
28+
std::vector<uint8_t>(message, message + length * sizeof(uint8_t));
29+
}
2430

2531
void SetMessageHandler(const std::string& channel,
2632
BinaryMessageHandler handler) override {
2733
last_message_handler_channel_ = channel;
2834
last_message_handler_ = handler;
2935
}
3036

37+
bool send_called() { return send_called_; }
38+
3139
std::string last_message_handler_channel() {
3240
return last_message_handler_channel_;
3341
}
3442

3543
BinaryMessageHandler last_message_handler() { return last_message_handler_; }
3644

45+
std::vector<uint8_t> last_message() { return last_message_; }
46+
3747
private:
48+
mutable bool send_called_ = false;
3849
std::string last_message_handler_channel_;
3950
BinaryMessageHandler last_message_handler_;
51+
mutable std::vector<uint8_t> last_message_;
4052
};
4153

4254
} // namespace
@@ -86,4 +98,68 @@ TEST(BasicMessageChannelTest, Unregistration) {
8698
EXPECT_EQ(messenger.last_message_handler(), nullptr);
8799
}
88100

101+
// Tests that calling Resize generates the binary message expected by the Dart
102+
// implementation.
103+
TEST(BasicMessageChannelTest, Resize) {
104+
TestBinaryMessenger messenger;
105+
const std::string channel_name("flutter/test");
106+
BasicMessageChannel channel(&messenger, channel_name,
107+
&flutter::StandardMessageCodec::GetInstance());
108+
109+
channel.Resize(3);
110+
111+
// Because the Dart implementation for the control channel implements its own
112+
// custom deserialization logic, this test compares the generated bytes array
113+
// to the expected one (for instance, the deserialization logic expects the
114+
// size parameter of the resize method call to be an uint32).
115+
//
116+
// The expected content was created from the following Dart code:
117+
// MethodCall call = MethodCall('resize', ['flutter/test',3]);
118+
// StandardMethodCodec().encodeMethodCall(call).buffer.asUint8List();
119+
const int expected_message_size = 29;
120+
121+
EXPECT_EQ(messenger.send_called(), true);
122+
EXPECT_EQ(static_cast<int>(messenger.last_message().size()),
123+
expected_message_size);
124+
125+
int expected[expected_message_size] = {
126+
7, 6, 114, 101, 115, 105, 122, 101, 12, 2, 7, 12, 102, 108, 117,
127+
116, 116, 101, 114, 47, 116, 101, 115, 116, 3, 3, 0, 0, 0};
128+
for (int i = 0; i < expected_message_size; i++) {
129+
EXPECT_EQ(messenger.last_message()[i], expected[i]);
130+
}
131+
}
132+
133+
// Tests that calling SetWarnsOnOverflow generates the binary message expected
134+
// by the Dart implementation.
135+
TEST(BasicMessageChannelTest, SetWarnsOnOverflow) {
136+
TestBinaryMessenger messenger;
137+
138+
const std::string channel_name("flutter/test");
139+
BasicMessageChannel channel(&messenger, channel_name,
140+
&flutter::StandardMessageCodec::GetInstance());
141+
142+
channel.SetWarnsOnOverflow(false);
143+
144+
// Because the Dart implementation for the control channel implements its own
145+
// custom deserialization logic, this test compares the generated bytes array
146+
// to the expected one.
147+
//
148+
// The expected content was created from the following Dart code:
149+
// MethodCall call = MethodCall('overflow',['flutter/test', true]);
150+
// StandardMethodCodec().encodeMethodCall(call).buffer.asUint8List();
151+
const int expected_message_size = 27;
152+
153+
EXPECT_EQ(messenger.send_called(), true);
154+
EXPECT_EQ(static_cast<int>(messenger.last_message().size()),
155+
expected_message_size);
156+
157+
int expected[expected_message_size] = {
158+
7, 8, 111, 118, 101, 114, 102, 108, 111, 119, 12, 2, 7, 12,
159+
102, 108, 117, 116, 116, 101, 114, 47, 116, 101, 115, 116, 1};
160+
for (int i = 0; i < expected_message_size; i++) {
161+
EXPECT_EQ(messenger.last_message()[i], expected[i]);
162+
}
163+
}
164+
89165
} // namespace flutter

shell/platform/common/client_wrapper/core_implementations.cc

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919

2020
#include "binary_messenger_impl.h"
2121
#include "include/flutter/engine_method_result.h"
22+
#include "include/flutter/method_channel.h"
23+
#include "include/flutter/standard_method_codec.h"
2224
#include "texture_registrar_impl.h"
2325

2426
namespace flutter {
@@ -164,6 +166,46 @@ void ReplyManager::SendResponseData(const std::vector<uint8_t>* data) {
164166

165167
} // namespace internal
166168

169+
// ========== method_channel.h ==========
170+
171+
namespace {
172+
173+
constexpr char kControlChannelName[] = "dev.flutter/channel-buffers";
174+
constexpr char kResizeMethod[] = "resize";
175+
constexpr char kOverflowMethod[] = "overflow";
176+
177+
} // namespace
178+
179+
namespace internal {
180+
181+
void ResizeChannel(BinaryMessenger* messenger, std::string name, int new_size) {
182+
auto control_channel = std::make_unique<MethodChannel<EncodableValue>>(
183+
messenger, kControlChannelName, &StandardMethodCodec::GetInstance());
184+
185+
// The deserialization logic handles only 32 bits values, see
186+
// https://github.com/flutter/engine/blob/93e8901490e78c7ba7e319cce4470d9c6478c6dc/lib/ui/channel_buffers.dart#L495.
187+
control_channel->InvokeMethod(
188+
kResizeMethod, std::make_unique<EncodableValue>(EncodableList{
189+
EncodableValue(name),
190+
EncodableValue(static_cast<int32_t>(new_size)),
191+
}));
192+
}
193+
194+
void SetChannelWarnsOnOverflow(BinaryMessenger* messenger,
195+
std::string name,
196+
bool warns) {
197+
auto control_channel = std::make_unique<MethodChannel<EncodableValue>>(
198+
messenger, kControlChannelName, &StandardMethodCodec::GetInstance());
199+
200+
control_channel->InvokeMethod(kOverflowMethod,
201+
std::make_unique<EncodableValue>(EncodableList{
202+
EncodableValue(name),
203+
EncodableValue(!warns),
204+
}));
205+
}
206+
207+
} // namespace internal
208+
167209
// ========== texture_registrar_impl.h ==========
168210

169211
TextureRegistrarImpl::TextureRegistrarImpl(

shell/platform/common/client_wrapper/include/flutter/basic_message_channel.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,26 @@
1414

1515
namespace flutter {
1616

17+
namespace internal {
18+
// Internal helper functions used by BasicMessageChannel and MethodChannel.
19+
20+
// Adjusts the number of messages that will get buffered when sending messages
21+
// to channels that aren't fully set up yet. For example, the engine isn't
22+
// running yet or the channel's message handler isn't set up on the Dart side
23+
// yet.
24+
void ResizeChannel(BinaryMessenger* messenger, std::string name, int new_size);
25+
26+
// Defines whether the channel should show warning messages when discarding
27+
// messages due to overflow.
28+
//
29+
// When |warns| is false, the channel is expected to overflow and warning
30+
// messages will not be shown.
31+
void SetChannelWarnsOnOverflow(BinaryMessenger* messenger,
32+
std::string name,
33+
bool warns);
34+
35+
} // namespace internal
36+
1737
class EncodableValue;
1838

1939
// A message reply callback.
@@ -101,6 +121,23 @@ class BasicMessageChannel {
101121
messenger_->SetMessageHandler(name_, std::move(binary_handler));
102122
}
103123

124+
// Adjusts the number of messages that will get buffered when sending messages
125+
// to channels that aren't fully set up yet. For example, the engine isn't
126+
// running yet or the channel's message handler isn't set up on the Dart side
127+
// yet.
128+
void Resize(int new_size) {
129+
internal::ResizeChannel(messenger_, name_, new_size);
130+
}
131+
132+
// Defines whether the channel should show warning messages when discarding
133+
// messages due to overflow.
134+
//
135+
// When |warns| is false, the channel is expected to overflow and warning
136+
// messages will not be shown.
137+
void SetWarnsOnOverflow(bool warns) {
138+
internal::SetChannelWarnsOnOverflow(messenger_, name_, warns);
139+
}
140+
104141
private:
105142
BinaryMessenger* messenger_;
106143
std::string name_;

shell/platform/common/client_wrapper/include/flutter/method_channel.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <iostream>
99
#include <string>
1010

11+
#include "basic_message_channel.h"
1112
#include "binary_messenger.h"
1213
#include "engine_method_result.h"
1314
#include "method_call.h"
@@ -122,6 +123,23 @@ class MethodChannel {
122123
messenger_->SetMessageHandler(name_, std::move(binary_handler));
123124
}
124125

126+
// Adjusts the number of messages that will get buffered when sending messages
127+
// to channels that aren't fully set up yet. For example, the engine isn't
128+
// running yet or the channel's message handler isn't set up on the Dart side
129+
// yet.
130+
void Resize(int new_size) {
131+
internal::ResizeChannel(messenger_, name_, new_size);
132+
}
133+
134+
// Defines whether the channel should show warning messages when discarding
135+
// messages due to overflow.
136+
//
137+
// When |warns| is false, the channel is expected to overflow and warning
138+
// messages will not be shown.
139+
void SetWarnsOnOverflow(bool warns) {
140+
internal::SetChannelWarnsOnOverflow(messenger_, name_, warns);
141+
}
142+
125143
private:
126144
BinaryMessenger* messenger_;
127145
std::string name_;

shell/platform/common/client_wrapper/method_channel_unittests.cc

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ class TestBinaryMessenger : public BinaryMessenger {
2424
BinaryReply reply) const override {
2525
send_called_ = true;
2626
last_reply_handler_ = reply;
27+
int length = static_cast<int>(message_size);
28+
last_message_ =
29+
std::vector<uint8_t>(message, message + length * sizeof(uint8_t));
2730
}
2831

2932
void SetMessageHandler(const std::string& channel,
@@ -42,11 +45,14 @@ class TestBinaryMessenger : public BinaryMessenger {
4245

4346
BinaryMessageHandler last_message_handler() { return last_message_handler_; }
4447

48+
std::vector<uint8_t> last_message() { return last_message_; }
49+
4550
private:
4651
mutable bool send_called_ = false;
4752
mutable BinaryReply last_reply_handler_;
4853
std::string last_message_handler_channel_;
4954
BinaryMessageHandler last_message_handler_;
55+
mutable std::vector<uint8_t> last_message_;
5056
};
5157

5258
} // namespace
@@ -156,4 +162,64 @@ TEST(MethodChannelTest, InvokeNotImplemented) {
156162
EXPECT_TRUE(received_not_implemented);
157163
}
158164

165+
// Tests that calling Resize generates the binary message expected by the Dart
166+
// implementation.
167+
TEST(MethodChannelTest, Resize) {
168+
TestBinaryMessenger messenger;
169+
const std::string channel_name("flutter/test");
170+
MethodChannel channel(&messenger, channel_name,
171+
&StandardMethodCodec::GetInstance());
172+
173+
channel.Resize(3);
174+
175+
// Because the Dart implementation for the control channel implements its own
176+
// custom deserialization logic, this test compares the generated bytes array
177+
// to the expected one (for instance, the deserialization logic expects the
178+
// size parameter of the resize method call to be an uint32).
179+
//
180+
// The expected content was created from the following Dart code:
181+
// MethodCall call = MethodCall('resize', ['flutter/test',3]);
182+
// StandardMethodCodec().encodeMethodCall(call).buffer.asUint8List();
183+
const int expected_message_size = 29;
184+
185+
EXPECT_EQ(messenger.send_called(), true);
186+
EXPECT_EQ(static_cast<int>(messenger.last_message().size()),
187+
expected_message_size);
188+
189+
int expected[expected_message_size] = {
190+
7, 6, 114, 101, 115, 105, 122, 101, 12, 2, 7, 12, 102, 108, 117,
191+
116, 116, 101, 114, 47, 116, 101, 115, 116, 3, 3, 0, 0, 0};
192+
for (int i = 0; i < expected_message_size; i++) {
193+
EXPECT_EQ(messenger.last_message()[i], expected[i]);
194+
}
195+
}
196+
197+
// Tests that calling SetWarnsOnOverflow generates the binary message expected
198+
// by the Dart implementation.
199+
TEST(MethodChannelTest, SetWarnsOnOverflow) {
200+
TestBinaryMessenger messenger;
201+
202+
const std::string channel_name("flutter/test");
203+
MethodChannel channel(&messenger, channel_name,
204+
&StandardMethodCodec::GetInstance());
205+
206+
channel.SetWarnsOnOverflow(false);
207+
208+
// The expected content was created from the following Dart code:
209+
// MethodCall call = MethodCall('overflow',['flutter/test', true]);
210+
// StandardMethodCodec().encodeMethodCall(call).buffer.asUint8List();
211+
const int expected_message_size = 27;
212+
213+
EXPECT_EQ(messenger.send_called(), true);
214+
EXPECT_EQ(static_cast<int>(messenger.last_message().size()),
215+
expected_message_size);
216+
217+
int expected[expected_message_size] = {
218+
7, 8, 111, 118, 101, 114, 102, 108, 111, 119, 12, 2, 7, 12,
219+
102, 108, 117, 116, 116, 101, 114, 47, 116, 101, 115, 116, 1};
220+
for (int i = 0; i < expected_message_size; i++) {
221+
EXPECT_EQ(messenger.last_message()[i], expected[i]);
222+
}
223+
}
224+
159225
} // namespace flutter

0 commit comments

Comments
 (0)