Move platform specific information to PlatformConfiguration class (#19652)

This commit is contained in:
Greg Spencer 2020-08-01 00:21:02 +00:00 committed by GitHub
parent 13e993ed1a
commit 98cfd1db78
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
43 changed files with 1322 additions and 699 deletions

View File

@ -399,6 +399,9 @@ FILE: ../../../flutter/lib/ui/ui_benchmarks.cc
FILE: ../../../flutter/lib/ui/ui_dart_state.cc
FILE: ../../../flutter/lib/ui/ui_dart_state.h
FILE: ../../../flutter/lib/ui/window.dart
FILE: ../../../flutter/lib/ui/window/platform_configuration.cc
FILE: ../../../flutter/lib/ui/window/platform_configuration.h
FILE: ../../../flutter/lib/ui/window/platform_configuration_unittests.cc
FILE: ../../../flutter/lib/ui/window/platform_message.cc
FILE: ../../../flutter/lib/ui/window/platform_message.h
FILE: ../../../flutter/lib/ui/window/platform_message_response.cc
@ -575,6 +578,8 @@ FILE: ../../../flutter/runtime/dart_vm_unittests.cc
FILE: ../../../flutter/runtime/embedder_resources.cc
FILE: ../../../flutter/runtime/embedder_resources.h
FILE: ../../../flutter/runtime/fixtures/runtime_test.dart
FILE: ../../../flutter/runtime/platform_data.cc
FILE: ../../../flutter/runtime/platform_data.h
FILE: ../../../flutter/runtime/ptrace_ios.cc
FILE: ../../../flutter/runtime/ptrace_ios.h
FILE: ../../../flutter/runtime/runtime_controller.cc
@ -587,8 +592,6 @@ FILE: ../../../flutter/runtime/skia_concurrent_executor.cc
FILE: ../../../flutter/runtime/skia_concurrent_executor.h
FILE: ../../../flutter/runtime/test_font_data.cc
FILE: ../../../flutter/runtime/test_font_data.h
FILE: ../../../flutter/runtime/window_data.cc
FILE: ../../../flutter/runtime/window_data.h
FILE: ../../../flutter/shell/common/animator.cc
FILE: ../../../flutter/shell/common/animator.h
FILE: ../../../flutter/shell/common/animator_unittests.cc

View File

@ -93,6 +93,8 @@ source_set_maybe_fuchsia_legacy("ui") {
"text/text_box.h",
"ui_dart_state.cc",
"ui_dart_state.h",
"window/platform_configuration.cc",
"window/platform_configuration.h",
"window/platform_message.cc",
"window/platform_message.h",
"window/platform_message_response.cc",
@ -180,6 +182,7 @@ if (enable_unittests) {
sources = [
"painting/image_encoding_unittests.cc",
"painting/vertices_unittests.cc",
"window/platform_configuration_unittests.cc",
"window/pointer_data_packet_converter_unittests.cc",
]

View File

@ -8,6 +8,7 @@
#include "flutter/lib/ui/painting/image.h"
#include "flutter/lib/ui/painting/picture.h"
#include "flutter/lib/ui/ui_dart_state.h"
#include "flutter/lib/ui/window/platform_configuration.h"
#include "flutter/lib/ui/window/window.h"
#include "third_party/skia/include/core/SkImageInfo.h"
#include "third_party/skia/include/core/SkSurface.h"
@ -41,7 +42,10 @@ Scene::Scene(std::shared_ptr<flutter::Layer> rootLayer,
uint32_t rasterizerTracingThreshold,
bool checkerboardRasterCacheImages,
bool checkerboardOffscreenLayers) {
auto viewport_metrics = UIDartState::Current()->window()->viewport_metrics();
auto viewport_metrics = UIDartState::Current()
->platform_configuration()
->window()
->viewport_metrics();
layer_tree_ = std::make_unique<LayerTree>(
SkISize::Make(viewport_metrics.physical_width,

View File

@ -30,7 +30,7 @@
#include "flutter/lib/ui/text/font_collection.h"
#include "flutter/lib/ui/text/paragraph.h"
#include "flutter/lib/ui/text/paragraph_builder.h"
#include "flutter/lib/ui/window/window.h"
#include "flutter/lib/ui/window/platform_configuration.h"
#include "third_party/tonic/converter/dart_converter.h"
#include "third_party/tonic/logging/dart_error.h"
@ -85,7 +85,7 @@ void DartUI::InitForGlobal() {
SemanticsUpdate::RegisterNatives(g_natives);
SemanticsUpdateBuilder::RegisterNatives(g_natives);
Vertices::RegisterNatives(g_natives);
Window::RegisterNatives(g_natives);
PlatformConfiguration::RegisterNatives(g_natives);
#if defined(LEGACY_FUCHSIA_EMBEDDER)
SceneHost::RegisterNatives(g_natives);
#endif

View File

@ -34,6 +34,7 @@ void createVertices() {
);
_validateVertices(vertices);
}
void _validateVertices(Vertices vertices) native 'ValidateVertices';
@pragma('vm:entry-point')
@ -42,8 +43,10 @@ void frameCallback(FrameInfo info) {
}
@pragma('vm:entry-point')
void messageCallback(dynamic data) {
}
void messageCallback(dynamic data) {}
@pragma('vm:entry-point')
void validateConfiguration() native 'ValidateConfiguration';
// Draw a circle on a Canvas that has a PictureRecorder. Take the image from

View File

@ -238,7 +238,7 @@ void _runMainZoned(Function startMainIsolateFunction,
}, null);
}
void _reportUnhandledException(String error, String stackTrace) native 'Window_reportUnhandledException';
void _reportUnhandledException(String error, String stackTrace) native 'PlatformConfiguration_reportUnhandledException';
/// Invokes [callback] inside the given [zone].
void _invoke(void callback()?, Zone zone) {

View File

@ -11,6 +11,7 @@
#include "flutter/lib/ui/painting/image.h"
#include "flutter/lib/ui/painting/matrix.h"
#include "flutter/lib/ui/ui_dart_state.h"
#include "flutter/lib/ui/window/platform_configuration.h"
#include "flutter/lib/ui/window/window.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkCanvas.h"
@ -474,8 +475,11 @@ void Canvas::drawShadow(const CanvasPath* path,
ToDart("Canvas.drawShader called with non-genuine Path."));
return;
}
SkScalar dpr =
UIDartState::Current()->window()->viewport_metrics().device_pixel_ratio;
SkScalar dpr = UIDartState::Current()
->platform_configuration()
->window()
->viewport_metrics()
.device_pixel_ratio;
external_allocation_size_ += path->path().approximateBytesUsed();
flutter::PhysicalShapeLayer::DrawShadow(canvas_, path->path(), color,
elevation, transparentOccluder, dpr);

View File

@ -8,7 +8,7 @@
#include "flutter/lib/ui/text/asset_manager_font_provider.h"
#include "flutter/lib/ui/ui_dart_state.h"
#include "flutter/lib/ui/window/window.h"
#include "flutter/lib/ui/window/platform_configuration.h"
#include "flutter/runtime/test_font_data.h"
#include "rapidjson/document.h"
#include "rapidjson/rapidjson.h"
@ -30,8 +30,10 @@ namespace {
void LoadFontFromList(tonic::Uint8List& font_data, // NOLINT
Dart_Handle callback,
std::string family_name) {
FontCollection& font_collection =
UIDartState::Current()->window()->client()->GetFontCollection();
FontCollection& font_collection = UIDartState::Current()
->platform_configuration()
->client()
->GetFontCollection();
font_collection.LoadFontFromList(font_data.data(), font_data.num_elements(),
family_name);
font_data.Release();

View File

@ -10,7 +10,7 @@
#include "flutter/fml/task_runner.h"
#include "flutter/lib/ui/text/font_collection.h"
#include "flutter/lib/ui/ui_dart_state.h"
#include "flutter/lib/ui/window/window.h"
#include "flutter/lib/ui/window/platform_configuration.h"
#include "flutter/third_party/txt/src/txt/font_style.h"
#include "flutter/third_party/txt/src/txt/font_weight.h"
#include "flutter/third_party/txt/src/txt/paragraph_style.h"
@ -288,8 +288,10 @@ ParagraphBuilder::ParagraphBuilder(
style.locale = locale;
}
FontCollection& font_collection =
UIDartState::Current()->window()->client()->GetFontCollection();
FontCollection& font_collection = UIDartState::Current()
->platform_configuration()
->client()
->GetFontCollection();
#if FLUTTER_ENABLE_SKSHAPER
#define FLUTTER_PARAGRAPH_BUILDER txt::ParagraphBuilder::CreateSkiaBuilder

View File

@ -5,7 +5,7 @@
#include "flutter/lib/ui/ui_dart_state.h"
#include "flutter/fml/message_loop.h"
#include "flutter/lib/ui/window/window.h"
#include "flutter/lib/ui/window/platform_configuration.h"
#include "third_party/tonic/converter/dart_converter.h"
#include "third_party/tonic/dart_message_handler.h"
@ -73,8 +73,9 @@ void UIDartState::ThrowIfUIOperationsProhibited() {
void UIDartState::SetDebugName(const std::string debug_name) {
debug_name_ = debug_name;
if (window_) {
window_->client()->UpdateIsolateDescription(debug_name_, main_port_);
if (platform_configuration_) {
platform_configuration_->client()->UpdateIsolateDescription(debug_name_,
main_port_);
}
}
@ -82,10 +83,12 @@ UIDartState* UIDartState::Current() {
return static_cast<UIDartState*>(DartState::Current());
}
void UIDartState::SetWindow(std::unique_ptr<Window> window) {
window_ = std::move(window);
if (window_) {
window_->client()->UpdateIsolateDescription(debug_name_, main_port_);
void UIDartState::SetPlatformConfiguration(
std::unique_ptr<PlatformConfiguration> platform_configuration) {
platform_configuration_ = std::move(platform_configuration);
if (platform_configuration_) {
platform_configuration_->client()->UpdateIsolateDescription(debug_name_,
main_port_);
}
}

View File

@ -27,7 +27,7 @@
namespace flutter {
class FontSelector;
class Window;
class PlatformConfiguration;
class UIDartState : public tonic::DartState {
public:
@ -44,7 +44,9 @@ class UIDartState : public tonic::DartState {
const std::string& logger_prefix() const { return logger_prefix_; }
Window* window() const { return window_.get(); }
PlatformConfiguration* platform_configuration() const {
return platform_configuration_.get();
}
const TaskRunners& GetTaskRunners() const;
@ -97,7 +99,8 @@ class UIDartState : public tonic::DartState {
~UIDartState() override;
void SetWindow(std::unique_ptr<Window> window);
void SetPlatformConfiguration(
std::unique_ptr<PlatformConfiguration> platform_configuration);
const std::string& GetAdvisoryScriptURI() const;
@ -119,7 +122,7 @@ class UIDartState : public tonic::DartState {
Dart_Port main_port_ = ILLEGAL_PORT;
const bool is_root_isolate_;
std::string debug_name_;
std::unique_ptr<Window> window_;
std::unique_ptr<PlatformConfiguration> platform_configuration_;
tonic::DartMicrotaskQueue microtask_queue_;
UnhandledExceptionCallback unhandled_exception_callback_;
const std::shared_ptr<IsolateNameServer> isolate_name_server_;

View File

@ -823,7 +823,7 @@ class Window {
}
return null;
}
List<String> _computePlatformResolvedLocale(List<String?> supportedLocalesData) native 'Window_computePlatformResolvedLocale';
List<String> _computePlatformResolvedLocale(List<String?> supportedLocalesData) native 'PlatformConfiguration_computePlatformResolvedLocale';
/// A callback that is invoked whenever [locale] changes value.
///
@ -1001,7 +1001,7 @@ class Window {
}
late _SetNeedsReportTimingsFunc _setNeedsReportTimings;
void _nativeSetNeedsReportTimings(bool value) native 'Window_setNeedsReportTimings';
void _nativeSetNeedsReportTimings(bool value) native 'PlatformConfiguration_setNeedsReportTimings';
/// A callback that is invoked when pointer data is available.
///
@ -1051,7 +1051,7 @@ class Window {
/// * [SystemChannels.navigation], which handles subsequent navigation
/// requests from the embedder.
String get defaultRouteName => _defaultRouteName();
String _defaultRouteName() native 'Window_defaultRouteName';
String _defaultRouteName() native 'PlatformConfiguration_defaultRouteName';
/// Requests that, at the next appropriate opportunity, the [onBeginFrame]
/// and [onDrawFrame] callbacks be invoked.
@ -1060,7 +1060,7 @@ class Window {
///
/// * [SchedulerBinding], the Flutter framework class which manages the
/// scheduling of frames.
void scheduleFrame() native 'Window_scheduleFrame';
void scheduleFrame() native 'PlatformConfiguration_scheduleFrame';
/// Updates the application's rendering on the GPU with the newly provided
/// [Scene]. This function must be called within the scope of the
@ -1086,7 +1086,7 @@ class Window {
/// scheduling of frames.
/// * [RendererBinding], the Flutter framework class which manages layout and
/// painting.
void render(Scene scene) native 'Window_render';
void render(Scene scene) native 'PlatformConfiguration_render';
/// Whether the user has requested that [updateSemantics] be called when
/// the semantic contents of window changes.
@ -1126,7 +1126,7 @@ class Window {
/// Additional accessibility features that may be enabled by the platform.
AccessibilityFeatures get accessibilityFeatures => _accessibilityFeatures;
// The zero value matches the default value in `window_data.h`.
// The zero value matches the default value in `platform_data.h`.
AccessibilityFeatures _accessibilityFeatures = const AccessibilityFeatures._(0);
/// A callback that is invoked when the value of [accessibilityFeatures] changes.
@ -1148,7 +1148,7 @@ class Window {
///
/// In either case, this function disposes the given update, which means the
/// semantics update cannot be used further.
void updateSemantics(SemanticsUpdate update) native 'Window_updateSemantics';
void updateSemantics(SemanticsUpdate update) native 'PlatformConfiguration_updateSemantics';
/// Set the debug name associated with this window's root isolate.
///
@ -1158,7 +1158,7 @@ class Window {
/// This can be combined with flutter tools `--isolate-filter` flag to debug
/// specific root isolates. For example: `flutter attach --isolate-filter=[name]`.
/// Note that this does not rename any child isolates of the root.
void setIsolateDebugName(String name) native 'Window_setIsolateDebugName';
void setIsolateDebugName(String name) native 'PlatformConfiguration_setIsolateDebugName';
/// Sends a message to a platform-specific plugin.
///
@ -1179,7 +1179,7 @@ class Window {
}
String? _sendPlatformMessage(String name,
PlatformMessageResponseCallback? callback,
ByteData? data) native 'Window_sendPlatformMessage';
ByteData? data) native 'PlatformConfiguration_sendPlatformMessage';
/// Called whenever this window receives a message from a platform-specific
/// plugin.
@ -1204,7 +1204,7 @@ class Window {
/// Called by [_dispatchPlatformMessage].
void _respondToPlatformMessage(int responseId, ByteData? data)
native 'Window_respondToPlatformMessage';
native 'PlatformConfiguration_respondToPlatformMessage';
/// Wraps the given [callback] in another callback that ensures that the
/// original callback is called in the zone it was registered in.
@ -1230,7 +1230,7 @@ class Window {
///
/// For asynchronous communication between the embedder and isolate, a
/// platform channel may be used.
ByteData? getPersistentIsolateData() native 'Window_getPersistentIsolateData';
ByteData? getPersistentIsolateData() native 'PlatformConfiguration_getPersistentIsolateData';
}
/// Additional accessibility features that may be enabled by the platform.

View File

@ -0,0 +1,437 @@
// 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.
#include "flutter/lib/ui/window/platform_configuration.h"
#include "flutter/lib/ui/compositing/scene.h"
#include "flutter/lib/ui/ui_dart_state.h"
#include "flutter/lib/ui/window/platform_message_response_dart.h"
#include "flutter/lib/ui/window/window.h"
#include "third_party/tonic/converter/dart_converter.h"
#include "third_party/tonic/dart_args.h"
#include "third_party/tonic/dart_library_natives.h"
#include "third_party/tonic/dart_microtask_queue.h"
#include "third_party/tonic/logging/dart_invoke.h"
#include "third_party/tonic/typed_data/dart_byte_data.h"
namespace flutter {
namespace {
void DefaultRouteName(Dart_NativeArguments args) {
UIDartState::ThrowIfUIOperationsProhibited();
std::string routeName = UIDartState::Current()
->platform_configuration()
->client()
->DefaultRouteName();
Dart_SetReturnValue(args, tonic::StdStringToDart(routeName));
}
void ScheduleFrame(Dart_NativeArguments args) {
UIDartState::ThrowIfUIOperationsProhibited();
UIDartState::Current()->platform_configuration()->client()->ScheduleFrame();
}
void Render(Dart_NativeArguments args) {
UIDartState::ThrowIfUIOperationsProhibited();
Dart_Handle exception = nullptr;
Scene* scene =
tonic::DartConverter<Scene*>::FromArguments(args, 1, exception);
if (exception) {
Dart_ThrowException(exception);
return;
}
UIDartState::Current()->platform_configuration()->client()->Render(scene);
}
void UpdateSemantics(Dart_NativeArguments args) {
UIDartState::ThrowIfUIOperationsProhibited();
Dart_Handle exception = nullptr;
SemanticsUpdate* update =
tonic::DartConverter<SemanticsUpdate*>::FromArguments(args, 1, exception);
if (exception) {
Dart_ThrowException(exception);
return;
}
UIDartState::Current()->platform_configuration()->client()->UpdateSemantics(
update);
}
void SetIsolateDebugName(Dart_NativeArguments args) {
UIDartState::ThrowIfUIOperationsProhibited();
Dart_Handle exception = nullptr;
const std::string name =
tonic::DartConverter<std::string>::FromArguments(args, 1, exception);
if (exception) {
Dart_ThrowException(exception);
return;
}
UIDartState::Current()->SetDebugName(name);
}
void SetNeedsReportTimings(Dart_NativeArguments args) {
UIDartState::ThrowIfUIOperationsProhibited();
Dart_Handle exception = nullptr;
bool value = tonic::DartConverter<bool>::FromArguments(args, 1, exception);
UIDartState::Current()
->platform_configuration()
->client()
->SetNeedsReportTimings(value);
}
void ReportUnhandledException(Dart_NativeArguments args) {
UIDartState::ThrowIfUIOperationsProhibited();
Dart_Handle exception = nullptr;
auto error_name =
tonic::DartConverter<std::string>::FromArguments(args, 0, exception);
if (exception) {
Dart_ThrowException(exception);
return;
}
auto stack_trace =
tonic::DartConverter<std::string>::FromArguments(args, 1, exception);
if (exception) {
Dart_ThrowException(exception);
return;
}
UIDartState::Current()->ReportUnhandledException(std::move(error_name),
std::move(stack_trace));
}
Dart_Handle SendPlatformMessage(Dart_Handle window,
const std::string& name,
Dart_Handle callback,
Dart_Handle data_handle) {
UIDartState* dart_state = UIDartState::Current();
if (!dart_state->platform_configuration()) {
return tonic::ToDart(
"Platform messages can only be sent from the main isolate");
}
fml::RefPtr<PlatformMessageResponse> response;
if (!Dart_IsNull(callback)) {
response = fml::MakeRefCounted<PlatformMessageResponseDart>(
tonic::DartPersistentValue(dart_state, callback),
dart_state->GetTaskRunners().GetUITaskRunner());
}
if (Dart_IsNull(data_handle)) {
dart_state->platform_configuration()->client()->HandlePlatformMessage(
fml::MakeRefCounted<PlatformMessage>(name, response));
} else {
tonic::DartByteData data(data_handle);
const uint8_t* buffer = static_cast<const uint8_t*>(data.data());
dart_state->platform_configuration()->client()->HandlePlatformMessage(
fml::MakeRefCounted<PlatformMessage>(
name, std::vector<uint8_t>(buffer, buffer + data.length_in_bytes()),
response));
}
return Dart_Null();
}
void _SendPlatformMessage(Dart_NativeArguments args) {
tonic::DartCallStatic(&SendPlatformMessage, args);
}
void RespondToPlatformMessage(Dart_Handle window,
int response_id,
const tonic::DartByteData& data) {
if (Dart_IsNull(data.dart_handle())) {
UIDartState::Current()
->platform_configuration()
->CompletePlatformMessageEmptyResponse(response_id);
} else {
// TODO(engine): Avoid this copy.
const uint8_t* buffer = static_cast<const uint8_t*>(data.data());
UIDartState::Current()
->platform_configuration()
->CompletePlatformMessageResponse(
response_id,
std::vector<uint8_t>(buffer, buffer + data.length_in_bytes()));
}
}
void _RespondToPlatformMessage(Dart_NativeArguments args) {
tonic::DartCallStatic(&RespondToPlatformMessage, args);
}
void GetPersistentIsolateData(Dart_NativeArguments args) {
UIDartState::ThrowIfUIOperationsProhibited();
auto persistent_isolate_data = UIDartState::Current()
->platform_configuration()
->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()));
}
Dart_Handle ToByteData(const std::vector<uint8_t>& buffer) {
return tonic::DartByteData::Create(buffer.data(), buffer.size());
}
} // namespace
PlatformConfigurationClient::~PlatformConfigurationClient() {}
PlatformConfiguration::PlatformConfiguration(
PlatformConfigurationClient* client)
: client_(client) {}
PlatformConfiguration::~PlatformConfiguration() {}
void PlatformConfiguration::DidCreateIsolate() {
library_.Set(tonic::DartState::Current(),
Dart_LookupLibrary(tonic::ToDart("dart:ui")));
window_.reset(new Window({1.0, 0.0, 0.0}));
}
void PlatformConfiguration::UpdateLocales(
const std::vector<std::string>& locales) {
std::shared_ptr<tonic::DartState> dart_state = library_.dart_state().lock();
if (!dart_state) {
return;
}
tonic::DartState::Scope scope(dart_state);
tonic::LogIfError(tonic::DartInvokeField(
library_.value(), "_updateLocales",
{
tonic::ToDart<std::vector<std::string>>(locales),
}));
}
void PlatformConfiguration::UpdateUserSettingsData(const std::string& data) {
std::shared_ptr<tonic::DartState> dart_state = library_.dart_state().lock();
if (!dart_state) {
return;
}
tonic::DartState::Scope scope(dart_state);
tonic::LogIfError(tonic::DartInvokeField(library_.value(),
"_updateUserSettingsData",
{
tonic::StdStringToDart(data),
}));
}
void PlatformConfiguration::UpdateLifecycleState(const std::string& data) {
std::shared_ptr<tonic::DartState> dart_state = library_.dart_state().lock();
if (!dart_state) {
return;
}
tonic::DartState::Scope scope(dart_state);
tonic::LogIfError(tonic::DartInvokeField(library_.value(),
"_updateLifecycleState",
{
tonic::StdStringToDart(data),
}));
}
void PlatformConfiguration::UpdateSemanticsEnabled(bool enabled) {
std::shared_ptr<tonic::DartState> dart_state = library_.dart_state().lock();
if (!dart_state) {
return;
}
tonic::DartState::Scope scope(dart_state);
UIDartState::ThrowIfUIOperationsProhibited();
tonic::LogIfError(tonic::DartInvokeField(
library_.value(), "_updateSemanticsEnabled", {tonic::ToDart(enabled)}));
}
void PlatformConfiguration::UpdateAccessibilityFeatures(int32_t values) {
std::shared_ptr<tonic::DartState> dart_state = library_.dart_state().lock();
if (!dart_state) {
return;
}
tonic::DartState::Scope scope(dart_state);
tonic::LogIfError(tonic::DartInvokeField(library_.value(),
"_updateAccessibilityFeatures",
{tonic::ToDart(values)}));
}
void PlatformConfiguration::DispatchPlatformMessage(
fml::RefPtr<PlatformMessage> message) {
std::shared_ptr<tonic::DartState> dart_state = library_.dart_state().lock();
if (!dart_state) {
FML_DLOG(WARNING)
<< "Dropping platform message for lack of DartState on channel: "
<< message->channel();
return;
}
tonic::DartState::Scope scope(dart_state);
Dart_Handle data_handle =
(message->hasData()) ? ToByteData(message->data()) : Dart_Null();
if (Dart_IsError(data_handle)) {
FML_DLOG(WARNING)
<< "Dropping platform message because of a Dart error on channel: "
<< message->channel();
return;
}
int response_id = 0;
if (auto response = message->response()) {
response_id = next_response_id_++;
pending_responses_[response_id] = response;
}
tonic::LogIfError(
tonic::DartInvokeField(library_.value(), "_dispatchPlatformMessage",
{tonic::ToDart(message->channel()), data_handle,
tonic::ToDart(response_id)}));
}
void PlatformConfiguration::DispatchSemanticsAction(int32_t id,
SemanticsAction action,
std::vector<uint8_t> args) {
std::shared_ptr<tonic::DartState> dart_state = library_.dart_state().lock();
if (!dart_state) {
return;
}
tonic::DartState::Scope scope(dart_state);
Dart_Handle args_handle = (args.empty()) ? Dart_Null() : ToByteData(args);
if (Dart_IsError(args_handle)) {
return;
}
tonic::LogIfError(tonic::DartInvokeField(
library_.value(), "_dispatchSemanticsAction",
{tonic::ToDart(id), tonic::ToDart(static_cast<int32_t>(action)),
args_handle}));
}
void PlatformConfiguration::BeginFrame(fml::TimePoint frameTime) {
std::shared_ptr<tonic::DartState> dart_state = library_.dart_state().lock();
if (!dart_state) {
return;
}
tonic::DartState::Scope scope(dart_state);
int64_t microseconds = (frameTime - fml::TimePoint()).ToMicroseconds();
tonic::LogIfError(tonic::DartInvokeField(library_.value(), "_beginFrame",
{
Dart_NewInteger(microseconds),
}));
UIDartState::Current()->FlushMicrotasksNow();
tonic::LogIfError(tonic::DartInvokeField(library_.value(), "_drawFrame", {}));
}
void PlatformConfiguration::ReportTimings(std::vector<int64_t> timings) {
std::shared_ptr<tonic::DartState> dart_state = library_.dart_state().lock();
if (!dart_state) {
return;
}
tonic::DartState::Scope scope(dart_state);
Dart_Handle data_handle =
Dart_NewTypedData(Dart_TypedData_kInt64, timings.size());
Dart_TypedData_Type type;
void* data = nullptr;
intptr_t num_acquired = 0;
FML_CHECK(!Dart_IsError(
Dart_TypedDataAcquireData(data_handle, &type, &data, &num_acquired)));
FML_DCHECK(num_acquired == static_cast<int>(timings.size()));
memcpy(data, timings.data(), sizeof(int64_t) * timings.size());
FML_CHECK(Dart_TypedDataReleaseData(data_handle));
tonic::LogIfError(tonic::DartInvokeField(library_.value(), "_reportTimings",
{
data_handle,
}));
}
void PlatformConfiguration::CompletePlatformMessageEmptyResponse(
int response_id) {
if (!response_id) {
return;
}
auto it = pending_responses_.find(response_id);
if (it == pending_responses_.end()) {
return;
}
auto response = std::move(it->second);
pending_responses_.erase(it);
response->CompleteEmpty();
}
void PlatformConfiguration::CompletePlatformMessageResponse(
int response_id,
std::vector<uint8_t> data) {
if (!response_id) {
return;
}
auto it = pending_responses_.find(response_id);
if (it == pending_responses_.end()) {
return;
}
auto response = std::move(it->second);
pending_responses_.erase(it);
response->Complete(std::make_unique<fml::DataMapping>(std::move(data)));
}
Dart_Handle ComputePlatformResolvedLocale(Dart_Handle supportedLocalesHandle) {
std::vector<std::string> supportedLocales =
tonic::DartConverter<std::vector<std::string>>::FromDart(
supportedLocalesHandle);
std::vector<std::string> results =
*UIDartState::Current()
->platform_configuration()
->client()
->ComputePlatformResolvedLocale(supportedLocales);
return tonic::DartConverter<std::vector<std::string>>::ToDart(results);
}
static void _ComputePlatformResolvedLocale(Dart_NativeArguments args) {
UIDartState::ThrowIfUIOperationsProhibited();
Dart_Handle result =
ComputePlatformResolvedLocale(Dart_GetNativeArgument(args, 1));
Dart_SetReturnValue(args, result);
}
void PlatformConfiguration::RegisterNatives(
tonic::DartLibraryNatives* natives) {
natives->Register({
{"PlatformConfiguration_defaultRouteName", DefaultRouteName, 1, true},
{"PlatformConfiguration_scheduleFrame", ScheduleFrame, 1, true},
{"PlatformConfiguration_sendPlatformMessage", _SendPlatformMessage, 4,
true},
{"PlatformConfiguration_respondToPlatformMessage",
_RespondToPlatformMessage, 3, true},
{"PlatformConfiguration_render", Render, 2, true},
{"PlatformConfiguration_updateSemantics", UpdateSemantics, 2, true},
{"PlatformConfiguration_setIsolateDebugName", SetIsolateDebugName, 2,
true},
{"PlatformConfiguration_reportUnhandledException",
ReportUnhandledException, 2, true},
{"PlatformConfiguration_setNeedsReportTimings", SetNeedsReportTimings, 2,
true},
{"PlatformConfiguration_getPersistentIsolateData",
GetPersistentIsolateData, 1, true},
{"PlatformConfiguration_computePlatformResolvedLocale",
_ComputePlatformResolvedLocale, 2, true},
});
}
} // namespace flutter

View File

@ -0,0 +1,421 @@
// 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.
#ifndef FLUTTER_LIB_UI_WINDOW_PLATFORM_CONFIGURATION_H_
#define FLUTTER_LIB_UI_WINDOW_PLATFORM_CONFIGURATION_H_
#include <memory>
#include <set>
#include <string>
#include <unordered_map>
#include <vector>
#include "flutter/fml/time/time_point.h"
#include "flutter/lib/ui/semantics/semantics_update.h"
#include "flutter/lib/ui/window/platform_message.h"
#include "flutter/lib/ui/window/pointer_data_packet.h"
#include "flutter/lib/ui/window/viewport_metrics.h"
#include "flutter/lib/ui/window/window.h"
#include "third_party/tonic/dart_persistent_value.h"
namespace tonic {
class DartLibraryNatives;
// So tonic::ToDart<std::vector<int64_t>> returns List<int> instead of
// List<dynamic>.
template <>
struct DartListFactory<int64_t> {
static Dart_Handle NewList(intptr_t length) {
return Dart_NewListOf(Dart_CoreType_Int, length);
}
};
} // namespace tonic
namespace flutter {
class FontCollection;
class PlatformMessage;
class Scene;
//--------------------------------------------------------------------------
/// @brief An enum for defining the different kinds of accessibility features
/// that can be enabled by the platform.
///
/// Must match the `AccessibilityFeatureFlag` enum in framework.
enum class AccessibilityFeatureFlag : int32_t {
kAccessibleNavigation = 1 << 0,
kInvertColors = 1 << 1,
kDisableAnimations = 1 << 2,
kBoldText = 1 << 3,
kReduceMotion = 1 << 4,
kHighContrast = 1 << 5,
};
//--------------------------------------------------------------------------
/// @brief A client interface that the `RuntimeController` uses to define
/// handlers for `PlatformConfiguration` requests.
///
/// @see `PlatformConfiguration`
///
class PlatformConfigurationClient {
public:
//--------------------------------------------------------------------------
/// @brief The route or path that the embedder requested when the
/// application was launched.
///
/// This will be the string "`/`" if no particular route was
/// requested.
///
virtual std::string DefaultRouteName() = 0;
//--------------------------------------------------------------------------
/// @brief Requests that, at the next appropriate opportunity, a new
/// frame be scheduled for rendering.
///
virtual void ScheduleFrame() = 0;
//--------------------------------------------------------------------------
/// @brief Updates the client's rendering on the GPU with the newly
/// provided Scene.
///
virtual void Render(Scene* scene) = 0;
//--------------------------------------------------------------------------
/// @brief Receives a updated semantics tree from the Framework.
///
/// @param[in] update The updated semantic tree to apply.
///
virtual void UpdateSemantics(SemanticsUpdate* update) = 0;
//--------------------------------------------------------------------------
/// @brief When the Flutter application has a message to send to the
/// underlying platform, the message needs to be forwarded to
/// the platform on the appropriate thread (via the platform
/// task runner). The PlatformConfiguration delegates this task
/// to the engine via this method.
///
/// @see `PlatformView::HandlePlatformMessage`
///
/// @param[in] message The message from the Flutter application to send to
/// the underlying platform.
///
virtual void HandlePlatformMessage(fml::RefPtr<PlatformMessage> message) = 0;
//--------------------------------------------------------------------------
/// @brief Returns the current collection of fonts available on the
/// platform.
///
/// This function reads an XML file and makes font families and
/// collections of them. MinikinFontForTest is used for FontFamily
/// creation.
virtual FontCollection& GetFontCollection() = 0;
//--------------------------------------------------------------------------
/// @brief Notifies this client of the name of the root isolate and its
/// port when that isolate is launched, restarted (in the
/// cold-restart scenario) or the application itself updates the
/// name of the root isolate (via `Window.setIsolateDebugName`
/// in `window.dart`). The name of the isolate is meaningless to
/// the engine but is used in instrumentation and tooling.
/// Currently, this information is to update the service
/// protocol list of available root isolates running in the VM
/// and their names so that the appropriate isolate can be
/// selected in the tools for debugging and instrumentation.
///
/// @param[in] isolate_name The isolate name
/// @param[in] isolate_port The isolate port
///
virtual void UpdateIsolateDescription(const std::string isolate_name,
int64_t isolate_port) = 0;
//--------------------------------------------------------------------------
/// @brief Notifies this client that the application has an opinion about
/// whether its frame timings need to be reported backed to it.
/// Due to the asynchronous nature of rendering in Flutter, it is
/// not possible for the application to determine the total time
/// it took to render a specific frame. While the layer-tree is
/// constructed on the UI thread, it needs to be rendering on the
/// raster thread. Dart code cannot execute on this thread. So any
/// instrumentation about the frame times gathered on this thread
/// needs to be aggregated and sent back to the UI thread for
/// processing in Dart.
///
/// When the application indicates that frame times need to be
/// reported, it collects this information till a specified number
/// of data points are gathered. Then this information is sent
/// back to Dart code via `Engine::ReportTimings`.
///
/// This option is engine counterpart of the
/// `Window._setNeedsReportTimings` in `window.dart`.
///
/// @param[in] needs_reporting If reporting information should be collected
/// and send back to Dart.
///
virtual void SetNeedsReportTimings(bool value) = 0;
//--------------------------------------------------------------------------
/// @brief 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.
///
/// @return A map of the isolate data that the framework can request upon
/// launch.
///
virtual std::shared_ptr<const fml::Mapping> GetPersistentIsolateData() = 0;
//--------------------------------------------------------------------------
/// @brief Directly invokes platform-specific APIs to compute the
/// locale the platform would have natively resolved to.
///
/// @param[in] supported_locale_data The vector of strings that represents
/// the locales supported by the app.
/// Each locale consists of three
/// strings: languageCode, countryCode,
/// and scriptCode in that order.
///
/// @return A vector of 3 strings languageCode, countryCode, and
/// scriptCode that represents the locale selected by the
/// platform. Empty strings mean the value was unassigned. Empty
/// vector represents a null locale.
///
virtual std::unique_ptr<std::vector<std::string>>
ComputePlatformResolvedLocale(
const std::vector<std::string>& supported_locale_data) = 0;
protected:
virtual ~PlatformConfigurationClient();
};
//----------------------------------------------------------------------------
/// @brief A class for holding and distributing platform-level information
/// to and from the Dart code in Flutter's framework.
///
/// It handles communication between the engine and the framework,
/// and owns the main window.
///
/// It communicates with the RuntimeController through the use of a
/// PlatformConfigurationClient interface, which the
/// RuntimeController defines.
///
class PlatformConfiguration final {
public:
//----------------------------------------------------------------------------
/// @brief Creates a new PlatformConfiguration, typically created by the
/// RuntimeController.
///
/// @param[in] client The `PlatformConfigurationClient` to be injected into
/// the PlatformConfiguration. This client is used to
/// forward requests to the RuntimeController.
///
explicit PlatformConfiguration(PlatformConfigurationClient* client);
// PlatformConfiguration is not copyable.
PlatformConfiguration(const PlatformConfiguration&) = delete;
PlatformConfiguration& operator=(const PlatformConfiguration&) = delete;
~PlatformConfiguration();
//----------------------------------------------------------------------------
/// @brief Access to the platform configuration client (which typically
/// is implemented by the RuntimeController).
///
/// @return Returns the client used to construct this
/// PlatformConfiguration.
///
PlatformConfigurationClient* client() const { return client_; }
//----------------------------------------------------------------------------
/// @brief Called by the RuntimeController once it has created the root
/// isolate, so that the PlatformController can get a handle to
/// the 'dart:ui' library.
///
/// It uses the handle to call the hooks in hooks.dart.
///
void DidCreateIsolate();
//----------------------------------------------------------------------------
/// @brief Update the specified locale data in the framework.
///
/// @deprecated The persistent isolate data must be used for this purpose
/// instead.
///
/// @param[in] locale_data The locale data. This should consist of groups of
/// 4 strings, each group representing a single locale.
///
void UpdateLocales(const std::vector<std::string>& locales);
//----------------------------------------------------------------------------
/// @brief Update the user settings data in the framework.
///
/// @deprecated The persistent isolate data must be used for this purpose
/// instead.
///
/// @param[in] data The user settings data.
///
void UpdateUserSettingsData(const std::string& data);
//----------------------------------------------------------------------------
/// @brief Updates the lifecycle state data in the framework.
///
/// @deprecated The persistent isolate data must be used for this purpose
/// instead.
///
/// @param[in] data The lifecycle state data.
///
void UpdateLifecycleState(const std::string& data);
//----------------------------------------------------------------------------
/// @brief Notifies the PlatformConfiguration that the embedder has
/// expressed an opinion about whether the accessibility tree
/// should be generated or not. This call originates in the
/// platform view and is forwarded to the PlatformConfiguration
/// here by the engine.
///
/// @param[in] enabled Whether the accessibility tree is enabled or
/// disabled.
///
void UpdateSemanticsEnabled(bool enabled);
//----------------------------------------------------------------------------
/// @brief Forward the preference of accessibility features that must be
/// enabled in the semantics tree to the framwork.
///
/// @param[in] flags The accessibility features that must be generated in
/// the semantics tree.
///
void UpdateAccessibilityFeatures(int32_t flags);
//----------------------------------------------------------------------------
/// @brief Notifies the PlatformConfiguration that the client has sent
/// it a message. This call originates in the platform view and
/// has been forwarded through the engine to here.
///
/// @param[in] message The message sent from the embedder to the Dart
/// application.
///
void DispatchPlatformMessage(fml::RefPtr<PlatformMessage> message);
//----------------------------------------------------------------------------
/// @brief Notifies the framework that the embedder encountered an
/// accessibility related action on the specified node. This call
/// originates on the platform view and has been forwarded to the
/// platform configuration here by the engine.
///
/// @param[in] id The identifier of the accessibility node.
/// @param[in] action The accessibility related action performed on the
/// node of the specified ID.
/// @param[in] args Optional data that applies to the specified action.
///
void DispatchSemanticsAction(int32_t id,
SemanticsAction action,
std::vector<uint8_t> args);
//----------------------------------------------------------------------------
/// @brief Notifies the framework that it is time to begin working on a
/// new
/// frame previously scheduled via a call to
/// `PlatformConfigurationClient::ScheduleFrame`. This call
/// originates in the animator.
///
/// The frame time given as the argument indicates the point at
/// which the current frame interval began. It is very slightly
/// (because of scheduling overhead) in the past. If a new layer
/// tree is not produced and given to the GPU task runner within
/// one frame interval from this point, the Flutter application
/// will jank.
///
/// This method calls the `::_beginFrame` method in `hooks.dart`.
///
/// @param[in] frame_time The point at which the current frame interval
/// began. May be used by animation interpolators,
/// physics simulations, etc..
///
void BeginFrame(fml::TimePoint frame_time);
//----------------------------------------------------------------------------
/// @brief Dart code cannot fully measure the time it takes for a
/// specific frame to be rendered. This is because Dart code only
/// runs on the UI task runner. That is only a small part of the
/// overall frame workload. The GPU task runner frame workload is
/// executed on a thread where Dart code cannot run (and hence
/// instrument). Besides, due to the pipelined nature of rendering
/// in Flutter, there may be multiple frame workloads being
/// processed at any given time. However, for non-Timeline based
/// profiling, it is useful for trace collection and processing to
/// happen in Dart. To do this, the GPU task runner frame
/// workloads need to be instrumented separately. After a set
/// number of these profiles have been gathered, they need to be
/// reported back to Dart code. The engine reports this extra
/// instrumentation information back to the framework by invoking
/// this method at predefined intervals.
///
/// @see `FrameTiming`
///
/// @param[in] timings Collection of `FrameTiming::kCount` * `n` timestamps
/// for `n` frames whose timings have not been reported
/// yet. A collection of integers is reported here for
/// easier conversions to Dart objects. The timestamps
/// are measured against the system monotonic clock
/// measured in microseconds.
///
void ReportTimings(std::vector<int64_t> timings);
//----------------------------------------------------------------------------
/// @brief Registers the native handlers for Dart functions that this
/// class handles.
///
/// @param[in] natives The natives registry that the functions will be
/// registered with.
///
static void RegisterNatives(tonic::DartLibraryNatives* natives);
//----------------------------------------------------------------------------
/// @brief Retrieves the Window managed by the PlatformConfiguration.
///
/// @return a pointer to the Window.
///
Window* window() const { return window_.get(); }
//----------------------------------------------------------------------------
/// @brief Responds to a previous platform message to the engine from the
/// framework.
///
/// @param[in] response_id The unique id that identifies the original platform
/// message to respond to.
/// @param[in] data The data to send back in the response.
///
void CompletePlatformMessageResponse(int response_id,
std::vector<uint8_t> data);
//----------------------------------------------------------------------------
/// @brief Responds to a previous platform message to the engine from the
/// framework with an empty response.
///
/// @param[in] response_id The unique id that identifies the original platform
/// message to respond to.
///
void CompletePlatformMessageEmptyResponse(int response_id);
private:
PlatformConfigurationClient* client_;
tonic::DartPersistentValue library_;
std::unique_ptr<Window> window_;
// We use id 0 to mean that no response is expected.
int next_response_id_ = 1;
std::unordered_map<int, fml::RefPtr<PlatformMessageResponse>>
pending_responses_;
};
} // namespace flutter
#endif // FLUTTER_LIB_UI_WINDOW_PLATFORM_CONFIGURATION_H_

View File

@ -0,0 +1,139 @@
// 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.
#define FML_USED_ON_EMBEDDER
#include <memory>
#include "flutter/lib/ui/window/platform_configuration.h"
#include "flutter/common/task_runners.h"
#include "flutter/fml/synchronization/waitable_event.h"
#include "flutter/lib/ui/painting/vertices.h"
#include "flutter/runtime/dart_vm.h"
#include "flutter/shell/common/shell_test.h"
#include "flutter/shell/common/thread_host.h"
#include "flutter/testing/testing.h"
namespace flutter {
namespace testing {
class DummyPlatformConfigurationClient : public PlatformConfigurationClient {
public:
DummyPlatformConfigurationClient() {
std::vector<uint8_t> data;
isolate_data_.reset(new ::fml::DataMapping(data));
}
std::string DefaultRouteName() override { return "TestRoute"; }
void ScheduleFrame() override {}
void Render(Scene* scene) override {}
void UpdateSemantics(SemanticsUpdate* update) override {}
void HandlePlatformMessage(fml::RefPtr<PlatformMessage> message) override {}
FontCollection& GetFontCollection() override { return font_collection_; }
void UpdateIsolateDescription(const std::string isolate_name,
int64_t isolate_port) override {}
void SetNeedsReportTimings(bool value) override {}
std::shared_ptr<const fml::Mapping> GetPersistentIsolateData() override {
return isolate_data_;
}
std::unique_ptr<std::vector<std::string>> ComputePlatformResolvedLocale(
const std::vector<std::string>& supported_locale_data) override {
return nullptr;
};
private:
FontCollection font_collection_;
std::shared_ptr<const fml::Mapping> isolate_data_;
};
TEST_F(ShellTest, PlatformConfigurationInitialization) {
auto message_latch = std::make_shared<fml::AutoResetWaitableEvent>();
auto nativeValidateConfiguration = [message_latch](
Dart_NativeArguments args) {
PlatformConfiguration* configuration =
UIDartState::Current()->platform_configuration();
ASSERT_NE(configuration->window(), nullptr);
ASSERT_EQ(configuration->window()->viewport_metrics().device_pixel_ratio,
1.0);
ASSERT_EQ(configuration->window()->viewport_metrics().physical_width, 0.0);
ASSERT_EQ(configuration->window()->viewport_metrics().physical_height, 0.0);
message_latch->Signal();
};
Settings settings = CreateSettingsForFixture();
TaskRunners task_runners("test", // label
GetCurrentTaskRunner(), // platform
CreateNewThread(), // raster
CreateNewThread(), // ui
CreateNewThread() // io
);
AddNativeCallback("ValidateConfiguration",
CREATE_NATIVE_ENTRY(nativeValidateConfiguration));
std::unique_ptr<Shell> shell =
CreateShell(std::move(settings), std::move(task_runners));
ASSERT_TRUE(shell->IsSetup());
auto run_configuration = RunConfiguration::InferFromSettings(settings);
run_configuration.SetEntrypoint("validateConfiguration");
shell->RunEngine(std::move(run_configuration), [&](auto result) {
ASSERT_EQ(result, Engine::RunStatus::Success);
});
message_latch->Wait();
DestroyShell(std::move(shell), std::move(task_runners));
}
TEST_F(ShellTest, PlatformConfigurationWindowMetricsUpdate) {
auto message_latch = std::make_shared<fml::AutoResetWaitableEvent>();
auto nativeValidateConfiguration = [message_latch](
Dart_NativeArguments args) {
PlatformConfiguration* configuration =
UIDartState::Current()->platform_configuration();
ASSERT_NE(configuration->window(), nullptr);
configuration->window()->UpdateWindowMetrics(
ViewportMetrics{2.0, 10.0, 20.0});
ASSERT_EQ(configuration->window()->viewport_metrics().device_pixel_ratio,
2.0);
ASSERT_EQ(configuration->window()->viewport_metrics().physical_width, 10.0);
ASSERT_EQ(configuration->window()->viewport_metrics().physical_height,
20.0);
message_latch->Signal();
};
Settings settings = CreateSettingsForFixture();
TaskRunners task_runners("test", // label
GetCurrentTaskRunner(), // platform
CreateNewThread(), // raster
CreateNewThread(), // ui
CreateNewThread() // io
);
AddNativeCallback("ValidateConfiguration",
CREATE_NATIVE_ENTRY(nativeValidateConfiguration));
std::unique_ptr<Shell> shell =
CreateShell(std::move(settings), std::move(task_runners));
ASSERT_TRUE(shell->IsSetup());
auto run_configuration = RunConfiguration::InferFromSettings(settings);
run_configuration.SetEntrypoint("validateConfiguration");
shell->RunEngine(std::move(run_configuration), [&](auto result) {
ASSERT_EQ(result, Engine::RunStatus::Success);
});
message_latch->Wait();
DestroyShell(std::move(shell), std::move(task_runners));
}
} // namespace testing
} // namespace flutter

View File

@ -80,4 +80,16 @@ ViewportMetrics::ViewportMetrics(double p_device_pixel_ratio,
FML_DCHECK(device_pixel_ratio > 0);
}
ViewportMetrics::ViewportMetrics(double p_device_pixel_ratio,
double p_physical_width,
double p_physical_height)
: device_pixel_ratio(p_device_pixel_ratio),
physical_width(p_physical_width),
physical_height(p_physical_height) {
// Ensure we don't have nonsensical dimensions.
FML_DCHECK(physical_width >= 0);
FML_DCHECK(physical_height >= 0);
FML_DCHECK(device_pixel_ratio > 0);
}
} // namespace flutter

View File

@ -52,6 +52,12 @@ struct ViewportMetrics {
double p_physical_view_inset_bottom,
double p_physical_view_inset_left);
// Create a ViewportMetrics instance that doesn't include depth, padding, or
// insets.
ViewportMetrics(double p_device_pixel_ratio,
double p_physical_width,
double p_physical_height);
double device_pixel_ratio = 1.0;
double physical_width = 0;
double physical_height = 0;

View File

@ -4,183 +4,35 @@
#include "flutter/lib/ui/window/window.h"
#include "flutter/lib/ui/compositing/scene.h"
#include "flutter/lib/ui/ui_dart_state.h"
#include "flutter/lib/ui/window/platform_message_response_dart.h"
#include "third_party/tonic/converter/dart_converter.h"
#include "third_party/tonic/dart_args.h"
#include "third_party/tonic/dart_library_natives.h"
#include "third_party/tonic/dart_microtask_queue.h"
#include "third_party/tonic/logging/dart_invoke.h"
#include "third_party/tonic/typed_data/dart_byte_data.h"
namespace flutter {
namespace {
void DefaultRouteName(Dart_NativeArguments args) {
UIDartState::ThrowIfUIOperationsProhibited();
std::string routeName =
UIDartState::Current()->window()->client()->DefaultRouteName();
Dart_SetReturnValue(args, tonic::StdStringToDart(routeName));
Window::Window(ViewportMetrics metrics) : viewport_metrics_(metrics) {
library_.Set(tonic::DartState::Current(),
Dart_LookupLibrary(tonic::ToDart("dart:ui")));
}
void ScheduleFrame(Dart_NativeArguments args) {
UIDartState::ThrowIfUIOperationsProhibited();
UIDartState::Current()->window()->client()->ScheduleFrame();
}
void Render(Dart_NativeArguments args) {
UIDartState::ThrowIfUIOperationsProhibited();
Dart_Handle exception = nullptr;
Scene* scene =
tonic::DartConverter<Scene*>::FromArguments(args, 1, exception);
if (exception) {
Dart_ThrowException(exception);
return;
}
UIDartState::Current()->window()->client()->Render(scene);
}
void UpdateSemantics(Dart_NativeArguments args) {
UIDartState::ThrowIfUIOperationsProhibited();
Dart_Handle exception = nullptr;
SemanticsUpdate* update =
tonic::DartConverter<SemanticsUpdate*>::FromArguments(args, 1, exception);
if (exception) {
Dart_ThrowException(exception);
return;
}
UIDartState::Current()->window()->client()->UpdateSemantics(update);
}
void SetIsolateDebugName(Dart_NativeArguments args) {
UIDartState::ThrowIfUIOperationsProhibited();
Dart_Handle exception = nullptr;
const std::string name =
tonic::DartConverter<std::string>::FromArguments(args, 1, exception);
if (exception) {
Dart_ThrowException(exception);
return;
}
UIDartState::Current()->SetDebugName(name);
}
void SetNeedsReportTimings(Dart_NativeArguments args) {
UIDartState::ThrowIfUIOperationsProhibited();
Dart_Handle exception = nullptr;
bool value = tonic::DartConverter<bool>::FromArguments(args, 1, exception);
UIDartState::Current()->window()->client()->SetNeedsReportTimings(value);
}
void ReportUnhandledException(Dart_NativeArguments args) {
UIDartState::ThrowIfUIOperationsProhibited();
Dart_Handle exception = nullptr;
auto error_name =
tonic::DartConverter<std::string>::FromArguments(args, 0, exception);
if (exception) {
Dart_ThrowException(exception);
return;
}
auto stack_trace =
tonic::DartConverter<std::string>::FromArguments(args, 1, exception);
if (exception) {
Dart_ThrowException(exception);
return;
}
UIDartState::Current()->ReportUnhandledException(std::move(error_name),
std::move(stack_trace));
}
Dart_Handle SendPlatformMessage(Dart_Handle window,
const std::string& name,
Dart_Handle callback,
Dart_Handle data_handle) {
UIDartState* dart_state = UIDartState::Current();
if (!dart_state->window()) {
return tonic::ToDart(
"Platform messages can only be sent from the main isolate");
}
fml::RefPtr<PlatformMessageResponse> response;
if (!Dart_IsNull(callback)) {
response = fml::MakeRefCounted<PlatformMessageResponseDart>(
tonic::DartPersistentValue(dart_state, callback),
dart_state->GetTaskRunners().GetUITaskRunner());
}
if (Dart_IsNull(data_handle)) {
dart_state->window()->client()->HandlePlatformMessage(
fml::MakeRefCounted<PlatformMessage>(name, response));
} else {
tonic::DartByteData data(data_handle);
const uint8_t* buffer = static_cast<const uint8_t*>(data.data());
dart_state->window()->client()->HandlePlatformMessage(
fml::MakeRefCounted<PlatformMessage>(
name, std::vector<uint8_t>(buffer, buffer + data.length_in_bytes()),
response));
}
return Dart_Null();
}
void _SendPlatformMessage(Dart_NativeArguments args) {
tonic::DartCallStatic(&SendPlatformMessage, args);
}
void RespondToPlatformMessage(Dart_Handle window,
int response_id,
const tonic::DartByteData& data) {
if (Dart_IsNull(data.dart_handle())) {
UIDartState::Current()->window()->CompletePlatformMessageEmptyResponse(
response_id);
} else {
// TODO(engine): Avoid this copy.
const uint8_t* buffer = static_cast<const uint8_t*>(data.data());
UIDartState::Current()->window()->CompletePlatformMessageResponse(
response_id,
std::vector<uint8_t>(buffer, buffer + data.length_in_bytes()));
}
}
void _RespondToPlatformMessage(Dart_NativeArguments args) {
tonic::DartCallStatic(&RespondToPlatformMessage, args);
}
void GetPersistentIsolateData(Dart_NativeArguments args) {
UIDartState::ThrowIfUIOperationsProhibited();
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()));
}
Dart_Handle ToByteData(const std::vector<uint8_t>& buffer) {
return tonic::DartByteData::Create(buffer.data(), buffer.size());
}
} // namespace
WindowClient::~WindowClient() {}
Window::Window(WindowClient* client) : client_(client) {}
Window::~Window() {}
void Window::DidCreateIsolate() {
library_.Set(tonic::DartState::Current(),
Dart_LookupLibrary(tonic::ToDart("dart:ui")));
void Window::DispatchPointerDataPacket(const PointerDataPacket& packet) {
std::shared_ptr<tonic::DartState> dart_state = library_.dart_state().lock();
if (!dart_state) {
return;
}
tonic::DartState::Scope scope(dart_state);
const std::vector<uint8_t>& buffer = packet.data();
Dart_Handle data_handle =
tonic::DartByteData::Create(buffer.data(), buffer.size());
if (Dart_IsError(data_handle)) {
return;
}
tonic::LogIfError(tonic::DartInvokeField(
library_.value(), "_dispatchPointerDataPacket", {data_handle}));
}
void Window::UpdateWindowMetrics(const ViewportMetrics& metrics) {
@ -213,244 +65,4 @@ void Window::UpdateWindowMetrics(const ViewportMetrics& metrics) {
}));
}
void Window::UpdateLocales(const std::vector<std::string>& locales) {
std::shared_ptr<tonic::DartState> dart_state = library_.dart_state().lock();
if (!dart_state) {
return;
}
tonic::DartState::Scope scope(dart_state);
tonic::LogIfError(tonic::DartInvokeField(
library_.value(), "_updateLocales",
{
tonic::ToDart<std::vector<std::string>>(locales),
}));
}
void Window::UpdateUserSettingsData(const std::string& data) {
std::shared_ptr<tonic::DartState> dart_state = library_.dart_state().lock();
if (!dart_state) {
return;
}
tonic::DartState::Scope scope(dart_state);
tonic::LogIfError(tonic::DartInvokeField(library_.value(),
"_updateUserSettingsData",
{
tonic::StdStringToDart(data),
}));
}
void Window::UpdateLifecycleState(const std::string& data) {
std::shared_ptr<tonic::DartState> dart_state = library_.dart_state().lock();
if (!dart_state) {
return;
}
tonic::DartState::Scope scope(dart_state);
tonic::LogIfError(tonic::DartInvokeField(library_.value(),
"_updateLifecycleState",
{
tonic::StdStringToDart(data),
}));
}
void Window::UpdateSemanticsEnabled(bool enabled) {
std::shared_ptr<tonic::DartState> dart_state = library_.dart_state().lock();
if (!dart_state) {
return;
}
tonic::DartState::Scope scope(dart_state);
UIDartState::ThrowIfUIOperationsProhibited();
tonic::LogIfError(tonic::DartInvokeField(
library_.value(), "_updateSemanticsEnabled", {tonic::ToDart(enabled)}));
}
void Window::UpdateAccessibilityFeatures(int32_t values) {
std::shared_ptr<tonic::DartState> dart_state = library_.dart_state().lock();
if (!dart_state) {
return;
}
tonic::DartState::Scope scope(dart_state);
tonic::LogIfError(tonic::DartInvokeField(library_.value(),
"_updateAccessibilityFeatures",
{tonic::ToDart(values)}));
}
void Window::DispatchPlatformMessage(fml::RefPtr<PlatformMessage> message) {
std::shared_ptr<tonic::DartState> dart_state = library_.dart_state().lock();
if (!dart_state) {
FML_DLOG(WARNING)
<< "Dropping platform message for lack of DartState on channel: "
<< message->channel();
return;
}
tonic::DartState::Scope scope(dart_state);
Dart_Handle data_handle =
(message->hasData()) ? ToByteData(message->data()) : Dart_Null();
if (Dart_IsError(data_handle)) {
FML_DLOG(WARNING)
<< "Dropping platform message because of a Dart error on channel: "
<< message->channel();
return;
}
int response_id = 0;
if (auto response = message->response()) {
response_id = next_response_id_++;
pending_responses_[response_id] = response;
}
tonic::LogIfError(
tonic::DartInvokeField(library_.value(), "_dispatchPlatformMessage",
{tonic::ToDart(message->channel()), data_handle,
tonic::ToDart(response_id)}));
}
void Window::DispatchPointerDataPacket(const PointerDataPacket& packet) {
std::shared_ptr<tonic::DartState> dart_state = library_.dart_state().lock();
if (!dart_state) {
return;
}
tonic::DartState::Scope scope(dart_state);
Dart_Handle data_handle = ToByteData(packet.data());
if (Dart_IsError(data_handle)) {
return;
}
tonic::LogIfError(tonic::DartInvokeField(
library_.value(), "_dispatchPointerDataPacket", {data_handle}));
}
void Window::DispatchSemanticsAction(int32_t id,
SemanticsAction action,
std::vector<uint8_t> args) {
std::shared_ptr<tonic::DartState> dart_state = library_.dart_state().lock();
if (!dart_state) {
return;
}
tonic::DartState::Scope scope(dart_state);
Dart_Handle args_handle = (args.empty()) ? Dart_Null() : ToByteData(args);
if (Dart_IsError(args_handle)) {
return;
}
tonic::LogIfError(tonic::DartInvokeField(
library_.value(), "_dispatchSemanticsAction",
{tonic::ToDart(id), tonic::ToDart(static_cast<int32_t>(action)),
args_handle}));
}
void Window::BeginFrame(fml::TimePoint frameTime) {
std::shared_ptr<tonic::DartState> dart_state = library_.dart_state().lock();
if (!dart_state) {
return;
}
tonic::DartState::Scope scope(dart_state);
int64_t microseconds = (frameTime - fml::TimePoint()).ToMicroseconds();
tonic::LogIfError(tonic::DartInvokeField(library_.value(), "_beginFrame",
{
Dart_NewInteger(microseconds),
}));
UIDartState::Current()->FlushMicrotasksNow();
tonic::LogIfError(tonic::DartInvokeField(library_.value(), "_drawFrame", {}));
}
void Window::ReportTimings(std::vector<int64_t> timings) {
std::shared_ptr<tonic::DartState> dart_state = library_.dart_state().lock();
if (!dart_state) {
return;
}
tonic::DartState::Scope scope(dart_state);
Dart_Handle data_handle =
Dart_NewTypedData(Dart_TypedData_kInt64, timings.size());
Dart_TypedData_Type type;
void* data = nullptr;
intptr_t num_acquired = 0;
FML_CHECK(!Dart_IsError(
Dart_TypedDataAcquireData(data_handle, &type, &data, &num_acquired)));
FML_DCHECK(num_acquired == static_cast<int>(timings.size()));
memcpy(data, timings.data(), sizeof(int64_t) * timings.size());
FML_CHECK(Dart_TypedDataReleaseData(data_handle));
tonic::LogIfError(tonic::DartInvokeField(library_.value(), "_reportTimings",
{
data_handle,
}));
}
void Window::CompletePlatformMessageEmptyResponse(int response_id) {
if (!response_id) {
return;
}
auto it = pending_responses_.find(response_id);
if (it == pending_responses_.end()) {
return;
}
auto response = std::move(it->second);
pending_responses_.erase(it);
response->CompleteEmpty();
}
void Window::CompletePlatformMessageResponse(int response_id,
std::vector<uint8_t> data) {
if (!response_id) {
return;
}
auto it = pending_responses_.find(response_id);
if (it == pending_responses_.end()) {
return;
}
auto response = std::move(it->second);
pending_responses_.erase(it);
response->Complete(std::make_unique<fml::DataMapping>(std::move(data)));
}
Dart_Handle ComputePlatformResolvedLocale(Dart_Handle supportedLocalesHandle) {
std::vector<std::string> supportedLocales =
tonic::DartConverter<std::vector<std::string>>::FromDart(
supportedLocalesHandle);
std::vector<std::string> results =
*UIDartState::Current()
->window()
->client()
->ComputePlatformResolvedLocale(supportedLocales);
return tonic::DartConverter<std::vector<std::string>>::ToDart(results);
}
static void _ComputePlatformResolvedLocale(Dart_NativeArguments args) {
UIDartState::ThrowIfUIOperationsProhibited();
Dart_Handle result =
ComputePlatformResolvedLocale(Dart_GetNativeArgument(args, 1));
Dart_SetReturnValue(args, result);
}
void Window::RegisterNatives(tonic::DartLibraryNatives* natives) {
natives->Register({
{"Window_defaultRouteName", DefaultRouteName, 1, true},
{"Window_scheduleFrame", ScheduleFrame, 1, true},
{"Window_sendPlatformMessage", _SendPlatformMessage, 4, true},
{"Window_respondToPlatformMessage", _RespondToPlatformMessage, 3, true},
{"Window_render", Render, 2, true},
{"Window_updateSemantics", UpdateSemantics, 2, true},
{"Window_setIsolateDebugName", SetIsolateDebugName, 2, true},
{"Window_reportUnhandledException", ReportUnhandledException, 2, true},
{"Window_setNeedsReportTimings", SetNeedsReportTimings, 2, true},
{"Window_getPersistentIsolateData", GetPersistentIsolateData, 1, true},
{"Window_computePlatformResolvedLocale", _ComputePlatformResolvedLocale,
2, true},
});
}
} // namespace flutter

View File

@ -9,102 +9,27 @@
#include <unordered_map>
#include <vector>
#include "flutter/fml/time/time_point.h"
#include "flutter/lib/ui/semantics/semantics_update.h"
#include "flutter/lib/ui/window/platform_message.h"
#include "flutter/lib/ui/window/pointer_data_packet.h"
#include "flutter/lib/ui/window/viewport_metrics.h"
#include "third_party/skia/include/gpu/GrDirectContext.h"
#include "third_party/tonic/dart_persistent_value.h"
namespace tonic {
class DartLibraryNatives;
// So tonice::ToDart<std::vector<int64_t>> returns List<int> instead of
// List<dynamic>.
template <>
struct DartListFactory<int64_t> {
static Dart_Handle NewList(intptr_t length) {
return Dart_NewListOf(Dart_CoreType_Int, length);
}
};
} // namespace tonic
namespace flutter {
class FontCollection;
class Scene;
// Must match the AccessibilityFeatureFlag enum in window.dart.
enum class AccessibilityFeatureFlag : int32_t {
kAccessibleNavigation = 1 << 0,
kInvertColors = 1 << 1,
kDisableAnimations = 1 << 2,
kBoldText = 1 << 3,
kReduceMotion = 1 << 4,
kHighContrast = 1 << 5,
};
class WindowClient {
public:
virtual std::string DefaultRouteName() = 0;
virtual void ScheduleFrame() = 0;
virtual void Render(Scene* scene) = 0;
virtual void UpdateSemantics(SemanticsUpdate* update) = 0;
virtual void HandlePlatformMessage(fml::RefPtr<PlatformMessage> message) = 0;
virtual FontCollection& GetFontCollection() = 0;
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;
virtual std::unique_ptr<std::vector<std::string>>
ComputePlatformResolvedLocale(
const std::vector<std::string>& supported_locale_data) = 0;
protected:
virtual ~WindowClient();
};
class Window final {
public:
explicit Window(WindowClient* client);
explicit Window(ViewportMetrics metrics);
~Window();
WindowClient* client() const { return client_; }
const ViewportMetrics& viewport_metrics() const { return viewport_metrics_; }
const ViewportMetrics& viewport_metrics() { return viewport_metrics_; }
void DidCreateIsolate();
void UpdateWindowMetrics(const ViewportMetrics& metrics);
void UpdateLocales(const std::vector<std::string>& locales);
void UpdateUserSettingsData(const std::string& data);
void UpdateLifecycleState(const std::string& data);
void UpdateSemanticsEnabled(bool enabled);
void UpdateAccessibilityFeatures(int32_t flags);
void DispatchPlatformMessage(fml::RefPtr<PlatformMessage> message);
void DispatchPointerDataPacket(const PointerDataPacket& packet);
void DispatchSemanticsAction(int32_t id,
SemanticsAction action,
std::vector<uint8_t> args);
void BeginFrame(fml::TimePoint frameTime);
void ReportTimings(std::vector<int64_t> timings);
void CompletePlatformMessageResponse(int response_id,
std::vector<uint8_t> data);
void CompletePlatformMessageEmptyResponse(int response_id);
static void RegisterNatives(tonic::DartLibraryNatives* natives);
void UpdateWindowMetrics(const ViewportMetrics& metrics);
private:
WindowClient* client_;
tonic::DartPersistentValue library_;
ViewportMetrics viewport_metrics_;
// We use id 0 to mean that no response is expected.
int next_response_id_ = 1;
std::unordered_map<int, fml::RefPtr<PlatformMessageResponse>>
pending_responses_;
};
} // namespace flutter

View File

@ -53,6 +53,8 @@ source_set_maybe_fuchsia_legacy("runtime") {
"dart_vm_lifecycle.h",
"embedder_resources.cc",
"embedder_resources.h",
"platform_data.cc",
"platform_data.h",
"ptrace_ios.cc",
"ptrace_ios.h",
"runtime_controller.cc",
@ -63,8 +65,6 @@ source_set_maybe_fuchsia_legacy("runtime") {
"service_protocol.h",
"skia_concurrent_executor.cc",
"skia_concurrent_executor.h",
"window_data.cc",
"window_data.h",
]
public_deps = [ "//third_party/rapidjson" ]

View File

@ -57,7 +57,7 @@ std::weak_ptr<DartIsolate> DartIsolate::CreateRootIsolate(
const Settings& settings,
fml::RefPtr<const DartSnapshot> isolate_snapshot,
TaskRunners task_runners,
std::unique_ptr<Window> window,
std::unique_ptr<PlatformConfiguration> platform_configuration,
fml::WeakPtr<SnapshotDelegate> snapshot_delegate,
fml::WeakPtr<IOManager> io_manager,
fml::RefPtr<SkiaUnrefQueue> unref_queue,
@ -112,7 +112,8 @@ std::weak_ptr<DartIsolate> DartIsolate::CreateRootIsolate(
std::shared_ptr<DartIsolate>* root_isolate_data =
static_cast<std::shared_ptr<DartIsolate>*>(Dart_IsolateData(vm_isolate));
(*root_isolate_data)->SetWindow(std::move(window));
(*root_isolate_data)
->SetPlatformConfiguration(std::move(platform_configuration));
return (*root_isolate_data)->GetWeakIsolatePtr();
}
@ -598,7 +599,7 @@ Dart_Isolate DartIsolate::DartCreateAndStartServiceIsolate(
vm_data->GetSettings(), // settings
vm_data->GetIsolateSnapshot(), // isolate snapshot
null_task_runners, // task runners
nullptr, // window
nullptr, // platform_configuration
{}, // snapshot delegate
{}, // IO Manager
{}, // Skia unref queue

View File

@ -16,7 +16,7 @@
#include "flutter/lib/ui/io_manager.h"
#include "flutter/lib/ui/snapshot_delegate.h"
#include "flutter/lib/ui/ui_dart_state.h"
#include "flutter/lib/ui/window/window.h"
#include "flutter/lib/ui/window/platform_configuration.h"
#include "flutter/runtime/dart_snapshot.h"
#include "third_party/dart/runtime/include/dart_api.h"
#include "third_party/tonic/dart_state.h"
@ -192,7 +192,7 @@ class DartIsolate : public UIDartState {
const Settings& settings,
fml::RefPtr<const DartSnapshot> isolate_snapshot,
TaskRunners task_runners,
std::unique_ptr<Window> window,
std::unique_ptr<PlatformConfiguration> platform_configuration,
fml::WeakPtr<SnapshotDelegate> snapshot_delegate,
fml::WeakPtr<IOManager> io_manager,
fml::RefPtr<SkiaUnrefQueue> skia_unref_queue,

View File

@ -2,11 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "flutter/runtime/window_data.h"
#include "flutter/runtime/platform_data.h"
namespace flutter {
WindowData::WindowData() = default;
PlatformData::PlatformData() = default;
WindowData::~WindowData() = default;
PlatformData::~PlatformData() = default;
} // namespace flutter

View File

@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef FLUTTER_RUNTIME_WINDOW_DATA_H_
#define FLUTTER_RUNTIME_WINDOW_DATA_H_
#ifndef FLUTTER_RUNTIME_PLATFORM_DATA_H_
#define FLUTTER_RUNTIME_PLATFORM_DATA_H_
#include "flutter/lib/ui/window/viewport_metrics.h"
@ -23,12 +23,12 @@ namespace flutter {
///
/// See also:
///
/// * flutter::Shell::Create, which takes a window_data to initialize the
/// * flutter::Shell::Create, which takes a platform_data to initialize the
/// ui.Window attached to it.
struct WindowData {
WindowData();
struct PlatformData {
PlatformData();
~WindowData();
~PlatformData();
ViewportMetrics viewport_metrics;
std::string language_code;
@ -45,4 +45,4 @@ struct WindowData {
} // namespace flutter
#endif // FLUTTER_RUNTIME_WINDOW_DATA_H_
#endif // FLUTTER_RUNTIME_PLATFORM_DATA_H_

View File

@ -8,8 +8,10 @@
#include "flutter/fml/trace_event.h"
#include "flutter/lib/ui/compositing/scene.h"
#include "flutter/lib/ui/ui_dart_state.h"
#include "flutter/lib/ui/window/platform_configuration.h"
#include "flutter/lib/ui/window/window.h"
#include "flutter/runtime/runtime_delegate.h"
#include "lib/ui/window/viewport_metrics.h"
#include "third_party/tonic/dart_message_handler.h"
namespace flutter {
@ -26,7 +28,7 @@ RuntimeController::RuntimeController(
std::string p_advisory_script_uri,
std::string p_advisory_script_entrypoint,
const std::function<void(int64_t)>& idle_notification_callback,
const WindowData& p_window_data,
const PlatformData& p_platform_data,
const fml::closure& p_isolate_create_callback,
const fml::closure& p_isolate_shutdown_callback,
std::shared_ptr<const fml::Mapping> p_persistent_isolate_data)
@ -41,7 +43,7 @@ RuntimeController::RuntimeController(
advisory_script_uri_(p_advisory_script_uri),
advisory_script_entrypoint_(p_advisory_script_entrypoint),
idle_notification_callback_(idle_notification_callback),
window_data_(std::move(p_window_data)),
platform_data_(std::move(p_platform_data)),
isolate_create_callback_(p_isolate_create_callback),
isolate_shutdown_callback_(p_isolate_shutdown_callback),
persistent_isolate_data_(std::move(p_persistent_isolate_data)) {
@ -49,20 +51,21 @@ RuntimeController::RuntimeController(
// 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_, //
task_runners_, //
std::make_unique<Window>(this), //
snapshot_delegate_, //
io_manager_, //
unref_queue_, //
image_decoder_, //
p_advisory_script_uri, //
p_advisory_script_entrypoint, //
nullptr, //
isolate_create_callback_, //
isolate_shutdown_callback_ //
)
DartIsolate::CreateRootIsolate(
vm_->GetVMData()->GetSettings(), //
isolate_snapshot_, //
task_runners_, //
std::make_unique<PlatformConfiguration>(this), //
snapshot_delegate_, //
io_manager_, //
unref_queue_, //
image_decoder_, //
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.";
@ -74,9 +77,9 @@ RuntimeController::RuntimeController(
root_isolate_return_code_ = {true, code};
});
if (auto* window = GetWindowIfAvailable()) {
if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
tonic::DartState::Scope scope(strong_root_isolate);
window->DidCreateIsolate();
platform_configuration->DidCreateIsolate();
if (!FlushRuntimeStateToIsolate()) {
FML_DLOG(ERROR) << "Could not setup initial isolate state.";
}
@ -121,7 +124,7 @@ std::unique_ptr<RuntimeController> RuntimeController::Clone() const {
advisory_script_uri_, //
advisory_script_entrypoint_, //
idle_notification_callback_, //
window_data_, //
platform_data_, //
isolate_create_callback_, //
isolate_shutdown_callback_, //
persistent_isolate_data_ //
@ -129,30 +132,32 @@ std::unique_ptr<RuntimeController> RuntimeController::Clone() const {
}
bool RuntimeController::FlushRuntimeStateToIsolate() {
return SetViewportMetrics(window_data_.viewport_metrics) &&
SetLocales(window_data_.locale_data) &&
SetSemanticsEnabled(window_data_.semantics_enabled) &&
SetAccessibilityFeatures(window_data_.accessibility_feature_flags_) &&
SetUserSettingsData(window_data_.user_settings_data) &&
SetLifecycleState(window_data_.lifecycle_state);
return SetViewportMetrics(platform_data_.viewport_metrics) &&
SetLocales(platform_data_.locale_data) &&
SetSemanticsEnabled(platform_data_.semantics_enabled) &&
SetAccessibilityFeatures(
platform_data_.accessibility_feature_flags_) &&
SetUserSettingsData(platform_data_.user_settings_data) &&
SetLifecycleState(platform_data_.lifecycle_state);
}
bool RuntimeController::SetViewportMetrics(const ViewportMetrics& metrics) {
window_data_.viewport_metrics = metrics;
platform_data_.viewport_metrics = metrics;
if (auto* window = GetWindowIfAvailable()) {
window->UpdateWindowMetrics(metrics);
if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
platform_configuration->window()->UpdateWindowMetrics(metrics);
return true;
}
return false;
}
bool RuntimeController::SetLocales(
const std::vector<std::string>& locale_data) {
window_data_.locale_data = locale_data;
platform_data_.locale_data = locale_data;
if (auto* window = GetWindowIfAvailable()) {
window->UpdateLocales(locale_data);
if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
platform_configuration->UpdateLocales(locale_data);
return true;
}
@ -160,10 +165,11 @@ bool RuntimeController::SetLocales(
}
bool RuntimeController::SetUserSettingsData(const std::string& data) {
window_data_.user_settings_data = data;
platform_data_.user_settings_data = data;
if (auto* window = GetWindowIfAvailable()) {
window->UpdateUserSettingsData(window_data_.user_settings_data);
if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
platform_configuration->UpdateUserSettingsData(
platform_data_.user_settings_data);
return true;
}
@ -171,10 +177,11 @@ bool RuntimeController::SetUserSettingsData(const std::string& data) {
}
bool RuntimeController::SetLifecycleState(const std::string& data) {
window_data_.lifecycle_state = data;
platform_data_.lifecycle_state = data;
if (auto* window = GetWindowIfAvailable()) {
window->UpdateLifecycleState(window_data_.lifecycle_state);
if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
platform_configuration->UpdateLifecycleState(
platform_data_.lifecycle_state);
return true;
}
@ -182,10 +189,11 @@ bool RuntimeController::SetLifecycleState(const std::string& data) {
}
bool RuntimeController::SetSemanticsEnabled(bool enabled) {
window_data_.semantics_enabled = enabled;
platform_data_.semantics_enabled = enabled;
if (auto* window = GetWindowIfAvailable()) {
window->UpdateSemanticsEnabled(window_data_.semantics_enabled);
if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
platform_configuration->UpdateSemanticsEnabled(
platform_data_.semantics_enabled);
return true;
}
@ -193,10 +201,10 @@ bool RuntimeController::SetSemanticsEnabled(bool enabled) {
}
bool RuntimeController::SetAccessibilityFeatures(int32_t flags) {
window_data_.accessibility_feature_flags_ = flags;
if (auto* window = GetWindowIfAvailable()) {
window->UpdateAccessibilityFeatures(
window_data_.accessibility_feature_flags_);
platform_data_.accessibility_feature_flags_ = flags;
if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
platform_configuration->UpdateAccessibilityFeatures(
platform_data_.accessibility_feature_flags_);
return true;
}
@ -204,18 +212,20 @@ bool RuntimeController::SetAccessibilityFeatures(int32_t flags) {
}
bool RuntimeController::BeginFrame(fml::TimePoint frame_time) {
if (auto* window = GetWindowIfAvailable()) {
window->BeginFrame(frame_time);
if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
platform_configuration->BeginFrame(frame_time);
return true;
}
return false;
}
bool RuntimeController::ReportTimings(std::vector<int64_t> timings) {
if (auto* window = GetWindowIfAvailable()) {
window->ReportTimings(std::move(timings));
if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
platform_configuration->ReportTimings(std::move(timings));
return true;
}
return false;
}
@ -239,23 +249,25 @@ bool RuntimeController::NotifyIdle(int64_t deadline) {
bool RuntimeController::DispatchPlatformMessage(
fml::RefPtr<PlatformMessage> message) {
if (auto* window = GetWindowIfAvailable()) {
if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
TRACE_EVENT1("flutter", "RuntimeController::DispatchPlatformMessage",
"mode", "basic");
window->DispatchPlatformMessage(std::move(message));
platform_configuration->DispatchPlatformMessage(std::move(message));
return true;
}
return false;
}
bool RuntimeController::DispatchPointerDataPacket(
const PointerDataPacket& packet) {
if (auto* window = GetWindowIfAvailable()) {
if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
TRACE_EVENT1("flutter", "RuntimeController::DispatchPointerDataPacket",
"mode", "basic");
window->DispatchPointerDataPacket(packet);
platform_configuration->window()->DispatchPointerDataPacket(packet);
return true;
}
return false;
}
@ -264,69 +276,72 @@ bool RuntimeController::DispatchSemanticsAction(int32_t id,
std::vector<uint8_t> args) {
TRACE_EVENT1("flutter", "RuntimeController::DispatchSemanticsAction", "mode",
"basic");
if (auto* window = GetWindowIfAvailable()) {
window->DispatchSemanticsAction(id, action, std::move(args));
if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
platform_configuration->DispatchSemanticsAction(id, action,
std::move(args));
return true;
}
return false;
}
Window* RuntimeController::GetWindowIfAvailable() {
PlatformConfiguration*
RuntimeController::GetPlatformConfigurationIfAvailable() {
std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
return root_isolate ? root_isolate->window() : nullptr;
return root_isolate ? root_isolate->platform_configuration() : nullptr;
}
// |WindowClient|
// |PlatformConfigurationClient|
std::string RuntimeController::DefaultRouteName() {
return client_.DefaultRouteName();
}
// |WindowClient|
// |PlatformConfigurationClient|
void RuntimeController::ScheduleFrame() {
client_.ScheduleFrame();
}
// |WindowClient|
// |PlatformConfigurationClient|
void RuntimeController::Render(Scene* scene) {
client_.Render(scene->takeLayerTree());
}
// |WindowClient|
// |PlatformConfigurationClient|
void RuntimeController::UpdateSemantics(SemanticsUpdate* update) {
if (window_data_.semantics_enabled) {
if (platform_data_.semantics_enabled) {
client_.UpdateSemantics(update->takeNodes(), update->takeActions());
}
}
// |WindowClient|
// |PlatformConfigurationClient|
void RuntimeController::HandlePlatformMessage(
fml::RefPtr<PlatformMessage> message) {
client_.HandlePlatformMessage(std::move(message));
}
// |WindowClient|
// |PlatformConfigurationClient|
FontCollection& RuntimeController::GetFontCollection() {
return client_.GetFontCollection();
}
// |WindowClient|
// |PlatformConfigurationClient|
void RuntimeController::UpdateIsolateDescription(const std::string isolate_name,
int64_t isolate_port) {
client_.UpdateIsolateDescription(isolate_name, isolate_port);
}
// |WindowClient|
// |PlatformConfigurationClient|
void RuntimeController::SetNeedsReportTimings(bool value) {
client_.SetNeedsReportTimings(value);
}
// |WindowClient|
// |PlatformConfigurationClient|
std::shared_ptr<const fml::Mapping>
RuntimeController::GetPersistentIsolateData() {
return persistent_isolate_data_;
}
// |WindowClient|
// |PlatformConfigurationClient|
std::unique_ptr<std::vector<std::string>>
RuntimeController::ComputePlatformResolvedLocale(
const std::vector<std::string>& supported_locale_data) {

View File

@ -14,10 +14,10 @@
#include "flutter/lib/ui/io_manager.h"
#include "flutter/lib/ui/text/font_collection.h"
#include "flutter/lib/ui/ui_dart_state.h"
#include "flutter/lib/ui/window/platform_configuration.h"
#include "flutter/lib/ui/window/pointer_data_packet.h"
#include "flutter/lib/ui/window/window.h"
#include "flutter/runtime/dart_vm.h"
#include "flutter/runtime/window_data.h"
#include "flutter/runtime/platform_data.h"
#include "rapidjson/document.h"
#include "rapidjson/stringbuffer.h"
@ -38,7 +38,7 @@ class Window;
/// used by the engine to copy the currently accumulated window state so it can
/// be referenced by the new runtime controller.
///
class RuntimeController final : public WindowClient {
class RuntimeController final : public PlatformConfigurationClient {
public:
//----------------------------------------------------------------------------
/// @brief Creates a new instance of a runtime controller. This is
@ -90,7 +90,7 @@ class RuntimeController final : public WindowClient {
/// code in isolate scope when the VM
/// is about to be notified that the
/// engine is going to be idle.
/// @param[in] window_data The window data (if exists).
/// @param[in] platform_data The window data (if exists).
/// @param[in] isolate_create_callback The isolate create callback. This
/// allows callers to run native code
/// in isolate scope on the UI task
@ -117,12 +117,12 @@ class RuntimeController final : public WindowClient {
std::string advisory_script_uri,
std::string advisory_script_entrypoint,
const std::function<void(int64_t)>& idle_notification_callback,
const WindowData& window_data,
const PlatformData& platform_data,
const fml::closure& isolate_create_callback,
const fml::closure& isolate_shutdown_callback,
std::shared_ptr<const fml::Mapping> persistent_isolate_data);
// |WindowClient|
// |PlatformConfigurationClient|
~RuntimeController() override;
//----------------------------------------------------------------------------
@ -136,11 +136,11 @@ class RuntimeController final : public WindowClient {
std::unique_ptr<RuntimeController> Clone() const;
//----------------------------------------------------------------------------
/// @brief Forward the specified window metrics to the running isolate.
/// @brief Forward the specified viewport metrics to the running isolate.
/// If the isolate is not running, these metrics will be saved and
/// flushed to the isolate when it starts.
///
/// @param[in] metrics The metrics.
/// @param[in] metrics The viewport metrics.
///
/// @return If the window metrics were forwarded to the running isolate.
///
@ -466,46 +466,46 @@ class RuntimeController final : public WindowClient {
std::string advisory_script_uri_;
std::string advisory_script_entrypoint_;
std::function<void(int64_t)> idle_notification_callback_;
WindowData window_data_;
PlatformData platform_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_;
std::shared_ptr<const fml::Mapping> persistent_isolate_data_;
Window* GetWindowIfAvailable();
PlatformConfiguration* GetPlatformConfigurationIfAvailable();
bool FlushRuntimeStateToIsolate();
// |WindowClient|
// |PlatformConfigurationClient|
std::string DefaultRouteName() override;
// |WindowClient|
// |PlatformConfigurationClient|
void ScheduleFrame() override;
// |WindowClient|
// |PlatformConfigurationClient|
void Render(Scene* scene) override;
// |WindowClient|
// |PlatformConfigurationClient|
void UpdateSemantics(SemanticsUpdate* update) override;
// |WindowClient|
// |PlatformConfigurationClient|
void HandlePlatformMessage(fml::RefPtr<PlatformMessage> message) override;
// |WindowClient|
// |PlatformConfigurationClient|
FontCollection& GetFontCollection() override;
// |WindowClient|
// |PlatformConfigurationClient|
void UpdateIsolateDescription(const std::string isolate_name,
int64_t isolate_port) override;
// |WindowClient|
// |PlatformConfigurationClient|
void SetNeedsReportTimings(bool value) override;
// |WindowClient|
// |PlatformConfigurationClient|
std::shared_ptr<const fml::Mapping> GetPersistentIsolateData() override;
// |WindowClient|
// |PlatformConfigurationClient|
std::unique_ptr<std::vector<std::string>> ComputePlatformResolvedLocale(
const std::vector<std::string>& supported_locale_data) override;

View File

@ -40,7 +40,7 @@ Engine::Engine(Delegate& delegate,
DartVM& vm,
fml::RefPtr<const DartSnapshot> isolate_snapshot,
TaskRunners task_runners,
const WindowData window_data,
const PlatformData platform_data,
Settings settings,
std::unique_ptr<Animator> animator,
fml::WeakPtr<IOManager> io_manager,
@ -71,7 +71,7 @@ Engine::Engine(Delegate& delegate,
settings_.advisory_script_uri, // advisory script uri
settings_.advisory_script_entrypoint, // advisory script entrypoint
settings_.idle_notification_callback, // idle notification callback
window_data, // window data
platform_data, // platform data
settings_.isolate_create_callback, // isolate create callback
settings_.isolate_shutdown_callback, // isolate shutdown callback
settings_.persistent_isolate_data // persistent isolate data
@ -276,7 +276,8 @@ void Engine::SetViewportMetrics(const ViewportMetrics& metrics) {
bool dimensions_changed =
viewport_metrics_.physical_height != metrics.physical_height ||
viewport_metrics_.physical_width != metrics.physical_width ||
viewport_metrics_.physical_depth != metrics.physical_depth;
viewport_metrics_.physical_depth != metrics.physical_depth ||
viewport_metrics_.device_pixel_ratio != metrics.device_pixel_ratio;
viewport_metrics_ = metrics;
runtime_controller_->SetViewportMetrics(viewport_metrics_);
if (animator_) {

View File

@ -295,7 +295,7 @@ class Engine final : public RuntimeDelegate, PointerDataDispatcher::Delegate {
DartVM& vm,
fml::RefPtr<const DartSnapshot> isolate_snapshot,
TaskRunners task_runners,
const WindowData window_data,
const PlatformData platform_data,
Settings settings,
std::unique_ptr<Animator> animator,
fml::WeakPtr<IOManager> io_manager,
@ -421,7 +421,7 @@ class Engine final : public RuntimeDelegate, PointerDataDispatcher::Delegate {
/// one frame interval from this point, the Flutter application
/// will jank.
///
/// If an root isolate is running, this method calls the
/// If a root isolate is running, this method calls the
/// `::_beginFrame` method in `hooks.dart`. If a root isolate is
/// not running, this call does nothing.
///
@ -701,9 +701,10 @@ class Engine final : public RuntimeDelegate, PointerDataDispatcher::Delegate {
//----------------------------------------------------------------------------
/// @brief Notifies the engine that the embedder has expressed an opinion
/// about where the accessibility tree should be generated or not.
/// This call originates in the platform view and is forwarded to
/// the engine here on the UI task runner by the shell.
/// about whether the accessibility tree should be generated or
/// not. This call originates in the platform view and is
/// forwarded to the engine here on the UI task runner by the
/// shell.
///
/// @param[in] enabled Whether the accessibility tree is enabled or
/// disabled.

View File

@ -23,7 +23,7 @@ class PointerDataDispatcher;
/// delivered packets, and dispatches them in sync with the VSYNC signal.
///
/// This object will be owned by the engine because it relies on the engine's
/// `Animator` (which owns `VsyncWaiter`) and `RuntomeController` to do the
/// `Animator` (which owns `VsyncWaiter`) and `RuntimeController` to do the
/// filtering. This object is currently designed to be only called from the UI
/// thread (no thread safety is guaranteed).
///

View File

@ -43,7 +43,7 @@ constexpr char kFontChange[] = "fontsChange";
std::unique_ptr<Shell> Shell::CreateShellOnPlatformThread(
DartVMRef vm,
TaskRunners task_runners,
const WindowData window_data,
const PlatformData platform_data,
Settings settings,
fml::RefPtr<const DartSnapshot> isolate_snapshot,
const Shell::CreateCallback<PlatformView>& on_create_platform_view,
@ -134,7 +134,7 @@ std::unique_ptr<Shell> Shell::CreateShellOnPlatformThread(
fml::MakeCopyable([&engine_promise, //
shell = shell.get(), //
&dispatcher_maker, //
&window_data, //
&platform_data, //
isolate_snapshot = std::move(isolate_snapshot), //
vsync_waiter = std::move(vsync_waiter), //
&weak_io_manager_future, //
@ -155,7 +155,7 @@ std::unique_ptr<Shell> Shell::CreateShellOnPlatformThread(
*shell->GetDartVM(), //
std::move(isolate_snapshot), //
task_runners, //
window_data, //
platform_data, //
shell->GetSettings(), //
std::move(animator), //
weak_io_manager_future.get(), //
@ -242,17 +242,17 @@ std::unique_ptr<Shell> Shell::Create(
Settings settings,
const Shell::CreateCallback<PlatformView>& on_create_platform_view,
const Shell::CreateCallback<Rasterizer>& on_create_rasterizer) {
return Shell::Create(std::move(task_runners), //
WindowData{/* default window data */}, //
std::move(settings), //
std::move(on_create_platform_view), //
std::move(on_create_rasterizer) //
return Shell::Create(std::move(task_runners), //
PlatformData{/* default platform data */}, //
std::move(settings), //
std::move(on_create_platform_view), //
std::move(on_create_rasterizer) //
);
}
std::unique_ptr<Shell> Shell::Create(
TaskRunners task_runners,
const WindowData window_data,
const PlatformData platform_data,
Settings settings,
Shell::CreateCallback<PlatformView> on_create_platform_view,
Shell::CreateCallback<Rasterizer> on_create_rasterizer) {
@ -267,7 +267,7 @@ std::unique_ptr<Shell> Shell::Create(
auto vm_data = vm->GetVMData();
return Shell::Create(std::move(task_runners), //
std::move(window_data), //
std::move(platform_data), //
std::move(settings), //
vm_data->GetIsolateSnapshot(), // isolate snapshot
on_create_platform_view, //
@ -278,7 +278,7 @@ std::unique_ptr<Shell> Shell::Create(
std::unique_ptr<Shell> Shell::Create(
TaskRunners task_runners,
const WindowData window_data,
const PlatformData platform_data,
Settings settings,
fml::RefPtr<const DartSnapshot> isolate_snapshot,
const Shell::CreateCallback<PlatformView>& on_create_platform_view,
@ -302,7 +302,7 @@ std::unique_ptr<Shell> Shell::Create(
vm = std::move(vm), //
&shell, //
task_runners = std::move(task_runners), //
window_data, //
platform_data, //
settings, //
isolate_snapshot = std::move(isolate_snapshot), //
on_create_platform_view, //
@ -310,7 +310,7 @@ std::unique_ptr<Shell> Shell::Create(
]() mutable {
shell = CreateShellOnPlatformThread(std::move(vm),
std::move(task_runners), //
window_data, //
platform_data, //
settings, //
std::move(isolate_snapshot), //
on_create_platform_view, //

View File

@ -138,7 +138,7 @@ class Shell final : public PlatformView::Delegate,
/// the Dart VM.
///
/// @param[in] task_runners The task runners
/// @param[in] window_data The default data for setting up
/// @param[in] platform_data The default data for setting up
/// ui.Window that attached to this
/// intance.
/// @param[in] settings The settings
@ -161,7 +161,7 @@ class Shell final : public PlatformView::Delegate,
///
static std::unique_ptr<Shell> Create(
TaskRunners task_runners,
const WindowData window_data,
const PlatformData platform_data,
Settings settings,
CreateCallback<PlatformView> on_create_platform_view,
CreateCallback<Rasterizer> on_create_rasterizer);
@ -176,7 +176,7 @@ class Shell final : public PlatformView::Delegate,
/// requires the specification of a running VM instance.
///
/// @param[in] task_runners The task runners
/// @param[in] window_data The default data for setting up
/// @param[in] platform_data The default data for setting up
/// ui.Window that attached to this
/// intance.
/// @param[in] settings The settings
@ -203,7 +203,7 @@ class Shell final : public PlatformView::Delegate,
///
static std::unique_ptr<Shell> Create(
TaskRunners task_runners,
const WindowData window_data,
const PlatformData platform_data,
Settings settings,
fml::RefPtr<const DartSnapshot> isolate_snapshot,
const CreateCallback<PlatformView>& on_create_platform_view,
@ -426,7 +426,7 @@ class Shell final : public PlatformView::Delegate,
static std::unique_ptr<Shell> CreateShellOnPlatformThread(
DartVMRef vm,
TaskRunners task_runners,
const WindowData window_data,
const PlatformData platform_data,
Settings settings,
fml::RefPtr<const DartSnapshot> isolate_snapshot,
const Shell::CreateCallback<PlatformView>& on_create_platform_view,

View File

@ -100,10 +100,7 @@ void ShellTest::PumpOneFrame(Shell* shell,
double width,
double height,
LayerTreeBuilder builder) {
PumpOneFrame(shell,
flutter::ViewportMetrics{1, width, height, flutter::kUnsetDepth,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
std::move(builder));
PumpOneFrame(shell, {1.0, width, height}, std::move(builder));
}
void ShellTest::PumpOneFrame(Shell* shell,

View File

@ -684,7 +684,7 @@ TEST_F(ShellTest, WaitForFirstFrameZeroSizeFrame) {
configuration.SetEntrypoint("emptyMain");
RunEngine(shell.get(), std::move(configuration));
PumpOneFrame(shell.get(), {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0});
PumpOneFrame(shell.get(), {1.0, 0.0, 0.0});
fml::Status result =
shell->WaitForFirstFrame(fml::TimeDelta::FromMilliseconds(1000));
ASSERT_FALSE(result.ok());
@ -802,8 +802,7 @@ TEST_F(ShellTest, SetResourceCacheSize) {
fml::TaskRunner::RunNowOrPostTask(
shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell]() {
shell->GetPlatformView()->SetViewportMetrics(
{1.0, 400, 200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0});
shell->GetPlatformView()->SetViewportMetrics({1.0, 400, 200});
});
PumpOneFrame(shell.get());
@ -822,8 +821,7 @@ TEST_F(ShellTest, SetResourceCacheSize) {
fml::TaskRunner::RunNowOrPostTask(
shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell]() {
shell->GetPlatformView()->SetViewportMetrics(
{1.0, 800, 400, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0});
shell->GetPlatformView()->SetViewportMetrics({1.0, 800, 400});
});
PumpOneFrame(shell.get());
@ -841,8 +839,7 @@ TEST_F(ShellTest, SetResourceCacheSizeEarly) {
fml::TaskRunner::RunNowOrPostTask(
shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell]() {
shell->GetPlatformView()->SetViewportMetrics(
{1.0, 400, 200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0});
shell->GetPlatformView()->SetViewportMetrics({1.0, 400, 200});
});
PumpOneFrame(shell.get());
@ -870,8 +867,7 @@ TEST_F(ShellTest, SetResourceCacheSizeNotifiesDart) {
fml::TaskRunner::RunNowOrPostTask(
shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell]() {
shell->GetPlatformView()->SetViewportMetrics(
{1.0, 400, 200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0});
shell->GetPlatformView()->SetViewportMetrics({1.0, 400, 200});
});
PumpOneFrame(shell.get());
@ -1235,7 +1231,7 @@ TEST_F(ShellTest, CanDecompressImageFromAsset) {
}
TEST_F(ShellTest, OnServiceProtocolGetSkSLsWorks) {
// Create 2 dummpy SkSL cache file IE (base32 encoding of A), II (base32
// Create 2 dummy SkSL cache file IE (base32 encoding of A), II (base32
// encoding of B) with content x and y.
fml::ScopedTemporaryDirectory temp_dir;
PersistentCache::SetCacheDirectoryPath(temp_dir.path());

View File

@ -22,10 +22,10 @@
namespace flutter {
static WindowData GetDefaultWindowData() {
WindowData window_data;
window_data.lifecycle_state = "AppLifecycleState.detached";
return window_data;
static PlatformData GetDefaultPlatformData() {
PlatformData platform_data;
platform_data.lifecycle_state = "AppLifecycleState.detached";
return platform_data;
}
bool AndroidShellHolder::use_embedded_view;
@ -121,9 +121,9 @@ AndroidShellHolder::AndroidShellHolder(
);
shell_ =
Shell::Create(task_runners, // task runners
GetDefaultWindowData(), // window data
settings_, // settings
Shell::Create(task_runners, // task runners
GetDefaultPlatformData(), // window data
settings_, // settings
on_create_platform_view, // platform view create callback
on_create_rasterizer // rasterizer create callback
);
@ -137,9 +137,9 @@ AndroidShellHolder::AndroidShellHolder(
);
shell_ =
Shell::Create(task_runners, // task runners
GetDefaultWindowData(), // window data
settings_, // settings
Shell::Create(task_runners, // task runners
GetDefaultPlatformData(), // window data
settings_, // settings
on_create_platform_view, // platform view create callback
on_create_rasterizer // rasterizer create callback
);

View File

@ -10,7 +10,7 @@
#include "flutter/fml/macros.h"
#include "flutter/fml/unique_fd.h"
#include "flutter/lib/ui/window/viewport_metrics.h"
#include "flutter/runtime/window_data.h"
#include "flutter/runtime/platform_data.h"
#include "flutter/shell/common/run_configuration.h"
#include "flutter/shell/common/shell.h"
#include "flutter/shell/common/thread_host.h"

View File

@ -1063,7 +1063,7 @@ public class FlutterView extends FrameLayout implements MouseCursorPlugin.MouseC
}
/**
* Adds a {@link FlutterEngineAttachmentListener}, which is notifed whenever this {@code
* Adds a {@link FlutterEngineAttachmentListener}, which is notified whenever this {@code
* FlutterView} attached to/detaches from a {@link FlutterEngine}.
*/
@VisibleForTesting

View File

@ -168,12 +168,12 @@ static flutter::Settings DefaultSettingsForProcess(NSBundle* bundle = nil) {
return self;
}
#pragma mark - WindowData accessors
#pragma mark - PlatformData accessors
- (const flutter::WindowData)defaultWindowData {
flutter::WindowData windowData;
windowData.lifecycle_state = std::string("AppLifecycleState.detached");
return windowData;
- (const flutter::PlatformData)defaultPlatformData {
flutter::PlatformData PlatformData;
PlatformData.lifecycle_state = std::string("AppLifecycleState.detached");
return PlatformData;
}
#pragma mark - Settings accessors
@ -261,6 +261,6 @@ static flutter::Settings DefaultSettingsForProcess(NSBundle* bundle = nil) {
);
}
#pragma mark - windowData utilities
#pragma mark - PlatformData utilities
@end

View File

@ -6,7 +6,7 @@
#define SHELL_PLATFORM_IOS_FRAMEWORK_SOURCE_FLUTTERDARTPROJECT_INTERNAL_H_
#include "flutter/common/settings.h"
#include "flutter/runtime/window_data.h"
#include "flutter/runtime/platform_data.h"
#include "flutter/shell/common/engine.h"
#include "flutter/shell/platform/darwin/ios/framework/Headers/FlutterDartProject.h"
@ -15,7 +15,7 @@ NS_ASSUME_NONNULL_BEGIN
@interface FlutterDartProject ()
- (const flutter::Settings&)settings;
- (const flutter::WindowData)defaultWindowData;
- (const flutter::PlatformData)defaultPlatformData;
- (flutter::RunConfiguration)runConfiguration;
- (flutter::RunConfiguration)runConfigurationForEntrypoint:(nullable NSString*)entrypointOrNil;

View File

@ -17,6 +17,9 @@
#include "flutter/shell/common/switches.h"
#include "flutter/shell/common/thread_host.h"
#include "flutter/shell/platform/darwin/common/command_line.h"
#include "flutter/shell/platform/darwin/ios/rendering_api_selection.h"
#include "flutter/shell/profiling/sampling_profiler.h"
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterBinaryMessengerRelay.h"
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterDartProject_Internal.h"
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterObservatoryPublisher.h"
@ -28,8 +31,6 @@
#import "flutter/shell/platform/darwin/ios/framework/Source/profiler_metrics_ios.h"
#import "flutter/shell/platform/darwin/ios/ios_surface.h"
#import "flutter/shell/platform/darwin/ios/platform_view_ios.h"
#include "flutter/shell/platform/darwin/ios/rendering_api_selection.h"
#include "flutter/shell/profiling/sampling_profiler.h"
NSString* const FlutterDefaultDartEntrypoint = nil;
static constexpr int kNumProfilerSamplesPerSec = 5;
@ -445,7 +446,7 @@ static constexpr int kNumProfilerSamplesPerSec = 5;
static size_t shellCount = 1;
auto settings = [_dartProject.get() settings];
auto windowData = [_dartProject.get() defaultWindowData];
auto platformData = [_dartProject.get() defaultPlatformData];
if (libraryURI) {
FML_DCHECK(entrypoint) << "Must specify entrypoint if specifying library";
@ -510,10 +511,10 @@ static constexpr int kNumProfilerSamplesPerSec = 5;
);
// Create the shell. This is a blocking operation.
_shell = flutter::Shell::Create(std::move(task_runners), // task runners
std::move(windowData), // window data
std::move(platformData), // platform data
std::move(settings), // settings
on_create_platform_view, // platform view creation
on_create_rasterizer // rasterzier creation
on_create_rasterizer // rasterizer creation
);
} else {
flutter::TaskRunners task_runners(threadLabel.UTF8String, // label
@ -524,10 +525,10 @@ static constexpr int kNumProfilerSamplesPerSec = 5;
);
// Create the shell. This is a blocking operation.
_shell = flutter::Shell::Create(std::move(task_runners), // task runners
std::move(windowData), // window data
std::move(platformData), // platform data
std::move(settings), // settings
on_create_platform_view, // platform view creation
on_create_rasterizer // rasterzier creation
on_create_rasterizer // rasterizer creation
);
}

View File

@ -9,6 +9,39 @@
#include <stddef.h>
#include <stdint.h>
// This file defines an Application Binary Interface (ABI), which requires more
// stability than regular code to remain functional for exchanging messages
// between different versions of the embedding and the engine, to allow for both
// forward and backward compatibility.
//
// Specifically,
// - The order, type, and size of the struct members below must remain the same,
// and members should not be removed.
// - New structures that are part of the ABI must be defined with "size_t
// struct_size;" as their first member, which should be initialized using
// "sizeof(Type)".
// - Enum values must not change or be removed.
// - Enum members without explicit values must not be reordered.
// - Function signatures (names, argument counts, argument order, and argument
// type) cannot change.
// - The core behavior of existing functions cannot change.
//
// These changes are allowed:
// - Adding new struct members at the end of a structure.
// - Adding new enum members with a new value.
// - Renaming a struct member as long as its type, size, and intent remain the
// same.
// - Renaming an enum member as long as its value and intent remains the same.
//
// It is expected that struct members and implicitly-valued enums will not
// always be declared in an order that is optimal for the reader, since members
// will be added over time, and they can't be reordered.
//
// Existing functions should continue to appear from the caller's point of view
// to operate as they did when they were first introduced, so introduce a new
// function instead of modifying the core behavior of a function (and continue
// to support the existing function with the previous behavior).
#if defined(__cplusplus)
extern "C" {
#endif

View File

@ -12,7 +12,6 @@
#include "flutter/shell/common/shell.h"
#include "flutter/shell/common/thread_host.h"
#include "flutter/shell/platform/embedder/embedder.h"
#include "flutter/shell/platform/embedder/embedder_engine.h"
#include "flutter/shell/platform/embedder/embedder_external_texture_gl.h"
#include "flutter/shell/platform/embedder/embedder_thread_host.h"

View File

@ -257,7 +257,7 @@ Engine::Engine(Delegate& delegate,
TRACE_EVENT0("flutter", "CreateShell");
shell_ = flutter::Shell::Create(
task_runners, // host task runners
flutter::WindowData(), // default window data
flutter::PlatformData(), // default window data
settings_, // shell launch settings
std::move(isolate_snapshot), // isolate snapshot
on_create_platform_view, // platform view create callback

View File

@ -235,10 +235,10 @@ int RunTester(const flutter::Settings& settings,
}
});
flutter::ViewportMetrics metrics;
flutter::ViewportMetrics metrics{};
metrics.device_pixel_ratio = 3.0;
metrics.physical_width = 2400; // 800 at 3x resolution
metrics.physical_height = 1800; // 600 at 3x resolution
metrics.physical_width = 2400.0; // 800 at 3x resolution.
metrics.physical_height = 1800.0; // 600 at 3x resolution.
shell->GetPlatformView()->SetViewportMetrics(metrics);
// Run the message loop and wait for the script to do its thing.