Add dart_entrypoint_argc/argv to the FlutterProjectArgs (#21737)
diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc
index 971ef22..06b45ac 100644
--- a/shell/platform/embedder/embedder.cc
+++ b/shell/platform/embedder/embedder.cc
@@ -1126,6 +1126,20 @@
}
}
+ if (SAFE_ACCESS(args, dart_entrypoint_argc, 0) > 0) {
+ if (SAFE_ACCESS(args, dart_entrypoint_argv, nullptr) == nullptr) {
+ return LOG_EMBEDDER_ERROR(kInvalidArguments,
+ "Could not determine Dart entrypoint arguments "
+ "as dart_entrypoint_argc "
+ "was set, but dart_entrypoint_argv was null.");
+ }
+ std::vector<std::string> arguments(args->dart_entrypoint_argc);
+ for (int i = 0; i < args->dart_entrypoint_argc; ++i) {
+ arguments[i] = std::string{args->dart_entrypoint_argv[i]};
+ }
+ settings.dart_entrypoint_args = std::move(arguments);
+ }
+
if (!run_configuration.IsValid()) {
return LOG_EMBEDDER_ERROR(
kInvalidArguments,
diff --git a/shell/platform/embedder/embedder.h b/shell/platform/embedder/embedder.h
index 8ed2dad..51d832b 100644
--- a/shell/platform/embedder/embedder.h
+++ b/shell/platform/embedder/embedder.h
@@ -1368,6 +1368,19 @@
/// matches what the platform would natively resolve to as possible.
FlutterComputePlatformResolvedLocaleCallback
compute_platform_resolved_locale_callback;
+
+ /// The command line argument count for arguments passed through to the Dart
+ /// entrypoint.
+ int dart_entrypoint_argc;
+
+ /// The command line arguments passed through to the Dart entrypoint. The
+ /// strings must be `NULL` terminated.
+ ///
+ /// The strings will be copied out and so any strings passed in here can
+ /// be safely collected after initializing the engine with
+ /// `FlutterProjectArgs`.
+ const char* const* dart_entrypoint_argv;
+
} FlutterProjectArgs;
//------------------------------------------------------------------------------
diff --git a/shell/platform/embedder/fixtures/main.dart b/shell/platform/embedder/fixtures/main.dart
index de4cf42..5dae4e4 100644
--- a/shell/platform/embedder/fixtures/main.dart
+++ b/shell/platform/embedder/fixtures/main.dart
@@ -733,3 +733,10 @@
};
window.scheduleFrame();
}
+
+void nativeArgumentsCallback(List<String> args) native 'NativeArgumentsCallback';
+
+@pragma('vm:entry-point')
+void dart_entrypoint_args(List<String> args) {
+ nativeArgumentsCallback(args);
+}
diff --git a/shell/platform/embedder/tests/embedder_config_builder.cc b/shell/platform/embedder/tests/embedder_config_builder.cc
index 5c1f741..93d4c6a 100644
--- a/shell/platform/embedder/tests/embedder_config_builder.cc
+++ b/shell/platform/embedder/tests/embedder_config_builder.cc
@@ -217,6 +217,14 @@
command_line_arguments_.emplace_back(std::move(arg));
}
+void EmbedderConfigBuilder::AddDartEntrypointArgument(std::string arg) {
+ if (arg.size() == 0) {
+ return;
+ }
+
+ dart_entrypoint_arguments_.emplace_back(std::move(arg));
+}
+
void EmbedderConfigBuilder::SetPlatformTaskRunner(
const FlutterTaskRunnerDescription* runner) {
if (runner == nullptr) {
@@ -317,6 +325,23 @@
project_args.command_line_argc = 0;
}
+ std::vector<const char*> dart_args;
+ dart_args.reserve(dart_entrypoint_arguments_.size());
+
+ for (const auto& arg : dart_entrypoint_arguments_) {
+ dart_args.push_back(arg.c_str());
+ }
+
+ if (dart_args.size() > 0) {
+ project_args.dart_entrypoint_argv = dart_args.data();
+ project_args.dart_entrypoint_argc = dart_args.size();
+ } else {
+ // Clear it out in case this is not the first engine launch from the
+ // embedder config builder.
+ project_args.dart_entrypoint_argv = nullptr;
+ project_args.dart_entrypoint_argc = 0;
+ }
+
auto result =
run ? FlutterEngineRun(FLUTTER_ENGINE_VERSION, &renderer_config_,
&project_args, &context_, &engine)
diff --git a/shell/platform/embedder/tests/embedder_config_builder.h b/shell/platform/embedder/tests/embedder_config_builder.h
index 29dc4ef..4c37d64 100644
--- a/shell/platform/embedder/tests/embedder_config_builder.h
+++ b/shell/platform/embedder/tests/embedder_config_builder.h
@@ -76,6 +76,8 @@
void AddCommandLineArgument(std::string arg);
+ void AddDartEntrypointArgument(std::string arg);
+
void SetPlatformTaskRunner(const FlutterTaskRunnerDescription* runner);
void SetRenderTaskRunner(const FlutterTaskRunnerDescription* runner);
@@ -106,6 +108,7 @@
FlutterCustomTaskRunners custom_task_runners_ = {};
FlutterCompositor compositor_ = {};
std::vector<std::string> command_line_arguments_;
+ std::vector<std::string> dart_entrypoint_arguments_;
UniqueEngine SetupEngine(bool run) const;
diff --git a/shell/platform/embedder/tests/embedder_unittests.cc b/shell/platform/embedder/tests/embedder_unittests.cc
index 786b7da..01309bb 100644
--- a/shell/platform/embedder/tests/embedder_unittests.cc
+++ b/shell/platform/embedder/tests/embedder_unittests.cc
@@ -474,6 +474,33 @@
}
//------------------------------------------------------------------------------
+///
+TEST_F(EmbedderTest, DartEntrypointArgs) {
+ auto& context = GetEmbedderContext(ContextType::kSoftwareContext);
+ EmbedderConfigBuilder builder(context);
+ builder.SetSoftwareRendererConfig();
+ builder.AddDartEntrypointArgument("foo");
+ builder.AddDartEntrypointArgument("bar");
+ builder.SetDartEntrypoint("dart_entrypoint_args");
+ fml::AutoResetWaitableEvent callback_latch;
+ std::vector<std::string> callback_args;
+ auto nativeArgumentsCallback = [&callback_args,
+ &callback_latch](Dart_NativeArguments args) {
+ Dart_Handle exception = nullptr;
+ callback_args =
+ tonic::DartConverter<std::vector<std::string>>::FromArguments(
+ args, 0, exception);
+ callback_latch.Signal();
+ };
+ context.AddNativeCallback("NativeArgumentsCallback",
+ CREATE_NATIVE_ENTRY(nativeArgumentsCallback));
+ auto engine = builder.LaunchEngine();
+ callback_latch.Wait();
+ ASSERT_EQ(callback_args[0], "foo");
+ ASSERT_EQ(callback_args[1], "bar");
+}
+
+//------------------------------------------------------------------------------
/// These snapshots may be materialized from symbols and the size field may not
/// be relevant. Since this information is redundant, engine launch should not
/// be gated on a non-zero buffer size.