diff --git a/engine/src/flutter/common/settings.h b/engine/src/flutter/common/settings.h index 76ec79c5d20..31b16fa9310 100644 --- a/engine/src/flutter/common/settings.h +++ b/engine/src/flutter/common/settings.h @@ -107,6 +107,8 @@ struct Settings { std::string isolate_snapshot_instr_path; // deprecated MappingCallback isolate_snapshot_instr; + std::string route; + // Returns the Mapping to a kernel buffer which contains sources for dart:* // libraries. MappingCallback dart_library_sources_kernel; diff --git a/engine/src/flutter/shell/common/switches.cc b/engine/src/flutter/shell/common/switches.cc index 7f507b0786b..5ce829f2b1b 100644 --- a/engine/src/flutter/shell/common/switches.cc +++ b/engine/src/flutter/shell/common/switches.cc @@ -356,6 +356,8 @@ Settings SettingsFromCommandLine(const fml::CommandLine& command_line) { command_line.GetOptionValue(FlagForSwitch(Switch::VmSnapshotData), &vm_snapshot_data_filename); + command_line.GetOptionValue(FlagForSwitch(Switch::Route), &settings.route); + std::string vm_snapshot_instr_filename; command_line.GetOptionValue(FlagForSwitch(Switch::VmSnapshotInstructions), &vm_snapshot_instr_filename); diff --git a/engine/src/flutter/shell/common/switches.h b/engine/src/flutter/shell/common/switches.h index 6f39926e74a..eab0ac3ead9 100644 --- a/engine/src/flutter/shell/common/switches.h +++ b/engine/src/flutter/shell/common/switches.h @@ -105,6 +105,9 @@ DEF_SWITCH(EnableSoftwareRendering, "Enable rendering using the Skia software backend. This is useful " "when testing Flutter on emulators. By default, Flutter will " "attempt to either use OpenGL, Metal, or Vulkan.") +DEF_SWITCH(Route, + "route", + "Start app with an specific route defined on the framework") DEF_SWITCH(SkiaDeterministicRendering, "skia-deterministic-rendering", "Skips the call to SkGraphics::Init(), thus avoiding swapping out " diff --git a/engine/src/flutter/shell/common/switches_unittests.cc b/engine/src/flutter/shell/common/switches_unittests.cc index 686a1596063..3b0dcce0722 100644 --- a/engine/src/flutter/shell/common/switches_unittests.cc +++ b/engine/src/flutter/shell/common/switches_unittests.cc @@ -46,5 +46,15 @@ TEST(SwitchesTest, SkiaTraceAllowlistFlag) { #endif } +TEST(SwitchesTest, RouteParsedFlag) { + fml::CommandLine command_line = + fml::CommandLineFromInitializerList({"command", "--route=/animation"}); + Settings settings = SettingsFromCommandLine(command_line); + EXPECT_EQ(settings.route, "/animation"); + command_line = fml::CommandLineFromInitializerList({"command", "--route"}); + settings = SettingsFromCommandLine(command_line); + EXPECT_TRUE(settings.route.empty()); +} + } // namespace testing } // namespace flutter diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm index 889cb783da9..fabec4e1116 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm @@ -695,6 +695,13 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS self.initialRoute = initialRoute; auto settings = [_dartProject.get() settings]; + if (initialRoute != nil) { + self.initialRoute = initialRoute; + } else if (settings.route.empty() == false) { + self.initialRoute = [NSString stringWithCString:settings.route.c_str() + encoding:NSUTF8StringEncoding]; + } + FlutterView.forceSoftwareRendering = settings.enable_software_rendering; auto platformData = [_dartProject.get() defaultPlatformData]; diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterEngineTest.mm b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterEngineTest.mm index 4a5f1f75d8c..f5ac867d9c7 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterEngineTest.mm +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterEngineTest.mm @@ -159,6 +159,26 @@ FLUTTER_ASSERT_ARC message:encodedSetInitialRouteMethod]); } +- (void)testInitialRouteSettingsSendsNavigationMessage { + id mockBinaryMessenger = OCMClassMock([FlutterBinaryMessengerRelay class]); + + auto settings = FLTDefaultSettingsForBundle(); + settings.route = "test"; + FlutterDartProject* project = [[FlutterDartProject alloc] initWithSettings:settings]; + FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"foobar" project:project]; + [engine setBinaryMessenger:mockBinaryMessenger]; + [engine run]; + + // Now check that an encoded method call has been made on the binary messenger to set the + // initial route to "test". + FlutterMethodCall* setInitialRouteMethodCall = + [FlutterMethodCall methodCallWithMethodName:@"setInitialRoute" arguments:@"test"]; + NSData* encodedSetInitialRouteMethod = + [[FlutterJSONMethodCodec sharedInstance] encodeMethodCall:setInitialRouteMethodCall]; + OCMVerify([mockBinaryMessenger sendOnChannel:@"flutter/navigation" + message:encodedSetInitialRouteMethod]); +} + - (void)testPlatformViewsControllerRenderingMetalBackend { FlutterEngine* engine = [[FlutterEngine alloc] init]; [engine run];