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

Commit bdbd075

Browse files
authored
Reland: iOS Background Platform Channels (#29665) (#30697)
* iOS Background Platform Channels (#29665) * added test that passes before this change, and fails after it * started supporting backwards compatible usage of setting handlers
1 parent 7b02c4a commit bdbd075

21 files changed

+675
-124
lines changed

ci/licenses_golden/licenses_flutter

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1177,8 +1177,6 @@ FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/connection_col
11771177
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/connection_collection_test.mm
11781178
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/platform_message_response_darwin.h
11791179
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/platform_message_response_darwin.mm
1180-
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/platform_message_router.h
1181-
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/platform_message_router.mm
11821180
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/profiler_metrics_ios.h
11831181
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/profiler_metrics_ios.mm
11841182
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/vsync_waiter_ios.h
@@ -1210,6 +1208,9 @@ FILE: ../../../flutter/shell/platform/darwin/ios/ios_surface_software.h
12101208
FILE: ../../../flutter/shell/platform/darwin/ios/ios_surface_software.mm
12111209
FILE: ../../../flutter/shell/platform/darwin/ios/ios_switchable_gl_context.h
12121210
FILE: ../../../flutter/shell/platform/darwin/ios/ios_switchable_gl_context.mm
1211+
FILE: ../../../flutter/shell/platform/darwin/ios/platform_message_handler_ios.h
1212+
FILE: ../../../flutter/shell/platform/darwin/ios/platform_message_handler_ios.mm
1213+
FILE: ../../../flutter/shell/platform/darwin/ios/platform_message_handler_ios_test.mm
12131214
FILE: ../../../flutter/shell/platform/darwin/ios/platform_view_ios.h
12141215
FILE: ../../../flutter/shell/platform/darwin/ios/platform_view_ios.mm
12151216
FILE: ../../../flutter/shell/platform/darwin/ios/rendering_api_selection.h

shell/common/shell.cc

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,13 @@ bool Shell::Setup(std::unique_ptr<PlatformView> platform_view,
632632

633633
platform_view_ = std::move(platform_view);
634634
platform_message_handler_ = platform_view_->GetPlatformMessageHandler();
635+
route_messages_through_platform_thread_.store(true);
636+
task_runners_.GetPlatformTaskRunner()->PostTask(
637+
[self = weak_factory_.GetWeakPtr()] {
638+
if (self) {
639+
self->route_messages_through_platform_thread_.store(false);
640+
}
641+
});
635642
engine_ = std::move(engine);
636643
rasterizer_ = std::move(rasterizer);
637644
io_manager_ = io_manager;
@@ -1183,7 +1190,30 @@ void Shell::OnEngineHandlePlatformMessage(
11831190
}
11841191

11851192
if (platform_message_handler_) {
1186-
platform_message_handler_->HandlePlatformMessage(std::move(message));
1193+
if (route_messages_through_platform_thread_) {
1194+
// We route messages through the platform thread temporarily when the
1195+
// shell is being initialized to be backwards compatible with setting
1196+
// message handlers in the same event as starting the isolate, but after
1197+
// it is started.
1198+
auto ui_task_runner = task_runners_.GetUITaskRunner();
1199+
task_runners_.GetPlatformTaskRunner()->PostTask(fml::MakeCopyable(
1200+
[weak_platform_message_handler =
1201+
std::weak_ptr<PlatformMessageHandler>(platform_message_handler_),
1202+
message = std::move(message), ui_task_runner]() mutable {
1203+
ui_task_runner->PostTask(fml::MakeCopyable(
1204+
[weak_platform_message_handler, message = std::move(message),
1205+
ui_task_runner]() mutable {
1206+
auto platform_message_handler =
1207+
weak_platform_message_handler.lock();
1208+
if (platform_message_handler) {
1209+
platform_message_handler->HandlePlatformMessage(
1210+
std::move(message));
1211+
}
1212+
}));
1213+
}));
1214+
} else {
1215+
platform_message_handler_->HandlePlatformMessage(std::move(message));
1216+
}
11871217
} else {
11881218
task_runners_.GetPlatformTaskRunner()->PostTask(
11891219
fml::MakeCopyable([view = platform_view_->GetWeakPtr(),

shell/common/shell.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,7 @@ class Shell final : public PlatformView::Delegate,
421421
std::shared_ptr<fml::SyncSwitch> is_gpu_disabled_sync_switch_;
422422
std::shared_ptr<VolatilePathTracker> volatile_path_tracker_;
423423
std::shared_ptr<PlatformMessageHandler> platform_message_handler_;
424+
std::atomic<bool> route_messages_through_platform_thread_ = false;
424425

425426
fml::WeakPtr<Engine> weak_engine_; // to be shared across threads
426427
fml::TaskRunnerAffineWeakPtr<Rasterizer>

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ typedef void (^FlutterBinaryMessageHandler)(NSData* _Nullable message, FlutterBi
3131

3232
typedef int64_t FlutterBinaryMessengerConnection;
3333

34+
@protocol FlutterTaskQueue;
35+
3436
/**
3537
* A facility for communicating with the Flutter side using asynchronous message
3638
* passing with binary messages.
@@ -44,6 +46,16 @@ typedef int64_t FlutterBinaryMessengerConnection;
4446
*/
4547
FLUTTER_DARWIN_EXPORT
4648
@protocol FlutterBinaryMessenger <NSObject>
49+
/// TODO(gaaclarke): Remove optional when macos supports Background Platform Channels.
50+
@optional
51+
- (NSObject<FlutterTaskQueue>*)makeBackgroundTaskQueue;
52+
53+
- (FlutterBinaryMessengerConnection)
54+
setMessageHandlerOnChannel:(NSString*)channel
55+
binaryMessageHandler:(FlutterBinaryMessageHandler _Nullable)handler
56+
taskQueue:(NSObject<FlutterTaskQueue>* _Nullable)taskQueue;
57+
58+
@required
4759
/**
4860
* Sends a binary message to the Flutter side on the specified channel, expecting
4961
* no reply.

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

Lines changed: 68 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
#import "FlutterBinaryMessenger.h"
99
#import "FlutterCodecs.h"
1010

11+
@protocol FlutterTaskQueue;
12+
1113
NS_ASSUME_NONNULL_BEGIN
1214
/**
1315
* A message reply callback.
@@ -24,7 +26,8 @@ typedef void (^FlutterReply)(id _Nullable reply);
2426
* asynchronous replies back to Flutter.
2527
*
2628
* @param message The message.
27-
* @param callback A callback for submitting a reply to the sender.
29+
* @param callback A callback for submitting a reply to the sender which can be invoked from any
30+
* thread.
2831
*/
2932
typedef void (^FlutterMessageHandler)(id _Nullable message, FlutterReply callback);
3033

@@ -88,6 +91,27 @@ FLUTTER_DARWIN_EXPORT
8891
binaryMessenger:(NSObject<FlutterBinaryMessenger>*)messenger
8992
codec:(NSObject<FlutterMessageCodec>*)codec;
9093

94+
/**
95+
* Initializes a `FlutterBasicMessageChannel` with the specified name, binary
96+
* messenger, and message codec.
97+
*
98+
* The channel name logically identifies the channel; identically named channels
99+
* interfere with each other's communication.
100+
*
101+
* The binary messenger is a facility for sending raw, binary messages to the
102+
* Flutter side. This protocol is implemented by `FlutterEngine` and `FlutterViewController`.
103+
*
104+
* @param name The channel name.
105+
* @param messenger The binary messenger.
106+
* @param codec The message codec.
107+
* @param taskQueue The FlutterTaskQueue that executes the handler (see
108+
-[FlutterBinaryMessenger makeBackgroundTaskQueue]).
109+
*/
110+
- (instancetype)initWithName:(NSString*)name
111+
binaryMessenger:(NSObject<FlutterBinaryMessenger>*)messenger
112+
codec:(NSObject<FlutterMessageCodec>*)codec
113+
taskQueue:(NSObject<FlutterTaskQueue>* _Nullable)taskQueue;
114+
91115
/**
92116
* Sends the specified message to the Flutter side, ignoring any reply.
93117
*
@@ -142,7 +166,7 @@ typedef void (^FlutterResult)(id _Nullable result);
142166
* Invoke the callback with a `FlutterError` to indicate that the call failed.
143167
* Invoke the callback with `FlutterMethodNotImplemented` to indicate that the
144168
* method was unknown. Any other values, including `nil`, are interpreted as
145-
* successful results.
169+
* successful results. This can be invoked from any thread.
146170
*/
147171
typedef void (^FlutterMethodCallHandler)(FlutterMethodCall* call, FlutterResult result);
148172

@@ -213,6 +237,27 @@ FLUTTER_DARWIN_EXPORT
213237
binaryMessenger:(NSObject<FlutterBinaryMessenger>*)messenger
214238
codec:(NSObject<FlutterMethodCodec>*)codec;
215239

240+
/**
241+
* Initializes a `FlutterMethodChannel` with the specified name, binary messenger,
242+
* method codec, and task queue.
243+
*
244+
* The channel name logically identifies the channel; identically named channels
245+
* interfere with each other's communication.
246+
*
247+
* The binary messenger is a facility for sending raw, binary messages to the
248+
* Flutter side. This protocol is implemented by `FlutterEngine` and `FlutterViewController`.
249+
*
250+
* @param name The channel name.
251+
* @param messenger The binary messenger.
252+
* @param codec The method codec.
253+
* @param taskQueue The FlutterTaskQueue that executes the handler (see
254+
-[FlutterBinaryMessenger makeBackgroundTaskQueue]).
255+
*/
256+
- (instancetype)initWithName:(NSString*)name
257+
binaryMessenger:(NSObject<FlutterBinaryMessenger>*)messenger
258+
codec:(NSObject<FlutterMethodCodec>*)codec
259+
taskQueue:(NSObject<FlutterTaskQueue>* _Nullable)taskQueue;
260+
216261
// clang-format off
217262
/**
218263
* Invokes the specified Flutter method with the specified arguments, expecting
@@ -371,6 +416,27 @@ FLUTTER_DARWIN_EXPORT
371416
- (instancetype)initWithName:(NSString*)name
372417
binaryMessenger:(NSObject<FlutterBinaryMessenger>*)messenger
373418
codec:(NSObject<FlutterMethodCodec>*)codec;
419+
420+
/**
421+
* Initializes a `FlutterEventChannel` with the specified name, binary messenger,
422+
* method codec and task queue.
423+
*
424+
* The channel name logically identifies the channel; identically named channels
425+
* interfere with each other's communication.
426+
*
427+
* The binary messenger is a facility for sending raw, binary messages to the
428+
* Flutter side. This protocol is implemented by `FlutterEngine` and `FlutterViewController`.
429+
*
430+
* @param name The channel name.
431+
* @param messenger The binary messenger.
432+
* @param codec The method codec.
433+
* @param taskQueue The FlutterTaskQueue that executes the handler (see
434+
-[FlutterBinaryMessenger makeBackgroundTaskQueue]).
435+
*/
436+
- (instancetype)initWithName:(NSString*)name
437+
binaryMessenger:(NSObject<FlutterBinaryMessenger>*)messenger
438+
codec:(NSObject<FlutterMethodCodec>*)codec
439+
taskQueue:(NSObject<FlutterTaskQueue>* _Nullable)taskQueue;
374440
/**
375441
* Registers a handler for stream setup requests from the Flutter side.
376442
*

0 commit comments

Comments
 (0)