diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 1e22176412b1df567f32c0e941cc855a31ad2fab..7a1b5923e6bae5c7bb69206ad64f75be2f542be2 100755 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -934,6 +934,9 @@ FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/accessibility_ FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/accessibility_text_entry.h FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/accessibility_text_entry.mm +FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/connection_collection.cc +FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/connection_collection.h +FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/connection_collection_test.mm FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/platform_message_response_darwin.h FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/platform_message_response_darwin.mm FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/platform_message_router.h diff --git a/shell/platform/darwin/common/framework/Headers/FlutterBinaryMessenger.h b/shell/platform/darwin/common/framework/Headers/FlutterBinaryMessenger.h index 2c35fd42599c4c10fe39130c8059b4b246c5d332..3ce459921011e2d6f66a078cbc1fef05b7a48835 100644 --- a/shell/platform/darwin/common/framework/Headers/FlutterBinaryMessenger.h +++ b/shell/platform/darwin/common/framework/Headers/FlutterBinaryMessenger.h @@ -29,6 +29,8 @@ typedef void (^FlutterBinaryReply)(NSData* _Nullable reply); */ typedef void (^FlutterBinaryMessageHandler)(NSData* _Nullable message, FlutterBinaryReply reply); +typedef int64_t FlutterBinaryMessengerConnection; + /** * A facility for communicating with the Flutter side using asynchronous message * passing with binary messages. @@ -72,9 +74,20 @@ FLUTTER_EXPORT * * @param channel The channel name. * @param handler The message handler. + * @return An identifier that represents the connection that was just created to the channel. + */ +- (FlutterBinaryMessengerConnection)setMessageHandlerOnChannel:(NSString*)channel + binaryMessageHandler: + (FlutterBinaryMessageHandler _Nullable)handler; + +/** + * Clears out a channel's message handler if that handler is still the one that + * was created as a result of + * `setMessageHandlerOnChannel:binaryMessageHandler:`. + * + * @param connection The result from `setMessageHandlerOnChannel:binaryMessageHandler:`. */ -- (void)setMessageHandlerOnChannel:(NSString*)channel - binaryMessageHandler:(FlutterBinaryMessageHandler _Nullable)handler; +- (void)cleanupConnection:(FlutterBinaryMessengerConnection)connection; @end NS_ASSUME_NONNULL_END #endif // FLUTTER_FLUTTERBINARYMESSENGER_H_ diff --git a/shell/platform/darwin/common/framework/Source/FlutterChannels.mm b/shell/platform/darwin/common/framework/Source/FlutterChannels.mm index a08628643980a2449cd7928666c8a63d7d91a850..0d06a88c5522f53482a91b71c72cc6807fc4403b 100644 --- a/shell/platform/darwin/common/framework/Source/FlutterChannels.mm +++ b/shell/platform/darwin/common/framework/Source/FlutterChannels.mm @@ -20,6 +20,7 @@ static void ResizeChannelBuffer(NSObject* binaryMessenge NSObject* _messenger; NSString* _name; NSObject* _codec; + FlutterBinaryMessengerConnection _connection; } + (instancetype)messageChannelWithName:(NSString*)name binaryMessenger:(NSObject*)messenger { @@ -68,7 +69,12 @@ static void ResizeChannelBuffer(NSObject* binaryMessenge - (void)setMessageHandler:(FlutterMessageHandler)handler { if (!handler) { - [_messenger setMessageHandlerOnChannel:_name binaryMessageHandler:nil]; + if (_connection > 0) { + [_messenger cleanupConnection:_connection]; + _connection = 0; + } else { + [_messenger setMessageHandlerOnChannel:_name binaryMessageHandler:nil]; + } return; } // Grab reference to avoid retain on self. @@ -78,7 +84,7 @@ static void ResizeChannelBuffer(NSObject* binaryMessenge callback([codec encode:reply]); }); }; - [_messenger setMessageHandlerOnChannel:_name binaryMessageHandler:messageHandler]; + _connection = [_messenger setMessageHandlerOnChannel:_name binaryMessageHandler:messageHandler]; } - (void)resizeChannelBuffer:(NSInteger)newSize { @@ -168,6 +174,7 @@ NSObject const* FlutterMethodNotImplemented = [NSObject new]; NSObject* _messenger; NSString* _name; NSObject* _codec; + FlutterBinaryMessengerConnection _connection; } + (instancetype)methodChannelWithName:(NSString*)name @@ -222,7 +229,12 @@ NSObject const* FlutterMethodNotImplemented = [NSObject new]; - (void)setMethodCallHandler:(FlutterMethodCallHandler)handler { if (!handler) { - [_messenger setMessageHandlerOnChannel:_name binaryMessageHandler:nil]; + if (_connection > 0) { + [_messenger cleanupConnection:_connection]; + _connection = 0; + } else { + [_messenger setMessageHandlerOnChannel:_name binaryMessageHandler:nil]; + } return; } // Make sure the block captures the codec, not self. @@ -238,7 +250,7 @@ NSObject const* FlutterMethodNotImplemented = [NSObject new]; callback([codec encodeSuccessEnvelope:result]); }); }; - [_messenger setMessageHandlerOnChannel:_name binaryMessageHandler:messageHandler]; + _connection = [_messenger setMessageHandlerOnChannel:_name binaryMessageHandler:messageHandler]; } - (void)resizeChannelBuffer:(NSInteger)newSize { diff --git a/shell/platform/darwin/common/framework/Source/FlutterChannelsTest.m b/shell/platform/darwin/common/framework/Source/FlutterChannelsTest.m index 941bef90cb3052cfc1a20ffdba3710d50352dd15..d95b905ca017e628b9545618a84befcdff30e06f 100644 --- a/shell/platform/darwin/common/framework/Source/FlutterChannelsTest.m +++ b/shell/platform/darwin/common/framework/Source/FlutterChannelsTest.m @@ -35,10 +35,16 @@ self.message = message; } -- (void)setMessageHandlerOnChannel:(NSString*)channel - binaryMessageHandler:(FlutterBinaryMessageHandler _Nullable)handler { +- (FlutterBinaryMessengerConnection)setMessageHandlerOnChannel:(NSString*)channel + binaryMessageHandler: + (FlutterBinaryMessageHandler _Nullable)handler { [self.handlers setObject:handler forKey:channel]; + return 0; } + +- (void)cleanupConnection:(FlutterBinaryMessengerConnection)connection { +} + @end @interface FlutterChannelsTest : XCTestCase @@ -155,6 +161,53 @@ OCMExpect([binaryMessenger sendOnChannel:@"dev.flutter/channel-buffers" message:expectedMessage]); [channel resizeChannelBuffer:100]; OCMVerifyAll(binaryMessenger); + [binaryMessenger stopMocking]; +} + +- (void)testBasicMessageChannelCleanup { + NSString* channelName = @"foo"; + FlutterBinaryMessengerConnection connection = 123; + id binaryMessenger = OCMProtocolMock(@protocol(FlutterBinaryMessenger)); + id codec = OCMProtocolMock(@protocol(FlutterMethodCodec)); + FlutterBasicMessageChannel* channel = + [[FlutterBasicMessageChannel alloc] initWithName:channelName + binaryMessenger:binaryMessenger + codec:codec]; + FlutterMessageHandler handler = ^(id _Nullable message, FlutterReply callback) { + NSLog(@"hey"); + }; + OCMStub([binaryMessenger setMessageHandlerOnChannel:channelName + binaryMessageHandler:[OCMArg any]]) + .andReturn(connection); + [channel setMessageHandler:handler]; + OCMVerify([binaryMessenger setMessageHandlerOnChannel:channelName + binaryMessageHandler:[OCMArg isNotNil]]); + [channel setMessageHandler:nil]; + OCMVerify([binaryMessenger cleanupConnection:connection]); +} + +- (void)testMethodChannelCleanup { + NSString* channelName = @"foo"; + FlutterBinaryMessengerConnection connection = 123; + id binaryMessenger = OCMProtocolMock(@protocol(FlutterBinaryMessenger)); + id codec = OCMProtocolMock(@protocol(FlutterMethodCodec)); + FlutterMethodChannel* channel = [[FlutterMethodChannel alloc] initWithName:channelName + binaryMessenger:binaryMessenger + codec:codec]; + XCTAssertNotNil(channel); + + OCMStub([binaryMessenger setMessageHandlerOnChannel:channelName + binaryMessageHandler:[OCMArg any]]) + .andReturn(connection); + + FlutterMethodCallHandler handler = + ^(FlutterMethodCall* _Nonnull call, FlutterResult _Nonnull result) { + }; + [channel setMethodCallHandler:handler]; + OCMVerify([binaryMessenger setMessageHandlerOnChannel:channelName + binaryMessageHandler:[OCMArg isNotNil]]); + [channel setMethodCallHandler:nil]; + OCMVerify([binaryMessenger cleanupConnection:connection]); } @end diff --git a/shell/platform/darwin/ios/BUILD.gn b/shell/platform/darwin/ios/BUILD.gn index dcfce0791396d8bf4e10ea21f5b5c5f76a90aaf7..762d5e03bcd1646f3c9c68f6f9393e2467f04527 100644 --- a/shell/platform/darwin/ios/BUILD.gn +++ b/shell/platform/darwin/ios/BUILD.gn @@ -74,6 +74,8 @@ source_set("flutter_framework_source") { "framework/Source/accessibility_bridge.mm", "framework/Source/accessibility_text_entry.h", "framework/Source/accessibility_text_entry.mm", + "framework/Source/connection_collection.cc", + "framework/Source/connection_collection.h", "framework/Source/platform_message_response_darwin.h", "framework/Source/platform_message_response_darwin.mm", "framework/Source/platform_message_router.h", @@ -208,6 +210,7 @@ shared_library("ios_test_flutter") { "framework/Source/FlutterTextInputPluginTest.m", "framework/Source/FlutterViewControllerTest.mm", "framework/Source/SemanticsObjectTest.mm", + "framework/Source/connection_collection_test.mm", ] deps = [ ":flutter_framework_source", diff --git a/shell/platform/darwin/ios/framework/Source/FlutterBinaryMessengerRelay.mm b/shell/platform/darwin/ios/framework/Source/FlutterBinaryMessengerRelay.mm index f21dce800a3c39176250c1be7a9934d33e9d142b..d0f59a5df98ef6372d0ecf39f1afc78912d9fa9c 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterBinaryMessengerRelay.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterBinaryMessengerRelay.mm @@ -35,10 +35,20 @@ } } -- (void)setMessageHandlerOnChannel:(NSString*)channel - binaryMessageHandler:(FlutterBinaryMessageHandler)handler { +- (FlutterBinaryMessengerConnection)setMessageHandlerOnChannel:(NSString*)channel + binaryMessageHandler: + (FlutterBinaryMessageHandler)handler { if (self.parent) { - [self.parent setMessageHandlerOnChannel:channel binaryMessageHandler:handler]; + return [self.parent setMessageHandlerOnChannel:channel binaryMessageHandler:handler]; + } else { + FML_LOG(WARNING) << "Communicating on a dead channel."; + return -1; + } +} + +- (void)cleanupConnection:(FlutterBinaryMessengerConnection)connection { + if (self.parent) { + return [self.parent cleanupConnection:connection]; } else { FML_LOG(WARNING) << "Communicating on a dead channel."; } diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm index 48b85585884401e3a5cd95d03bea8fe36235a2af..57d531ec7420da259986261fc62169c6d5260783 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm @@ -23,6 +23,7 @@ #import "flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.h" #import "flutter/shell/platform/darwin/ios/framework/Source/FlutterTextInputDelegate.h" #import "flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController_Internal.h" +#import "flutter/shell/platform/darwin/ios/framework/Source/connection_collection.h" #import "flutter/shell/platform/darwin/ios/framework/Source/platform_message_response_darwin.h" #import "flutter/shell/platform/darwin/ios/framework/Source/profiler_metrics_ios.h" #import "flutter/shell/platform/darwin/ios/ios_surface.h" @@ -78,6 +79,7 @@ static constexpr int kNumProfilerSamplesPerSec = 5; BOOL _allowHeadlessExecution; FlutterBinaryMessengerRelay* _binaryMessenger; + std::unique_ptr _connections; } - (instancetype)initWithName:(NSString*)labelPrefix { @@ -110,6 +112,7 @@ static constexpr int kNumProfilerSamplesPerSec = 5; _platformViewsController.reset(new flutter::FlutterPlatformViewsController()); _binaryMessenger = [[FlutterBinaryMessengerRelay alloc] initWithParent:self]; + _connections.reset(new flutter::ConnectionCollection()); NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; [center addObserver:self @@ -693,14 +696,26 @@ static constexpr int kNumProfilerSamplesPerSec = 5; _shell->GetPlatformView()->DispatchPlatformMessage(platformMessage); } -- (void)setMessageHandlerOnChannel:(NSString*)channel - binaryMessageHandler:(FlutterBinaryMessageHandler)handler { +- (FlutterBinaryMessengerConnection)setMessageHandlerOnChannel:(NSString*)channel + binaryMessageHandler: + (FlutterBinaryMessageHandler)handler { NSParameterAssert(channel); if (_shell && _shell->IsSetup()) { self.iosPlatformView->GetPlatformMessageRouter().SetMessageHandler(channel.UTF8String, handler); + return _connections->AquireConnection(channel.UTF8String); } else { NSAssert(!handler, @"Setting a message handler before the FlutterEngine has been run."); // Setting a handler to nil for a not setup channel is a noop. + return flutter::ConnectionCollection::MakeErrorConnection(-1); + } +} + +- (void)cleanupConnection:(FlutterBinaryMessengerConnection)connection { + if (_shell && _shell->IsSetup()) { + std::string channel = _connections->CleanupConnection(connection); + if (!channel.empty()) { + self.iosPlatformView->GetPlatformMessageRouter().SetMessageHandler(channel.c_str(), nil); + } } } diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm index f2a8c186a7479c70dbb0e09caabf9ee008c65c12..24079b436d6b95112fd6eed3004200a2c23b2990 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm @@ -1204,10 +1204,16 @@ static flutter::PointerData::DeviceKind DeviceKindFromTouchType(UITouch* touch) [_engine.get().binaryMessenger sendOnChannel:channel message:message binaryReply:callback]; } -- (void)setMessageHandlerOnChannel:(NSString*)channel - binaryMessageHandler:(FlutterBinaryMessageHandler)handler { +- (FlutterBinaryMessengerConnection)setMessageHandlerOnChannel:(NSString*)channel + binaryMessageHandler: + (FlutterBinaryMessageHandler)handler { NSAssert(channel, @"The channel must not be null"); - [_engine.get().binaryMessenger setMessageHandlerOnChannel:channel binaryMessageHandler:handler]; + return [_engine.get().binaryMessenger setMessageHandlerOnChannel:channel + binaryMessageHandler:handler]; +} + +- (void)cleanupConnection:(FlutterBinaryMessengerConnection)connection { + [_engine.get().binaryMessenger cleanupConnection:connection]; } #pragma mark - FlutterTextureRegistry diff --git a/shell/platform/darwin/ios/framework/Source/accessibility_bridge.mm b/shell/platform/darwin/ios/framework/Source/accessibility_bridge.mm index 2a111edb5168d83be21b77fd97eb91b0e5b38c04..aba324180e88176888b6869a8d612d3ea07edecc 100644 --- a/shell/platform/darwin/ios/framework/Source/accessibility_bridge.mm +++ b/shell/platform/darwin/ios/framework/Source/accessibility_bridge.mm @@ -72,6 +72,7 @@ AccessibilityBridge::AccessibilityBridge(UIView* view, } AccessibilityBridge::~AccessibilityBridge() { + [accessibility_channel_.get() setMessageHandler:nil]; clearState(); view_.accessibilityElements = nil; } diff --git a/shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm b/shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm index 2cf8b74538ed5ec2f1e1d83fe101898d22c03832..47a0b0c0272b7c7231b46df813ba31ab0b1040ea 100644 --- a/shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm +++ b/shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm @@ -4,6 +4,7 @@ #import +#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterBinaryMessenger.h" #import "flutter/shell/platform/darwin/common/framework/Headers/FlutterMacros.h" #import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterPlatformViews.h" #import "flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h" @@ -368,4 +369,46 @@ fml::RefPtr CreateNewThread(std::string name) { XCTAssertEqual([accessibility_notifications count], 0ul); } +- (void)testAccessibilityMessageAfterDeletion { + flutter::MockDelegate mock_delegate; + auto thread = std::make_unique("AccessibilityBridgeTest"); + auto thread_task_runner = thread->GetTaskRunner(); + flutter::TaskRunners runners(/*label=*/self.name.UTF8String, + /*platform=*/thread_task_runner, + /*raster=*/thread_task_runner, + /*ui=*/thread_task_runner, + /*io=*/thread_task_runner); + id messenger = OCMProtocolMock(@protocol(FlutterBinaryMessenger)); + id engine = OCMClassMock([FlutterEngine class]); + id flutterViewController = OCMClassMock([FlutterViewController class]); + + OCMStub([flutterViewController engine]).andReturn(engine); + OCMStub([engine binaryMessenger]).andReturn(messenger); + FlutterBinaryMessengerConnection connection = 123; + OCMStub([messenger setMessageHandlerOnChannel:@"flutter/accessibility" + binaryMessageHandler:[OCMArg any]]) + .andReturn(connection); + + auto platform_view = std::make_unique( + /*delegate=*/mock_delegate, + /*rendering_api=*/flutter::IOSRenderingAPI::kSoftware, + /*task_runners=*/runners); + fml::AutoResetWaitableEvent latch; + thread_task_runner->PostTask([&] { + auto weakFactory = + std::make_unique>(flutterViewController); + platform_view->SetOwnerViewController(weakFactory->GetWeakPtr()); + auto bridge = + std::make_unique(/*view=*/nil, + /*platform_view=*/platform_view.get(), + /*platform_views_controller=*/nil); + XCTAssertTrue(bridge.get()); + OCMVerify([messenger setMessageHandlerOnChannel:@"flutter/accessibility" + binaryMessageHandler:[OCMArg isNotNil]]); + bridge.reset(); + latch.Signal(); + }); + latch.Wait(); + OCMVerify([messenger cleanupConnection:connection]); +} @end diff --git a/shell/platform/darwin/ios/framework/Source/connection_collection.cc b/shell/platform/darwin/ios/framework/Source/connection_collection.cc new file mode 100644 index 0000000000000000000000000000000000000000..be042b7dd3ccdbdd60116376de75d9ae8786b6dc --- /dev/null +++ b/shell/platform/darwin/ios/framework/Source/connection_collection.cc @@ -0,0 +1,46 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/shell/platform/darwin/ios/framework/Source/connection_collection.h" + +namespace flutter { +ConnectionCollection::Connection ConnectionCollection::AquireConnection( + const std::string& name) { + Connection nextConnection = ++counter_; + connections_[name] = nextConnection; + return nextConnection; +} + +std::string ConnectionCollection::CleanupConnection( + ConnectionCollection::Connection connection) { + if (connection > 0) { + std::string channel; + for (auto& keyValue : connections_) { + if (keyValue.second == connection) { + channel = keyValue.first; + break; + } + } + if (channel.length() > 0) { + connections_.erase(channel); + return channel; + } + } + return ""; +} + +bool ConnectionCollection::IsValidConnection( + ConnectionCollection::Connection connection) { + return connection > 0; +} + +ConnectionCollection::Connection ConnectionCollection::MakeErrorConnection( + int errCode) { + if (errCode < 0) { + return -1 * errCode; + } + return errCode; +} + +} // namespace flutter diff --git a/shell/platform/darwin/ios/framework/Source/connection_collection.h b/shell/platform/darwin/ios/framework/Source/connection_collection.h new file mode 100644 index 0000000000000000000000000000000000000000..3f93435b83ca988b1486966f2b9a44fa3c66ff61 --- /dev/null +++ b/shell/platform/darwin/ios/framework/Source/connection_collection.h @@ -0,0 +1,36 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SHELL_PLATFORM_IOS_FRAMEWORK_SOURCE_CONNECTION_COLLECTION_H_ +#define SHELL_PLATFORM_IOS_FRAMEWORK_SOURCE_CONNECTION_COLLECTION_H_ + +#include +#include +#include + +namespace flutter { + +/// Maintains a current integer assigned to a name (connections). +class ConnectionCollection { + public: + typedef int64_t Connection; + static const Connection kInvalidConnection = 0; + + Connection AquireConnection(const std::string& name); + ///\returns the name of the channel when cleanup is successful, otherwise + /// the empty string. + std::string CleanupConnection(Connection connection); + + static bool IsValidConnection(Connection connection); + + static Connection MakeErrorConnection(int errCode); + + private: + std::map connections_; + Connection counter_ = 0; +}; + +} // namespace flutter + +#endif // SHELL_PLATFORM_IOS_FRAMEWORK_SOURCE_CONNECTION_COLLECTION_H_ diff --git a/shell/platform/darwin/ios/framework/Source/connection_collection_test.mm b/shell/platform/darwin/ios/framework/Source/connection_collection_test.mm new file mode 100644 index 0000000000000000000000000000000000000000..5672b9f127f19c98e07ea1ff8cb8ecf86d07c897 --- /dev/null +++ b/shell/platform/darwin/ios/framework/Source/connection_collection_test.mm @@ -0,0 +1,22 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import +#import + +#import "flutter/shell/platform/darwin/ios/framework/Source/connection_collection.h" + +@interface ConnectionCollectionTest : XCTestCase +@end + +@implementation ConnectionCollectionTest + +- (void)testSimple { + auto connections = std::make_unique(); + flutter::ConnectionCollection::Connection connection = connections->AquireConnection("foo"); + XCTAssertTrue(connections->CleanupConnection(connection) == "foo"); + XCTAssertTrue(connections->CleanupConnection(connection).empty()); +} + +@end diff --git a/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm b/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm index e00db7014b67cf4d738921f39e71296b15a758f8..e16cb6efde8663e13ddba4e14eb449d3aff21434 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm @@ -447,9 +447,15 @@ static bool OnAcquireExternalTexture(FlutterEngine* engine, } } -- (void)setMessageHandlerOnChannel:(nonnull NSString*)channel - binaryMessageHandler:(nullable FlutterBinaryMessageHandler)handler { +- (FlutterBinaryMessengerConnection)setMessageHandlerOnChannel:(nonnull NSString*)channel + binaryMessageHandler: + (nullable FlutterBinaryMessageHandler)handler { _messageHandlers[channel] = [handler copy]; + return 0; +} + +- (void)cleanupConnection:(FlutterBinaryMessengerConnection)connection { + // There hasn't been a need to implement this yet for macOS. } #pragma mark - FlutterPluginRegistry