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
2 changes: 1 addition & 1 deletion DEPS
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ deps = {
# and not have to specific specific hashes.

'src/third_party/tonic':
Var('fuchsia_git') + '/tonic' + '@' + 'bd27b4549199df72fcaeefd259ebc12a31c2e4ee',
Var('fuchsia_git') + '/tonic' + '@' + '1a8ed9be2e2b56b32e888266d6db465d36012df4',

'src/third_party/benchmark':
Var('fuchsia_git') + '/third_party/benchmark' + '@' + 'a779ffce872b4c811beef482e18bd0b63626aa42',
Expand Down
2 changes: 1 addition & 1 deletion ci/licenses_golden/licenses_third_party
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Signature: 500cc19ee17ba4703537a9ae9ac78b8f
Signature: a2d49b14022a4fb8fc74726a0861087f

UNUSED LICENSES:

Expand Down
8 changes: 8 additions & 0 deletions common/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,14 @@ struct Settings {
// soon as a frame is rasterized.
FrameRasterizedCallback frame_rasterized_callback;

// This data will be available to the isolate immediately on launch via the
// Window.getPersistentIsolateData callback. This is meant for information
// that the isolate cannot request asynchronously (platform messages can be
// used for that purpose). This data is held for the lifetime of the shell and
// is available on isolate restarts in the the shell instance. Due to this,
// the buffer must be as small as possible.
std::shared_ptr<const fml::Mapping> persistent_isolate_data;

std::string ToString() const;
};

Expand Down
4 changes: 4 additions & 0 deletions fml/mapping.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include "flutter/fml/mapping.h"

#include <algorithm>
#include <sstream>

namespace fml {
Expand Down Expand Up @@ -67,6 +68,9 @@ std::unique_ptr<FileMapping> FileMapping::CreateReadExecute(

DataMapping::DataMapping(std::vector<uint8_t> data) : data_(std::move(data)) {}

DataMapping::DataMapping(const std::string& string)
: data_(string.begin(), string.end()) {}

DataMapping::~DataMapping() = default;

size_t DataMapping::GetSize() const {
Expand Down
2 changes: 2 additions & 0 deletions fml/mapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ class DataMapping final : public Mapping {
public:
DataMapping(std::vector<uint8_t> data);

DataMapping(const std::string& string);

~DataMapping() override;

// |Mapping|
Expand Down
12 changes: 12 additions & 0 deletions lib/ui/window.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1176,6 +1176,18 @@ class Window {
registrationZone.runUnaryGuarded(callback, data);
};
}


/// The embedder can specify data that the isolate can request synchronously
/// on launch. This accessor fetches that data.
///
/// This data is persistent for the duration of the Flutter application and is
/// available even after isolate restarts. Because of this lifecycle, the size
/// of this data must be kept to a minimum.
///
/// For asynchronous communication between the embedder and isolate, a
/// platform channel may be used.
ByteData getPersistentIsolateData() native 'Window_getPersistentIsolateData';
}

/// Additional accessibility features that may be enabled by the platform.
Expand Down
15 changes: 15 additions & 0 deletions lib/ui/window/window.cc
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,20 @@ void _RespondToPlatformMessage(Dart_NativeArguments args) {
tonic::DartCallStatic(&RespondToPlatformMessage, args);
}

void GetPersistentIsolateData(Dart_NativeArguments args) {
auto persistent_isolate_data =
UIDartState::Current()->window()->client()->GetPersistentIsolateData();

if (!persistent_isolate_data) {
Dart_SetReturnValue(args, Dart_Null());
return;
}

Dart_SetReturnValue(
args, tonic::DartByteData::Create(persistent_isolate_data->GetMapping(),
persistent_isolate_data->GetSize()));
}

} // namespace

Dart_Handle ToByteData(const std::vector<uint8_t>& buffer) {
Expand Down Expand Up @@ -398,6 +412,7 @@ void Window::RegisterNatives(tonic::DartLibraryNatives* natives) {
{"Window_setIsolateDebugName", SetIsolateDebugName, 2, true},
{"Window_reportUnhandledException", ReportUnhandledException, 2, true},
{"Window_setNeedsReportTimings", SetNeedsReportTimings, 2, true},
{"Window_getPersistentIsolateData", GetPersistentIsolateData, 1, true},
});
}

Expand Down
1 change: 1 addition & 0 deletions lib/ui/window/window.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ class WindowClient {
virtual void UpdateIsolateDescription(const std::string isolate_name,
int64_t isolate_port) = 0;
virtual void SetNeedsReportTimings(bool value) = 0;
virtual std::shared_ptr<const fml::Mapping> GetPersistentIsolateData() = 0;

protected:
virtual ~WindowClient();
Expand Down
2 changes: 2 additions & 0 deletions lib/web_ui/lib/src/ui/window.dart
Original file line number Diff line number Diff line change
Expand Up @@ -995,6 +995,8 @@ abstract class Window {
String _initialLifecycleState;

void setIsolateDebugName(String name) {}

ByteData getPersistentIsolateData() => null;
}

VoidCallback webOnlyScheduleFrameCallback;
Expand Down
29 changes: 24 additions & 5 deletions runtime/runtime_controller.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ RuntimeController::RuntimeController(
std::string p_advisory_script_entrypoint,
std::function<void(int64_t)> p_idle_notification_callback,
fml::closure p_isolate_create_callback,
fml::closure p_isolate_shutdown_callback)
fml::closure p_isolate_shutdown_callback,
std::shared_ptr<const fml::Mapping> p_persistent_isolate_data)
: RuntimeController(p_client,
p_vm,
std::move(p_isolate_snapshot),
Expand All @@ -39,7 +40,8 @@ RuntimeController::RuntimeController(
p_idle_notification_callback,
WindowData{/* default window data */},
p_isolate_create_callback,
p_isolate_shutdown_callback) {}
p_isolate_shutdown_callback,
std::move(p_persistent_isolate_data)) {}

RuntimeController::RuntimeController(
RuntimeDelegate& p_client,
Expand All @@ -54,7 +56,8 @@ RuntimeController::RuntimeController(
std::function<void(int64_t)> idle_notification_callback,
WindowData p_window_data,
fml::closure p_isolate_create_callback,
fml::closure p_isolate_shutdown_callback)
fml::closure p_isolate_shutdown_callback,
std::shared_ptr<const fml::Mapping> p_persistent_isolate_data)
: client_(p_client),
vm_(p_vm),
isolate_snapshot_(std::move(p_isolate_snapshot)),
Expand All @@ -67,7 +70,8 @@ RuntimeController::RuntimeController(
idle_notification_callback_(idle_notification_callback),
window_data_(std::move(p_window_data)),
isolate_create_callback_(p_isolate_create_callback),
isolate_shutdown_callback_(p_isolate_shutdown_callback) {
isolate_shutdown_callback_(p_isolate_shutdown_callback),
persistent_isolate_data_(std::move(p_persistent_isolate_data)) {
// 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.
Expand Down Expand Up @@ -144,7 +148,8 @@ std::unique_ptr<RuntimeController> RuntimeController::Clone() const {
idle_notification_callback_, //
window_data_, //
isolate_create_callback_, //
isolate_shutdown_callback_ //
isolate_shutdown_callback_, //
persistent_isolate_data_ //
));
}

Expand Down Expand Up @@ -296,42 +301,56 @@ Window* RuntimeController::GetWindowIfAvailable() {
return root_isolate ? root_isolate->window() : nullptr;
}

// |WindowClient|
std::string RuntimeController::DefaultRouteName() {
return client_.DefaultRouteName();
}

// |WindowClient|
void RuntimeController::ScheduleFrame() {
client_.ScheduleFrame();
}

// |WindowClient|
void RuntimeController::Render(Scene* scene) {
client_.Render(scene->takeLayerTree());
}

// |WindowClient|
void RuntimeController::UpdateSemantics(SemanticsUpdate* update) {
if (window_data_.semantics_enabled) {
client_.UpdateSemantics(update->takeNodes(), update->takeActions());
}
}

// |WindowClient|
void RuntimeController::HandlePlatformMessage(
fml::RefPtr<PlatformMessage> message) {
client_.HandlePlatformMessage(std::move(message));
}

// |WindowClient|
FontCollection& RuntimeController::GetFontCollection() {
return client_.GetFontCollection();
}

// |WindowClient|
void RuntimeController::UpdateIsolateDescription(const std::string isolate_name,
int64_t isolate_port) {
client_.UpdateIsolateDescription(isolate_name, isolate_port);
}

// |WindowClient|
void RuntimeController::SetNeedsReportTimings(bool value) {
client_.SetNeedsReportTimings(value);
}

// |WindowClient|
std::shared_ptr<const fml::Mapping>
RuntimeController::GetPersistentIsolateData() {
return persistent_isolate_data_;
}

Dart_Port RuntimeController::GetMainPort() {
std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
return root_isolate ? root_isolate->main_port() : ILLEGAL_PORT;
Expand Down
60 changes: 34 additions & 26 deletions runtime/runtime_controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,20 @@ class Window;

class RuntimeController final : public WindowClient {
public:
RuntimeController(RuntimeDelegate& client,
DartVM* vm,
fml::RefPtr<const DartSnapshot> isolate_snapshot,
fml::RefPtr<const DartSnapshot> shared_snapshot,
TaskRunners task_runners,
fml::WeakPtr<IOManager> io_manager,
fml::WeakPtr<ImageDecoder> iamge_decoder,
std::string advisory_script_uri,
std::string advisory_script_entrypoint,
std::function<void(int64_t)> idle_notification_callback,
fml::closure isolate_create_callback,
fml::closure isolate_shutdown_callback);
RuntimeController(
RuntimeDelegate& client,
DartVM* vm,
fml::RefPtr<const DartSnapshot> isolate_snapshot,
fml::RefPtr<const DartSnapshot> shared_snapshot,
TaskRunners task_runners,
fml::WeakPtr<IOManager> io_manager,
fml::WeakPtr<ImageDecoder> iamge_decoder,
std::string advisory_script_uri,
std::string advisory_script_entrypoint,
std::function<void(int64_t)> idle_notification_callback,
fml::closure isolate_create_callback,
fml::closure isolate_shutdown_callback,
std::shared_ptr<const fml::Mapping> persistent_isolate_data);

~RuntimeController() override;

Expand Down Expand Up @@ -138,20 +140,23 @@ class RuntimeController final : public WindowClient {
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,
fml::RefPtr<const DartSnapshot> isolate_snapshot,
fml::RefPtr<const DartSnapshot> shared_snapshot,
TaskRunners task_runners,
fml::WeakPtr<IOManager> io_manager,
fml::WeakPtr<ImageDecoder> image_decoder,
std::string advisory_script_uri,
std::string advisory_script_entrypoint,
std::function<void(int64_t)> idle_notification_callback,
WindowData data,
fml::closure isolate_create_callback,
fml::closure isolate_shutdown_callback);
std::shared_ptr<const fml::Mapping> persistent_isolate_data_;

RuntimeController(
RuntimeDelegate& client,
DartVM* vm,
fml::RefPtr<const DartSnapshot> isolate_snapshot,
fml::RefPtr<const DartSnapshot> shared_snapshot,
TaskRunners task_runners,
fml::WeakPtr<IOManager> io_manager,
fml::WeakPtr<ImageDecoder> image_decoder,
std::string advisory_script_uri,
std::string advisory_script_entrypoint,
std::function<void(int64_t)> idle_notification_callback,
WindowData data,
fml::closure isolate_create_callback,
fml::closure isolate_shutdown_callback,
std::shared_ptr<const fml::Mapping> persistent_isolate_data);

Window* GetWindowIfAvailable();

Expand Down Expand Up @@ -182,6 +187,9 @@ class RuntimeController final : public WindowClient {
// |WindowClient|
void SetNeedsReportTimings(bool value) override;

// |WindowClient|
std::shared_ptr<const fml::Mapping> GetPersistentIsolateData() override;

FML_DISALLOW_COPY_AND_ASSIGN(RuntimeController);
};

Expand Down
3 changes: 2 additions & 1 deletion shell/common/engine.cc
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ Engine::Engine(Delegate& delegate,
settings_.advisory_script_entrypoint, // advisory script entrypoint
settings_.idle_notification_callback, // idle notification callback
settings_.isolate_create_callback, // isolate create callback
settings_.isolate_shutdown_callback // isolate shutdown callback
settings_.isolate_shutdown_callback, // isolate shutdown callback
settings_.persistent_isolate_data // persistent isolate data
);

pointer_data_dispatcher_ = dispatcher_maker(*this);
Expand Down
7 changes: 7 additions & 0 deletions shell/common/fixtures/shell_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,10 @@ void canCreateImageFromDecompressedData() {
notifyWidthHeight(image.width, image.height);
});
}

@pragma('vm:entry-point')
void canAccessIsolateLaunchData() {
notifyMessage(utf8.decode(window.getPersistentIsolateData().buffer.asUint8List()));
}

void notifyMessage(String string) native 'NotifyMessage';
39 changes: 39 additions & 0 deletions shell/common/shell_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#define FML_USED_ON_EMBEDDER

#include <algorithm>
#include <functional>
#include <future>
#include <memory>
Expand Down Expand Up @@ -873,5 +874,43 @@ TEST_F(ShellTest, TextureFrameMarkedAvailableAndUnregister) {
EXPECT_EQ(mockTexture->unregistered(), true);
}

TEST_F(ShellTest, IsolateCanAccessPersistentIsolateData) {
const std::string message = "dummy isolate launch data.";

Settings settings = CreateSettingsForFixture();
settings.persistent_isolate_data =
std::make_shared<fml::DataMapping>(message);
TaskRunners task_runners("test", // label
GetCurrentTaskRunner(), // platform
CreateNewThread(), // gpu
CreateNewThread(), // ui
CreateNewThread() // io
);

fml::AutoResetWaitableEvent message_latch;
AddNativeCallback("NotifyMessage",
CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) {
const auto message_from_dart =
tonic::DartConverter<std::string>::FromDart(
Dart_GetNativeArgument(args, 0));
ASSERT_EQ(message, message_from_dart);
message_latch.Signal();
}));

std::unique_ptr<Shell> shell =
CreateShell(std::move(settings), std::move(task_runners));

ASSERT_TRUE(shell->IsSetup());
auto configuration = RunConfiguration::InferFromSettings(settings);
configuration.SetEntrypoint("canAccessIsolateLaunchData");

fml::AutoResetWaitableEvent event;
shell->RunEngine(std::move(configuration), [&](auto result) {
ASSERT_EQ(result, Engine::RunStatus::Success);
});

message_latch.Wait();
}

} // namespace testing
} // namespace flutter
Loading