Dart Plugin Registrant - Reland e525aced27 (flutter/engine#32189)
This commit is contained in:
@@ -187,6 +187,7 @@ if (enable_unittests) {
|
||||
public_deps = [
|
||||
":plugin_registrant",
|
||||
"//flutter/fml",
|
||||
"//flutter/runtime:dart_plugin_registrant",
|
||||
"//flutter/testing",
|
||||
"//flutter/testing:fixture_test",
|
||||
]
|
||||
|
||||
@@ -706,7 +706,12 @@ bool DartIsolate::RunFromLibrary(std::optional<std::string> library_name,
|
||||
? tonic::ToDart(entrypoint.value().c_str())
|
||||
: tonic::ToDart("main");
|
||||
|
||||
InvokeDartPluginRegistrantIfAvailable(library_handle);
|
||||
if (!FindAndInvokeDartPluginRegistrant()) {
|
||||
// TODO(gaaclarke): Remove once the framework PR lands that uses `--source`
|
||||
// to compile the Dart Plugin Registrant
|
||||
// (https://github.com/flutter/flutter/pull/100572).
|
||||
InvokeDartPluginRegistrantIfAvailable(library_handle);
|
||||
}
|
||||
|
||||
auto user_entrypoint_function =
|
||||
::Dart_GetField(library_handle, entrypoint_handle);
|
||||
|
||||
@@ -6,40 +6,14 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "flutter/fml/logging.h"
|
||||
#include "flutter/fml/trace_event.h"
|
||||
#include "third_party/tonic/converter/dart_converter.h"
|
||||
#include "third_party/tonic/logging/dart_invoke.h"
|
||||
|
||||
namespace flutter {
|
||||
|
||||
namespace {
|
||||
bool EndsWith(const std::string& str, const std::string& ending) {
|
||||
if (str.size() >= ending.size()) {
|
||||
return (0 ==
|
||||
str.compare(str.size() - ending.size(), ending.size(), ending));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Dart_Handle FindDartPluginRegistrantLibrary() {
|
||||
// TODO(99308): Instead of finding this, it could be passed down from the
|
||||
// tool.
|
||||
Dart_Handle libraries = Dart_GetLoadedLibraries();
|
||||
intptr_t length = 0;
|
||||
Dart_ListLength(libraries, &length);
|
||||
for (intptr_t i = 0; i < length; ++i) {
|
||||
Dart_Handle library = Dart_ListGetAt(libraries, i);
|
||||
std::string library_name =
|
||||
tonic::DartConverter<std::string>::FromDart(Dart_ToString(library));
|
||||
if (EndsWith(library_name,
|
||||
"dart_tool/flutter_build/dart_plugin_registrant.dart'")) {
|
||||
return library;
|
||||
}
|
||||
}
|
||||
return Dart_Null();
|
||||
}
|
||||
} // namespace
|
||||
const char* dart_plugin_registrant_library_override = nullptr;
|
||||
|
||||
bool InvokeDartPluginRegistrantIfAvailable(Dart_Handle library_handle) {
|
||||
TRACE_EVENT0("flutter", "InvokeDartPluginRegistrantIfAvailable");
|
||||
@@ -65,12 +39,30 @@ bool InvokeDartPluginRegistrantIfAvailable(Dart_Handle library_handle) {
|
||||
}
|
||||
|
||||
bool FindAndInvokeDartPluginRegistrant() {
|
||||
auto dart_plugin_registrant_library = FindDartPluginRegistrantLibrary();
|
||||
if (!Dart_IsNull(dart_plugin_registrant_library)) {
|
||||
return InvokeDartPluginRegistrantIfAvailable(
|
||||
dart_plugin_registrant_library);
|
||||
} else {
|
||||
std::string library_name =
|
||||
dart_plugin_registrant_library_override == nullptr
|
||||
? "package:flutter/src/dart_plugin_registrant.dart"
|
||||
: dart_plugin_registrant_library_override;
|
||||
Dart_Handle library = Dart_LookupLibrary(tonic::ToDart(library_name));
|
||||
if (Dart_IsError(library)) {
|
||||
return false;
|
||||
}
|
||||
Dart_Handle registrant_file_uri =
|
||||
Dart_GetField(library, tonic::ToDart("dartPluginRegistrantLibrary"));
|
||||
if (Dart_IsError(registrant_file_uri)) {
|
||||
// TODO(gaaclarke): Find a way to remove this branch so the field is
|
||||
// required. I couldn't get it working with unit tests.
|
||||
return InvokeDartPluginRegistrantIfAvailable(library);
|
||||
}
|
||||
|
||||
std::string registrant_file_uri_string =
|
||||
tonic::DartConverter<std::string>::FromDart(registrant_file_uri);
|
||||
if (registrant_file_uri_string.empty()) {
|
||||
FML_LOG(ERROR) << "Unexpected empty dartPluginRegistrantLibrary.";
|
||||
return false;
|
||||
}
|
||||
|
||||
Dart_Handle registrant_library = Dart_LookupLibrary(registrant_file_uri);
|
||||
return InvokeDartPluginRegistrantIfAvailable(registrant_library);
|
||||
}
|
||||
} // namespace flutter
|
||||
|
||||
@@ -9,6 +9,10 @@
|
||||
|
||||
namespace flutter {
|
||||
|
||||
/// The name of the library where the Dart Plugin Registrant will be looked for.
|
||||
/// This is available for testing.
|
||||
extern const char* dart_plugin_registrant_library_override;
|
||||
|
||||
/// Looks for the Dart Plugin Registrant in `library_handle` and invokes it if
|
||||
/// it is found.
|
||||
/// @return `true` when the registrant has been invoked.
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
|
||||
#include "flutter/runtime/dart_isolate.h"
|
||||
|
||||
#include <cstdlib>
|
||||
#include "flutter/fml/paths.h"
|
||||
#include "flutter/runtime/dart_plugin_registrant.h"
|
||||
#include "flutter/runtime/dart_vm.h"
|
||||
#include "flutter/runtime/dart_vm_lifecycle.h"
|
||||
#include "flutter/testing/dart_isolate_runner.h"
|
||||
@@ -23,6 +25,30 @@ const std::string elf_file_name = "plugin_registrant_app_elf_snapshot.so";
|
||||
class DartIsolateTest : public FixtureTest {
|
||||
public:
|
||||
DartIsolateTest() : FixtureTest(kernel_file_name, elf_file_name, "") {}
|
||||
|
||||
void OverrideDartPluginRegistrant(const std::string& override_value) {
|
||||
dart_plugin_registrant_library_ = override_value;
|
||||
dart_plugin_registrant_library_override =
|
||||
dart_plugin_registrant_library_.c_str();
|
||||
}
|
||||
|
||||
void SetUp() override {
|
||||
std::string source_path = GetSourcePath();
|
||||
if (source_path[0] != '/') {
|
||||
// On windows we need an extra '/' prefix.
|
||||
source_path = "/" + source_path;
|
||||
}
|
||||
std::string registrant_uri = std::string("file://") + source_path +
|
||||
"flutter/runtime/fixtures/dart_tool/"
|
||||
"flutter_build/dart_plugin_registrant.dart";
|
||||
OverrideDartPluginRegistrant(registrant_uri);
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
dart_plugin_registrant_library_override = nullptr;
|
||||
}
|
||||
|
||||
std::string dart_plugin_registrant_library_;
|
||||
};
|
||||
|
||||
TEST_F(DartIsolateTest, DartPluginRegistrantIsPresent) {
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
import 'dart:isolate';
|
||||
import 'dart:ui';
|
||||
import 'dart:io' show Platform;
|
||||
|
||||
void passMessage(String message) native 'PassMessage';
|
||||
|
||||
|
||||
@@ -27,11 +27,13 @@ template("fixtures_location") {
|
||||
|
||||
location_path = rebase_path(invoker.assets_dir)
|
||||
testing_assets_path = rebase_path("$root_out_dir/gen/flutter/testing/assets")
|
||||
source_path = rebase_path("//")
|
||||
|
||||
# Array of source lines. We use a list to ensure a trailing newline is
|
||||
# emitted by write_file() to comply with -Wnewline-eof.
|
||||
location_source = [
|
||||
"namespace flutter { namespace testing { ",
|
||||
"const char* GetSourcePath() {return \"$source_path\";} ",
|
||||
"const char* GetFixturesPath() {return \"$location_path\";} ",
|
||||
"const char* GetTestingAssetsPath() {return \"$testing_assets_path\";} ",
|
||||
"}}",
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
namespace flutter {
|
||||
namespace testing {
|
||||
|
||||
const char* GetSourcePath();
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/// @brief Returns the directory containing the test fixture for the target
|
||||
/// if this target has fixtures configured. If there are no
|
||||
|
||||
Reference in New Issue
Block a user