Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions runtime/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ if (enable_unittests) {
public_deps = [
":plugin_registrant",
"//flutter/fml",
"//flutter/runtime:dart_plugin_registrant",
"//flutter/testing",
"//flutter/testing:fixture_test",
]
Expand Down
7 changes: 6 additions & 1 deletion runtime/dart_isolate.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
58 changes: 25 additions & 33 deletions runtime/dart_plugin_registrant.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand All @@ -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
4 changes: 4 additions & 0 deletions runtime/dart_plugin_registrant.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
26 changes: 26 additions & 0 deletions runtime/dart_plugin_registrant_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import 'dart:isolate';
import 'dart:ui';
import 'dart:io' show Platform;

void passMessage(String message) native 'PassMessage';

Expand Down
2 changes: 2 additions & 0 deletions testing/testing.gni
Original file line number Diff line number Diff line change
Expand Up @@ -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\";} ",
"}}",
Expand Down
2 changes: 2 additions & 0 deletions testing/testing.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down