Make updating window metrics multi-view (flutter/engine#43366)

This PR adds multi-view support to various methods that updates the window metrics by adding a `view_id` parameter.

[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
This commit is contained in:
Tong Mu 2023-07-07 22:54:16 -07:00 committed by GitHub
parent 9cd4338940
commit 489f9c3d01
28 changed files with 228 additions and 73 deletions

View File

@ -308,6 +308,15 @@ void PlatformConfiguration::ReportTimings(std::vector<int64_t> timings) {
}));
}
Window* PlatformConfiguration::get_window(int window_id) {
auto found = windows_.find(window_id);
if (found != windows_.end()) {
return found->second.get();
} else {
return nullptr;
}
}
void PlatformConfiguration::CompletePlatformMessageEmptyResponse(
int response_id) {
if (!response_id) {

View File

@ -413,9 +413,10 @@ class PlatformConfiguration final {
///
/// @param[in] window_id The id of the window to find and return.
///
/// @return a pointer to the Window.
/// @return a pointer to the Window. Returns nullptr if the ID is not
/// found.
///
Window* get_window(int window_id) { return windows_[window_id].get(); }
Window* get_window(int window_id);
//----------------------------------------------------------------------------
/// @brief Responds to a previous platform message to the engine from the

View File

@ -19,7 +19,9 @@
namespace flutter {
namespace testing {
TEST_F(ShellTest, PlatformConfigurationInitialization) {
class PlatformConfigurationTest : public ShellTest {};
TEST_F(PlatformConfigurationTest, Initialization) {
auto message_latch = std::make_shared<fml::AutoResetWaitableEvent>();
auto nativeValidateConfiguration = [message_latch](
@ -63,7 +65,7 @@ TEST_F(ShellTest, PlatformConfigurationInitialization) {
DestroyShell(std::move(shell), task_runners);
}
TEST_F(ShellTest, PlatformConfigurationWindowMetricsUpdate) {
TEST_F(PlatformConfigurationTest, WindowMetricsUpdate) {
auto message_latch = std::make_shared<fml::AutoResetWaitableEvent>();
auto nativeValidateConfiguration = [message_latch](
@ -113,7 +115,46 @@ TEST_F(ShellTest, PlatformConfigurationWindowMetricsUpdate) {
DestroyShell(std::move(shell), task_runners);
}
TEST_F(ShellTest, PlatformConfigurationOnErrorHandlesError) {
TEST_F(PlatformConfigurationTest, GetWindowReturnsNullForNonexistentId) {
auto message_latch = std::make_shared<fml::AutoResetWaitableEvent>();
auto nativeValidateConfiguration =
[message_latch](Dart_NativeArguments args) {
PlatformConfiguration* configuration =
UIDartState::Current()->platform_configuration();
ASSERT_EQ(configuration->get_window(1), nullptr);
ASSERT_EQ(configuration->get_window(2), nullptr);
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(settings, 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), task_runners);
}
TEST_F(PlatformConfigurationTest, OnErrorHandlesError) {
auto message_latch = std::make_shared<fml::AutoResetWaitableEvent>();
bool did_throw = false;
@ -159,7 +200,7 @@ TEST_F(ShellTest, PlatformConfigurationOnErrorHandlesError) {
DestroyShell(std::move(shell), task_runners);
}
TEST_F(ShellTest, PlatformConfigurationOnErrorDoesNotHandleError) {
TEST_F(PlatformConfigurationTest, OnErrorDoesNotHandleError) {
auto message_latch = std::make_shared<fml::AutoResetWaitableEvent>();
std::string ex;
std::string st;
@ -211,7 +252,7 @@ TEST_F(ShellTest, PlatformConfigurationOnErrorDoesNotHandleError) {
DestroyShell(std::move(shell), task_runners);
}
TEST_F(ShellTest, PlatformConfigurationOnErrorThrows) {
TEST_F(PlatformConfigurationTest, OnErrorThrows) {
auto message_latch = std::make_shared<fml::AutoResetWaitableEvent>();
std::vector<std::string> errors;
size_t throw_count = 0;
@ -266,7 +307,7 @@ TEST_F(ShellTest, PlatformConfigurationOnErrorThrows) {
DestroyShell(std::move(shell), task_runners);
}
TEST_F(ShellTest, PlatformConfigurationSetDartPerformanceMode) {
TEST_F(PlatformConfigurationTest, SetDartPerformanceMode) {
auto message_latch = std::make_shared<fml::AutoResetWaitableEvent>();
auto finish = [message_latch](Dart_NativeArguments args) {
// call needs to happen on the UI thread.

View File

@ -20,7 +20,7 @@
namespace flutter {
const uint64_t kFlutterImplicitViewId = 0llu;
constexpr uint64_t kFlutterImplicitViewId = 0ll;
RuntimeController::RuntimeController(RuntimeDelegate& p_client,
const TaskRunners& task_runners)
@ -115,7 +115,10 @@ std::unique_ptr<RuntimeController> RuntimeController::Clone() const {
}
bool RuntimeController::FlushRuntimeStateToIsolate() {
return SetViewportMetrics(platform_data_.viewport_metrics) &&
// TODO(dkwingsmt): Needs a view ID here (or platform_data should probably
// have multiple view metrics).
return SetViewportMetrics(kFlutterImplicitViewId,
platform_data_.viewport_metrics) &&
SetLocales(platform_data_.locale_data) &&
SetSemanticsEnabled(platform_data_.semantics_enabled) &&
SetAccessibilityFeatures(
@ -125,13 +128,19 @@ bool RuntimeController::FlushRuntimeStateToIsolate() {
SetDisplays(platform_data_.displays);
}
bool RuntimeController::SetViewportMetrics(const ViewportMetrics& metrics) {
bool RuntimeController::SetViewportMetrics(int64_t view_id,
const ViewportMetrics& metrics) {
TRACE_EVENT0("flutter", "SetViewportMetrics");
platform_data_.viewport_metrics = metrics;
if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
platform_configuration->get_window(0)->UpdateWindowMetrics(metrics);
return true;
Window* window = platform_configuration->get_window(view_id);
if (window) {
window->UpdateWindowMetrics(metrics);
return true;
} else {
FML_LOG(WARNING) << "View ID " << view_id << " does not exist.";
}
}
return false;

View File

@ -168,11 +168,12 @@ class RuntimeController : public PlatformConfigurationClient {
/// If the isolate is not running, these metrics will be saved and
/// flushed to the isolate when it starts.
///
/// @param[in] view_id The ID for the view that `metrics` describes.
/// @param[in] metrics The window's viewport metrics.
///
/// @return If the window metrics were forwarded to the running isolate.
///
bool SetViewportMetrics(const ViewportMetrics& metrics);
bool SetViewportMetrics(int64_t view_id, const ViewportMetrics& metrics);
//----------------------------------------------------------------------------
/// @brief Forward the specified display metrics to the running isolate.

View File

@ -292,8 +292,9 @@ tonic::DartErrorHandleType Engine::GetUIIsolateLastError() {
return runtime_controller_->GetLastError();
}
void Engine::SetViewportMetrics(const ViewportMetrics& metrics) {
runtime_controller_->SetViewportMetrics(metrics);
void Engine::SetViewportMetrics(int64_t view_id,
const ViewportMetrics& metrics) {
runtime_controller_->SetViewportMetrics(view_id, metrics);
ScheduleFrame();
}

View File

@ -677,16 +677,16 @@ class Engine final : public RuntimeDelegate, PointerDataDispatcher::Delegate {
std::optional<uint32_t> GetUIIsolateReturnCode();
//----------------------------------------------------------------------------
/// @brief Updates the viewport metrics for the currently running Flutter
/// application. The viewport metrics detail the size of the
/// rendering viewport in texels as well as edge insets if
/// present.
/// @brief Updates the viewport metrics for a view. The viewport metrics
/// detail the size of the rendering viewport in texels as well as
/// edge insets if present.
///
/// @see `ViewportMetrics`
///
/// @param[in] metrics The metrics
/// @param[in] view_id The ID for the view that `metrics` describes.
/// @param[in] metrics The metrics.
///
void SetViewportMetrics(const ViewportMetrics& metrics);
void SetViewportMetrics(int64_t view_id, const ViewportMetrics& metrics);
//----------------------------------------------------------------------------
/// @brief Updates the display metrics for the currently running Flutter

View File

@ -21,6 +21,8 @@
namespace flutter {
namespace {
constexpr int64_t kImplicitViewId = 0ll;
class MockDelegate : public Engine::Delegate {
public:
MOCK_METHOD2(OnEngineUpdateSemantics,
@ -330,7 +332,8 @@ TEST_F(EngineTest, SpawnResetsViewportMetrics) {
const double kViewHeight = 1024;
old_viewport_metrics.physical_width = kViewWidth;
old_viewport_metrics.physical_height = kViewHeight;
mock_runtime_controller->SetViewportMetrics(old_viewport_metrics);
mock_runtime_controller->SetViewportMetrics(kImplicitViewId,
old_viewport_metrics);
auto engine = std::make_unique<Engine>(
/*delegate=*/delegate_,
/*dispatcher_maker=*/dispatcher_maker_,

View File

@ -51,8 +51,9 @@ void PlatformView::SetAccessibilityFeatures(int32_t flags) {
delegate_.OnPlatformViewSetAccessibilityFeatures(flags);
}
void PlatformView::SetViewportMetrics(const ViewportMetrics& metrics) {
delegate_.OnPlatformViewSetViewportMetrics(metrics);
void PlatformView::SetViewportMetrics(int64_t view_id,
const ViewportMetrics& metrics) {
delegate_.OnPlatformViewSetViewportMetrics(view_id, metrics);
}
void PlatformView::NotifyCreated() {

View File

@ -104,14 +104,15 @@ class PlatformView {
const fml::closure& closure) = 0;
//--------------------------------------------------------------------------
/// @brief Notifies the delegate the viewport metrics of the platform
/// view have been updated. The rasterizer will need to be
/// reconfigured to render the frame in the updated viewport
/// metrics.
/// @brief Notifies the delegate the viewport metrics of a view have
/// been updated. The rasterizer will need to be reconfigured to
/// render the frame in the updated viewport metrics.
///
/// @param[in] view_id The ID for the view that `metrics` describes.
/// @param[in] metrics The updated viewport metrics.
///
virtual void OnPlatformViewSetViewportMetrics(
int64_t view_id,
const ViewportMetrics& metrics) = 0;
//--------------------------------------------------------------------------
@ -465,16 +466,17 @@ class PlatformView {
CustomAccessibilityActionUpdates actions);
//----------------------------------------------------------------------------
/// @brief Used by embedders to specify the updated viewport metrics. In
/// response to this call, on the raster thread, the rasterizer
/// may need to be reconfigured to the updated viewport
/// @brief Used by embedders to specify the updated viewport metrics for
/// a view. In response to this call, on the raster thread, the
/// rasterizer may need to be reconfigured to the updated viewport
/// dimensions. On the UI thread, the framework may need to start
/// generating a new frame for the updated viewport metrics as
/// well.
///
/// @param[in] view_id The ID for the view that `metrics` describes.
/// @param[in] metrics The updated viewport metrics.
///
void SetViewportMetrics(const ViewportMetrics& metrics);
void SetViewportMetrics(int64_t view_id, const ViewportMetrics& metrics);
//----------------------------------------------------------------------------
/// @brief Used by embedders to notify the shell that a platform view

View File

@ -954,7 +954,8 @@ void Shell::OnPlatformViewScheduleFrame() {
}
// |PlatformView::Delegate|
void Shell::OnPlatformViewSetViewportMetrics(const ViewportMetrics& metrics) {
void Shell::OnPlatformViewSetViewportMetrics(int64_t view_id,
const ViewportMetrics& metrics) {
FML_DCHECK(is_setup_);
FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread());
@ -978,9 +979,9 @@ void Shell::OnPlatformViewSetViewportMetrics(const ViewportMetrics& metrics) {
});
task_runners_.GetUITaskRunner()->PostTask(
[engine = engine_->GetWeakPtr(), metrics]() {
[engine = engine_->GetWeakPtr(), view_id, metrics]() {
if (engine) {
engine->SetViewportMetrics(metrics);
engine->SetViewportMetrics(view_id, metrics);
}
});

View File

@ -544,6 +544,7 @@ class Shell final : public PlatformView::Delegate,
// |PlatformView::Delegate|
void OnPlatformViewSetViewportMetrics(
int64_t view_id,
const ViewportMetrics& metrics) override;
// |PlatformView::Delegate|

View File

@ -20,6 +20,8 @@
namespace flutter {
namespace testing {
constexpr int64_t kImplicitViewId = 0;
ShellTest::ShellTest()
: thread_host_("io.flutter.test." + GetCurrentTestName() + ".",
ThreadHost::Type::Platform | ThreadHost::Type::IO |
@ -144,7 +146,7 @@ void ShellTest::SetViewportMetrics(Shell* shell, double width, double height) {
shell->GetTaskRunners().GetUITaskRunner()->PostTask(
[&latch, engine = shell->weak_engine_, viewport_metrics]() {
if (engine) {
engine->SetViewportMetrics(viewport_metrics);
engine->SetViewportMetrics(kImplicitViewId, viewport_metrics);
const auto frame_begin_time = fml::TimePoint::Now();
const auto frame_end_time =
frame_begin_time + fml::TimeDelta::FromSecondsF(1.0 / 60.0);
@ -186,7 +188,7 @@ void ShellTest::PumpOneFrame(Shell* shell,
fml::AutoResetWaitableEvent latch;
shell->GetTaskRunners().GetUITaskRunner()->PostTask(
[&latch, engine = shell->weak_engine_, viewport_metrics]() {
engine->SetViewportMetrics(viewport_metrics);
engine->SetViewportMetrics(kImplicitViewId, viewport_metrics);
const auto frame_begin_time = fml::TimePoint::Now();
const auto frame_end_time =
frame_begin_time + fml::TimeDelta::FromSecondsF(1.0 / 60.0);

View File

@ -60,6 +60,8 @@
namespace flutter {
namespace testing {
constexpr int64_t kImplicitViewId = 0ll;
using ::testing::_;
using ::testing::Return;
@ -74,8 +76,8 @@ class MockPlatformViewDelegate : public PlatformView::Delegate {
MOCK_METHOD1(OnPlatformViewSetNextFrameCallback,
void(const fml::closure& closure));
MOCK_METHOD1(OnPlatformViewSetViewportMetrics,
void(const ViewportMetrics& metrics));
MOCK_METHOD2(OnPlatformViewSetViewportMetrics,
void(int64_t view_id, const ViewportMetrics& metrics));
MOCK_METHOD1(OnPlatformViewDispatchPlatformMessage,
void(std::unique_ptr<PlatformMessage> message));
@ -1637,7 +1639,8 @@ TEST_F(ShellTest, MultipleFluttersSetResourceCacheBytes) {
RunEngine(shell.get(), std::move(configuration));
PostSync(shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell]() {
shell->GetPlatformView()->SetViewportMetrics({1.0, 100, 100, 22, 0});
shell->GetPlatformView()->SetViewportMetrics(kImplicitViewId,
{1.0, 100, 100, 22, 0});
});
// first cache bytes
@ -1666,7 +1669,7 @@ TEST_F(ShellTest, MultipleFluttersSetResourceCacheBytes) {
PostSync(second_shell->GetTaskRunners().GetPlatformTaskRunner(),
[&second_shell]() {
second_shell->GetPlatformView()->SetViewportMetrics(
{1.0, 100, 100, 22, 0});
kImplicitViewId, {1.0, 100, 100, 22, 0});
});
// first cache bytes + second cache bytes
EXPECT_EQ(GetRasterizerResourceCacheBytesSync(*shell),
@ -1675,7 +1678,7 @@ TEST_F(ShellTest, MultipleFluttersSetResourceCacheBytes) {
PostSync(second_shell->GetTaskRunners().GetPlatformTaskRunner(),
[&second_shell]() {
second_shell->GetPlatformView()->SetViewportMetrics(
{1.0, 100, 300, 22, 0});
kImplicitViewId, {1.0, 100, 300, 22, 0});
});
// first cache bytes + second cache bytes
EXPECT_EQ(GetRasterizerResourceCacheBytesSync(*shell),
@ -1686,7 +1689,7 @@ TEST_F(ShellTest, MultipleFluttersSetResourceCacheBytes) {
PostSync(third_shell->GetTaskRunners().GetPlatformTaskRunner(),
[&third_shell]() {
third_shell->GetPlatformView()->SetViewportMetrics(
{1.0, 400, 100, 22, 0});
kImplicitViewId, {1.0, 400, 100, 22, 0});
});
// first cache bytes + second cache bytes + third cache bytes
EXPECT_EQ(GetRasterizerResourceCacheBytesSync(*shell),
@ -1695,7 +1698,7 @@ TEST_F(ShellTest, MultipleFluttersSetResourceCacheBytes) {
PostSync(third_shell->GetTaskRunners().GetPlatformTaskRunner(),
[&third_shell]() {
third_shell->GetPlatformView()->SetViewportMetrics(
{1.0, 800, 100, 22, 0});
kImplicitViewId, {1.0, 800, 100, 22, 0});
});
// max bytes threshold
EXPECT_EQ(GetRasterizerResourceCacheBytesSync(*shell),
@ -1708,7 +1711,7 @@ TEST_F(ShellTest, MultipleFluttersSetResourceCacheBytes) {
PostSync(second_shell->GetTaskRunners().GetPlatformTaskRunner(),
[&second_shell]() {
second_shell->GetPlatformView()->SetViewportMetrics(
{1.0, 100, 100, 22, 0});
kImplicitViewId, {1.0, 100, 100, 22, 0});
});
// first cache bytes + second cache bytes
EXPECT_EQ(GetRasterizerResourceCacheBytesSync(*shell),
@ -1752,7 +1755,8 @@ TEST_F(ShellTest, SetResourceCacheSize) {
fml::TaskRunner::RunNowOrPostTask(
shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell]() {
shell->GetPlatformView()->SetViewportMetrics({1.0, 400, 200, 22, 0});
shell->GetPlatformView()->SetViewportMetrics(kImplicitViewId,
{1.0, 400, 200, 22, 0});
});
PumpOneFrame(shell.get());
@ -1772,7 +1776,8 @@ TEST_F(ShellTest, SetResourceCacheSize) {
fml::TaskRunner::RunNowOrPostTask(
shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell]() {
shell->GetPlatformView()->SetViewportMetrics({1.0, 800, 400, 22, 0});
shell->GetPlatformView()->SetViewportMetrics(kImplicitViewId,
{1.0, 800, 400, 22, 0});
});
PumpOneFrame(shell.get());
@ -1789,7 +1794,8 @@ TEST_F(ShellTest, SetResourceCacheSizeEarly) {
fml::TaskRunner::RunNowOrPostTask(
shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell]() {
shell->GetPlatformView()->SetViewportMetrics({1.0, 400, 200, 22, 0});
shell->GetPlatformView()->SetViewportMetrics(kImplicitViewId,
{1.0, 400, 200, 22, 0});
});
PumpOneFrame(shell.get());
@ -1816,7 +1822,8 @@ TEST_F(ShellTest, SetResourceCacheSizeNotifiesDart) {
fml::TaskRunner::RunNowOrPostTask(
shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell]() {
shell->GetPlatformView()->SetViewportMetrics({1.0, 400, 200, 22, 0});
shell->GetPlatformView()->SetViewportMetrics(kImplicitViewId,
{1.0, 400, 200, 22, 0});
});
PumpOneFrame(shell.get());
@ -2683,6 +2690,7 @@ TEST_F(ShellTest, DISABLED_DiscardLayerTreeOnResize) {
shell->GetTaskRunners().GetPlatformTaskRunner(),
[&shell, &expected_size]() {
shell->GetPlatformView()->SetViewportMetrics(
kImplicitViewId,
{1.0, static_cast<double>(expected_size.width()),
static_cast<double>(expected_size.height()), 22, 0});
});
@ -2760,6 +2768,7 @@ TEST_F(ShellTest, DISABLED_DiscardResubmittedLayerTreeOnResize) {
shell->GetTaskRunners().GetPlatformTaskRunner(),
[&shell, &origin_size]() {
shell->GetPlatformView()->SetViewportMetrics(
kImplicitViewId,
{1.0, static_cast<double>(origin_size.width()),
static_cast<double>(origin_size.height()), 22, 0});
});
@ -2779,8 +2788,8 @@ TEST_F(ShellTest, DISABLED_DiscardResubmittedLayerTreeOnResize) {
shell->GetTaskRunners().GetPlatformTaskRunner(),
[&shell, &new_size, &resize_latch]() {
shell->GetPlatformView()->SetViewportMetrics(
{1.0, static_cast<double>(new_size.width()),
static_cast<double>(new_size.height()), 22, 0});
kImplicitViewId, {1.0, static_cast<double>(new_size.width()),
static_cast<double>(new_size.height()), 22, 0});
resize_latch.Signal();
});
@ -2843,14 +2852,21 @@ TEST_F(ShellTest, IgnoresInvalidMetrics) {
RunEngine(shell.get(), std::move(configuration));
task_runner->PostTask([&]() {
shell->GetPlatformView()->SetViewportMetrics({0.0, 400, 200, 22, 0});
// This one is invalid for having 0 pixel ratio.
shell->GetPlatformView()->SetViewportMetrics(kImplicitViewId,
{0.0, 400, 200, 22, 0});
task_runner->PostTask([&]() {
shell->GetPlatformView()->SetViewportMetrics({0.8, 0.0, 200, 22, 0});
// This one is invalid for having 0 width.
shell->GetPlatformView()->SetViewportMetrics(kImplicitViewId,
{0.8, 0.0, 200, 22, 0});
task_runner->PostTask([&]() {
shell->GetPlatformView()->SetViewportMetrics({0.8, 400, 0.0, 22, 0});
// This one is invalid for having 0 height.
shell->GetPlatformView()->SetViewportMetrics(kImplicitViewId,
{0.8, 400, 0.0, 22, 0});
task_runner->PostTask([&]() {
// This one makes it through.
shell->GetPlatformView()->SetViewportMetrics(
{0.8, 400, 200.0, 22, 0});
kImplicitViewId, {0.8, 400, 200.0, 22, 0});
});
});
});
@ -2862,7 +2878,8 @@ TEST_F(ShellTest, IgnoresInvalidMetrics) {
latch.Reset();
task_runner->PostTask([&]() {
shell->GetPlatformView()->SetViewportMetrics({1.2, 600, 300, 22, 0});
shell->GetPlatformView()->SetViewportMetrics(kImplicitViewId,
{1.2, 600, 300, 22, 0});
});
latch.Wait();
ASSERT_EQ(last_device_pixel_ratio, 1.2);
@ -2872,6 +2889,52 @@ TEST_F(ShellTest, IgnoresInvalidMetrics) {
DestroyShell(std::move(shell), task_runners);
}
TEST_F(ShellTest, IgnoresMetricsUpdateToInvalidView) {
fml::AutoResetWaitableEvent latch;
double last_device_pixel_ratio;
// This callback will be called whenever any view's metrics change.
auto native_report_device_pixel_ratio = [&](Dart_NativeArguments args) {
// The correct call will have a DPR of 3.
auto dpr_handle = Dart_GetNativeArgument(args, 0);
ASSERT_TRUE(Dart_IsDouble(dpr_handle));
Dart_DoubleValue(dpr_handle, &last_device_pixel_ratio);
ASSERT_TRUE(last_device_pixel_ratio > 2.5);
latch.Signal();
};
Settings settings = CreateSettingsForFixture();
auto task_runner = CreateNewThread();
TaskRunners task_runners("test", task_runner, task_runner, task_runner,
task_runner);
AddNativeCallback("ReportMetrics",
CREATE_NATIVE_ENTRY(native_report_device_pixel_ratio));
std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
auto configuration = RunConfiguration::InferFromSettings(settings);
configuration.SetEntrypoint("reportMetrics");
RunEngine(shell.get(), std::move(configuration));
task_runner->PostTask([&]() {
// This one is invalid for having an nonexistent view ID.
// Also, it has a DPR of 2.0 for detection.
shell->GetPlatformView()->SetViewportMetrics(2, {2.0, 400, 200, 22, 0});
task_runner->PostTask([&]() {
// This one is valid with DPR 3.0.
shell->GetPlatformView()->SetViewportMetrics(kImplicitViewId,
{3.0, 400, 200, 22, 0});
});
});
latch.Wait();
ASSERT_EQ(last_device_pixel_ratio, 3.0);
latch.Reset();
DestroyShell(std::move(shell), task_runners);
}
TEST_F(ShellTest, OnServiceProtocolSetAssetBundlePathWorks) {
Settings settings = CreateSettingsForFixture();
std::unique_ptr<Shell> shell = CreateShell(settings);

View File

@ -37,6 +37,8 @@
namespace flutter {
static constexpr int64_t kFlutterImplicitViewId = 0ll;
static fml::jni::ScopedJavaGlobalRef<jclass>* g_flutter_callback_info_class =
nullptr;
@ -338,7 +340,8 @@ static void SetViewportMetrics(JNIEnv* env,
0, // Display ID
};
ANDROID_SHELL_HOLDER->GetPlatformView()->SetViewportMetrics(metrics);
ANDROID_SHELL_HOLDER->GetPlatformView()->SetViewportMetrics(
kFlutterImplicitViewId, metrics);
}
static void UpdateDisplayMetrics(JNIEnv* env,

View File

@ -38,6 +38,8 @@
#import "flutter/shell/platform/darwin/ios/rendering_api_selection.h"
#include "flutter/shell/profiling/sampling_profiler.h"
static constexpr int64_t kFlutterImplicitViewId = 0ll;
/// Inheriting ThreadConfigurer and use iOS platform thread API to configure the thread priorities
/// Using iOS platform thread API to configure thread priority
static void IOSPlatformThreadConfigSetter(const fml::Thread::ThreadConfig& config) {
@ -308,7 +310,7 @@ static constexpr int kNumProfilerSamplesPerSec = 5;
if (!self.platformView) {
return;
}
self.platformView->SetViewportMetrics(viewportMetrics);
self.platformView->SetViewportMetrics(kFlutterImplicitViewId, viewportMetrics);
}
- (void)dispatchPointerDataPacket:(std::unique_ptr<flutter::PointerDataPacket>)packet {

View File

@ -24,7 +24,7 @@ class FakeDelegate : public PlatformView::Delegate {
void OnPlatformViewDestroyed() override {}
void OnPlatformViewScheduleFrame() override {}
void OnPlatformViewSetNextFrameCallback(const fml::closure& closure) override {}
void OnPlatformViewSetViewportMetrics(const ViewportMetrics& metrics) override {}
void OnPlatformViewSetViewportMetrics(int64_t view_id, const ViewportMetrics& metrics) override {}
const flutter::Settings& OnPlatformViewGetSettings() const override { return settings_; }
void OnPlatformViewDispatchPlatformMessage(std::unique_ptr<PlatformMessage> message) override {}
void OnPlatformViewDispatchPointerDataPacket(std::unique_ptr<PointerDataPacket> packet) override {

View File

@ -93,7 +93,7 @@ class FlutterPlatformViewsTestMockPlatformViewDelegate : public PlatformView::De
void OnPlatformViewDestroyed() override {}
void OnPlatformViewScheduleFrame() override {}
void OnPlatformViewSetNextFrameCallback(const fml::closure& closure) override {}
void OnPlatformViewSetViewportMetrics(const ViewportMetrics& metrics) override {}
void OnPlatformViewSetViewportMetrics(int64_t view_id, const ViewportMetrics& metrics) override {}
const flutter::Settings& OnPlatformViewGetSettings() const override { return settings_; }
void OnPlatformViewDispatchPlatformMessage(std::unique_ptr<PlatformMessage> message) override {}
void OnPlatformViewDispatchPointerDataPacket(std::unique_ptr<PointerDataPacket> packet) override {

View File

@ -77,7 +77,7 @@ class MockDelegate : public PlatformView::Delegate {
void OnPlatformViewDestroyed() override {}
void OnPlatformViewScheduleFrame() override {}
void OnPlatformViewSetNextFrameCallback(const fml::closure& closure) override {}
void OnPlatformViewSetViewportMetrics(const ViewportMetrics& metrics) override {}
void OnPlatformViewSetViewportMetrics(int64_t view_id, const ViewportMetrics& metrics) override {}
const flutter::Settings& OnPlatformViewGetSettings() const override { return settings_; }
void OnPlatformViewDispatchPlatformMessage(std::unique_ptr<PlatformMessage> message) override {}
void OnPlatformViewDispatchPointerDataPacket(std::unique_ptr<PointerDataPacket> packet) override {

View File

@ -83,6 +83,8 @@ extern const intptr_t kPlatformStrongDillSize;
const int32_t kFlutterSemanticsNodeIdBatchEnd = -1;
const int32_t kFlutterSemanticsCustomActionIdBatchEnd = -1;
static constexpr int64_t kFlutterImplicitViewId = 0;
// A message channel to send platform-independent FlutterKeyData to the
// framework.
//
@ -2186,6 +2188,8 @@ FlutterEngineResult FlutterEngineSendWindowMetricsEvent(
if (engine == nullptr || flutter_metrics == nullptr) {
return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid.");
}
// TODO(dkwingsmt): Use a real view ID when multiview is supported.
int64_t view_id = kFlutterImplicitViewId;
flutter::ViewportMetrics metrics;
@ -2227,7 +2231,7 @@ FlutterEngineResult FlutterEngineSendWindowMetricsEvent(
}
return reinterpret_cast<flutter::EmbedderEngine*>(engine)->SetViewportMetrics(
metrics)
view_id, metrics)
? kSuccess
: LOG_EMBEDDER_ERROR(kInvalidArguments,
"Viewport metrics were invalid.");

View File

@ -100,6 +100,7 @@ bool EmbedderEngine::NotifyDestroyed() {
}
bool EmbedderEngine::SetViewportMetrics(
int64_t view_id,
const flutter::ViewportMetrics& metrics) {
if (!IsValid()) {
return false;
@ -109,7 +110,7 @@ bool EmbedderEngine::SetViewportMetrics(
if (!platform_view) {
return false;
}
platform_view->SetViewportMetrics(metrics);
platform_view->SetViewportMetrics(view_id, metrics);
return true;
}

View File

@ -48,7 +48,8 @@ class EmbedderEngine {
bool IsValid() const;
bool SetViewportMetrics(const flutter::ViewportMetrics& metrics);
bool SetViewportMetrics(int64_t view_id,
const flutter::ViewportMetrics& metrics);
bool DispatchPointerDataPacket(
std::unique_ptr<flutter::PointerDataPacket> packet);

View File

@ -21,8 +21,8 @@ class MockDelegate : public PlatformView::Delegate {
MOCK_METHOD0(OnPlatformViewScheduleFrame, void());
MOCK_METHOD1(OnPlatformViewSetNextFrameCallback,
void(const fml::closure& closure));
MOCK_METHOD1(OnPlatformViewSetViewportMetrics,
void(const ViewportMetrics& metrics));
MOCK_METHOD2(OnPlatformViewSetViewportMetrics,
void(int64_t view_id, const ViewportMetrics& metrics));
MOCK_METHOD1(OnPlatformViewDispatchPlatformMessage,
void(std::unique_ptr<PlatformMessage> message));
MOCK_METHOD1(OnPlatformViewDispatchPointerDataPacket,

View File

@ -8,6 +8,8 @@
namespace flutter_runner {
static constexpr int64_t kFlutterImplicitViewId = 0ll;
FlatlandPlatformView::FlatlandPlatformView(
flutter::PlatformView::Delegate& delegate,
flutter::TaskRunners task_runners,
@ -84,8 +86,7 @@ void FlatlandPlatformView::OnGetLayout(
}
float pixel_ratio = view_pixel_ratio_ ? *view_pixel_ratio_ : 1.0f;
SetViewportMetrics({
flutter::ViewportMetrics metrics{
pixel_ratio, // device_pixel_ratio
std::round(view_logical_size_.value()[0] *
pixel_ratio), // physical_width
@ -108,7 +109,8 @@ void FlatlandPlatformView::OnGetLayout(
{}, // p_physical_display_features_type
{}, // p_physical_display_features_state
0, // p_display_id
});
};
SetViewportMetrics(kFlutterImplicitViewId, metrics);
parent_viewport_watcher_->GetLayout(
fit::bind_member(this, &FlatlandPlatformView::OnGetLayout));

View File

@ -8,6 +8,8 @@
namespace flutter_runner {
static constexpr int64_t kFlutterImplicitViewId = 0ll;
GfxPlatformView::GfxPlatformView(
flutter::PlatformView::Delegate& delegate,
flutter::TaskRunners task_runners,
@ -213,7 +215,7 @@ void GfxPlatformView::OnScenicEvent(
metrics_changed) {
const float pixel_ratio = *view_pixel_ratio_;
const std::array<float, 2> logical_size = *view_logical_size_;
SetViewportMetrics({
flutter::ViewportMetrics metrics{
pixel_ratio, // device_pixel_ratio
std::round(logical_size[0] * pixel_ratio), // physical_width
std::round(logical_size[1] * pixel_ratio), // physical_height
@ -234,7 +236,8 @@ void GfxPlatformView::OnScenicEvent(
{}, // p_physical_display_features_type
{}, // p_physical_display_features_state
0, // pdisplay_id
});
};
SetViewportMetrics(kFlutterImplicitViewId, metrics);
}
}

View File

@ -90,6 +90,7 @@ class MockPlatformViewDelegate : public flutter::PlatformView::Delegate {
void OnPlatformViewSetNextFrameCallback(const fml::closure& closure) {}
// |flutter::PlatformView::Delegate|
void OnPlatformViewSetViewportMetrics(
int64_t view_id,
const flutter::ViewportMetrics& metrics) {
metrics_ = metrics;
}

View File

@ -89,6 +89,7 @@ class MockPlatformViewDelegate : public flutter::PlatformView::Delegate {
void OnPlatformViewSetNextFrameCallback(const fml::closure& closure) {}
// |flutter::PlatformView::Delegate|
void OnPlatformViewSetViewportMetrics(
int64_t view_id,
const flutter::ViewportMetrics& metrics) {
metrics_ = metrics;
}

View File

@ -39,6 +39,8 @@
namespace flutter {
static constexpr int64_t kImplicitViewId = 0ll;
class TesterExternalViewEmbedder : public ExternalViewEmbedder {
// |ExternalViewEmbedder|
DlCanvas* GetRootCanvas() override { return nullptr; }
@ -353,7 +355,7 @@ int RunTester(const flutter::Settings& settings,
metrics.physical_width = physical_width;
metrics.physical_height = physical_height;
metrics.display_id = 0;
shell->GetPlatformView()->SetViewportMetrics(metrics);
shell->GetPlatformView()->SetViewportMetrics(kImplicitViewId, metrics);
// Run the message loop and wait for the script to do its thing.
fml::MessageLoop::GetCurrent().Run();