diff --git a/lib/ui/window/platform_configuration.cc b/lib/ui/window/platform_configuration.cc index b1cd11fad30e7..fe6ff03d62b69 100644 --- a/lib/ui/window/platform_configuration.cc +++ b/lib/ui/window/platform_configuration.cc @@ -308,6 +308,15 @@ void PlatformConfiguration::ReportTimings(std::vector 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) { diff --git a/lib/ui/window/platform_configuration.h b/lib/ui/window/platform_configuration.h index c03f38194bf50..9226b457d07e8 100644 --- a/lib/ui/window/platform_configuration.h +++ b/lib/ui/window/platform_configuration.h @@ -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 diff --git a/lib/ui/window/platform_configuration_unittests.cc b/lib/ui/window/platform_configuration_unittests.cc index e89a5cc7d381c..017055a41d91e 100644 --- a/lib/ui/window/platform_configuration_unittests.cc +++ b/lib/ui/window/platform_configuration_unittests.cc @@ -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(); 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(); 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(); + + 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 = 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(); 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(); 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(); std::vector 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(); auto finish = [message_latch](Dart_NativeArguments args) { // call needs to happen on the UI thread. diff --git a/runtime/runtime_controller.cc b/runtime/runtime_controller.cc index 4837c5946c532..751fa696a5719 100644 --- a/runtime/runtime_controller.cc +++ b/runtime/runtime_controller.cc @@ -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::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; diff --git a/runtime/runtime_controller.h b/runtime/runtime_controller.h index 1df085262f605..aaef6da631694 100644 --- a/runtime/runtime_controller.h +++ b/runtime/runtime_controller.h @@ -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. diff --git a/shell/common/engine.cc b/shell/common/engine.cc index 2c0b22d1863f8..33d8e52baf40d 100644 --- a/shell/common/engine.cc +++ b/shell/common/engine.cc @@ -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(); } diff --git a/shell/common/engine.h b/shell/common/engine.h index 1890589729b04..ca258ac392159 100644 --- a/shell/common/engine.h +++ b/shell/common/engine.h @@ -677,16 +677,16 @@ class Engine final : public RuntimeDelegate, PointerDataDispatcher::Delegate { std::optional 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 diff --git a/shell/common/engine_unittests.cc b/shell/common/engine_unittests.cc index 5011f266557c8..d1a7d24d39cbc 100644 --- a/shell/common/engine_unittests.cc +++ b/shell/common/engine_unittests.cc @@ -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( /*delegate=*/delegate_, /*dispatcher_maker=*/dispatcher_maker_, diff --git a/shell/common/platform_view.cc b/shell/common/platform_view.cc index 7cb0b091d5bcd..77a33bfb76e2a 100644 --- a/shell/common/platform_view.cc +++ b/shell/common/platform_view.cc @@ -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() { diff --git a/shell/common/platform_view.h b/shell/common/platform_view.h index 9ec848e34568d..e6c7dab924e5c 100644 --- a/shell/common/platform_view.h +++ b/shell/common/platform_view.h @@ -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 diff --git a/shell/common/shell.cc b/shell/common/shell.cc index 859a2668c3762..82b3b831ebb68 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -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); } }); diff --git a/shell/common/shell.h b/shell/common/shell.h index d913c3e9c84a6..6c104f8558f4a 100644 --- a/shell/common/shell.h +++ b/shell/common/shell.h @@ -544,6 +544,7 @@ class Shell final : public PlatformView::Delegate, // |PlatformView::Delegate| void OnPlatformViewSetViewportMetrics( + int64_t view_id, const ViewportMetrics& metrics) override; // |PlatformView::Delegate| diff --git a/shell/common/shell_test.cc b/shell/common/shell_test.cc index 5e5d38d2b2b94..1ea8c7f0b3248 100644 --- a/shell/common/shell_test.cc +++ b/shell/common/shell_test.cc @@ -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); diff --git a/shell/common/shell_unittests.cc b/shell/common/shell_unittests.cc index 18dec36314c68..4c4c85f8b768b 100644 --- a/shell/common/shell_unittests.cc +++ b/shell/common/shell_unittests.cc @@ -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 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(expected_size.width()), static_cast(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(origin_size.width()), static_cast(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(new_size.width()), - static_cast(new_size.height()), 22, 0}); + kImplicitViewId, {1.0, static_cast(new_size.width()), + static_cast(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 = 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 = CreateShell(settings); diff --git a/shell/platform/android/platform_view_android_jni_impl.cc b/shell/platform/android/platform_view_android_jni_impl.cc index c4580bc0562d7..72abd446061b0 100644 --- a/shell/platform/android/platform_view_android_jni_impl.cc +++ b/shell/platform/android/platform_view_android_jni_impl.cc @@ -37,6 +37,8 @@ namespace flutter { +static constexpr int64_t kFlutterImplicitViewId = 0ll; + static fml::jni::ScopedJavaGlobalRef* 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, diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm index 85e1f7d4d5e8e..70192b39a3508 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm @@ -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 @@ - (void)updateViewportMetrics:(flutter::ViewportMetrics)viewportMetrics { if (!self.platformView) { return; } - self.platformView->SetViewportMetrics(viewportMetrics); + self.platformView->SetViewportMetrics(kFlutterImplicitViewId, viewportMetrics); } - (void)dispatchPointerDataPacket:(std::unique_ptr)packet { diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEnginePlatformViewTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterEnginePlatformViewTest.mm index e4341a065c2af..0b5526a5341a2 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEnginePlatformViewTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEnginePlatformViewTest.mm @@ -24,7 +24,7 @@ void OnPlatformViewCreated(std::unique_ptr surface) override {} 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 message) override {} void OnPlatformViewDispatchPointerDataPacket(std::unique_ptr packet) override { diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm index 974eb31de9f44..bba450217747a 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm @@ -93,7 +93,7 @@ void OnPlatformViewCreated(std::unique_ptr surface) override {} 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 message) override {} void OnPlatformViewDispatchPointerDataPacket(std::unique_ptr packet) override { diff --git a/shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm b/shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm index 40995c9111284..283d4fe02decd 100644 --- a/shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm +++ b/shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm @@ -77,7 +77,7 @@ void OnPlatformViewCreated(std::unique_ptr surface) override {} 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 message) override {} void OnPlatformViewDispatchPointerDataPacket(std::unique_ptr packet) override { diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index c9d1ce9866744..008ea576482d5 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -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(engine)->SetViewportMetrics( - metrics) + view_id, metrics) ? kSuccess : LOG_EMBEDDER_ERROR(kInvalidArguments, "Viewport metrics were invalid."); diff --git a/shell/platform/embedder/embedder_engine.cc b/shell/platform/embedder/embedder_engine.cc index cc4da738f72fc..b34da8a287f4e 100644 --- a/shell/platform/embedder/embedder_engine.cc +++ b/shell/platform/embedder/embedder_engine.cc @@ -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; } diff --git a/shell/platform/embedder/embedder_engine.h b/shell/platform/embedder/embedder_engine.h index 60d33ba76e652..a587eeb3eaa74 100644 --- a/shell/platform/embedder/embedder_engine.h +++ b/shell/platform/embedder/embedder_engine.h @@ -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 packet); diff --git a/shell/platform/embedder/platform_view_embedder_unittests.cc b/shell/platform/embedder/platform_view_embedder_unittests.cc index 3e795f1fb530f..d22dc030e7292 100644 --- a/shell/platform/embedder/platform_view_embedder_unittests.cc +++ b/shell/platform/embedder/platform_view_embedder_unittests.cc @@ -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 message)); MOCK_METHOD1(OnPlatformViewDispatchPointerDataPacket, diff --git a/shell/platform/fuchsia/flutter/flatland_platform_view.cc b/shell/platform/fuchsia/flutter/flatland_platform_view.cc index cbadf9d47b6e0..39febd8c6db64 100644 --- a/shell/platform/fuchsia/flutter/flatland_platform_view.cc +++ b/shell/platform/fuchsia/flutter/flatland_platform_view.cc @@ -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)); diff --git a/shell/platform/fuchsia/flutter/gfx_platform_view.cc b/shell/platform/fuchsia/flutter/gfx_platform_view.cc index df0e9906caf50..ddb0ce029e2a1 100644 --- a/shell/platform/fuchsia/flutter/gfx_platform_view.cc +++ b/shell/platform/fuchsia/flutter/gfx_platform_view.cc @@ -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 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); } } diff --git a/shell/platform/fuchsia/flutter/platform_view_unittest.cc b/shell/platform/fuchsia/flutter/platform_view_unittest.cc index c0aa42e0a5dbf..54a9c7a593f3b 100644 --- a/shell/platform/fuchsia/flutter/platform_view_unittest.cc +++ b/shell/platform/fuchsia/flutter/platform_view_unittest.cc @@ -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; } diff --git a/shell/platform/fuchsia/flutter/tests/flatland_platform_view_unittest.cc b/shell/platform/fuchsia/flutter/tests/flatland_platform_view_unittest.cc index 78f6f9588958a..ff4347015eb49 100644 --- a/shell/platform/fuchsia/flutter/tests/flatland_platform_view_unittest.cc +++ b/shell/platform/fuchsia/flutter/tests/flatland_platform_view_unittest.cc @@ -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; } diff --git a/shell/testing/tester_main.cc b/shell/testing/tester_main.cc index 342b4ea7aebe9..3bb48710c8bb1 100644 --- a/shell/testing/tester_main.cc +++ b/shell/testing/tester_main.cc @@ -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();