Skip to content

Commit

Permalink
[macOS,iOS] Expose channel buffers 'resize' and 'overflow' control co…
Browse files Browse the repository at this point in the history
…mmands
  • Loading branch information
bleroux committed Aug 18, 2023
1 parent 2f9a4ef commit 4248e61
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 7 deletions.
37 changes: 37 additions & 0 deletions shell/platform/darwin/common/framework/Headers/FlutterChannels.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,46 @@ FLUTTER_DARWIN_EXPORT
* 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.
*
* @param name The channel name.
* @param messenger The binary messenger.
* @param newSize The new size of the buffer.
*/
+ (void)resizeChannelWithName:(NSString*)name
binaryMessenger:(NSObject<FlutterBinaryMessenger>*)messenger
newSize:(NSInteger)newSize;

/**
* 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.
*
* @param newSize The new size of the buffer.
*/
- (void)resizeChannelBuffer:(NSInteger)newSize;

/**
* Toggles whether the channel should show warning messages when discarding messages
* due to overflow.
*
* @param name The channel name.
* @param messenger The binary messenger.
* @param allowed When true, the channel is expected to overflow and warning messages
* will not be shown.
*/
+ (void)setAllowOverflowChannelWithName:(NSString*)name
binaryMessenger:(NSObject<FlutterBinaryMessenger>*)messenger
allowed:(BOOL)allowed;

/**
* Toggles whether the channel should show warning messages when discarding messages
* due to overflow.
*
* @param allowed When true, the channel is expected to overflow and warning messages
* will not be shown.
*/
- (void)setAllowOverflow:(BOOL)allowed;

@end

/**
Expand Down
36 changes: 34 additions & 2 deletions shell/platform/darwin/common/framework/Source/FlutterChannels.mm
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,28 @@
#pragma mark - Basic message channel

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

static void ResizeChannelBuffer(NSObject<FlutterBinaryMessenger>* binaryMessenger,
NSString* channel,
NSInteger newSize) {
NSString* messageString = [NSString stringWithFormat:@"resize\r%@\r%@", channel, @(newSize)];
NSData* message = [messageString dataUsingEncoding:NSUTF8StringEncoding];
NSArray* args = @[ channel, [NSNumber numberWithInt:newSize] ];
FlutterMethodCall* resizeMethodCall = [FlutterMethodCall methodCallWithMethodName:kResizeMethod
arguments:args];
NSObject<FlutterMethodCodec>* codec = [FlutterStandardMethodCodec sharedInstance];
NSData* message = [codec encodeMethodCall:resizeMethodCall];
[binaryMessenger sendOnChannel:kFlutterChannelBuffersChannel message:message];
}

static void SetAllowChannelOverflow(NSObject<FlutterBinaryMessenger>* binaryMessenger,
NSString* channel,
BOOL allowed) {
NSArray* args = @[ channel, [NSNumber numberWithBool:allowed] ];
FlutterMethodCall* overflowMethodCall =
[FlutterMethodCall methodCallWithMethodName:kOverflowMethod arguments:args];
NSObject<FlutterMethodCodec>* codec = [FlutterStandardMethodCodec sharedInstance];
NSData* message = [codec encodeMethodCall:overflowMethodCall];
[binaryMessenger sendOnChannel:kFlutterChannelBuffersChannel message:message];
}

Expand Down Expand Up @@ -114,10 +130,26 @@ - (void)setMessageHandler:(FlutterMessageHandler)handler {
_connection = SetMessageHandler(_messenger, _name, messageHandler, _taskQueue);
}

+ (void)resizeChannelWithName:(NSString*)name
binaryMessenger:(NSObject<FlutterBinaryMessenger>*)messenger
newSize:(NSInteger)newSize {
ResizeChannelBuffer(messenger, name, newSize);
}

- (void)resizeChannelBuffer:(NSInteger)newSize {
ResizeChannelBuffer(_messenger, _name, newSize);
}

+ (void)setAllowOverflowChannelWithName:(NSString*)name
binaryMessenger:(NSObject<FlutterBinaryMessenger>*)messenger
allowed:(BOOL)allowed {
SetAllowChannelOverflow(messenger, name, allowed);
}

- (void)setAllowOverflow:(BOOL)allowed {
SetAllowChannelOverflow(_messenger, _name, allowed);
}

@end

#pragma mark - Method channel
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,31 @@ - (void)testCallMethodHandler {
}

- (void)testResize {
NSString* channelName = @"foo";
NSString* channelName = @"flutter/test";
id binaryMessenger = OCMStrictProtocolMock(@protocol(FlutterBinaryMessenger));
id codec = OCMProtocolMock(@protocol(FlutterMethodCodec));
FlutterBasicMessageChannel* channel =
[[FlutterBasicMessageChannel alloc] initWithName:channelName
binaryMessenger:binaryMessenger
codec:codec];
XCTAssertNotNil(channel);

// The expected content was created from the following Dart code:
// MethodCall call = MethodCall('resize', ['flutter/test',3]);
// StandardMethodCodec().encodeMethodCall(call).buffer.asUint8List();
const unsigned char bytes[] = {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};
NSData* expectedMessage = [NSData dataWithBytes:bytes length:sizeof(bytes)];

OCMExpect([binaryMessenger sendOnChannel:@"dev.flutter/channel-buffers" message:expectedMessage]);
[channel resizeChannelBuffer:3];
OCMVerifyAll(binaryMessenger);
[binaryMessenger stopMocking];
}

- (bool)testetAllowChannelOverflow {
NSString* channelName = @"flutter/test";
id binaryMessenger = OCMStrictProtocolMock(@protocol(FlutterBinaryMessenger));
id codec = OCMProtocolMock(@protocol(FlutterMethodCodec));
FlutterBasicMessageChannel* channel =
Expand All @@ -156,11 +180,15 @@ - (void)testResize {
codec:codec];
XCTAssertNotNil(channel);

NSString* expectedMessageString =
[NSString stringWithFormat:@"resize\r%@\r%@", channelName, @100];
NSData* expectedMessage = [expectedMessageString dataUsingEncoding:NSUTF8StringEncoding];
// The expected content was created from the following Dart code:
// MethodCall call = MethodCall('overflow',['flutter/test', true]);
// StandardMethodCodec().encodeMethodCall(call).buffer.asUint8List();
const unsigned char bytes[] = {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};
NSData* expectedMessage = [NSData dataWithBytes:bytes length:sizeof(bytes)];

OCMExpect([binaryMessenger sendOnChannel:@"dev.flutter/channel-buffers" message:expectedMessage]);
[channel resizeChannelBuffer:100];
[channel setAllowOverflow:YES];
OCMVerifyAll(binaryMessenger);
[binaryMessenger stopMocking];
}
Expand Down

0 comments on commit 4248e61

Please sign in to comment.