From b5f7f557acfbb897ce4d5806853368d7609c11fa Mon Sep 17 00:00:00 2001 From: gaaclarke <30870216+gaaclarke@users.noreply.github.com> Date: Fri, 23 Sep 2022 11:36:09 -0700 Subject: [PATCH] Made sure to call the plugin registrant when registering a background isolate (flutter/engine#36383) --- .../flutter/lib/ui/platform_dispatcher.dart | 1 + .../dart_plugin_registrant_unittests.cc | 48 +++++++++++++++++++ .../flutter_build/dart_plugin_registrant.dart | 20 ++++++++ 3 files changed, 69 insertions(+) diff --git a/engine/src/flutter/lib/ui/platform_dispatcher.dart b/engine/src/flutter/lib/ui/platform_dispatcher.dart index e0f53b4a737..5509ccb3f18 100644 --- a/engine/src/flutter/lib/ui/platform_dispatcher.dart +++ b/engine/src/flutter/lib/ui/platform_dispatcher.dart @@ -586,6 +586,7 @@ class PlatformDispatcher { /// [token]. This is required if platform channels are to be used on a /// background isolate. void registerBackgroundIsolate(RootIsolateToken token) { + DartPluginRegistrant.ensureInitialized(); __registerBackgroundIsolate(token._token); } @FfiNative('PlatformConfigurationNativeApi::RegisterBackgroundIsolate') diff --git a/engine/src/flutter/runtime/dart_plugin_registrant_unittests.cc b/engine/src/flutter/runtime/dart_plugin_registrant_unittests.cc index 1c6f9b6f628..b3f7892617c 100644 --- a/engine/src/flutter/runtime/dart_plugin_registrant_unittests.cc +++ b/engine/src/flutter/runtime/dart_plugin_registrant_unittests.cc @@ -195,6 +195,54 @@ TEST_F(DartIsolateTest, DartPluginRegistrantNotFromBackgroundIsolate) { "_PluginRegistrant.register() was not called on background isolate"); } +TEST_F(DartIsolateTest, DartPluginRegistrantWhenRegisteringBackgroundIsolate) { + ASSERT_FALSE(DartVMRef::IsInstanceRunning()); + + std::vector messages; + fml::AutoResetWaitableEvent latch; + + AddNativeCallback( + "PassMessage", + CREATE_NATIVE_ENTRY(([&latch, &messages](Dart_NativeArguments args) { + auto message = tonic::DartConverter::FromDart( + Dart_GetNativeArgument(args, 0)); + messages.push_back(message); + latch.Signal(); + }))); + + auto settings = CreateSettingsForFixture(); + auto did_throw_exception = false; + settings.unhandled_exception_callback = [&](const std::string& error, + const std::string& stack_trace) { + did_throw_exception = true; + return true; + }; + + auto vm_ref = DartVMRef::Create(settings); + auto thread = CreateNewThread(); + TaskRunners task_runners(GetCurrentTestName(), // + thread, // + thread, // + thread, // + thread // + ); + + auto kernel_path = + fml::paths::JoinPaths({GetFixturesPath(), kKernelFileName}); + auto isolate = RunDartCodeInIsolate( + vm_ref, settings, task_runners, + "registerBackgroundIsolateCallsDartPluginRegistrant", {}, kernel_path); + + ASSERT_TRUE(isolate); + ASSERT_EQ(isolate->get()->GetPhase(), DartIsolate::Phase::Running); + + latch.Wait(); + + ASSERT_EQ(messages.size(), 1u); + ASSERT_EQ(messages[0], + "_PluginRegistrant.register() was called on background isolate"); +} + } // namespace testing } // namespace flutter diff --git a/engine/src/flutter/runtime/fixtures/dart_tool/flutter_build/dart_plugin_registrant.dart b/engine/src/flutter/runtime/fixtures/dart_tool/flutter_build/dart_plugin_registrant.dart index 907e831eb10..1622a892b5a 100644 --- a/engine/src/flutter/runtime/fixtures/dart_tool/flutter_build/dart_plugin_registrant.dart +++ b/engine/src/flutter/runtime/fixtures/dart_tool/flutter_build/dart_plugin_registrant.dart @@ -41,6 +41,13 @@ void dartPluginRegistrantIsolate(SendPort sendPort) { sendPort.send(didCallRegistrantBeforeEntrypoint); } +void registerBackgroundIsolate(List args) { + SendPort sendPort = args[0] as SendPort; + RootIsolateToken token = args[1] as RootIsolateToken; + PlatformDispatcher.instance.registerBackgroundIsolate(token); + sendPort.send(didCallRegistrantBeforeEntrypoint); +} + @pragma('vm:entry-point') void callDartPluginRegistrantFromBackgroundIsolate() async { ReceivePort receivePort = ReceivePort(); @@ -70,3 +77,16 @@ void dontCallDartPluginRegistrantFromBackgroundIsolate() async { } isolate.kill(); } + +@pragma('vm:entry-point') +void registerBackgroundIsolateCallsDartPluginRegistrant() async { + ReceivePort receivePort = ReceivePort(); + Isolate isolate = await Isolate.spawn(registerBackgroundIsolate, [receivePort.sendPort, RootIsolateToken.instance]); + bool didCallEntrypoint = await receivePort.first; + if (didCallEntrypoint) { + passMessage('_PluginRegistrant.register() was called on background isolate'); + } else { + passMessage('_PluginRegistrant.register() was not called on background isolate'); + } + isolate.kill(); +}