diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 636d287928d58..573bb02d9572e 100755 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -1156,6 +1156,8 @@ FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/connection_col 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 +FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/platform_message_router.mm FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/profiler_metrics_ios.h FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/profiler_metrics_ios.mm FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/vsync_waiter_ios.h @@ -1187,9 +1189,6 @@ FILE: ../../../flutter/shell/platform/darwin/ios/ios_surface_software.h FILE: ../../../flutter/shell/platform/darwin/ios/ios_surface_software.mm FILE: ../../../flutter/shell/platform/darwin/ios/ios_switchable_gl_context.h FILE: ../../../flutter/shell/platform/darwin/ios/ios_switchable_gl_context.mm -FILE: ../../../flutter/shell/platform/darwin/ios/platform_message_handler_ios.h -FILE: ../../../flutter/shell/platform/darwin/ios/platform_message_handler_ios.mm -FILE: ../../../flutter/shell/platform/darwin/ios/platform_message_handler_ios_test.mm FILE: ../../../flutter/shell/platform/darwin/ios/platform_view_ios.h FILE: ../../../flutter/shell/platform/darwin/ios/platform_view_ios.mm FILE: ../../../flutter/shell/platform/darwin/ios/rendering_api_selection.h diff --git a/shell/platform/darwin/common/framework/Headers/FlutterBinaryMessenger.h b/shell/platform/darwin/common/framework/Headers/FlutterBinaryMessenger.h index 9f59ec82a0ebf..6b39687162e60 100644 --- a/shell/platform/darwin/common/framework/Headers/FlutterBinaryMessenger.h +++ b/shell/platform/darwin/common/framework/Headers/FlutterBinaryMessenger.h @@ -31,8 +31,6 @@ typedef void (^FlutterBinaryMessageHandler)(NSData* _Nullable message, FlutterBi typedef int64_t FlutterBinaryMessengerConnection; -@protocol FlutterTaskQueue; - /** * A facility for communicating with the Flutter side using asynchronous message * passing with binary messages. @@ -46,16 +44,6 @@ typedef int64_t FlutterBinaryMessengerConnection; */ FLUTTER_DARWIN_EXPORT @protocol FlutterBinaryMessenger -/// TODO(gaaclarke): Remove optional when macos supports Background Platform Channels. -@optional -- (NSObject*)makeBackgroundTaskQueue; - -- (FlutterBinaryMessengerConnection) - setMessageHandlerOnChannel:(NSString*)channel - binaryMessageHandler:(FlutterBinaryMessageHandler _Nullable)handler - taskQueue:(NSObject* _Nullable)taskQueue; - -@required /** * Sends a binary message to the Flutter side on the specified channel, expecting * no reply. diff --git a/shell/platform/darwin/common/framework/Headers/FlutterChannels.h b/shell/platform/darwin/common/framework/Headers/FlutterChannels.h index 9b84cd64c7178..8b24faed0f961 100644 --- a/shell/platform/darwin/common/framework/Headers/FlutterChannels.h +++ b/shell/platform/darwin/common/framework/Headers/FlutterChannels.h @@ -8,8 +8,6 @@ #import "FlutterBinaryMessenger.h" #import "FlutterCodecs.h" -@protocol FlutterTaskQueue; - NS_ASSUME_NONNULL_BEGIN /** * A message reply callback. @@ -26,8 +24,7 @@ typedef void (^FlutterReply)(id _Nullable reply); * asynchronous replies back to Flutter. * * @param message The message. - * @param callback A callback for submitting a reply to the sender which can be invoked from any - * thread. + * @param callback A callback for submitting a reply to the sender. */ typedef void (^FlutterMessageHandler)(id _Nullable message, FlutterReply callback); @@ -91,27 +88,6 @@ FLUTTER_DARWIN_EXPORT binaryMessenger:(NSObject*)messenger codec:(NSObject*)codec; -/** - * Initializes a `FlutterBasicMessageChannel` with the specified name, binary - * messenger, and message codec. - * - * The channel name logically identifies the channel; identically named channels - * interfere with each other's communication. - * - * The binary messenger is a facility for sending raw, binary messages to the - * Flutter side. This protocol is implemented by `FlutterEngine` and `FlutterViewController`. - * - * @param name The channel name. - * @param messenger The binary messenger. - * @param codec The message codec. - * @param taskQueue The FlutterTaskQueue that executes the handler (see - -[FlutterBinaryMessenger makeBackgroundTaskQueue]). - */ -- (instancetype)initWithName:(NSString*)name - binaryMessenger:(NSObject*)messenger - codec:(NSObject*)codec - taskQueue:(NSObject* _Nullable)taskQueue; - /** * Sends the specified message to the Flutter side, ignoring any reply. * @@ -166,7 +142,7 @@ typedef void (^FlutterResult)(id _Nullable result); * Invoke the callback with a `FlutterError` to indicate that the call failed. * Invoke the callback with `FlutterMethodNotImplemented` to indicate that the * method was unknown. Any other values, including `nil`, are interpreted as - * successful results. This can be invoked from any thread. + * successful results. */ typedef void (^FlutterMethodCallHandler)(FlutterMethodCall* call, FlutterResult result); @@ -237,27 +213,6 @@ FLUTTER_DARWIN_EXPORT binaryMessenger:(NSObject*)messenger codec:(NSObject*)codec; -/** - * Initializes a `FlutterMethodChannel` with the specified name, binary messenger, - * method codec, and task queue. - * - * The channel name logically identifies the channel; identically named channels - * interfere with each other's communication. - * - * The binary messenger is a facility for sending raw, binary messages to the - * Flutter side. This protocol is implemented by `FlutterEngine` and `FlutterViewController`. - * - * @param name The channel name. - * @param messenger The binary messenger. - * @param codec The method codec. - * @param taskQueue The FlutterTaskQueue that executes the handler (see - -[FlutterBinaryMessenger makeBackgroundTaskQueue]). - */ -- (instancetype)initWithName:(NSString*)name - binaryMessenger:(NSObject*)messenger - codec:(NSObject*)codec - taskQueue:(NSObject* _Nullable)taskQueue; - // clang-format off /** * Invokes the specified Flutter method with the specified arguments, expecting @@ -416,27 +371,6 @@ FLUTTER_DARWIN_EXPORT - (instancetype)initWithName:(NSString*)name binaryMessenger:(NSObject*)messenger codec:(NSObject*)codec; - -/** - * Initializes a `FlutterEventChannel` with the specified name, binary messenger, - * method codec and task queue. - * - * The channel name logically identifies the channel; identically named channels - * interfere with each other's communication. - * - * The binary messenger is a facility for sending raw, binary messages to the - * Flutter side. This protocol is implemented by `FlutterEngine` and `FlutterViewController`. - * - * @param name The channel name. - * @param messenger The binary messenger. - * @param codec The method codec. - * @param taskQueue The FlutterTaskQueue that executes the handler (see - -[FlutterBinaryMessenger makeBackgroundTaskQueue]). - */ -- (instancetype)initWithName:(NSString*)name - binaryMessenger:(NSObject*)messenger - codec:(NSObject*)codec - taskQueue:(NSObject* _Nullable)taskQueue; /** * Registers a handler for stream setup requests from the Flutter side. * diff --git a/shell/platform/darwin/common/framework/Source/FlutterChannels.mm b/shell/platform/darwin/common/framework/Source/FlutterChannels.mm index a0bf05c10f4aa..b59098d646d19 100644 --- a/shell/platform/darwin/common/framework/Source/FlutterChannels.mm +++ b/shell/platform/darwin/common/framework/Source/FlutterChannels.mm @@ -16,30 +16,11 @@ static void ResizeChannelBuffer(NSObject* binaryMessenge [binaryMessenger sendOnChannel:FlutterChannelBuffersChannel message:message]; } -static FlutterBinaryMessengerConnection SetMessageHandler( - NSObject* messenger, - NSString* name, - FlutterBinaryMessageHandler handler, - NSObject* taskQueue) { - if (taskQueue) { - NSCAssert([messenger respondsToSelector:@selector(setMessageHandlerOnChannel: - binaryMessageHandler:taskQueue:)], - @""); - return [messenger setMessageHandlerOnChannel:name - binaryMessageHandler:handler - taskQueue:taskQueue]; - } else { - return [messenger setMessageHandlerOnChannel:name binaryMessageHandler:handler]; - } -} - -//////////////////////////////////////////////////////////////////////////////// @implementation FlutterBasicMessageChannel { NSObject* _messenger; NSString* _name; NSObject* _codec; FlutterBinaryMessengerConnection _connection; - NSObject* _taskQueue; } + (instancetype)messageChannelWithName:(NSString*)name binaryMessenger:(NSObject*)messenger { @@ -59,20 +40,11 @@ + (instancetype)messageChannelWithName:(NSString*)name - (instancetype)initWithName:(NSString*)name binaryMessenger:(NSObject*)messenger codec:(NSObject*)codec { - self = [self initWithName:name binaryMessenger:messenger codec:codec taskQueue:nil]; - return self; -} - -- (instancetype)initWithName:(NSString*)name - binaryMessenger:(NSObject*)messenger - codec:(NSObject*)codec - taskQueue:(NSObject*)taskQueue { self = [super init]; NSAssert(self, @"Super init cannot be nil"); _name = [name retain]; _messenger = [messenger retain]; _codec = [codec retain]; - _taskQueue = [taskQueue retain]; return self; } @@ -80,7 +52,6 @@ - (void)dealloc { [_name release]; [_messenger release]; [_codec release]; - [_taskQueue release]; [super dealloc]; } @@ -114,7 +85,7 @@ - (void)setMessageHandler:(FlutterMessageHandler)handler { callback([codec encode:reply]); }); }; - _connection = SetMessageHandler(_messenger, _name, messageHandler, _taskQueue); + _connection = [_messenger setMessageHandlerOnChannel:_name binaryMessageHandler:messageHandler]; } - (void)resizeChannelBuffer:(NSInteger)newSize { @@ -125,7 +96,6 @@ - (void)resizeChannelBuffer:(NSInteger)newSize { #pragma mark - Method channel -//////////////////////////////////////////////////////////////////////////////// @implementation FlutterError + (instancetype)errorWithCode:(NSString*)code message:(NSString*)message details:(id)details { return [[[FlutterError alloc] initWithCode:code message:message details:details] autorelease]; @@ -166,7 +136,6 @@ - (NSUInteger)hash { } @end -//////////////////////////////////////////////////////////////////////////////// @implementation FlutterMethodCall + (instancetype)methodCallWithMethodName:(NSString*)method arguments:(id)arguments { return [[[FlutterMethodCall alloc] initWithMethodName:method arguments:arguments] autorelease]; @@ -206,13 +175,11 @@ - (NSUInteger)hash { NSObject const* FlutterMethodNotImplemented = [[NSObject alloc] init]; -//////////////////////////////////////////////////////////////////////////////// @implementation FlutterMethodChannel { NSObject* _messenger; NSString* _name; NSObject* _codec; FlutterBinaryMessengerConnection _connection; - NSObject* _taskQueue; } + (instancetype)methodChannelWithName:(NSString*)name @@ -231,19 +198,11 @@ + (instancetype)methodChannelWithName:(NSString*)name - (instancetype)initWithName:(NSString*)name binaryMessenger:(NSObject*)messenger codec:(NSObject*)codec { - self = [self initWithName:name binaryMessenger:messenger codec:codec taskQueue:nil]; - return self; -} -- (instancetype)initWithName:(NSString*)name - binaryMessenger:(NSObject*)messenger - codec:(NSObject*)codec - taskQueue:(NSObject*)taskQueue { self = [super init]; NSAssert(self, @"Super init cannot be nil"); _name = [name retain]; _messenger = [messenger retain]; _codec = [codec retain]; - _taskQueue = [taskQueue retain]; return self; } @@ -251,7 +210,6 @@ - (void)dealloc { [_name release]; [_messenger release]; [_codec release]; - [_taskQueue release]; [super dealloc]; } @@ -298,7 +256,7 @@ - (void)setMethodCallHandler:(FlutterMethodCallHandler)handler { } }); }; - _connection = SetMessageHandler(_messenger, _name, messageHandler, _taskQueue); + _connection = [_messenger setMessageHandlerOnChannel:_name binaryMessageHandler:messageHandler]; } - (void)resizeChannelBuffer:(NSInteger)newSize { @@ -311,13 +269,10 @@ - (void)resizeChannelBuffer:(NSInteger)newSize { NSObject const* FlutterEndOfEventStream = [[NSObject alloc] init]; -//////////////////////////////////////////////////////////////////////////////// @implementation FlutterEventChannel { NSObject* _messenger; NSString* _name; NSObject* _codec; - NSObject* _taskQueue; - FlutterBinaryMessengerConnection _connection; } + (instancetype)eventChannelWithName:(NSString*)name binaryMessenger:(NSObject*)messenger { @@ -335,19 +290,11 @@ + (instancetype)eventChannelWithName:(NSString*)name - (instancetype)initWithName:(NSString*)name binaryMessenger:(NSObject*)messenger codec:(NSObject*)codec { - return [self initWithName:name binaryMessenger:messenger codec:codec taskQueue:nil]; -} - -- (instancetype)initWithName:(NSString*)name - binaryMessenger:(NSObject*)messenger - codec:(NSObject*)codec - taskQueue:(NSObject* _Nullable)taskQueue { self = [super init]; NSAssert(self, @"Super init cannot be nil"); _name = [name retain]; _messenger = [messenger retain]; _codec = [codec retain]; - _taskQueue = [taskQueue retain]; return self; } @@ -355,16 +302,13 @@ - (void)dealloc { [_name release]; [_codec release]; [_messenger release]; - [_taskQueue release]; [super dealloc]; } -static FlutterBinaryMessengerConnection SetStreamHandlerMessageHandlerOnChannel( - NSObject* handler, - NSString* name, - NSObject* messenger, - NSObject* codec, - NSObject* taskQueue) { +static void SetStreamHandlerMessageHandlerOnChannel(NSObject* handler, + NSString* name, + NSObject* messenger, + NSObject* codec) { __block FlutterEventSink currentSink = nil; FlutterBinaryMessageHandler messageHandler = ^(NSData* message, FlutterBinaryReply callback) { FlutterMethodCall* call = [codec decodeMethodCall:message]; @@ -410,16 +354,14 @@ static FlutterBinaryMessengerConnection SetStreamHandlerMessageHandlerOnChannel( callback(nil); } }; - return SetMessageHandler(messenger, name, messageHandler, taskQueue); + [messenger setMessageHandlerOnChannel:name binaryMessageHandler:messageHandler]; } - (void)setStreamHandler:(NSObject*)handler { if (!handler) { - [_messenger cleanUpConnection:_connection]; - _connection = 0; + [_messenger setMessageHandlerOnChannel:_name binaryMessageHandler:nil]; return; } - _connection = - SetStreamHandlerMessageHandlerOnChannel(handler, _name, _messenger, _codec, _taskQueue); + SetStreamHandlerMessageHandlerOnChannel(handler, _name, _messenger, _codec); } @end diff --git a/shell/platform/darwin/common/framework/Source/FlutterChannelsTest.m b/shell/platform/darwin/common/framework/Source/FlutterChannelsTest.m index a499fbea8f34d..fbefe90a8d7c6 100644 --- a/shell/platform/darwin/common/framework/Source/FlutterChannelsTest.m +++ b/shell/platform/darwin/common/framework/Source/FlutterChannelsTest.m @@ -108,6 +108,7 @@ - (void)testMethodMessageHandler { OCMStub([codec encodeMethodCall:[OCMArg any]]).andReturn(encodedMethodCall); FlutterMethodCallHandler handler = ^(FlutterMethodCall* _Nonnull call, FlutterResult _Nonnull result) { + NSLog(@"hey"); }; [channel setMethodCallHandler:handler]; OCMVerify([binaryMessenger setMessageHandlerOnChannel:channelName @@ -174,6 +175,7 @@ - (void)testBasicMessageChannelCleanup { binaryMessenger:binaryMessenger codec:codec]; FlutterMessageHandler handler = ^(id _Nullable message, FlutterReply callback) { + NSLog(@"hey"); }; OCMStub([binaryMessenger setMessageHandlerOnChannel:channelName binaryMessageHandler:[OCMArg any]]) @@ -209,78 +211,4 @@ - (void)testMethodChannelCleanup { OCMVerify([binaryMessenger cleanUpConnection:connection]); } -- (void)testBasicMessageChannelTaskQueue { - NSString* channelName = @"foo"; - FlutterBinaryMessengerConnection connection = 123; - id binaryMessenger = OCMProtocolMock(@protocol(FlutterBinaryMessenger)); - id codec = OCMProtocolMock(@protocol(FlutterMethodCodec)); - id taskQueue = OCMClassMock([NSObject class]); - FlutterBasicMessageChannel* channel = - [[FlutterBasicMessageChannel alloc] initWithName:channelName - binaryMessenger:binaryMessenger - codec:codec - taskQueue:taskQueue]; - FlutterMessageHandler handler = ^(id _Nullable message, FlutterReply callback) { - }; - OCMStub([binaryMessenger setMessageHandlerOnChannel:channelName - binaryMessageHandler:[OCMArg any] - taskQueue:taskQueue]) - .andReturn(connection); - [channel setMessageHandler:handler]; - OCMVerify([binaryMessenger setMessageHandlerOnChannel:channelName - binaryMessageHandler:[OCMArg isNotNil] - taskQueue:taskQueue]); - [channel setMessageHandler:nil]; - OCMVerify([binaryMessenger cleanUpConnection:connection]); -} - -- (void)testMethodChannelTaskQueue { - NSString* channelName = @"foo"; - FlutterBinaryMessengerConnection connection = 123; - id binaryMessenger = OCMProtocolMock(@protocol(FlutterBinaryMessenger)); - id codec = OCMProtocolMock(@protocol(FlutterMethodCodec)); - id taskQueue = OCMClassMock([NSObject class]); - FlutterMethodChannel* channel = [[FlutterMethodChannel alloc] initWithName:channelName - binaryMessenger:binaryMessenger - codec:codec - taskQueue:taskQueue]; - XCTAssertNotNil(channel); - FlutterMethodCallHandler handler = ^(FlutterMethodCall* call, FlutterResult result) { - }; - OCMStub([binaryMessenger setMessageHandlerOnChannel:channelName - binaryMessageHandler:[OCMArg any] - taskQueue:taskQueue]) - .andReturn(connection); - [channel setMethodCallHandler:handler]; - OCMVerify([binaryMessenger setMessageHandlerOnChannel:channelName - binaryMessageHandler:[OCMArg isNotNil] - taskQueue:taskQueue]); - [channel setMethodCallHandler:nil]; - OCMVerify([binaryMessenger cleanUpConnection:connection]); -} - -- (void)testEventChannelTaskQueue { - NSString* channelName = @"foo"; - FlutterBinaryMessengerConnection connection = 123; - id binaryMessenger = OCMProtocolMock(@protocol(FlutterBinaryMessenger)); - id codec = OCMProtocolMock(@protocol(FlutterMethodCodec)); - id taskQueue = OCMClassMock([NSObject class]); - id handler = OCMProtocolMock(@protocol(FlutterStreamHandler)); - FlutterEventChannel* channel = [[FlutterEventChannel alloc] initWithName:channelName - binaryMessenger:binaryMessenger - codec:codec - taskQueue:taskQueue]; - XCTAssertNotNil(channel); - OCMStub([binaryMessenger setMessageHandlerOnChannel:channelName - binaryMessageHandler:[OCMArg any] - taskQueue:taskQueue]) - .andReturn(connection); - [channel setStreamHandler:handler]; - OCMVerify([binaryMessenger setMessageHandlerOnChannel:channelName - binaryMessageHandler:[OCMArg isNotNil] - taskQueue:taskQueue]); - [channel setStreamHandler:nil]; - OCMVerify([binaryMessenger cleanUpConnection:connection]); -} - @end diff --git a/shell/platform/darwin/ios/BUILD.gn b/shell/platform/darwin/ios/BUILD.gn index 7a09f6b691c01..303e1edddb7a2 100644 --- a/shell/platform/darwin/ios/BUILD.gn +++ b/shell/platform/darwin/ios/BUILD.gn @@ -100,6 +100,8 @@ source_set("flutter_framework_source") { "framework/Source/connection_collection.mm", "framework/Source/platform_message_response_darwin.h", "framework/Source/platform_message_response_darwin.mm", + "framework/Source/platform_message_router.h", + "framework/Source/platform_message_router.mm", "framework/Source/profiler_metrics_ios.h", "framework/Source/profiler_metrics_ios.mm", "framework/Source/vsync_waiter_ios.h", @@ -124,8 +126,6 @@ source_set("flutter_framework_source") { "ios_surface_software.mm", "ios_switchable_gl_context.h", "ios_switchable_gl_context.mm", - "platform_message_handler_ios.h", - "platform_message_handler_ios.mm", "platform_view_ios.h", "platform_view_ios.mm", "rendering_api_selection.h", @@ -205,12 +205,9 @@ source_set("ios_test_flutter_mrc") { "framework/Source/FlutterPlatformViewsTest.mm", "framework/Source/FlutterViewTest.mm", "framework/Source/accessibility_bridge_test.mm", - "platform_message_handler_ios_test.mm", ] deps = [ ":flutter_framework_source", - "//flutter/common:common", - "//flutter/shell/common:common", "//flutter/shell/platform/darwin/common:framework_shared", "//flutter/shell/platform/embedder:embedder_as_internal_library", "//flutter/third_party/tonic", diff --git a/shell/platform/darwin/ios/framework/Source/FlutterBinaryMessengerRelay.mm b/shell/platform/darwin/ios/framework/Source/FlutterBinaryMessengerRelay.mm index 22d364b5e957c..24f9beb2d2a19 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterBinaryMessengerRelay.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterBinaryMessengerRelay.mm @@ -35,14 +35,6 @@ - (void)sendOnChannel:(NSString*)channel } } -- (NSObject*)makeBackgroundTaskQueue { - if (self.parent) { - return [self.parent makeBackgroundTaskQueue]; - } else { - return nil; - }; -} - - (FlutterBinaryMessengerConnection)setMessageHandlerOnChannel:(NSString*)channel binaryMessageHandler: (FlutterBinaryMessageHandler)handler { @@ -54,20 +46,6 @@ - (FlutterBinaryMessengerConnection)setMessageHandlerOnChannel:(NSString*)channe } } -- (FlutterBinaryMessengerConnection)setMessageHandlerOnChannel:(NSString*)channel - binaryMessageHandler:(FlutterBinaryMessageHandler)handler - taskQueue: - (NSObject*)taskQueue { - if (self.parent) { - return [self.parent setMessageHandlerOnChannel:channel - binaryMessageHandler:handler - taskQueue:taskQueue]; - } else { - FML_LOG(WARNING) << "Communicating on a dead channel."; - return -1; - } -} - - (void)cleanUpConnection:(FlutterBinaryMessengerConnection)connection { if (self.parent) { return [self.parent cleanUpConnection:connection]; diff --git a/shell/platform/darwin/ios/framework/Source/FlutterBinaryMessengerRelayTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterBinaryMessengerRelayTest.mm index e50097f6d6dc0..f4e6374a9745d 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterBinaryMessengerRelayTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterBinaryMessengerRelayTest.mm @@ -11,9 +11,6 @@ FLUTTER_ASSERT_ARC -@protocol FlutterTaskQueue -@end - @interface FlutterBinaryMessengerRelayTest : XCTestCase @end @@ -55,26 +52,4 @@ - (void)testDoesntPassCallOn { [relay sendOnChannel:channel message:message binaryReply:nil]; } -- (void)testSetMessageHandlerWithTaskQueue { - id messenger = OCMProtocolMock(@protocol(FlutterBinaryMessenger)); - FlutterBinaryMessengerRelay* relay = - [[FlutterBinaryMessengerRelay alloc] initWithParent:messenger]; - NSString* channel = @"foobar"; - NSObject* taskQueue = OCMProtocolMock(@protocol(FlutterTaskQueue)); - FlutterBinaryMessageHandler handler = ^(NSData* _Nullable, FlutterBinaryReply _Nonnull) { - }; - [relay setMessageHandlerOnChannel:channel binaryMessageHandler:handler taskQueue:taskQueue]; - OCMVerify([messenger setMessageHandlerOnChannel:channel - binaryMessageHandler:handler - taskQueue:taskQueue]); -} - -- (void)testMakeBackgroundTaskQueue { - id messenger = OCMProtocolMock(@protocol(FlutterBinaryMessenger)); - FlutterBinaryMessengerRelay* relay = - [[FlutterBinaryMessengerRelay alloc] initWithParent:messenger]; - [relay makeBackgroundTaskQueue]; - OCMVerify([messenger makeBackgroundTaskQueue]); -} - @end diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm index 9890f46836762..03fe0a06e8e39 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm @@ -952,24 +952,12 @@ - (void)sendOnChannel:(NSString*)channel _shell->GetPlatformView()->DispatchPlatformMessage(std::move(platformMessage)); } -- (NSObject*)makeBackgroundTaskQueue { - return flutter::PlatformMessageHandlerIos::MakeBackgroundTaskQueue(); -} - - (FlutterBinaryMessengerConnection)setMessageHandlerOnChannel:(NSString*)channel binaryMessageHandler: (FlutterBinaryMessageHandler)handler { - return [self setMessageHandlerOnChannel:channel binaryMessageHandler:handler taskQueue:nil]; -} - -- (FlutterBinaryMessengerConnection) - setMessageHandlerOnChannel:(NSString*)channel - binaryMessageHandler:(FlutterBinaryMessageHandler)handler - taskQueue:(NSObject* _Nullable)taskQueue { NSParameterAssert(channel); if (_shell && _shell->IsSetup()) { - self.iosPlatformView->GetPlatformMessageHandlerIos()->SetMessageHandler(channel.UTF8String, - handler, taskQueue); + 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."); @@ -982,8 +970,7 @@ - (void)cleanUpConnection:(FlutterBinaryMessengerConnection)connection { if (_shell && _shell->IsSetup()) { std::string channel = _connections->CleanupConnection(connection); if (!channel.empty()) { - self.iosPlatformView->GetPlatformMessageHandlerIos()->SetMessageHandler(channel.c_str(), nil, - nil); + 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 708d3faa98cce..1f727a17d28e2 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm @@ -1608,24 +1608,12 @@ - (void)sendOnChannel:(NSString*)channel [_engine.get().binaryMessenger sendOnChannel:channel message:message binaryReply:callback]; } -- (NSObject*)makeBackgroundTaskQueue { - return [_engine.get().binaryMessenger makeBackgroundTaskQueue]; -} - - (FlutterBinaryMessengerConnection)setMessageHandlerOnChannel:(NSString*)channel binaryMessageHandler: (FlutterBinaryMessageHandler)handler { - return [self setMessageHandlerOnChannel:channel binaryMessageHandler:handler taskQueue:nil]; -} - -- (FlutterBinaryMessengerConnection) - setMessageHandlerOnChannel:(NSString*)channel - binaryMessageHandler:(FlutterBinaryMessageHandler _Nullable)handler - taskQueue:(NSObject* _Nullable)taskQueue { NSAssert(channel, @"The channel must not be null"); return [_engine.get().binaryMessenger setMessageHandlerOnChannel:channel - binaryMessageHandler:handler - taskQueue:taskQueue]; + binaryMessageHandler:handler]; } - (void)cleanUpConnection:(FlutterBinaryMessengerConnection)connection { diff --git a/shell/platform/darwin/ios/framework/Source/platform_message_router.h b/shell/platform/darwin/ios/framework/Source/platform_message_router.h new file mode 100644 index 0000000000000..e8927552ddc32 --- /dev/null +++ b/shell/platform/darwin/ios/framework/Source/platform_message_router.h @@ -0,0 +1,37 @@ +// 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_PLATFORM_MESSAGE_ROUTER_H_ +#define SHELL_PLATFORM_IOS_FRAMEWORK_SOURCE_PLATFORM_MESSAGE_ROUTER_H_ + +#include + +#include "flutter/fml/memory/weak_ptr.h" +#include "flutter/fml/platform/darwin/scoped_block.h" +#include "flutter/lib/ui/window/platform_message.h" +#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterBinaryMessenger.h" + +namespace flutter { + +class PlatformMessageRouter { + public: + PlatformMessageRouter(); + ~PlatformMessageRouter(); + + void HandlePlatformMessage( + std::unique_ptr message) const; + + void SetMessageHandler(const std::string& channel, + FlutterBinaryMessageHandler handler); + + private: + std::unordered_map> + message_handlers_; + + FML_DISALLOW_COPY_AND_ASSIGN(PlatformMessageRouter); +}; + +} // namespace flutter + +#endif // SHELL_PLATFORM_IOS_FRAMEWORK_SOURCE_ACCESSIBILITY_BRIDGE_H_ diff --git a/shell/platform/darwin/ios/framework/Source/platform_message_router.mm b/shell/platform/darwin/ios/framework/Source/platform_message_router.mm new file mode 100644 index 0000000000000..841d54627e8df --- /dev/null +++ b/shell/platform/darwin/ios/framework/Source/platform_message_router.mm @@ -0,0 +1,52 @@ +// 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 "flutter/shell/platform/darwin/ios/framework/Source/platform_message_router.h" + +#include + +#import "flutter/shell/platform/darwin/common/buffer_conversions.h" + +namespace flutter { + +PlatformMessageRouter::PlatformMessageRouter() = default; + +PlatformMessageRouter::~PlatformMessageRouter() = default; + +void PlatformMessageRouter::HandlePlatformMessage( + std::unique_ptr message) const { + fml::RefPtr completer = message->response(); + auto it = message_handlers_.find(message->channel()); + if (it != message_handlers_.end()) { + FlutterBinaryMessageHandler handler = it->second; + NSData* data = nil; + if (message->hasData()) { + data = ConvertMappingToNSData(message->releaseData()); + } + handler(data, ^(NSData* reply) { + if (completer) { + if (reply) { + completer->Complete(ConvertNSDataToMappingPtr(reply)); + } else { + completer->CompleteEmpty(); + } + } + }); + } else { + if (completer) { + completer->CompleteEmpty(); + } + } +} + +void PlatformMessageRouter::SetMessageHandler(const std::string& channel, + FlutterBinaryMessageHandler handler) { + message_handlers_.erase(channel); + if (handler) { + message_handlers_[channel] = + fml::ScopedBlock{handler, fml::OwnershipPolicy::Retain}; + } +} + +} // namespace flutter diff --git a/shell/platform/darwin/ios/platform_message_handler_ios.h b/shell/platform/darwin/ios/platform_message_handler_ios.h deleted file mode 100644 index 24247b392072e..0000000000000 --- a/shell/platform/darwin/ios/platform_message_handler_ios.h +++ /dev/null @@ -1,51 +0,0 @@ -// 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 FLUTTER_SHELL_PLATFORM_DARWIN_IOS_PLATFORM_MESSAGE_HANDLER_IOS_H_ -#define FLUTTER_SHELL_PLATFORM_DARWIN_IOS_PLATFORM_MESSAGE_HANDLER_IOS_H_ - -#include - -#include "flutter/common/task_runners.h" -#include "flutter/fml/platform/darwin/scoped_block.h" -#include "flutter/fml/platform/darwin/scoped_nsobject.h" -#include "flutter/shell/common/platform_message_handler.h" -#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterBinaryMessenger.h" - -@protocol FlutterTaskQueue; - -namespace flutter { - -class PlatformMessageHandlerIos : public PlatformMessageHandler { - public: - static NSObject* MakeBackgroundTaskQueue(); - - PlatformMessageHandlerIos(TaskRunners task_runners); - - void HandlePlatformMessage(std::unique_ptr message) override; - - void InvokePlatformMessageResponseCallback(int response_id, - std::unique_ptr mapping) override; - - void InvokePlatformMessageEmptyResponseCallback(int response_id) override; - - void SetMessageHandler(const std::string& channel, - FlutterBinaryMessageHandler handler, - NSObject* task_queue); - - struct HandlerInfo { - fml::scoped_nsprotocol*> task_queue; - fml::ScopedBlock handler; - }; - - private: - std::unordered_map message_handlers_; - TaskRunners task_runners_; - std::mutex message_handlers_mutex_; - FML_DISALLOW_COPY_AND_ASSIGN(PlatformMessageHandlerIos); -}; - -} // namespace flutter - -#endif diff --git a/shell/platform/darwin/ios/platform_message_handler_ios.mm b/shell/platform/darwin/ios/platform_message_handler_ios.mm deleted file mode 100644 index 9e316cc3514a7..0000000000000 --- a/shell/platform/darwin/ios/platform_message_handler_ios.mm +++ /dev/null @@ -1,118 +0,0 @@ -// 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 "flutter/shell/platform/darwin/ios/platform_message_handler_ios.h" - -#import "flutter/shell/platform/darwin/common/buffer_conversions.h" -#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterBinaryMessenger.h" - -@protocol FlutterTaskQueue -- (void)dispatch:(dispatch_block_t)block; -@end - -@interface FLTSerialTaskQueue : NSObject -@property(nonatomic, strong) dispatch_queue_t queue; -@end - -@implementation FLTSerialTaskQueue -- (instancetype)init { - self = [super init]; - if (self) { - _queue = dispatch_queue_create("FLTSerialTaskQueue", DISPATCH_QUEUE_SERIAL); - } - return self; -} - -- (void)dealloc { - dispatch_release(_queue); - [super dealloc]; -} - -- (void)dispatch:(dispatch_block_t)block { - dispatch_async(self.queue, block); -} -@end - -namespace flutter { - -NSObject* PlatformMessageHandlerIos::MakeBackgroundTaskQueue() { - return [[[FLTSerialTaskQueue alloc] init] autorelease]; -} - -PlatformMessageHandlerIos::PlatformMessageHandlerIos(TaskRunners task_runners) - : task_runners_(task_runners) {} - -void PlatformMessageHandlerIos::HandlePlatformMessage(std::unique_ptr message) { - FML_CHECK(task_runners_.GetUITaskRunner()->RunsTasksOnCurrentThread()); - fml::RefPtr completer = message->response(); - HandlerInfo handler_info; - { - std::lock_guard lock(message_handlers_mutex_); - auto it = message_handlers_.find(message->channel()); - if (it != message_handlers_.end()) { - handler_info = it->second; - } - } - if (handler_info.handler) { - FlutterBinaryMessageHandler handler = handler_info.handler; - NSData* data = nil; - if (message->hasData()) { - data = ConvertMappingToNSData(message->releaseData()); - } - - dispatch_block_t run_handler = ^{ - handler(data, ^(NSData* reply) { - // Called from any thread. - if (completer) { - if (reply) { - completer->Complete(ConvertNSDataToMappingPtr(reply)); - } else { - completer->CompleteEmpty(); - } - } - }); - }; - - if (handler_info.task_queue.get()) { - [handler_info.task_queue.get() dispatch:run_handler]; - } else { - dispatch_async(dispatch_get_main_queue(), run_handler); - } - } else { - if (completer) { - completer->CompleteEmpty(); - } - } -} - -void PlatformMessageHandlerIos::InvokePlatformMessageResponseCallback( - int response_id, - std::unique_ptr mapping) { - // Called from any thread. - // TODO(gaaclarke): This vestigal from the Android implementation, find a way - // to migrate this to PlatformMessageHandlerAndroid. -} - -void PlatformMessageHandlerIos::InvokePlatformMessageEmptyResponseCallback(int response_id) { - // Called from any thread. - // TODO(gaaclarke): This vestigal from the Android implementation, find a way - // to migrate this to PlatformMessageHandlerAndroid. -} - -void PlatformMessageHandlerIos::SetMessageHandler(const std::string& channel, - FlutterBinaryMessageHandler handler, - NSObject* task_queue) { - FML_CHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()); - /// TODO(gaaclarke): This should be migrated to a lockfree datastructure. - std::lock_guard lock(message_handlers_mutex_); - message_handlers_.erase(channel); - if (handler) { - message_handlers_[channel] = { - .task_queue = fml::scoped_nsprotocol([task_queue retain]), - .handler = - fml::ScopedBlock{handler, fml::OwnershipPolicy::Retain}, - }; - } -} -} // namespace flutter diff --git a/shell/platform/darwin/ios/platform_message_handler_ios_test.mm b/shell/platform/darwin/ios/platform_message_handler_ios_test.mm deleted file mode 100644 index 376162ead5980..0000000000000 --- a/shell/platform/darwin/ios/platform_message_handler_ios_test.mm +++ /dev/null @@ -1,132 +0,0 @@ -// 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 "flutter/shell/platform/darwin/ios/platform_message_handler_ios.h" - -#import "flutter/common/task_runners.h" -#import "flutter/fml/message_loop.h" -#import "flutter/fml/thread.h" -#import "flutter/shell/common/thread_host.h" -#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterMacros.h" - -FLUTTER_ASSERT_NOT_ARC - -namespace { -using namespace flutter; -fml::RefPtr CreateNewThread(std::string name) { - auto thread = std::make_unique(name); - auto runner = thread->GetTaskRunner(); - return runner; -} - -fml::RefPtr GetCurrentTaskRunner() { - fml::MessageLoop::EnsureInitializedForCurrentThread(); - return fml::MessageLoop::GetCurrent().GetTaskRunner(); -} - -class MockPlatformMessageResponse : public PlatformMessageResponse { - public: - static fml::RefPtr Create() { - return fml::AdoptRef(new MockPlatformMessageResponse()); - } - void Complete(std::unique_ptr data) override { is_complete_ = true; } - void CompleteEmpty() override { is_complete_ = true; } -}; -} // namespace - -@interface PlatformMessageHandlerIosTest : XCTestCase -@end - -@implementation PlatformMessageHandlerIosTest -- (void)testCreate { - flutter::TaskRunners task_runners("test", GetCurrentTaskRunner(), CreateNewThread("raster"), - CreateNewThread("ui"), CreateNewThread("io")); - auto handler = std::make_unique(task_runners); - XCTAssertTrue(handler); -} - -- (void)testSetAndCallHandler { - ThreadHost thread_host("io.flutter.test." + std::string(self.name.UTF8String), - ThreadHost::Type::RASTER | ThreadHost::Type::IO | ThreadHost::Type::UI); - TaskRunners task_runners( - "test", GetCurrentTaskRunner(), thread_host.raster_thread->GetTaskRunner(), - thread_host.ui_thread->GetTaskRunner(), thread_host.io_thread->GetTaskRunner()); - - auto handler = std::make_unique(task_runners); - std::string channel = "foo"; - XCTestExpectation* didCallReply = [self expectationWithDescription:@"didCallReply"]; - handler->SetMessageHandler( - channel, - ^(NSData* _Nullable data, FlutterBinaryReply _Nonnull reply) { - reply(nil); - [didCallReply fulfill]; - }, - nil); - auto response = MockPlatformMessageResponse::Create(); - task_runners.GetUITaskRunner()->PostTask([channel, response, &handler] { - auto platform_message = std::make_unique(channel, response); - handler->HandlePlatformMessage(std::move(platform_message)); - }); - [self waitForExpectationsWithTimeout:1.0 handler:nil]; - XCTAssertTrue(response->is_complete()); -} - -- (void)testSetClearAndCallHandler { - ThreadHost thread_host("io.flutter.test." + std::string(self.name.UTF8String), - ThreadHost::Type::RASTER | ThreadHost::Type::IO | ThreadHost::Type::UI); - TaskRunners task_runners( - "test", GetCurrentTaskRunner(), thread_host.raster_thread->GetTaskRunner(), - thread_host.ui_thread->GetTaskRunner(), thread_host.io_thread->GetTaskRunner()); - - auto handler = std::make_unique(task_runners); - std::string channel = "foo"; - XCTestExpectation* didCallMessage = [self expectationWithDescription:@"didCallMessage"]; - handler->SetMessageHandler( - channel, - ^(NSData* _Nullable data, FlutterBinaryReply _Nonnull reply) { - XCTFail(@"This shouldn't be called"); - reply(nil); - }, - nil); - handler->SetMessageHandler(channel, nil, nil); - auto response = MockPlatformMessageResponse::Create(); - task_runners.GetUITaskRunner()->PostTask([channel, response, &handler, &didCallMessage] { - auto platform_message = std::make_unique(channel, response); - handler->HandlePlatformMessage(std::move(platform_message)); - [didCallMessage fulfill]; - }); - [self waitForExpectationsWithTimeout:1.0 handler:nil]; - XCTAssertTrue(response->is_complete()); -} - -- (void)testSetAndCallHandlerTaskQueue { - ThreadHost thread_host("io.flutter.test." + std::string(self.name.UTF8String), - ThreadHost::Type::RASTER | ThreadHost::Type::IO | ThreadHost::Type::UI); - TaskRunners task_runners( - "test", GetCurrentTaskRunner(), thread_host.raster_thread->GetTaskRunner(), - thread_host.ui_thread->GetTaskRunner(), thread_host.io_thread->GetTaskRunner()); - - auto handler = std::make_unique(task_runners); - std::string channel = "foo"; - XCTestExpectation* didCallReply = [self expectationWithDescription:@"didCallReply"]; - NSObject* taskQueue = PlatformMessageHandlerIos::MakeBackgroundTaskQueue(); - handler->SetMessageHandler( - channel, - ^(NSData* _Nullable data, FlutterBinaryReply _Nonnull reply) { - XCTAssertFalse([NSThread isMainThread]); - reply(nil); - [didCallReply fulfill]; - }, - taskQueue); - auto response = MockPlatformMessageResponse::Create(); - task_runners.GetUITaskRunner()->PostTask([channel, response, &handler] { - auto platform_message = std::make_unique(channel, response); - handler->HandlePlatformMessage(std::move(platform_message)); - }); - [self waitForExpectationsWithTimeout:1.0 handler:nil]; - XCTAssertTrue(response->is_complete()); -} -@end diff --git a/shell/platform/darwin/ios/platform_view_ios.h b/shell/platform/darwin/ios/platform_view_ios.h index 74c17eb332392..3af69b7b2bf8a 100644 --- a/shell/platform/darwin/ios/platform_view_ios.h +++ b/shell/platform/darwin/ios/platform_view_ios.h @@ -16,10 +16,10 @@ #import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h" #import "flutter/shell/platform/darwin/ios/framework/Source/FlutterView.h" #import "flutter/shell/platform/darwin/ios/framework/Source/accessibility_bridge.h" +#import "flutter/shell/platform/darwin/ios/framework/Source/platform_message_router.h" #import "flutter/shell/platform/darwin/ios/ios_context.h" #import "flutter/shell/platform/darwin/ios/ios_external_view_embedder.h" #import "flutter/shell/platform/darwin/ios/ios_surface.h" -#import "flutter/shell/platform/darwin/ios/platform_message_handler_ios.h" #import "flutter/shell/platform/darwin/ios/rendering_api_selection.h" @class FlutterViewController; @@ -53,6 +53,12 @@ class PlatformViewIOS final : public PlatformView { ~PlatformViewIOS() override; + /** + * The `PlatformMessageRouter` is the iOS bridge connecting the shell's + * platform agnostic `PlatformMessage` to iOS's channel message handler. + */ + PlatformMessageRouter& GetPlatformMessageRouter(); + /** * Returns the `FlutterViewController` currently attached to the `FlutterEngine` owning * this PlatformViewIOS. @@ -90,14 +96,6 @@ class PlatformViewIOS final : public PlatformView { /** Accessor for the `IOSContext` associated with the platform view. */ const std::shared_ptr& GetIosContext() { return ios_context_; } - std::shared_ptr GetPlatformMessageHandlerIos() const { - return platform_message_handler_; - } - - std::shared_ptr GetPlatformMessageHandler() const override { - return platform_message_handler_; - } - private: /// Smart pointer for use with objective-c observers. /// This guarantees we remove the observer. @@ -138,12 +136,12 @@ class PlatformViewIOS final : public PlatformView { std::unique_ptr ios_surface_; std::shared_ptr ios_context_; const std::shared_ptr& platform_views_controller_; + PlatformMessageRouter platform_message_router_; AccessibilityBridgePtr accessibility_bridge_; fml::scoped_nsprotocol text_input_plugin_; fml::closure firstFrameCallback_; ScopedObserver dealloc_view_controller_observer_; std::vector platform_resolved_locale_; - std::shared_ptr platform_message_handler_; // |PlatformView| void HandlePlatformMessage(std::unique_ptr message) override; diff --git a/shell/platform/darwin/ios/platform_view_ios.mm b/shell/platform/darwin/ios/platform_view_ios.mm index 8ae73189874a3..081bbe0db130a 100644 --- a/shell/platform/darwin/ios/platform_view_ios.mm +++ b/shell/platform/darwin/ios/platform_view_ios.mm @@ -53,8 +53,7 @@ : PlatformView(delegate, std::move(task_runners)), ios_context_(context), platform_views_controller_(platform_views_controller), - accessibility_bridge_([this](bool enabled) { PlatformView::SetSemanticsEnabled(enabled); }), - platform_message_handler_(new PlatformMessageHandlerIos(task_runners)) {} + accessibility_bridge_([this](bool enabled) { PlatformView::SetSemanticsEnabled(enabled); }) {} PlatformViewIOS::PlatformViewIOS( PlatformView::Delegate& delegate, @@ -68,9 +67,13 @@ PlatformViewIOS::~PlatformViewIOS() = default; +PlatformMessageRouter& PlatformViewIOS::GetPlatformMessageRouter() { + return platform_message_router_; +} + // |PlatformView| void PlatformViewIOS::HandlePlatformMessage(std::unique_ptr message) { - platform_message_handler_->HandlePlatformMessage(std::move(message)); + platform_message_router_.HandlePlatformMessage(std::move(message)); } fml::WeakPtr PlatformViewIOS::GetOwnerViewController() const {