mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Reland: Call Dart plugin registrant if available (flutter/engine#25375)
This commit is contained in:
parent
26574f5de2
commit
d20f5e016a
@ -132,10 +132,14 @@ typedef _ListStringArgFunction(List<String> args);
|
||||
@pragma('vm:entry-point')
|
||||
// ignore: unused_element
|
||||
void _runMainZoned(Function startMainIsolateFunction,
|
||||
Function? dartPluginRegistrant,
|
||||
Function userMainFunction,
|
||||
List<String> args) {
|
||||
startMainIsolateFunction(() {
|
||||
runZonedGuarded<void>(() {
|
||||
if (dartPluginRegistrant != null) {
|
||||
dartPluginRegistrant();
|
||||
}
|
||||
if (userMainFunction is _ListStringArgFunction) {
|
||||
(userMainFunction as dynamic)(args);
|
||||
} else {
|
||||
|
||||
@ -700,6 +700,7 @@ bool DartIsolate::MarkIsolateRunnable() {
|
||||
|
||||
[[nodiscard]] static bool InvokeMainEntrypoint(
|
||||
Dart_Handle user_entrypoint_function,
|
||||
Dart_Handle plugin_registrant_function,
|
||||
Dart_Handle args) {
|
||||
if (tonic::LogIfError(user_entrypoint_function)) {
|
||||
FML_LOG(ERROR) << "Could not resolve main entrypoint function.";
|
||||
@ -717,7 +718,8 @@ bool DartIsolate::MarkIsolateRunnable() {
|
||||
|
||||
if (tonic::LogIfError(tonic::DartInvokeField(
|
||||
Dart_LookupLibrary(tonic::ToDart("dart:ui")), "_runMainZoned",
|
||||
{start_main_isolate_function, user_entrypoint_function, args}))) {
|
||||
{start_main_isolate_function, plugin_registrant_function,
|
||||
user_entrypoint_function, args}))) {
|
||||
FML_LOG(ERROR) << "Could not invoke the main entrypoint.";
|
||||
return false;
|
||||
}
|
||||
@ -742,12 +744,34 @@ bool DartIsolate::RunFromLibrary(std::optional<std::string> library_name,
|
||||
auto entrypoint_handle = entrypoint.has_value() && !entrypoint.value().empty()
|
||||
? tonic::ToDart(entrypoint.value().c_str())
|
||||
: tonic::ToDart("main");
|
||||
auto entrypoint_args = tonic::ToDart(args);
|
||||
auto user_entrypoint_function =
|
||||
::Dart_GetField(library_handle, entrypoint_handle);
|
||||
|
||||
auto entrypoint_args = tonic::ToDart(args);
|
||||
// The Dart plugin registrant is a function named `_registerPlugins`
|
||||
// generated by the Flutter tool.
|
||||
//
|
||||
// This function binds a plugin implementation to their platform
|
||||
// interface based on the configuration of the app's pubpec.yaml, and the
|
||||
// plugin's pubspec.yaml.
|
||||
//
|
||||
// Since this function may or may not be defined. Check that it is a top
|
||||
// level function, and call it in hooks.dart before the main entrypoint
|
||||
// function.
|
||||
//
|
||||
// If it's not defined, then just call the main entrypoint function
|
||||
// as usual.
|
||||
//
|
||||
// This allows embeddings to change the name of the entrypoint function.
|
||||
auto plugin_registrant_function =
|
||||
::Dart_GetField(library_handle, tonic::ToDart("_registerPlugins"));
|
||||
|
||||
if (!InvokeMainEntrypoint(user_entrypoint_function, entrypoint_args)) {
|
||||
if (Dart_IsError(plugin_registrant_function)) {
|
||||
plugin_registrant_function = Dart_Null();
|
||||
}
|
||||
|
||||
if (!InvokeMainEntrypoint(user_entrypoint_function,
|
||||
plugin_registrant_function, entrypoint_args)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -613,5 +613,39 @@ TEST_F(DartIsolateTest, DISABLED_ValidLoadingUnitSucceeds) {
|
||||
Wait();
|
||||
}
|
||||
|
||||
TEST_F(DartIsolateTest, DartPluginRegistrantIsCalled) {
|
||||
ASSERT_FALSE(DartVMRef::IsInstanceRunning());
|
||||
|
||||
std::vector<std::string> messages;
|
||||
fml::AutoResetWaitableEvent latch;
|
||||
|
||||
AddNativeCallback(
|
||||
"PassMessage",
|
||||
CREATE_NATIVE_ENTRY(([&latch, &messages](Dart_NativeArguments args) {
|
||||
auto message = tonic::DartConverter<std::string>::FromDart(
|
||||
Dart_GetNativeArgument(args, 0));
|
||||
messages.push_back(message);
|
||||
latch.Signal();
|
||||
})));
|
||||
|
||||
const auto settings = CreateSettingsForFixture();
|
||||
auto vm_ref = DartVMRef::Create(settings);
|
||||
auto thread = CreateNewThread();
|
||||
TaskRunners task_runners(GetCurrentTestName(), //
|
||||
thread, //
|
||||
thread, //
|
||||
thread, //
|
||||
thread //
|
||||
);
|
||||
auto isolate = RunDartCodeInIsolate(vm_ref, settings, task_runners,
|
||||
"mainForPluginRegistrantTest", {},
|
||||
GetFixturesPath());
|
||||
ASSERT_TRUE(isolate);
|
||||
ASSERT_EQ(isolate->get()->GetPhase(), DartIsolate::Phase::Running);
|
||||
latch.Wait();
|
||||
ASSERT_EQ(messages.size(), 1u);
|
||||
ASSERT_EQ(messages[0], "_registerPlugins was called");
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
} // namespace flutter
|
||||
|
||||
@ -10,8 +10,7 @@ import 'dart:ui';
|
||||
|
||||
import 'split_lib_test.dart' deferred as splitlib;
|
||||
|
||||
void main() {
|
||||
}
|
||||
void main() {}
|
||||
|
||||
@pragma('vm:entry-point')
|
||||
void sayHi() {
|
||||
@ -115,3 +114,24 @@ void testCanConvertListOfInts(List<int> args){
|
||||
args[2] == 3 &&
|
||||
args[3] == 4);
|
||||
}
|
||||
|
||||
bool didCallRegistrantBeforeEntrypoint = false;
|
||||
|
||||
// Test the Dart plugin registrant.
|
||||
// _registerPlugins requires the entrypoint annotation, so the compiler doesn't tree shake it.
|
||||
@pragma('vm:entry-point')
|
||||
void _registerPlugins() { // ignore: unused_element
|
||||
if (didCallRegistrantBeforeEntrypoint) {
|
||||
throw '_registerPlugins is being called twice';
|
||||
}
|
||||
didCallRegistrantBeforeEntrypoint = true;
|
||||
}
|
||||
|
||||
@pragma('vm:entry-point')
|
||||
void mainForPluginRegistrantTest() { // ignore: unused_element
|
||||
if (didCallRegistrantBeforeEntrypoint) {
|
||||
passMessage('_registerPlugins was called');
|
||||
} else {
|
||||
passMessage('_registerPlugins was not called');
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user