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

Commit 53430c7

Browse files
authored
[macOS,iOS] Expose channel buffers 'resize' and 'overflow' control co… (#44848)
## Description This PR update the helper function that invokes the control channel 'resize' command (previous implementation relied on a deprecated format). It also adds a similar helper function for the 'overflow' commands exposed by the control channel. See: https://github.com/flutter/engine/blob/93e8901490e78c7ba7e319cce4470d9c6478c6dc/lib/ui/channel_buffers.dart#L302-L309 ## Related Issue iOS and macOS implementation for flutter/flutter#132386 Similar implementations: - Android: #44434 - Linux: #44636 ## Tests Adds two tests.
1 parent 57723a9 commit 53430c7

File tree

3 files changed

+117
-7
lines changed

3 files changed

+117
-7
lines changed

shell/platform/darwin/common/framework/Headers/FlutterChannels.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,9 +143,46 @@ FLUTTER_DARWIN_EXPORT
143143
* Adjusts the number of messages that will get buffered when sending messages to
144144
* channels that aren't fully set up yet. For example, the engine isn't running
145145
* yet or the channel's message handler isn't set up on the Dart side yet.
146+
*
147+
* @param name The channel name.
148+
* @param messenger The binary messenger.
149+
* @param newSize The number of messages that will get buffered.
150+
*/
151+
+ (void)resizeChannelWithName:(NSString*)name
152+
binaryMessenger:(NSObject<FlutterBinaryMessenger>*)messenger
153+
size:(NSInteger)newSize;
154+
155+
/**
156+
* Adjusts the number of messages that will get buffered when sending messages to
157+
* channels that aren't fully set up yet. For example, the engine isn't running
158+
* yet or the channel's message handler isn't set up on the Dart side yet.
159+
*
160+
* @param newSize The number of messages that will get buffered.
146161
*/
147162
- (void)resizeChannelBuffer:(NSInteger)newSize;
148163

164+
/**
165+
* Defines whether the channel should show warning messages when discarding messages
166+
* due to overflow.
167+
*
168+
* @param warns When false, the channel is expected to overflow and warning messages
169+
* will not be shown.
170+
* @param name The channel name.
171+
* @param messenger The binary messenger.
172+
*/
173+
+ (void)setWarnsOnOverflow:(BOOL)warns
174+
forChannelWithName:(NSString*)name
175+
binaryMessenger:(NSObject<FlutterBinaryMessenger>*)messenger;
176+
177+
/**
178+
* Defines whether the channel should show warning messages when discarding messages
179+
* due to overflow.
180+
*
181+
* @param warns When false, the channel is expected to overflow and warning messages
182+
* will not be shown.
183+
*/
184+
- (void)setWarnsOnOverflow:(BOOL)warns;
185+
149186
@end
150187

151188
/**

shell/platform/darwin/common/framework/Source/FlutterChannels.mm

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,41 @@
99
#pragma mark - Basic message channel
1010

1111
static NSString* const kFlutterChannelBuffersChannel = @"dev.flutter/channel-buffers";
12+
static NSString* const kResizeMethod = @"resize";
13+
static NSString* const kOverflowMethod = @"overflow";
1214

1315
static void ResizeChannelBuffer(NSObject<FlutterBinaryMessenger>* binaryMessenger,
1416
NSString* channel,
1517
NSInteger newSize) {
16-
NSString* messageString = [NSString stringWithFormat:@"resize\r%@\r%@", channel, @(newSize)];
17-
NSData* message = [messageString dataUsingEncoding:NSUTF8StringEncoding];
18+
NSCAssert(newSize >= 0, @"Channel buffer size must be non-negative");
19+
// Cast newSize to int because the deserialization logic handles only 32 bits values,
20+
// see
21+
// https://github.com/flutter/engine/blob/93e8901490e78c7ba7e319cce4470d9c6478c6dc/lib/ui/channel_buffers.dart#L495.
22+
NSArray* args = @[ channel, @(static_cast<int>(newSize)) ];
23+
FlutterMethodCall* resizeMethodCall = [FlutterMethodCall methodCallWithMethodName:kResizeMethod
24+
arguments:args];
25+
NSObject<FlutterMethodCodec>* codec = [FlutterStandardMethodCodec sharedInstance];
26+
NSData* message = [codec encodeMethodCall:resizeMethodCall];
27+
[binaryMessenger sendOnChannel:kFlutterChannelBuffersChannel message:message];
28+
}
29+
30+
/**
31+
* Defines whether a channel should show warning messages when discarding messages
32+
* due to overflow.
33+
*
34+
* @param binaryMessenger The binary messenger.
35+
* @param channel The channel name.
36+
* @param warns When false, the channel is expected to overflow and warning messages
37+
* will not be shown.
38+
*/
39+
static void SetWarnsOnOverflow(NSObject<FlutterBinaryMessenger>* binaryMessenger,
40+
NSString* channel,
41+
BOOL warns) {
42+
FlutterMethodCall* overflowMethodCall =
43+
[FlutterMethodCall methodCallWithMethodName:kOverflowMethod
44+
arguments:@[ channel, @(!warns) ]];
45+
NSObject<FlutterMethodCodec>* codec = [FlutterStandardMethodCodec sharedInstance];
46+
NSData* message = [codec encodeMethodCall:overflowMethodCall];
1847
[binaryMessenger sendOnChannel:kFlutterChannelBuffersChannel message:message];
1948
}
2049

@@ -114,10 +143,26 @@ - (void)setMessageHandler:(FlutterMessageHandler)handler {
114143
_connection = SetMessageHandler(_messenger, _name, messageHandler, _taskQueue);
115144
}
116145

146+
+ (void)resizeChannelWithName:(NSString*)name
147+
binaryMessenger:(NSObject<FlutterBinaryMessenger>*)messenger
148+
size:(NSInteger)newSize {
149+
ResizeChannelBuffer(messenger, name, newSize);
150+
}
151+
117152
- (void)resizeChannelBuffer:(NSInteger)newSize {
118153
ResizeChannelBuffer(_messenger, _name, newSize);
119154
}
120155

156+
+ (void)setWarnsOnOverflow:(BOOL)warns
157+
forChannelWithName:(NSString*)name
158+
binaryMessenger:(NSObject<FlutterBinaryMessenger>*)messenger {
159+
SetWarnsOnOverflow(messenger, name, warns);
160+
}
161+
162+
- (void)setWarnsOnOverflow:(BOOL)warns {
163+
SetWarnsOnOverflow(_messenger, _name, warns);
164+
}
165+
121166
@end
122167

123168
#pragma mark - Method channel

shell/platform/darwin/common/framework/Source/FlutterChannelsTest.m

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,31 @@ - (void)testCallMethodHandler {
147147
}
148148

149149
- (void)testResize {
150-
NSString* channelName = @"foo";
150+
NSString* channelName = @"flutter/test";
151+
id binaryMessenger = OCMStrictProtocolMock(@protocol(FlutterBinaryMessenger));
152+
id codec = OCMProtocolMock(@protocol(FlutterMethodCodec));
153+
FlutterBasicMessageChannel* channel =
154+
[[FlutterBasicMessageChannel alloc] initWithName:channelName
155+
binaryMessenger:binaryMessenger
156+
codec:codec];
157+
XCTAssertNotNil(channel);
158+
159+
// The expected content was created from the following Dart code:
160+
// MethodCall call = MethodCall('resize', ['flutter/test',3]);
161+
// StandardMethodCodec().encodeMethodCall(call).buffer.asUint8List();
162+
const unsigned char bytes[] = {7, 6, 114, 101, 115, 105, 122, 101, 12, 2,
163+
7, 12, 102, 108, 117, 116, 116, 101, 114, 47,
164+
116, 101, 115, 116, 3, 3, 0, 0, 0};
165+
NSData* expectedMessage = [NSData dataWithBytes:bytes length:sizeof(bytes)];
166+
167+
OCMExpect([binaryMessenger sendOnChannel:@"dev.flutter/channel-buffers" message:expectedMessage]);
168+
[channel resizeChannelBuffer:3];
169+
OCMVerifyAll(binaryMessenger);
170+
[binaryMessenger stopMocking];
171+
}
172+
173+
- (bool)testSetWarnsOnOverflow {
174+
NSString* channelName = @"flutter/test";
151175
id binaryMessenger = OCMStrictProtocolMock(@protocol(FlutterBinaryMessenger));
152176
id codec = OCMProtocolMock(@protocol(FlutterMethodCodec));
153177
FlutterBasicMessageChannel* channel =
@@ -156,11 +180,15 @@ - (void)testResize {
156180
codec:codec];
157181
XCTAssertNotNil(channel);
158182

159-
NSString* expectedMessageString =
160-
[NSString stringWithFormat:@"resize\r%@\r%@", channelName, @100];
161-
NSData* expectedMessage = [expectedMessageString dataUsingEncoding:NSUTF8StringEncoding];
183+
// The expected content was created from the following Dart code:
184+
// MethodCall call = MethodCall('overflow',['flutter/test', true]);
185+
// StandardMethodCodec().encodeMethodCall(call).buffer.asUint8List();
186+
const unsigned char bytes[] = {7, 8, 111, 118, 101, 114, 102, 108, 111, 119, 12, 2, 7, 12,
187+
102, 108, 117, 116, 116, 101, 114, 47, 116, 101, 115, 116, 1};
188+
NSData* expectedMessage = [NSData dataWithBytes:bytes length:sizeof(bytes)];
189+
162190
OCMExpect([binaryMessenger sendOnChannel:@"dev.flutter/channel-buffers" message:expectedMessage]);
163-
[channel resizeChannelBuffer:100];
191+
[channel setWarnsOnOverflow:NO];
164192
OCMVerifyAll(binaryMessenger);
165193
[binaryMessenger stopMocking];
166194
}

0 commit comments

Comments
 (0)