Skip to content

Commit 9e49ffb

Browse files
Make FlutterEngineGroup support dart entrypoint args (flutter#29096)
1 parent d8a3b06 commit 9e49ffb

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+752
-62
lines changed

common/settings.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,8 @@ struct Settings {
127127
std::string temp_directory_path;
128128
std::vector<std::string> dart_flags;
129129
// Arguments passed as a List<String> to Dart's entrypoint function.
130+
// TODO(93459): Remove it when it is no longer used.
131+
// https://github.com/flutter/flutter/issues/93459
130132
std::vector<std::string> dart_entrypoint_args;
131133

132134
// Isolate settings

fml/platform/android/jni_util.cc

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,35 @@ std::vector<std::string> StringArrayToVector(JNIEnv* env, jobjectArray array) {
125125
return out;
126126
}
127127

128+
std::vector<std::string> StringListToVector(JNIEnv* env, jobject list) {
129+
std::vector<std::string> out;
130+
if (env == nullptr || list == nullptr) {
131+
return out;
132+
}
133+
134+
ScopedJavaLocalRef<jclass> list_clazz(env, env->FindClass("java/util/List"));
135+
FML_DCHECK(!list_clazz.is_null());
136+
137+
jmethodID list_get =
138+
env->GetMethodID(list_clazz.obj(), "get", "(I)Ljava/lang/Object;");
139+
jmethodID list_size = env->GetMethodID(list_clazz.obj(), "size", "()I");
140+
141+
jint size = env->CallIntMethod(list, list_size);
142+
143+
if (size == 0) {
144+
return out;
145+
}
146+
147+
out.resize(size);
148+
for (jint i = 0; i < size; ++i) {
149+
ScopedJavaLocalRef<jstring> java_string(
150+
env, static_cast<jstring>(env->CallObjectMethod(list, list_get, i)));
151+
out[i] = JavaStringToString(env, java_string.obj());
152+
}
153+
154+
return out;
155+
}
156+
128157
ScopedJavaLocalRef<jobjectArray> VectorToStringArray(
129158
JNIEnv* env,
130159
const std::vector<std::string>& vector) {

fml/platform/android/jni_util.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ ScopedJavaLocalRef<jstring> StringToJavaString(JNIEnv* env,
3030

3131
std::vector<std::string> StringArrayToVector(JNIEnv* env, jobjectArray jargs);
3232

33+
std::vector<std::string> StringListToVector(JNIEnv* env, jobject list);
34+
3335
ScopedJavaLocalRef<jobjectArray> VectorToStringArray(
3436
JNIEnv* env,
3537
const std::vector<std::string>& vector);

runtime/dart_isolate.cc

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ std::weak_ptr<DartIsolate> DartIsolate::SpawnIsolate(
9393
const fml::closure& isolate_shutdown_callback,
9494
std::optional<std::string> dart_entrypoint,
9595
std::optional<std::string> dart_entrypoint_library,
96+
const std::vector<std::string>& dart_entrypoint_args,
9697
std::unique_ptr<IsolateConfiguration> isolate_configuration) const {
9798
return CreateRunningRootIsolate(
9899
settings, //
@@ -104,6 +105,7 @@ std::weak_ptr<DartIsolate> DartIsolate::SpawnIsolate(
104105
isolate_shutdown_callback, //
105106
dart_entrypoint, //
106107
dart_entrypoint_library, //
108+
dart_entrypoint_args, //
107109
std::move(isolate_configuration), //
108110
UIDartState::Context{GetTaskRunners(), //
109111
snapshot_delegate, //
@@ -128,6 +130,7 @@ std::weak_ptr<DartIsolate> DartIsolate::CreateRunningRootIsolate(
128130
const fml::closure& isolate_shutdown_callback,
129131
std::optional<std::string> dart_entrypoint,
130132
std::optional<std::string> dart_entrypoint_library,
133+
const std::vector<std::string>& dart_entrypoint_args,
131134
std::unique_ptr<IsolateConfiguration> isolate_configuration,
132135
const UIDartState::Context& context,
133136
const DartIsolate* spawning_isolate) {
@@ -195,10 +198,14 @@ std::weak_ptr<DartIsolate> DartIsolate::CreateRunningRootIsolate(
195198
root_isolate_create_callback();
196199
}
197200

198-
if (!isolate->RunFromLibrary(dart_entrypoint_library, //
199-
dart_entrypoint, //
200-
settings.dart_entrypoint_args //
201-
)) {
201+
FML_DCHECK(dart_entrypoint_args.empty() ||
202+
settings.dart_entrypoint_args.empty());
203+
const std::vector<std::string>& args = !dart_entrypoint_args.empty()
204+
? dart_entrypoint_args
205+
: settings.dart_entrypoint_args;
206+
if (!isolate->RunFromLibrary(dart_entrypoint_library, //
207+
dart_entrypoint, //
208+
args)) {
202209
FML_LOG(ERROR) << "Could not run the run main Dart entrypoint.";
203210
return {};
204211
}

runtime/dart_isolate.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,8 @@ class DartIsolate : public UIDartState {
170170
/// function to invoke.
171171
/// @param[in] dart_entrypoint_library The name of the dart library
172172
/// containing the entrypoint.
173+
/// @param[in] dart_entrypoint_args Arguments passed as a List<String>
174+
/// to Dart's entrypoint function.
173175
/// @param[in] isolate_configuration The isolate configuration used to
174176
/// configure the isolate before
175177
/// invoking the entrypoint.
@@ -215,6 +217,7 @@ class DartIsolate : public UIDartState {
215217
const fml::closure& isolate_shutdown_callback,
216218
std::optional<std::string> dart_entrypoint,
217219
std::optional<std::string> dart_entrypoint_library,
220+
const std::vector<std::string>& dart_entrypoint_args,
218221
std::unique_ptr<IsolateConfiguration> isolate_configuration,
219222
const UIDartState::Context& context,
220223
const DartIsolate* spawning_isolate = nullptr);
@@ -245,6 +248,7 @@ class DartIsolate : public UIDartState {
245248
const fml::closure& isolate_shutdown_callback,
246249
std::optional<std::string> dart_entrypoint,
247250
std::optional<std::string> dart_entrypoint_library,
251+
const std::vector<std::string>& dart_entrypoint_args,
248252
std::unique_ptr<IsolateConfiguration> isolate_configuration) const;
249253

250254
// |UIDartState|

runtime/dart_isolate_unittests.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ TEST_F(DartIsolateTest, RootIsolateCreationAndShutdown) {
6464
settings.isolate_shutdown_callback, // isolate shutdown callback
6565
"main", // dart entrypoint
6666
std::nullopt, // dart entrypoint library
67+
{}, // dart entrypoint arguments
6768
std::move(isolate_configuration), // isolate configuration
6869
std::move(context) // engine context
6970
);
@@ -103,6 +104,7 @@ TEST_F(DartIsolateTest, SpawnIsolate) {
103104
settings.isolate_shutdown_callback, // isolate shutdown callback
104105
"main", // dart entrypoint
105106
std::nullopt, // dart entrypoint library
107+
{}, // dart entrypoint arguments
106108
std::move(isolate_configuration), // isolate configuration
107109
std::move(context) // engine context
108110
);
@@ -123,6 +125,7 @@ TEST_F(DartIsolateTest, SpawnIsolate) {
123125
/*isolate_shutdown_callback=*/settings.isolate_shutdown_callback,
124126
/*dart_entrypoint=*/"main",
125127
/*dart_entrypoint_library=*/std::nullopt,
128+
/*dart_entrypoint_args=*/{},
126129
/*isolate_configuration=*/std::move(spawn_configuration));
127130
auto spawn = weak_spawn.lock();
128131
ASSERT_TRUE(spawn);
@@ -177,6 +180,7 @@ TEST_F(DartIsolateTest, IsolateShutdownCallbackIsInIsolateScope) {
177180
settings.isolate_shutdown_callback, // isolate shutdown callback
178181
"main", // dart entrypoint
179182
std::nullopt, // dart entrypoint library
183+
{}, // dart entrypoint arguments
180184
std::move(isolate_configuration), // isolate configuration
181185
std::move(context) // engine context
182186
);
@@ -400,6 +404,7 @@ TEST_F(DartIsolateTest, CanCreateServiceIsolate) {
400404
settings.isolate_shutdown_callback, // isolate shutdown callback
401405
"main", // dart entrypoint
402406
std::nullopt, // dart entrypoint library
407+
{}, // dart entrypoint arguments
403408
std::move(isolate_configuration), // isolate configuration
404409
std::move(context) // engine context
405410
);
@@ -499,6 +504,7 @@ TEST_F(DartIsolateTest, InvalidLoadingUnitFails) {
499504
settings.isolate_shutdown_callback, // isolate shutdown callback
500505
"main", // dart entrypoint
501506
std::nullopt, // dart entrypoint library
507+
{}, // dart entrypoint arguments
502508
std::move(isolate_configuration), // isolate configuration
503509
std::move(context) // engine context
504510
);

runtime/dart_lifecycle_unittests.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ static std::shared_ptr<DartIsolate> CreateAndRunRootIsolate(
6969
settings.isolate_shutdown_callback, // isolate shutdown callback,
7070
entrypoint, // dart entrypoint
7171
std::nullopt, // dart entrypoint library
72+
{}, // dart entrypoint arguments
7273
std::move(isolate_configuration), // isolate configuration
7374
std::move(context) // engine context
7475
)

runtime/runtime_controller.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,7 @@ bool RuntimeController::LaunchRootIsolate(
344344
fml::closure root_isolate_create_callback,
345345
std::optional<std::string> dart_entrypoint,
346346
std::optional<std::string> dart_entrypoint_library,
347+
const std::vector<std::string>& dart_entrypoint_args,
347348
std::unique_ptr<IsolateConfiguration> isolate_configuration) {
348349
if (root_isolate_.lock()) {
349350
FML_LOG(ERROR) << "Root isolate was already running.";
@@ -361,6 +362,7 @@ bool RuntimeController::LaunchRootIsolate(
361362
isolate_shutdown_callback_, //
362363
dart_entrypoint, //
363364
dart_entrypoint_library, //
365+
dart_entrypoint_args, //
364366
std::move(isolate_configuration), //
365367
context_, //
366368
spawning_isolate_.lock().get()) //

runtime/runtime_controller.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ class RuntimeController : public PlatformConfigurationClient {
132132
/// @param[in] dart_entrypoint_library The dart entrypoint library. If
133133
/// `std::nullopt` or empty, the core
134134
/// library will be attempted.
135+
/// @param[in] dart_entrypoint_args Arguments passed as a List<String>
136+
/// to Dart's entrypoint function.
135137
/// @param[in] isolate_configuration The isolate configuration
136138
///
137139
/// @return If the isolate could be launched and guided to the
@@ -142,6 +144,7 @@ class RuntimeController : public PlatformConfigurationClient {
142144
fml::closure root_isolate_create_callback,
143145
std::optional<std::string> dart_entrypoint,
144146
std::optional<std::string> dart_entrypoint_library,
147+
const std::vector<std::string>& dart_entrypoint_args,
145148
std::unique_ptr<IsolateConfiguration> isolate_configuration);
146149

147150
//----------------------------------------------------------------------------

shell/common/engine.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,10 @@ Engine::RunStatus Engine::Run(RunConfiguration configuration) {
199199

200200
last_entry_point_ = configuration.GetEntrypoint();
201201
last_entry_point_library_ = configuration.GetEntrypointLibrary();
202+
#if (FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG)
203+
// This is only used to support restart.
204+
last_entry_point_args_ = configuration.GetEntrypointArgs();
205+
#endif
202206

203207
UpdateAssetManager(configuration.GetAssetManager());
204208

@@ -220,6 +224,7 @@ Engine::RunStatus Engine::Run(RunConfiguration configuration) {
220224
root_isolate_create_callback, //
221225
configuration.GetEntrypoint(), //
222226
configuration.GetEntrypointLibrary(), //
227+
configuration.GetEntrypointArgs(), //
223228
configuration.TakeIsolateConfiguration()) //
224229
) {
225230
return RunStatus::Failure;
@@ -562,6 +567,10 @@ const std::string& Engine::GetLastEntrypointLibrary() const {
562567
return last_entry_point_library_;
563568
}
564569

570+
const std::vector<std::string>& Engine::GetLastEntrypointArgs() const {
571+
return last_entry_point_args_;
572+
}
573+
565574
// |RuntimeDelegate|
566575
void Engine::RequestDartDeferredLibrary(intptr_t loading_unit_id) {
567576
return delegate_.RequestDartDeferredLibrary(loading_unit_id);

shell/common/engine.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -819,6 +819,13 @@ class Engine final : public RuntimeDelegate, PointerDataDispatcher::Delegate {
819819
///
820820
const std::string& GetLastEntrypointLibrary() const;
821821

822+
//----------------------------------------------------------------------------
823+
/// @brief Get the last Entrypoint Arguments that was used in the
824+
/// RunConfiguration when |Engine::Run| was called.This is only
825+
/// valid in debug mode.
826+
///
827+
const std::vector<std::string>& GetLastEntrypointArgs() const;
828+
822829
//----------------------------------------------------------------------------
823830
/// @brief Getter for the initial route. This can be set with a platform
824831
/// message.
@@ -955,6 +962,7 @@ class Engine final : public RuntimeDelegate, PointerDataDispatcher::Delegate {
955962

956963
std::string last_entry_point_;
957964
std::string last_entry_point_library_;
965+
std::vector<std::string> last_entry_point_args_;
958966
std::string initial_route_;
959967
ViewportMetrics viewport_metrics_;
960968
std::shared_ptr<AssetManager> asset_manager_;

shell/common/fixtures/shell_test.dart

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,3 +247,17 @@ void canAccessResourceFromAssetDir() async {
247247
},
248248
);
249249
}
250+
251+
void notifyNativeWhenEngineRun(bool success) native 'NotifyNativeWhenEngineRun';
252+
253+
void notifyNativeWhenEngineSpawn(bool success) native 'NotifyNativeWhenEngineSpawn';
254+
255+
@pragma('vm:entry-point')
256+
void canRecieveArgumentsWhenEngineRun(List<String> args) {
257+
notifyNativeWhenEngineRun(args.length == 2 && args[0] == 'foo' && args[1] == 'bar');
258+
}
259+
260+
@pragma('vm:entry-point')
261+
void canRecieveArgumentsWhenEngineSpawn(List<String> args) {
262+
notifyNativeWhenEngineSpawn(args.length == 2 && args[0] == 'arg1' && args[1] == 'arg2');
263+
}

shell/common/run_configuration.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,11 @@ void RunConfiguration::SetEntrypointAndLibrary(std::string entrypoint,
7777
entrypoint_library_ = std::move(library);
7878
}
7979

80+
void RunConfiguration::SetEntrypointArgs(
81+
const std::vector<std::string>& entrypoint_args) {
82+
entrypoint_args_ = entrypoint_args;
83+
}
84+
8085
std::shared_ptr<AssetManager> RunConfiguration::GetAssetManager() const {
8186
return asset_manager_;
8287
}
@@ -89,6 +94,10 @@ const std::string& RunConfiguration::GetEntrypointLibrary() const {
8994
return entrypoint_library_;
9095
}
9196

97+
const std::vector<std::string>& RunConfiguration::GetEntrypointArgs() const {
98+
return entrypoint_args_;
99+
}
100+
92101
std::unique_ptr<IsolateConfiguration>
93102
RunConfiguration::TakeIsolateConfiguration() {
94103
return std::move(isolate_configuration_);

shell/common/run_configuration.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,12 @@ class RunConfiguration {
151151
///
152152
void SetEntrypointAndLibrary(std::string entrypoint, std::string library);
153153

154+
//----------------------------------------------------------------------------
155+
/// @brief Updates the main application entrypoint arguments.
156+
///
157+
/// @param[in] entrypoint_args The entrypoint arguments to use.
158+
void SetEntrypointArgs(const std::vector<std::string>& entrypoint_args);
159+
154160
//----------------------------------------------------------------------------
155161
/// @return The asset manager referencing all previously registered asset
156162
/// resolvers.
@@ -168,6 +174,12 @@ class RunConfiguration {
168174
///
169175
const std::string& GetEntrypointLibrary() const;
170176

177+
//----------------------------------------------------------------------------
178+
/// @return Arguments passed as a List<String> to Dart's entrypoint
179+
/// function.
180+
///
181+
const std::vector<std::string>& GetEntrypointArgs() const;
182+
171183
//----------------------------------------------------------------------------
172184
/// @brief The engine uses this to take the isolate configuration from
173185
/// the run configuration. The run configuration is no longer
@@ -184,6 +196,7 @@ class RunConfiguration {
184196
std::shared_ptr<AssetManager> asset_manager_;
185197
std::string entrypoint_ = "main";
186198
std::string entrypoint_library_ = "";
199+
std::vector<std::string> entrypoint_args_;
187200

188201
FML_DISALLOW_COPY_AND_ASSIGN(RunConfiguration);
189202
};

shell/common/shell.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1556,6 +1556,7 @@ bool Shell::OnServiceProtocolRunInView(
15561556

15571557
configuration.SetEntrypointAndLibrary(engine_->GetLastEntrypoint(),
15581558
engine_->GetLastEntrypointLibrary());
1559+
configuration.SetEntrypointArgs(engine_->GetLastEntrypointArgs());
15591560

15601561
configuration.AddAssetResolver(std::make_unique<DirectoryAssetBundle>(
15611562
fml::OpenDirectory(asset_directory_path.c_str(), false,

0 commit comments

Comments
 (0)