Skip to content

Commit

Permalink
Reland: iOS Background Platform Channels (flutter#29665) (flutter#30697)
Browse files Browse the repository at this point in the history
* iOS Background Platform Channels (flutter#29665)

* added test that passes before this change, and fails after it

* started supporting backwards compatible usage of setting handlers
  • Loading branch information
gaaclarke authored Jan 12, 2022
1 parent 7b02c4a commit bdbd075
Show file tree
Hide file tree
Showing 21 changed files with 675 additions and 124 deletions.
5 changes: 3 additions & 2 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -1177,8 +1177,6 @@ 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
Expand Down Expand Up @@ -1210,6 +1208,9 @@ 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
Expand Down
32 changes: 31 additions & 1 deletion shell/common/shell.cc
Original file line number Diff line number Diff line change
Expand Up @@ -632,6 +632,13 @@ bool Shell::Setup(std::unique_ptr<PlatformView> platform_view,

platform_view_ = std::move(platform_view);
platform_message_handler_ = platform_view_->GetPlatformMessageHandler();
route_messages_through_platform_thread_.store(true);
task_runners_.GetPlatformTaskRunner()->PostTask(
[self = weak_factory_.GetWeakPtr()] {
if (self) {
self->route_messages_through_platform_thread_.store(false);
}
});
engine_ = std::move(engine);
rasterizer_ = std::move(rasterizer);
io_manager_ = io_manager;
Expand Down Expand Up @@ -1183,7 +1190,30 @@ void Shell::OnEngineHandlePlatformMessage(
}

if (platform_message_handler_) {
platform_message_handler_->HandlePlatformMessage(std::move(message));
if (route_messages_through_platform_thread_) {
// We route messages through the platform thread temporarily when the
// shell is being initialized to be backwards compatible with setting
// message handlers in the same event as starting the isolate, but after
// it is started.
auto ui_task_runner = task_runners_.GetUITaskRunner();
task_runners_.GetPlatformTaskRunner()->PostTask(fml::MakeCopyable(
[weak_platform_message_handler =
std::weak_ptr<PlatformMessageHandler>(platform_message_handler_),
message = std::move(message), ui_task_runner]() mutable {
ui_task_runner->PostTask(fml::MakeCopyable(
[weak_platform_message_handler, message = std::move(message),
ui_task_runner]() mutable {
auto platform_message_handler =
weak_platform_message_handler.lock();
if (platform_message_handler) {
platform_message_handler->HandlePlatformMessage(
std::move(message));
}
}));
}));
} else {
platform_message_handler_->HandlePlatformMessage(std::move(message));
}
} else {
task_runners_.GetPlatformTaskRunner()->PostTask(
fml::MakeCopyable([view = platform_view_->GetWeakPtr(),
Expand Down
1 change: 1 addition & 0 deletions shell/common/shell.h
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,7 @@ class Shell final : public PlatformView::Delegate,
std::shared_ptr<fml::SyncSwitch> is_gpu_disabled_sync_switch_;
std::shared_ptr<VolatilePathTracker> volatile_path_tracker_;
std::shared_ptr<PlatformMessageHandler> platform_message_handler_;
std::atomic<bool> route_messages_through_platform_thread_ = false;

fml::WeakPtr<Engine> weak_engine_; // to be shared across threads
fml::TaskRunnerAffineWeakPtr<Rasterizer>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ 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.
Expand All @@ -44,6 +46,16 @@ typedef int64_t FlutterBinaryMessengerConnection;
*/
FLUTTER_DARWIN_EXPORT
@protocol FlutterBinaryMessenger <NSObject>
/// TODO(gaaclarke): Remove optional when macos supports Background Platform Channels.
@optional
- (NSObject<FlutterTaskQueue>*)makeBackgroundTaskQueue;

- (FlutterBinaryMessengerConnection)
setMessageHandlerOnChannel:(NSString*)channel
binaryMessageHandler:(FlutterBinaryMessageHandler _Nullable)handler
taskQueue:(NSObject<FlutterTaskQueue>* _Nullable)taskQueue;

@required
/**
* Sends a binary message to the Flutter side on the specified channel, expecting
* no reply.
Expand Down
70 changes: 68 additions & 2 deletions shell/platform/darwin/common/framework/Headers/FlutterChannels.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#import "FlutterBinaryMessenger.h"
#import "FlutterCodecs.h"

@protocol FlutterTaskQueue;

NS_ASSUME_NONNULL_BEGIN
/**
* A message reply callback.
Expand All @@ -24,7 +26,8 @@ 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.
* @param callback A callback for submitting a reply to the sender which can be invoked from any
* thread.
*/
typedef void (^FlutterMessageHandler)(id _Nullable message, FlutterReply callback);

Expand Down Expand Up @@ -88,6 +91,27 @@ FLUTTER_DARWIN_EXPORT
binaryMessenger:(NSObject<FlutterBinaryMessenger>*)messenger
codec:(NSObject<FlutterMessageCodec>*)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<FlutterBinaryMessenger>*)messenger
codec:(NSObject<FlutterMessageCodec>*)codec
taskQueue:(NSObject<FlutterTaskQueue>* _Nullable)taskQueue;

/**
* Sends the specified message to the Flutter side, ignoring any reply.
*
Expand Down Expand Up @@ -142,7 +166,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.
* successful results. This can be invoked from any thread.
*/
typedef void (^FlutterMethodCallHandler)(FlutterMethodCall* call, FlutterResult result);

Expand Down Expand Up @@ -213,6 +237,27 @@ FLUTTER_DARWIN_EXPORT
binaryMessenger:(NSObject<FlutterBinaryMessenger>*)messenger
codec:(NSObject<FlutterMethodCodec>*)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<FlutterBinaryMessenger>*)messenger
codec:(NSObject<FlutterMethodCodec>*)codec
taskQueue:(NSObject<FlutterTaskQueue>* _Nullable)taskQueue;

// clang-format off
/**
* Invokes the specified Flutter method with the specified arguments, expecting
Expand Down Expand Up @@ -371,6 +416,27 @@ FLUTTER_DARWIN_EXPORT
- (instancetype)initWithName:(NSString*)name
binaryMessenger:(NSObject<FlutterBinaryMessenger>*)messenger
codec:(NSObject<FlutterMethodCodec>*)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<FlutterBinaryMessenger>*)messenger
codec:(NSObject<FlutterMethodCodec>*)codec
taskQueue:(NSObject<FlutterTaskQueue>* _Nullable)taskQueue;
/**
* Registers a handler for stream setup requests from the Flutter side.
*
Expand Down
Loading

0 comments on commit bdbd075

Please sign in to comment.