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

Commit 6dbd735

Browse files
[engine] reland: always post tasks for platform channel responses. (#55006)
Reland of #54975 Fixes the initial route behavior for iOS. Previously the initial route setting would _always_ be posted as a task, which after merging the threads would fire after isolate creation, thus it would not actually update the initial route setting. Fixed Engine constructor so that it reads the initial route from the settings.
1 parent 2f1c8b8 commit 6dbd735

File tree

5 files changed

+40
-18
lines changed

5 files changed

+40
-18
lines changed

shell/common/engine.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ Engine::Engine(
6161
task_runners_(task_runners),
6262
weak_factory_(this) {
6363
pointer_data_dispatcher_ = dispatcher_maker(*this);
64+
initial_route_ = settings_.route;
6465
}
6566

6667
Engine::Engine(Delegate& delegate,

shell/common/engine_unittests.cc

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,27 @@ TEST_F(EngineTest, Create) {
252252
});
253253
}
254254

255+
TEST_F(EngineTest, CreateWithRoute) {
256+
PostUITaskSync([this] {
257+
auto settings = settings_;
258+
settings.route = "/testo";
259+
auto engine = std::make_unique<Engine>(
260+
/*delegate=*/delegate_,
261+
/*dispatcher_maker=*/dispatcher_maker_,
262+
/*image_decoder_task_runner=*/image_decoder_task_runner_,
263+
/*task_runners=*/task_runners_,
264+
/*settings=*/settings,
265+
/*animator=*/std::move(animator_),
266+
/*io_manager=*/io_manager_,
267+
/*font_collection=*/std::make_shared<FontCollection>(),
268+
/*runtime_controller=*/std::move(runtime_controller_),
269+
/*gpu_disabled_switch=*/std::make_shared<fml::SyncSwitch>());
270+
271+
EXPECT_TRUE(engine);
272+
EXPECT_EQ(engine->InitialRoute(), "/testo");
273+
});
274+
}
275+
255276
TEST_F(EngineTest, DispatchPlatformMessageUnknown) {
256277
PostUITaskSync([this] {
257278
MockRuntimeDelegate client;

shell/common/shell.cc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1076,10 +1076,10 @@ void Shell::OnPlatformViewDispatchPlatformMessage(
10761076

10771077
// The static leak checker gets confused by the use of fml::MakeCopyable.
10781078
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
1079-
fml::TaskRunner::RunNowOrPostTask(
1080-
task_runners_.GetUITaskRunner(),
1081-
fml::MakeCopyable([engine = engine_->GetWeakPtr(),
1082-
message = std::move(message)]() mutable {
1079+
// This logic must always explicitly post a task so that we are guaranteed
1080+
// to wake up the UI message loop to flush tasks.
1081+
task_runners_.GetUITaskRunner()->PostTask(fml::MakeCopyable(
1082+
[engine = engine_->GetWeakPtr(), message = std::move(message)]() mutable {
10831083
if (engine) {
10841084
engine->DispatchPlatformMessage(std::move(message));
10851085
}

shell/platform/darwin/ios/framework/Source/FlutterEngine.mm

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -602,13 +602,6 @@ - (void)setUpChannels {
602602
binaryMessenger:self.binaryMessenger
603603
codec:[FlutterJSONMethodCodec sharedInstance]]);
604604

605-
if ([_initialRoute length] > 0) {
606-
// Flutter isn't ready to receive this method call yet but the channel buffer will cache this.
607-
[_navigationChannel invokeMethod:@"setInitialRoute" arguments:_initialRoute];
608-
[_initialRoute release];
609-
_initialRoute = nil;
610-
}
611-
612605
_restorationChannel.reset([[FlutterMethodChannel alloc]
613606
initWithName:@"flutter/restoration"
614607
binaryMessenger:self.binaryMessenger
@@ -904,6 +897,13 @@ - (BOOL)createShell:(NSString*)entrypoint
904897
_isGpuDisabled =
905898
[UIApplication sharedApplication].applicationState == UIApplicationStateBackground;
906899
#endif
900+
// Override the setting route, as the dart project or function may have specified
901+
// different values. During construction, the Engine constuctor will read the
902+
// value of settings.route to determine the initial route value.
903+
if (self.initialRoute) {
904+
settings.route = [self.initialRoute UTF8String];
905+
self.initialRoute = nil;
906+
}
907907

908908
// Create the shell. This is a blocking operation.
909909
std::unique_ptr<flutter::Shell> shell = flutter::Shell::Create(

shell/platform/darwin/ios/framework/Source/FlutterEngineTest.mm

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -201,17 +201,17 @@ - (void)testRunningInitialRouteSendsNavigationMessage {
201201
// Run with an initial route.
202202
[engine runWithEntrypoint:FlutterDefaultDartEntrypoint initialRoute:@"test"];
203203

204-
// Now check that an encoded method call has been made on the binary messenger to set the
205-
// initial route to "test".
204+
// Initial route is set directly in the shell/engine and should not send a platform
205+
// channel message as it will arrive too late.
206206
FlutterMethodCall* setInitialRouteMethodCall =
207207
[FlutterMethodCall methodCallWithMethodName:@"setInitialRoute" arguments:@"test"];
208208
NSData* encodedSetInitialRouteMethod =
209209
[[FlutterJSONMethodCodec sharedInstance] encodeMethodCall:setInitialRouteMethodCall];
210-
OCMVerify([mockBinaryMessenger sendOnChannel:@"flutter/navigation"
210+
OCMReject([mockBinaryMessenger sendOnChannel:@"flutter/navigation"
211211
message:encodedSetInitialRouteMethod]);
212212
}
213213

214-
- (void)testInitialRouteSettingsSendsNavigationMessage {
214+
- (void)testInitialRouteSettingsDoesNotSendNavigationMessage {
215215
id mockBinaryMessenger = OCMClassMock([FlutterBinaryMessengerRelay class]);
216216

217217
auto settings = FLTDefaultSettingsForBundle();
@@ -221,13 +221,13 @@ - (void)testInitialRouteSettingsSendsNavigationMessage {
221221
[engine setBinaryMessenger:mockBinaryMessenger];
222222
[engine run];
223223

224-
// Now check that an encoded method call has been made on the binary messenger to set the
225-
// initial route to "test".
224+
// Initial route is set directly in the shell/engine and should not send a platform
225+
// channel message as it will arrive too late.
226226
FlutterMethodCall* setInitialRouteMethodCall =
227227
[FlutterMethodCall methodCallWithMethodName:@"setInitialRoute" arguments:@"test"];
228228
NSData* encodedSetInitialRouteMethod =
229229
[[FlutterJSONMethodCodec sharedInstance] encodeMethodCall:setInitialRouteMethodCall];
230-
OCMVerify([mockBinaryMessenger sendOnChannel:@"flutter/navigation"
230+
OCMReject([mockBinaryMessenger sendOnChannel:@"flutter/navigation"
231231
message:encodedSetInitialRouteMethod]);
232232
}
233233

0 commit comments

Comments
 (0)