diff --git a/content/web_test/browser/web_test_content_browser_client.cc b/content/web_test/browser/web_test_content_browser_client.cc index e0f55d75e7f39..4bb1004a8a06d 100644 --- a/content/web_test/browser/web_test_content_browser_client.cc +++ b/content/web_test/browser/web_test_content_browser_client.cc @@ -366,6 +366,12 @@ void WebTestContentBrowserClient::ExposeInterfacesToRenderer( base::BindRepeating(&WebTestContentBrowserClient::BindWebTestControlHost, base::Unretained(this), render_process_host->GetID())); + + registry->AddInterface( + base::BindRepeating( + &WebTestContentBrowserClient::BindNonAssociatedWebTestControlHost, + base::Unretained(this)), + ui_task_runner); } void WebTestContentBrowserClient::BindPermissionAutomation( @@ -657,6 +663,14 @@ void WebTestContentBrowserClient::BindWebTestControlHost( render_process_id, std::move(receiver)); } +void WebTestContentBrowserClient::BindNonAssociatedWebTestControlHost( + mojo::PendingReceiver<mojom::NonAssociatedWebTestControlHost> receiver) { + if (WebTestControlHost::Get()) { + WebTestControlHost::Get()->BindNonAssociatedWebTestControlHost( + std::move(receiver)); + } +} + #if BUILDFLAG(IS_WIN) bool WebTestContentBrowserClient::PreSpawnChild( sandbox::TargetConfig* config, diff --git a/content/web_test/browser/web_test_content_browser_client.h b/content/web_test/browser/web_test_content_browser_client.h index e6b2df55b872f..cb46d458e9713 100644 --- a/content/web_test/browser/web_test_content_browser_client.h +++ b/content/web_test/browser/web_test_content_browser_client.h @@ -160,6 +160,9 @@ class WebTestContentBrowserClient : public ShellContentBrowserClient { int render_process_id, mojo::PendingAssociatedReceiver<mojom::WebTestControlHost> receiver); + void BindNonAssociatedWebTestControlHost( + mojo::PendingReceiver<mojom::NonAssociatedWebTestControlHost> receiver); + bool block_popups_ = true; bool screen_orientation_changed_ = false; diff --git a/content/web_test/browser/web_test_control_host.cc b/content/web_test/browser/web_test_control_host.cc index 962a792c08d71..96297e20b0348 100644 --- a/content/web_test/browser/web_test_control_host.cc +++ b/content/web_test/browser/web_test_control_host.cc @@ -685,6 +685,7 @@ bool WebTestControlHost::ResetBrowserAfterWebTest() { expected_pixel_hash_.clear(); test_url_ = GURL(); prefs_ = blink::web_pref::WebPreferences(); + lcpp_hint_ = absl::nullopt; should_override_prefs_ = false; WebTestContentBrowserClient::Get()->SetPopupBlockingEnabled(true); WebTestContentBrowserClient::Get()->ResetMockClipboardHosts(); @@ -1065,6 +1066,13 @@ void WebTestControlHost::RenderViewDeleted(RenderViewHost* render_view_host) { main_window_render_view_hosts_.erase(render_view_host); } +void WebTestControlHost::DidStartNavigation( + NavigationHandle* navigation_handle) { + if (lcpp_hint_) { + navigation_handle->SetLCPPNavigationHint(lcpp_hint_.value()); + } +} + void WebTestControlHost::ReadyToCommitNavigation( NavigationHandle* navigation_handle) { NavigationRequest* request = NavigationRequest::From(navigation_handle); @@ -1783,6 +1791,11 @@ void WebTestControlHost::DisableAutoResize(const gfx::Size& new_size) { main_window_->ResizeWebContentForTests(new_size); } +void WebTestControlHost::SetLCPPNavigationHint( + blink::mojom::LCPCriticalPathPredictorNavigationTimeHintPtr hint) { + lcpp_hint_ = *hint.get(); +} + void WebTestControlHost::GoToOffset(int offset) { main_window_->GoBackOrForward(offset); } @@ -1844,6 +1857,10 @@ void WebTestControlHost::PrepareRendererForNextWebTest() { // // Note: this navigation might happen in a new process, depending on the // COOP policy of the previous document. + + // Avoid sending LCPP hint on the about:blank navigation. + lcpp_hint_ = absl::nullopt; + NavigationController::LoadURLParams params((GURL(kAboutBlankResetWebTest))); params.transition_type = ui::PageTransitionFromInt(ui::PAGE_TRANSITION_TYPED); params.should_clear_history_list = true; @@ -2001,6 +2018,11 @@ void WebTestControlHost::BindWebTestControlHostForRenderer( receiver_bindings_.Add(this, std::move(receiver), render_process_id); } +void WebTestControlHost::BindNonAssociatedWebTestControlHost( + mojo::PendingReceiver<mojom::NonAssociatedWebTestControlHost> receiver) { + non_associated_receiver_bindings_.Add(this, std::move(receiver)); +} + mojo::AssociatedRemote<mojom::WebTestRenderFrame>& WebTestControlHost::GetWebTestRenderFrameRemote(RenderFrameHost* frame) { GlobalRenderFrameHostId key(frame->GetProcess()->GetID(), diff --git a/content/web_test/browser/web_test_control_host.h b/content/web_test/browser/web_test_control_host.h index b0efbb4fe321a..1876233fc4cc7 100644 --- a/content/web_test/browser/web_test_control_host.h +++ b/content/web_test/browser/web_test_control_host.h @@ -38,6 +38,7 @@ #include "mojo/public/cpp/bindings/associated_receiver_set.h" #include "mojo/public/cpp/bindings/associated_remote.h" #include "third_party/blink/public/common/web_preferences/web_preferences.h" +#include "third_party/blink/public/mojom/lcp_critical_path_predictor/lcp_critical_path_predictor.mojom.h" #include "ui/gfx/geometry/size.h" class SkBitmap; @@ -114,7 +115,8 @@ class WebTestResultPrinter { class WebTestControlHost : public WebContentsObserver, public RenderProcessHostObserver, public GpuDataManagerObserver, - public mojom::WebTestControlHost { + public mojom::WebTestControlHost, + public mojom::NonAssociatedWebTestControlHost { public: static WebTestControlHost* Get(); @@ -153,6 +155,9 @@ class WebTestControlHost : public WebContentsObserver, int render_process_id, mojo::PendingAssociatedReceiver<mojom::WebTestControlHost> receiver); + void BindNonAssociatedWebTestControlHost( + mojo::PendingReceiver<mojom::NonAssociatedWebTestControlHost> receiver); + const WebTestRuntimeFlags& web_test_runtime_flags() const { return web_test_runtime_flags_; } @@ -190,6 +195,7 @@ class WebTestControlHost : public WebContentsObserver, void RenderFrameHostChanged(RenderFrameHost* old_host, RenderFrameHost* new_host) override; void RenderViewDeleted(RenderViewHost* render_view_host) override; + void DidStartNavigation(NavigationHandle* navigation_handle) override; void ReadyToCommitNavigation(NavigationHandle* navigation_handle) override; void DidFinishNavigation(NavigationHandle* navigation) override; @@ -261,6 +267,9 @@ class WebTestControlHost : public WebContentsObserver, void EnableAutoResize(const gfx::Size& min_size, const gfx::Size& max_size) override; void DisableAutoResize(const gfx::Size& new_size) override; + void SetLCPPNavigationHint( + blink::mojom::LCPCriticalPathPredictorNavigationTimeHintPtr hint) + override; void DiscardMainWindow(); // Closes all windows opened by the test. This is every window but the main @@ -358,6 +367,14 @@ class WebTestControlHost : public WebContentsObserver, bool should_override_prefs_ = false; blink::web_pref::WebPreferences prefs_; + // When populated, simulate a LCPP backend by sending this hint data along + // navigations (typically reload of the same page). + // This is set by the LCPP web_tests via + // NonAssociatedWebTestControlHost::SetLCPPNavigationHint mojom interface. + // This is reset before switching to the next test page. + absl::optional<blink::mojom::LCPCriticalPathPredictorNavigationTimeHint> + lcpp_hint_; + bool crash_when_leak_found_ = false; std::unique_ptr<LeakDetector> leak_detector_; @@ -426,6 +443,9 @@ class WebTestControlHost : public WebContentsObserver, int /*render_process_id*/> receiver_bindings_; + mojo::ReceiverSet<mojom::NonAssociatedWebTestControlHost> + non_associated_receiver_bindings_; + base::ScopedTempDir writable_directory_for_tests_; enum class NextPointerLockAction { diff --git a/content/web_test/common/web_test.mojom b/content/web_test/common/web_test.mojom index ca2e1d509497b..6b07671be92c3 100644 --- a/content/web_test/common/web_test.mojom +++ b/content/web_test/common/web_test.mojom @@ -8,6 +8,7 @@ import "mojo/public/mojom/base/file_path.mojom"; import "mojo/public/mojom/base/string16.mojom"; import "mojo/public/mojom/base/values.mojom"; import "skia/public/mojom/bitmap.mojom"; +import "third_party/blink/public/mojom/lcp_critical_path_predictor/lcp_critical_path_predictor.mojom"; // presubmit: ignore-long-line import "third_party/blink/public/mojom/permissions/permission_status.mojom"; import "third_party/blink/public/mojom/webpreferences/web_preferences.mojom"; import "ui/gfx/geometry/mojom/geometry.mojom"; @@ -338,3 +339,15 @@ interface WebTestControlHost { // Disable Auto Resize mode, resizing the contents to `new_size`. DisableAutoResize(gfx.mojom.Size new_size); }; + +// Web test messages sent from the renderer process to the browser. +// This provides a message pipe from each renderer to the global +// WebTestControlHost in the browser. +// This is very similar to WebTestControlHost, but the interface is not +// associated to the legacy IPC channel, so can be used from mojo JS binding +// directly. +interface NonAssociatedWebTestControlHost { + // Provide the specified LCPP navigation time hint to next navigation. + SetLCPPNavigationHint( + blink.mojom.LCPCriticalPathPredictorNavigationTimeHint hint); +}; diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 9c691b0936ac1..a3fb39396ebf1 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations @@ -6495,6 +6495,9 @@ crbug.com/626703 virtual/css-highlight-overlay-painting/external/wpt/css/css-hig # Gardening 2023-07-06 crbug.com/1462500 [ Win ] media/picture-in-picture/picture-in-picture-interstitial-sizing.html [ Failure Pass ] +# Until LCPP is unflagged, LCPP tests run in virtual tests. +crbug.com/1419756 http/tests/lcp_critical_path_predictor/* [ Crash ] + # Gardnener 2023-07-07 crbug.com/1462462 http/tests/history/replacestate-post-to-get-2.html [ Failure Pass Timeout ] diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites index a7e11d7ac3df2..d611a438d0a34 100644 --- a/third_party/blink/web_tests/VirtualTestSuites +++ b/third_party/blink/web_tests/VirtualTestSuites @@ -2230,5 +2230,24 @@ "args": ["--enable-features=ServiceWorkerStaticRouter"], "expires": "Jul 14, 2024", "owners": ["yyanagisawa@chromium.org", "sisidovski@chromium.org"] + }, + { + "prefix": "lcpp", + "platforms": [ + "Linux", + "Mac", + "Win" + ], + "bases": [ + "http/tests/lcp_critical_path_predictor" + ], + "args": [ + "--enable-features=LCPCriticalPathPredictor" + ], + "expires": "Jul 10, 2024", + "owners": [ + "chikamune@chromium.org", + "kouhei@chromium.org" + ] } ] diff --git a/third_party/blink/web_tests/http/tests/lcp_critical_path_predictor/prioritize_lcp_image.php b/third_party/blink/web_tests/http/tests/lcp_critical_path_predictor/prioritize_lcp_image.php new file mode 100644 index 0000000000000..5d60f585513cb --- /dev/null +++ b/third_party/blink/web_tests/http/tests/lcp_critical_path_predictor/prioritize_lcp_image.php @@ -0,0 +1,56 @@ +<!doctype html> +<script src="/priorities/resources/common.js"></script> +<script type=module> +import {mojo} from "/gen/mojo/public/js/bindings.js"; +import {NonAssociatedWebTestControlHostRemote} from "/gen/content/web_test/common/web_test.mojom.m.js"; +import {ByteString} from "/gen/mojo/public/mojom/base/byte_string.mojom.m.js"; +import {LCPCriticalPathPredictorNavigationTimeHint} from "/gen/third_party/blink/public/mojom/lcp_critical_path_predictor/lcp_critical_path_predictor.mojom.m.js"; + +if (!window.testRunner) { + console.log("This test requires window.testRunner.") +} + +testRunner.dumpAsText(); +testRunner.waitUntilDone(); +if (window.location.search != "?start") { + const hint = new LCPCriticalPathPredictorNavigationTimeHint(); + + const resp = await fetch("/gen/third_party/blink/renderer/core/lcp_critical_path_predictor/test_proto/lcp_image_id.pb"); + + const bytes = new ByteString; + bytes.data = new Uint8Array(await resp.arrayBuffer()); + + hint.lcpElementLocators = [bytes]; + + const web_test_control_host_remote = new NonAssociatedWebTestControlHostRemote(); + web_test_control_host_remote.$.bindNewPipeAndPassReceiver().bindInBrowser('process'); + web_test_control_host_remote.setLCPPNavigationHint(hint); + + window.location.search = '?start'; +} +</script> +<?php +// Do not output the HTML below this PHP block until the test is reloaded with +// "?start" to avoid it being picked up by the HTMLPreloadScanner. +if ($_SERVER['QUERY_STRING'] != "start") + exit; +?> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> + promise_test(async t => { + const url = new URL('/resources/square.png', location).toString(); + const hint_matched_img_priority = await internals.getInitialResourcePriority(url, document); + + assert_equals(hint_matched_img_priority, kVeryHigh); + }, "Ensure LCPP hinted images were loaded with VeryHigh priority.") + + promise_test(async t => { + const url = new URL('/resources/square100.png', location).toString(); + const hint_matched_img_priority = await internals.getInitialResourcePriority(url, document); + + assert_equals(hint_matched_img_priority, kMedium); + }, "Ensure non-LCPP hinted images were loaded unaffected with Medium priority.") +</script> +<img src="/resources/square.png" id="lcp_image"> +<img src="/resources/square100.png"> diff --git a/third_party/blink/web_tests/virtual/lcpp/README.md b/third_party/blink/web_tests/virtual/lcpp/README.md new file mode 100644 index 0000000000000..6cf05d65812d7 --- /dev/null +++ b/third_party/blink/web_tests/virtual/lcpp/README.md @@ -0,0 +1,2 @@ +A virtual test suite for LCP Critical Path Predictor. +See crbug.com/1419756