未验证 提交 1239df96 编写于 作者: C Chinmay Garde 提交者: GitHub

Allow native bindings in secondary isolates. (#8658)

The callbacks can be wired in via the Settings object. Both runtime and shell unit-tests have been patched to test this.
上级 b0cbce41
......@@ -392,7 +392,7 @@ FILE: ../../../flutter/runtime/dart_vm_lifecycle.h
FILE: ../../../flutter/runtime/dart_vm_unittests.cc
FILE: ../../../flutter/runtime/embedder_resources.cc
FILE: ../../../flutter/runtime/embedder_resources.h
FILE: ../../../flutter/runtime/fixtures/simple_main.dart
FILE: ../../../flutter/runtime/fixtures/runtime_test.dart
FILE: ../../../flutter/runtime/runtime_controller.cc
FILE: ../../../flutter/runtime/runtime_controller.h
FILE: ../../../flutter/runtime/runtime_delegate.cc
......@@ -409,7 +409,7 @@ FILE: ../../../flutter/shell/common/animator.cc
FILE: ../../../flutter/shell/common/animator.h
FILE: ../../../flutter/shell/common/engine.cc
FILE: ../../../flutter/shell/common/engine.h
FILE: ../../../flutter/shell/common/fixtures/main.dart
FILE: ../../../flutter/shell/common/fixtures/shell_test.dart
FILE: ../../../flutter/shell/common/isolate_configuration.cc
FILE: ../../../flutter/shell/common/isolate_configuration.h
FILE: ../../../flutter/shell/common/persistent_cache.cc
......
......@@ -113,9 +113,11 @@ struct Settings {
// The main isolate is current when this callback is made. This is a good spot
// to perform native Dart bindings for libraries not built in.
fml::closure root_isolate_create_callback;
fml::closure isolate_create_callback;
// The isolate is not current and may have already been destroyed when this
// call is made.
fml::closure root_isolate_shutdown_callback;
fml::closure isolate_shutdown_callback;
// The callback made on the UI thread in an isolate scope when the engine
// detects that the framework is idle. The VM also uses this time to perform
// tasks suitable when idling. Due to this, embedders are still advised to be
......
......@@ -96,7 +96,7 @@ source_set("runtime") {
}
test_fixtures("runtime_fixtures") {
fixtures = [ "fixtures/simple_main.dart" ]
fixtures = [ "fixtures/runtime_test.dart" ]
}
source_set("runtime_unittests_common") {
......
......@@ -39,7 +39,9 @@ std::weak_ptr<DartIsolate> DartIsolate::CreateRootIsolate(
fml::WeakPtr<IOManager> io_manager,
std::string advisory_script_uri,
std::string advisory_script_entrypoint,
Dart_IsolateFlags* flags) {
Dart_IsolateFlags* flags,
fml::closure isolate_create_callback,
fml::closure isolate_shutdown_callback) {
TRACE_EVENT0("flutter", "DartIsolate::CreateRootIsolate");
Dart_Isolate vm_isolate = nullptr;
std::weak_ptr<DartIsolate> embedder_isolate;
......@@ -49,6 +51,9 @@ std::weak_ptr<DartIsolate> DartIsolate::CreateRootIsolate(
// Since this is the root isolate, we fake a parent embedder data object. We
// cannot use unique_ptr here because the destructor is private (since the
// isolate lifecycle is entirely managed by the VM).
//
// The child isolate preparer is null but will be set when the isolate is
// being prepared to run.
auto root_embedder_data = std::make_unique<std::shared_ptr<DartIsolate>>(
std::make_shared<DartIsolate>(
settings, // settings
......@@ -59,8 +64,9 @@ std::weak_ptr<DartIsolate> DartIsolate::CreateRootIsolate(
std::move(io_manager), // IO manager
advisory_script_uri, // advisory URI
advisory_script_entrypoint, // advisory entrypoint
nullptr // child isolate preparer will be set when this isolate is
// prepared to run
nullptr, // child isolate preparer
isolate_create_callback, // isolate create callback
isolate_shutdown_callback // isolate shutdown callback
));
std::tie(vm_isolate, embedder_isolate) = CreateDartVMAndEmbedderObjectPair(
......@@ -102,7 +108,9 @@ DartIsolate::DartIsolate(const Settings& settings,
fml::WeakPtr<IOManager> io_manager,
std::string advisory_script_uri,
std::string advisory_script_entrypoint,
ChildIsolatePreparer child_isolate_preparer)
ChildIsolatePreparer child_isolate_preparer,
fml::closure isolate_create_callback,
fml::closure isolate_shutdown_callback)
: UIDartState(std::move(task_runners),
settings.task_observer_add,
settings.task_observer_remove,
......@@ -116,7 +124,9 @@ DartIsolate::DartIsolate(const Settings& settings,
settings_(settings),
isolate_snapshot_(std::move(isolate_snapshot)),
shared_snapshot_(std::move(shared_snapshot)),
child_isolate_preparer_(std::move(child_isolate_preparer)) {
child_isolate_preparer_(std::move(child_isolate_preparer)),
isolate_create_callback_(isolate_create_callback),
isolate_shutdown_callback_(isolate_shutdown_callback) {
FML_DCHECK(isolate_snapshot_) << "Must contain a valid isolate snapshot.";
phase_ = Phase::Uninitialized;
}
......@@ -279,6 +289,11 @@ bool DartIsolate::PrepareForRunningFromPrecompiledCode() {
child_isolate_preparer_ = [](DartIsolate* isolate) {
return isolate->PrepareForRunningFromPrecompiledCode();
};
if (isolate_create_callback_) {
isolate_create_callback_();
}
phase_ = Phase::Ready;
return true;
}
......@@ -365,7 +380,13 @@ bool DartIsolate::PrepareForRunningFromKernel(
return true;
};
}
if (isolate_create_callback_) {
isolate_create_callback_();
}
phase_ = Phase::Ready;
return true;
}
......@@ -563,7 +584,9 @@ Dart_Isolate DartIsolate::DartCreateAndStartServiceIsolate(
{}, // IO Manager
DART_VM_SERVICE_ISOLATE_NAME, // script uri
DART_VM_SERVICE_ISOLATE_NAME, // script entrypoint
flags // flags
flags, // flags
nullptr, // isolate create callback
nullptr // isolate shutdown callback
);
std::shared_ptr<DartIsolate> service_isolate = weak_service_isolate.lock();
......@@ -662,6 +685,7 @@ DartIsolate::CreateDartVMAndEmbedderObjectPair(
TaskRunners null_task_runners(advisory_script_uri, nullptr, nullptr,
nullptr, nullptr);
// Copy most fields from the parent to the child.
embedder_isolate = std::make_unique<std::shared_ptr<DartIsolate>>(
std::make_shared<DartIsolate>(
(*raw_embedder_isolate)->GetSettings(), // settings
......@@ -672,7 +696,12 @@ DartIsolate::CreateDartVMAndEmbedderObjectPair(
fml::WeakPtr<IOManager>{}, // io_manager
advisory_script_uri, // advisory_script_uri
advisory_script_entrypoint, // advisory_script_entrypoint
(*raw_embedder_isolate)->child_isolate_preparer_));
(*raw_embedder_isolate)->child_isolate_preparer_, // preparer
(*raw_embedder_isolate)->isolate_create_callback_, // on create
(*raw_embedder_isolate)->isolate_shutdown_callback_ // on shutdown
)
);
}
// Create the Dart VM isolate and give it the embedder object as the baton.
......@@ -755,6 +784,9 @@ void DartIsolate::AddIsolateShutdownCallback(fml::closure closure) {
void DartIsolate::OnShutdownCallback() {
shutdown_callbacks_.clear();
if (isolate_shutdown_callback_) {
isolate_shutdown_callback_();
}
}
DartIsolate::AutoFireClosure::AutoFireClosure(fml::closure closure)
......
......@@ -51,7 +51,9 @@ class DartIsolate : public UIDartState {
fml::WeakPtr<IOManager> io_manager,
std::string advisory_script_uri,
std::string advisory_script_entrypoint,
Dart_IsolateFlags* flags = nullptr);
Dart_IsolateFlags* flags,
fml::closure isolate_create_callback,
fml::closure isolate_shutdown_callback);
DartIsolate(const Settings& settings,
fml::RefPtr<const DartSnapshot> isolate_snapshot,
......@@ -61,7 +63,9 @@ class DartIsolate : public UIDartState {
fml::WeakPtr<IOManager> io_manager,
std::string advisory_script_uri,
std::string advisory_script_entrypoint,
ChildIsolatePreparer child_isolate_preparer);
ChildIsolatePreparer child_isolate_preparer,
fml::closure isolate_create_callback,
fml::closure isolate_shutdown_callback);
~DartIsolate() override;
......@@ -128,9 +132,11 @@ class DartIsolate : public UIDartState {
std::vector<std::unique_ptr<AutoFireClosure>> shutdown_callbacks_;
ChildIsolatePreparer child_isolate_preparer_ = nullptr;
fml::RefPtr<fml::TaskRunner> message_handling_task_runner_;
const fml::closure isolate_create_callback_;
const fml::closure isolate_shutdown_callback_;
FML_WARN_UNUSED_RESULT
bool Initialize(Dart_Isolate isolate, bool is_root_isolate);
FML_WARN_UNUSED_RESULT bool Initialize(Dart_Isolate isolate,
bool is_root_isolate);
void SetMessageHandlingTaskRunner(fml::RefPtr<fml::TaskRunner> runner,
bool is_root_isolate);
......
......@@ -5,6 +5,7 @@
#include "flutter/fml/make_copyable.h"
#include "flutter/fml/mapping.h"
#include "flutter/fml/paths.h"
#include "flutter/fml/synchronization/count_down_latch.h"
#include "flutter/fml/synchronization/waitable_event.h"
#include "flutter/fml/thread.h"
#include "flutter/runtime/dart_isolate.h"
......@@ -35,15 +36,18 @@ TEST_F(DartIsolateTest, RootIsolateCreationAndShutdown) {
GetCurrentTaskRunner() //
);
auto weak_isolate = DartIsolate::CreateRootIsolate(
vm_data->GetSettings(), // settings
vm_data->GetIsolateSnapshot(), // isolate snapshot
vm_data->GetSharedSnapshot(), // shared snapshot
std::move(task_runners), // task runners
nullptr, // window
{}, // snapshot delegate
{}, // io manager
"main.dart", // advisory uri
"main" // advisory entrypoint
vm_data->GetSettings(), // settings
vm_data->GetIsolateSnapshot(), // isolate snapshot
vm_data->GetSharedSnapshot(), // shared snapshot
std::move(task_runners), // task runners
nullptr, // window
{}, // snapshot delegate
{}, // io manager
"main.dart", // advisory uri
"main", // advisory entrypoint,
nullptr, // flags
settings.isolate_create_callback, // isolate create callback
settings.isolate_shutdown_callback // isolate shutdown callback
);
auto root_isolate = weak_isolate.lock();
ASSERT_TRUE(root_isolate);
......@@ -65,15 +69,18 @@ TEST_F(DartIsolateTest, IsolateShutdownCallbackIsInIsolateScope) {
GetCurrentTaskRunner() //
);
auto weak_isolate = DartIsolate::CreateRootIsolate(
vm_data->GetSettings(), // settings
vm_data->GetIsolateSnapshot(), // isolate snapshot
vm_data->GetSharedSnapshot(), // shared snapshot
std::move(task_runners), // task runners
nullptr, // window
{}, // snapshot delegate
{}, // io manager
"main.dart", // advisory uri
"main" // advisory entrypoint
vm_data->GetSettings(), // settings
vm_data->GetIsolateSnapshot(), // isolate snapshot
vm_data->GetSharedSnapshot(), // shared snapshot
std::move(task_runners), // task runners
nullptr, // window
{}, // snapshot delegate
{}, // io manager
"main.dart", // advisory uri
"main", // advisory entrypoint
nullptr, // flags
settings.isolate_create_callback, // isolate create callback
settings.isolate_shutdown_callback // isolate shutdown callback
);
auto root_isolate = weak_isolate.lock();
ASSERT_TRUE(root_isolate);
......@@ -171,15 +178,18 @@ static void RunDartCodeInIsolate(DartVMRef& vm_ref,
}
auto weak_isolate = DartIsolate::CreateRootIsolate(
vm_data->GetSettings(), // settings
vm_data->GetIsolateSnapshot(), // isolate snapshot
vm_data->GetSharedSnapshot(), // shared snapshot
std::move(task_runners), // task runners
nullptr, // window
{}, // snapshot delegate
{}, // io manager
"main.dart", // advisory uri
"main" // advisory entrypoint
vm_data->GetSettings(), // settings
vm_data->GetIsolateSnapshot(), // isolate snapshot
vm_data->GetSharedSnapshot(), // shared snapshot
std::move(task_runners), // task runners
nullptr, // window
{}, // snapshot delegate
{}, // io manager
"main.dart", // advisory uri
"main", // advisory entrypoint
nullptr, // flags
settings.isolate_create_callback, // isolate create callback
settings.isolate_shutdown_callback // isolate shutdown callback
);
auto root_isolate =
......@@ -345,5 +355,28 @@ TEST_F(DartIsolateTest, CanSaveCompilationTrace) {
latch.Wait();
}
TEST_F(DartIsolateTest, CanLaunchSecondaryIsolates) {
fml::CountDownLatch latch(3);
AddNativeCallback("NotifyNative",
CREATE_NATIVE_ENTRY(([&latch](Dart_NativeArguments args) {
latch.CountDown();
})));
AddNativeCallback(
"PassMessage", CREATE_NATIVE_ENTRY(([&latch](Dart_NativeArguments args) {
auto message = tonic::DartConverter<std::string>::FromDart(
Dart_GetNativeArgument(args, 0));
ASSERT_EQ("Hello from code is secondary isolate.", message);
latch.CountDown();
})));
const auto settings = CreateSettingsForFixture();
auto vm_ref = DartVMRef::Create(settings);
auto isolate = RunDartCodeInIsolate(vm_ref, settings, GetThreadTaskRunner(),
"testCanLaunchSecondaryIsolate");
ASSERT_TRUE(isolate);
ASSERT_EQ(isolate->get()->GetPhase(), DartIsolate::Phase::Running);
latch.Wait();
}
} // namespace testing
} // namespace flutter
......@@ -51,16 +51,18 @@ static std::shared_ptr<DartIsolate> CreateAndRunRootIsolate(
TaskRunners runners("io.flutter.test", task_runner, task_runner, task_runner,
task_runner);
auto isolate_weak = DartIsolate::CreateRootIsolate(
vm.GetSettings(), // settings
vm.GetIsolateSnapshot(), // isolate_snapshot
vm.GetSharedSnapshot(), // shared_snapshot
runners, // task_runners
{}, // window
{}, // snapshot_delegate
{}, // io_manager
"main.dart", // advisory_script_uri
entrypoint.c_str(), // advisory_script_entrypoint
nullptr // flags
vm.GetSettings(), // settings
vm.GetIsolateSnapshot(), // isolate_snapshot
vm.GetSharedSnapshot(), // shared_snapshot
runners, // task_runners
{}, // window
{}, // snapshot_delegate
{}, // io_manager
"main.dart", // advisory_script_uri
entrypoint.c_str(), // advisory_script_entrypoint
nullptr, // flags
settings.isolate_create_callback, // isolate create callback
settings.isolate_shutdown_callback // isolate shutdown callback
);
auto isolate = isolate_weak.lock();
......
......@@ -42,3 +42,16 @@ void testCanSaveCompilationTrace() {
}
void NotifyResult(bool success) native "NotifyNative";
void PassMessage(String message) native "PassMessage";
void secondaryIsolateMain(String message) {
print("Secondary isolate got message: " + message);
PassMessage("Hello from code is secondary isolate.");
NotifyNative();
}
@pragma('vm:entry-point')
void testCanLaunchSecondaryIsolate() {
Isolate.spawn(secondaryIsolateMain, "Hello from root isolate.");
NotifyNative();
}
......@@ -24,7 +24,9 @@ RuntimeController::RuntimeController(
fml::WeakPtr<IOManager> p_io_manager,
std::string p_advisory_script_uri,
std::string p_advisory_script_entrypoint,
std::function<void(int64_t)> p_idle_notification_callback)
std::function<void(int64_t)> p_idle_notification_callback,
fml::closure p_isolate_create_callback,
fml::closure p_isolate_shutdown_callback)
: RuntimeController(p_client,
p_vm,
std::move(p_isolate_snapshot),
......@@ -35,7 +37,9 @@ RuntimeController::RuntimeController(
std::move(p_advisory_script_uri),
std::move(p_advisory_script_entrypoint),
p_idle_notification_callback,
WindowData{/* default window data */}) {}
WindowData{/* default window data */},
p_isolate_create_callback,
p_isolate_shutdown_callback) {}
RuntimeController::RuntimeController(
RuntimeDelegate& p_client,
......@@ -48,7 +52,9 @@ RuntimeController::RuntimeController(
std::string p_advisory_script_uri,
std::string p_advisory_script_entrypoint,
std::function<void(int64_t)> idle_notification_callback,
WindowData p_window_data)
WindowData p_window_data,
fml::closure p_isolate_create_callback,
fml::closure p_isolate_shutdown_callback)
: client_(p_client),
vm_(p_vm),
isolate_snapshot_(std::move(p_isolate_snapshot)),
......@@ -60,22 +66,38 @@ RuntimeController::RuntimeController(
advisory_script_entrypoint_(p_advisory_script_entrypoint),
idle_notification_callback_(idle_notification_callback),
window_data_(std::move(p_window_data)),
root_isolate_(
DartIsolate::CreateRootIsolate(vm_->GetVMData()->GetSettings(),
isolate_snapshot_,
shared_snapshot_,
task_runners_,
std::make_unique<Window>(this),
snapshot_delegate_,
io_manager_,
p_advisory_script_uri,
p_advisory_script_entrypoint)) {
std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
root_isolate->SetReturnCodeCallback([this](uint32_t code) {
isolate_create_callback_(p_isolate_create_callback),
isolate_shutdown_callback_(p_isolate_shutdown_callback) {
// Create the root isolate as soon as the runtime controller is initialized.
// It will be run at a later point when the engine provides a run
// configuration and then runs the isolate.
auto strong_root_isolate =
DartIsolate::CreateRootIsolate(vm_->GetVMData()->GetSettings(), //
isolate_snapshot_, //
shared_snapshot_, //
task_runners_, //
std::make_unique<Window>(this), //
snapshot_delegate_, //
io_manager_, //
p_advisory_script_uri, //
p_advisory_script_entrypoint, //
nullptr, //
isolate_create_callback_, //
isolate_shutdown_callback_ //
)
.lock();
FML_CHECK(strong_root_isolate) << "Could not create root isolate.";
// The root isolate ivar is weak.
root_isolate_ = strong_root_isolate;
strong_root_isolate->SetReturnCodeCallback([this](uint32_t code) {
root_isolate_return_code_ = {true, code};
});
if (auto* window = GetWindowIfAvailable()) {
tonic::DartState::Scope scope(root_isolate);
tonic::DartState::Scope scope(strong_root_isolate);
window->DidCreateIsolate();
if (!FlushRuntimeStateToIsolate()) {
FML_DLOG(ERROR) << "Could not setup intial isolate state.";
......@@ -83,6 +105,7 @@ RuntimeController::RuntimeController(
} else {
FML_DCHECK(false) << "RuntimeController created without window binding.";
}
FML_DCHECK(Dart_CurrentIsolate() == nullptr);
}
......@@ -119,7 +142,9 @@ std::unique_ptr<RuntimeController> RuntimeController::Clone() const {
advisory_script_uri_, //
advisory_script_entrypoint_, //
idle_notification_callback_, //
window_data_ //
window_data_, //
isolate_create_callback_, //
isolate_shutdown_callback_ //
));
}
......
......@@ -37,7 +37,9 @@ class RuntimeController final : public WindowClient {
fml::WeakPtr<IOManager> io_manager,
std::string advisory_script_uri,
std::string advisory_script_entrypoint,
std::function<void(int64_t)> idle_notification_callback);
std::function<void(int64_t)> idle_notification_callback,
fml::closure isolate_create_callback,
fml::closure isolate_shutdown_callback);
~RuntimeController() override;
......@@ -132,6 +134,8 @@ class RuntimeController final : public WindowClient {
WindowData window_data_;
std::weak_ptr<DartIsolate> root_isolate_;
std::pair<bool, uint32_t> root_isolate_return_code_ = {false, 0};
const fml::closure isolate_create_callback_;
const fml::closure isolate_shutdown_callback_;
RuntimeController(RuntimeDelegate& client,
DartVM* vm,
......@@ -143,7 +147,9 @@ class RuntimeController final : public WindowClient {
std::string advisory_script_uri,
std::string advisory_script_entrypoint,
std::function<void(int64_t)> idle_notification_callback,
WindowData data);
WindowData data,
fml::closure isolate_create_callback,
fml::closure isolate_shutdown_callback);
Window* GetWindowIfAvailable();
......
......@@ -60,7 +60,7 @@ Settings RuntimeTest::CreateSettingsForFixture() {
settings.leak_vm = false;
settings.task_observer_add = [](intptr_t, fml::closure) {};
settings.task_observer_remove = [](intptr_t) {};
settings.root_isolate_create_callback = [this]() {
settings.isolate_create_callback = [this]() {
native_resolver_->SetNativeResolverForIsolate();
};
SetSnapshotsAndAssets(settings);
......
......@@ -148,7 +148,7 @@ shell_gpu_configuration("shell_unittests_gpu_configuration") {
}
test_fixtures("shell_unittests_fixtures") {
fixtures = [ "fixtures/main.dart" ]
fixtures = [ "fixtures/shell_test.dart" ]
}
shell_host_executable("shell_unittests") {
......
......@@ -62,7 +62,9 @@ Engine::Engine(Delegate& delegate,
std::move(io_manager), // io manager
settings_.advisory_script_uri, // advisory script uri
settings_.advisory_script_entrypoint, // advisory script entrypoint
settings_.idle_notification_callback // idle notification callback
settings_.idle_notification_callback, // idle notification callback
settings_.isolate_create_callback, // isolate create callback
settings_.isolate_shutdown_callback // isolate shutdown callback
);
}
......
main() {}
@pragma('vm:entry-point')
fixturesAreFunctionalMain() {
SayHiFromFixturesAreFunctionalMain();
}
void SayHiFromFixturesAreFunctionalMain() native "SayHiFromFixturesAreFunctionalMain";
\ No newline at end of file
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:isolate';
main() {}
@pragma('vm:entry-point')
fixturesAreFunctionalMain() {
SayHiFromFixturesAreFunctionalMain();
}
void SayHiFromFixturesAreFunctionalMain() native "SayHiFromFixturesAreFunctionalMain";
void NotifyNative() native "NotifyNative";
void secondaryIsolateMain(String message) {
print("Secondary isolate got message: " + message);
NotifyNative();
}
@pragma('vm:entry-point')
void testCanLaunchSecondaryIsolate() {
Isolate.spawn(secondaryIsolateMain, "Hello from root isolate.");
NotifyNative();
}
......@@ -67,7 +67,7 @@ Settings ShellTest::CreateSettingsForFixture() {
settings.task_observer_remove = [](intptr_t key) {
fml::MessageLoop::GetCurrent().RemoveTaskObserver(key);
};
settings.root_isolate_create_callback = [this]() {
settings.isolate_create_callback = [this]() {
native_resolver_->SetNativeResolverForIsolate();
};
SetSnapshotsAndAssets(settings);
......
......@@ -10,6 +10,7 @@
#include "flutter/fml/make_copyable.h"
#include "flutter/fml/message_loop.h"
#include "flutter/fml/synchronization/count_down_latch.h"
#include "flutter/fml/synchronization/waitable_event.h"
#include "flutter/shell/common/platform_view.h"
#include "flutter/shell/common/rasterizer.h"
......@@ -267,5 +268,43 @@ TEST_F(ShellTest, FixturesAreFunctional) {
ASSERT_FALSE(DartVMRef::IsInstanceRunning());
}
TEST_F(ShellTest, SecondaryIsolateBindingsAreSetupViaShellSettings) {
ASSERT_FALSE(DartVMRef::IsInstanceRunning());
const auto settings = CreateSettingsForFixture();
auto shell = Shell::Create(
GetTaskRunnersForFixture(), settings,
[](Shell& shell) {
return std::make_unique<TestPlatformView>(shell,
shell.GetTaskRunners());
},
[](Shell& shell) {
return std::make_unique<Rasterizer>(shell.GetTaskRunners());
});
ASSERT_TRUE(ValidateShell(shell.get()));
auto configuration = RunConfiguration::InferFromSettings(settings);
ASSERT_TRUE(configuration.IsValid());
configuration.SetEntrypoint("testCanLaunchSecondaryIsolate");
fml::CountDownLatch latch(2);
AddNativeCallback("NotifyNative", CREATE_NATIVE_ENTRY([&latch](auto args) {
latch.CountDown();
}));
fml::TaskRunner::RunNowOrPostTask(
shell->GetTaskRunners().GetUITaskRunner(),
fml::MakeCopyable([config = std::move(configuration),
engine = shell->GetEngine()]() mutable {
ASSERT_TRUE(engine);
ASSERT_EQ(engine->Run(std::move(config)), Engine::RunStatus::Success);
}));
latch.Wait();
ASSERT_TRUE(DartVMRef::IsInstanceRunning());
shell.reset();
ASSERT_FALSE(DartVMRef::IsInstanceRunning());
}
} // namespace testing
} // namespace flutter
......@@ -7,7 +7,9 @@
#include <mutex>
#include <vector>
#include "flutter/fml/logging.h"
#include "flutter/fml/synchronization/thread_annotations.h"
#include "third_party/tonic/logging/dart_error.h"
#include "tonic/converter/dart_converter.h"
namespace testing {
......@@ -44,6 +46,7 @@ Dart_NativeFunction TestDartNativeResolver::DartNativeEntryResolverCallback(
std::lock_guard<std::mutex> lock(gIsolateResolversMutex);
auto found = gIsolateResolvers.find(Dart_CurrentIsolate());
if (found == gIsolateResolvers.end()) {
FML_LOG(ERROR) << "Could not resolve native method for :" << name;
return nullptr;
}
......@@ -53,6 +56,7 @@ Dart_NativeFunction TestDartNativeResolver::DartNativeEntryResolverCallback(
gIsolateResolvers.erase(found);
}
FML_LOG(ERROR) << "Could not resolve native method for :" << name;
return nullptr;
}
......@@ -62,13 +66,12 @@ static const uint8_t* DartNativeEntrySymbolCallback(
}
void TestDartNativeResolver::SetNativeResolverForIsolate() {
FML_CHECK(!Dart_IsError(Dart_RootLibrary()));
auto result = Dart_SetNativeResolver(Dart_RootLibrary(),
DartNativeEntryResolverCallback,
DartNativeEntrySymbolCallback);
if (Dart_IsError(result)) {
return;
}
FML_CHECK(!tonic::LogIfError(result))
<< "Could not set native resolver in test.";
std::lock_guard<std::mutex> lock(gIsolateResolversMutex);
gIsolateResolvers[Dart_CurrentIsolate()] = shared_from_this();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册