0

[webui] Propagate WebUI bundled code cache to renderers on process-lock

This CL propagates the WebUI resource URL to code cache resource ID
mapping to renderers.

These mappings are only set to renderers locked to WebUI URLs for
which WebUIBundledCodeCache is enabled. Only chrome://resource code
cache mappings are currently supported.

Bug: 378504039, 378504631, 402625343
Change-Id: I1e6ef2c31a65369254c6017c78d6b22dbb7caedb
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6281247
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
Reviewed-by: Demetrios Papadopoulos <dpapad@chromium.org>
Reviewed-by: Alex Moshchuk <alexmos@chromium.org>
Commit-Queue: Tom Lukaszewicz <tluk@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1431881}
This commit is contained in:
Thomas Lukaszewicz
2025-03-12 18:53:36 -07:00
committed by Chromium LUCI CQ
parent d375683e4b
commit a8a6984f2b
16 changed files with 207 additions and 0 deletions

@ -3816,6 +3816,22 @@ std::string ChromeContentBrowserClient::GetWebUIHostnameForCodeCacheMetrics(
#endif
}
bool ChromeContentBrowserClient::IsWebUIBundledCodeCachingEnabled(
const GURL& webui_lock_url) const {
// Enable bundled code caching only for top-chrome WebUI hosts.
return base::FeatureList::IsEnabled(features::kWebUIBundledCodeCache) &&
IsTopChromeWebUIURL(webui_lock_url);
}
base::flat_map<GURL, int>
ChromeContentBrowserClient::GetWebUIResourceUrlToCodeCacheMap() const {
#if !BUILDFLAG(IS_ANDROID)
return webui::GetWebUIResourceUrlToCodeCacheMap();
#else
return ContentBrowserClient::GetWebUIResourceUrlToCodeCacheMap();
#endif
}
void ChromeContentBrowserClient::AllowCertificateError(
content::WebContents* web_contents,
int cert_error,

@ -451,6 +451,9 @@ class ChromeContentBrowserClient : public content::ContentBrowserClient {
content::BrowserContext* context) override;
std::string GetWebUIHostnameForCodeCacheMetrics(
const GURL& webui_url) const override;
bool IsWebUIBundledCodeCachingEnabled(
const GURL& webui_lock_url) const override;
base::flat_map<GURL, int> GetWebUIResourceUrlToCodeCacheMap() const override;
void AllowCertificateError(
content::WebContents* web_contents,
int cert_error,

@ -1864,6 +1864,7 @@ static_library("ui") {
"//ui/color/dynamic_color",
"//ui/events",
"//ui/web_dialogs",
"//ui/webui:buildflags",
"//ui/webui/resources/cr_components/app_management:mojo_bindings",
"//ui/webui/resources/cr_components/help_bubble:mojo_bindings",
"//ui/webui/resources/cr_components/history:mojo_bindings",
@ -5697,6 +5698,13 @@ static_library("ui") {
if (enable_reporting) {
deps += [ "//components/tpcd/enterprise_reporting" ]
}
if (enable_webui_generate_code_cache) {
deps += [
"//ui/webui:buildflags",
"//ui/webui/resources:code_cache_resources",
]
}
}
# These are the dependencies for the "ui" target that are outside of

@ -6,14 +6,23 @@
#include "base/containers/fixed_flat_map.h"
#include "base/containers/map_util.h"
#include "base/strings/strcat.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/webui/top_chrome/webui_url_utils.h"
#include "chrome/common/webui_url_constants.h"
#include "content/public/common/url_constants.h"
#include "content/public/common/url_utils.h"
#include "ui/native_theme/native_theme.h"
#include "ui/views/widget/widget.h"
#include "ui/webui/buildflags.h"
#if BUILDFLAG(ENABLE_WEBUI_GENERATE_CODE_CACHE)
#include "ui/webui/resources/grit/webui_code_cache_resources_map.h"
#endif // BUILDFLAG(ENABLE_WEBUI_GENERATE_CODE_CACHE)
namespace webui {
@ -129,4 +138,42 @@ std::string GetWebUIHostnameForCodeCacheMetrics(const GURL& webui_url) {
return hostname ? std::string(*hostname) : std::string();
}
void AppendWebUIResourceURLToCodeCachePairs(
std::string_view scheme,
std::string_view host,
base::span<const ResourcePath> code_cache_resources,
std::vector<std::pair<GURL, int>>& resource_code_cache_pairs) {
for (const ResourcePath& code_cache_resource : code_cache_resources) {
std::string_view code_cache_path = code_cache_resource.path;
// Stripping the .code_cache suffix from code cache resource paths
// yields the corresponding resource paths.
constexpr std::string_view kCodeCacheResourceSuffix = ".code_cache";
DCHECK(code_cache_path.ends_with(kCodeCacheResourceSuffix));
std::string_view resource_path = code_cache_path.substr(
0, code_cache_path.size() - kCodeCacheResourceSuffix.size());
resource_code_cache_pairs.emplace_back(
GURL(base::StrCat({scheme, "://", host, "/", resource_path})),
code_cache_resource.id);
}
}
base::flat_map<GURL, int> GetWebUIResourceUrlToCodeCacheMap() {
// Collects relevant code cache pairs used to initialize the requested map.
std::vector<std::pair<GURL, int>> url_to_code_cache_pairs;
#if BUILDFLAG(ENABLE_WEBUI_GENERATE_CODE_CACHE)
// Currently only shared resources are supported.
AppendWebUIResourceURLToCodeCachePairs(
content::kChromeUIScheme, content::kChromeUIResourcesHost,
kWebuiCodeCacheResources, url_to_code_cache_pairs);
AppendWebUIResourceURLToCodeCachePairs(
content::kChromeUIUntrustedScheme, content::kChromeUIResourcesHost,
kWebuiCodeCacheResources, url_to_code_cache_pairs);
#endif // BUILDFLAG(ENABLE_WEBUI_GENERATE_CODE_CACHE)
return {url_to_code_cache_pairs};
}
} // namespace webui

@ -7,6 +7,9 @@
#include <string>
#include "base/containers/flat_map.h"
#include "ui/base/webui/resource_path.h"
namespace content {
class WebContents;
}
@ -40,6 +43,17 @@ void SetThemeProviderForTestingDeprecated(
// metrics. Returns an empty string if no relevant mapping has been defined.
std::string GetWebUIHostnameForCodeCacheMetrics(const GURL& webui_url);
// Appends WebUI resource URLs to code cache resource ID pairs from the given
// `code_cache_resources` into `resource_code_cache_pairs`.
void AppendWebUIResourceURLToCodeCachePairs(
std::string_view scheme,
std::string_view host,
base::span<const ResourcePath> code_cache_resources,
std::vector<std::pair<GURL, int>>& resource_code_cache_pairs);
// Gets the WebUI URL to code cache resource ID map.
base::flat_map<GURL, int> GetWebUIResourceUrlToCodeCacheMap();
} // namespace webui
#endif // CHROME_BROWSER_UI_WEBUI_WEBUI_UTIL_DESKTOP_H_

@ -0,0 +1,44 @@
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/webui/webui_util_desktop.h"
#include "base/containers/contains.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/webui/resource_path.h"
#include "url/gurl.h"
TEST(WebUIUtilDesktopTest,
AppendWebUIResourceURLToCodeCachePairs_AppendsPairs) {
constexpr webui::ResourcePath kTestResources[] = {
{"resource_1.js.code_cache", 1},
{"resource_2.js.code_cache", 2},
{"path/resource_3.js.code_cache", 3},
};
std::vector<std::pair<GURL, int>> url_to_code_cache_pairs;
AppendWebUIResourceURLToCodeCachePairs("chrome", "test", kTestResources,
url_to_code_cache_pairs);
EXPECT_EQ(3u, url_to_code_cache_pairs.size());
EXPECT_TRUE(base::Contains(
url_to_code_cache_pairs,
std::pair<GURL, int>(GURL("chrome://test/resource_1.js"), 1)));
EXPECT_TRUE(base::Contains(
url_to_code_cache_pairs,
std::pair<GURL, int>(GURL("chrome://test/resource_2.js"), 2)));
EXPECT_TRUE(base::Contains(
url_to_code_cache_pairs,
std::pair<GURL, int>(GURL("chrome://test/path/resource_3.js"), 3)));
}
TEST(WebUIUtilDesktopTest,
AppendWebUIResourceURLToCodeCachePairs_EmptyCodeCacheResources) {
std::vector<std::pair<GURL, int>> url_to_code_cache_pairs;
AppendWebUIResourceURLToCodeCachePairs(
"chrome", "test", base::span<const webui::ResourcePath>(),
url_to_code_cache_pairs);
EXPECT_TRUE(url_to_code_cache_pairs.empty());
}

@ -7853,6 +7853,7 @@ test("unit_tests") {
"../browser/ui/webui/web_dialog_web_contents_delegate_unittest.cc",
"../browser/ui/webui/webui_allowlist_provider_unittest.cc",
"../browser/ui/webui/webui_embedding_context_unittest.cc",
"../browser/ui/webui/webui_util_desktop_unittest.cc",
"../browser/upgrade_detector/build_state_unittest.cc",
"../browser/upgrade_detector/mock_build_state_observer.cc",
"../browser/upgrade_detector/mock_build_state_observer.h",

@ -3189,6 +3189,16 @@ void RenderProcessHostImpl::NotifyRendererOfLockedStateUpdate() {
base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDisableWebSecurity));
if (GetContentClient()->browser()->IsWebUIBundledCodeCachingEnabled(
process_lock.lock_url())) {
auto url_to_code_cache_map =
GetContentClient()->browser()->GetWebUIResourceUrlToCodeCacheMap();
if (!url_to_code_cache_map.empty()) {
GetRendererInterface()->SetWebUIResourceUrlToCodeCacheMap(
std::move(url_to_code_cache_map));
}
}
if (!process_lock.IsASiteOrOrigin())
return;

@ -15,6 +15,7 @@ import "services/network/public/mojom/network_types.mojom";
import "third_party/blink/public/mojom/browser_interface_broker.mojom";
import "third_party/blink/public/mojom/origin_trials/origin_trials_settings.mojom";
import "third_party/blink/public/mojom/user_agent/user_agent_metadata.mojom";
import "url/mojom/url.mojom";
struct UpdateScrollbarThemeParams {
// TODO(avi): Update these to optional values when optional numeric types are
@ -147,6 +148,11 @@ interface Renderer {
// TODO(crbug.com/40180791): We need a specification for this restriction.
SetIsIsolatedContext(bool value);
// Sets the mapping from WebUI resource URLs to the resource ID of their
// corresponding bundled bytecode cache. This is called once after a
// renderer's process lock has been set.
SetWebUIResourceUrlToCodeCacheMap(map<url.mojom.Url, int32> resource_map);
// Initialize renderer user agent string, user agent metadata, CORS exempt
// header list and origin trials settings on renderer startup.
//

@ -720,6 +720,16 @@ std::string ContentBrowserClient::GetWebUIHostnameForCodeCacheMetrics(
return std::string();
}
bool ContentBrowserClient::IsWebUIBundledCodeCachingEnabled(
const GURL& webui_lock_url) const {
return false;
}
base::flat_map<GURL, int>
ContentBrowserClient::GetWebUIResourceUrlToCodeCacheMap() const {
return base::flat_map<GURL, int>();
}
void ContentBrowserClient::AllowCertificateError(
WebContents* web_contents,
int cert_error,

@ -1294,6 +1294,18 @@ class CONTENT_EXPORT ContentBrowserClient {
virtual std::string GetWebUIHostnameForCodeCacheMetrics(
const GURL& webui_url) const;
// Returns true if WebUI bundled code caching is supported for
// `webui_lock_url`.
virtual bool IsWebUIBundledCodeCachingEnabled(
const GURL& webui_lock_url) const;
// Gets a mapping from the WebUI resource URL to its corresponding bundled
// bytecode cache resource ID. These mappings are used at load-time in
// renderers to get the appropriate bytecode cache during WebUI resource
// fetch. This mapping is propagated once to renderers once shortly after
// process-lock to ensure it's available for all subsequent resource fetches.
virtual base::flat_map<GURL, int> GetWebUIResourceUrlToCodeCacheMap() const;
// Informs the embedder that a certificate error has occurred. If
// |overridable| is true and if |strict_enforcement| is false, the user
// can ignore the error and continue. The embedder can call the callback

@ -1460,6 +1460,11 @@ void RenderThreadImpl::SetIsIsolatedContext(bool value) {
blink::SetIsIsolatedContext(value);
}
void RenderThreadImpl::SetWebUIResourceUrlToCodeCacheMap(
const base::flat_map<GURL, int>& resource_map) {
blink_platform_impl_->set_webui_resource_to_code_cache_id_map(resource_map);
}
void RenderThreadImpl::CompositingModeFallbackToSoftware() {
gpu_->LoseChannel();
is_gpu_compositing_disabled_ = true;

@ -445,6 +445,8 @@ class CONTENT_EXPORT RenderThreadImpl
void SetIsCrossOriginIsolated(bool value) override;
void SetIsWebSecurityDisabled(bool value) override;
void SetIsIsolatedContext(bool value) override;
void SetWebUIResourceUrlToCodeCacheMap(
const base::flat_map<GURL, int>& resource_map) override;
void OnMemoryPressure(
base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level);

@ -290,6 +290,15 @@ void RendererBlinkPlatformImpl::SetThreadType(base::PlatformThreadId thread_id,
}
#endif
std::optional<int>
RendererBlinkPlatformImpl::GetWebUIBundledCodeCacheResourceId(
const GURL& webui_resource_url) {
auto it = webui_resource_to_code_cache_id_map_.find(webui_resource_url);
return it == webui_resource_to_code_cache_id_map_.end()
? std::nullopt
: std::optional<int>(it->second);
}
blink::WebSandboxSupport* RendererBlinkPlatformImpl::GetSandboxSupport() {
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC) || \
BUILDFLAG(IS_WIN)

@ -189,6 +189,8 @@ class CONTENT_EXPORT RendererBlinkPlatformImpl : public BlinkPlatformImpl {
void SetThreadType(base::PlatformThreadId thread_id,
base::ThreadType) override;
#endif
std::optional<int> GetWebUIBundledCodeCacheResourceId(
const GURL& webui_resource_url) override;
std::unique_ptr<blink::WebDedicatedWorkerHostFactoryClient>
CreateDedicatedWorkerHostFactoryClient(
blink::WebDedicatedWorker*,
@ -253,6 +255,11 @@ class CONTENT_EXPORT RendererBlinkPlatformImpl : public BlinkPlatformImpl {
// plus eTLD+1, such as https://google.com), or to a more specific origin.
void SetIsLockedToSite();
void set_webui_resource_to_code_cache_id_map(
const base::flat_map<GURL, int>& resource_map) {
webui_resource_to_code_cache_id_map_ = resource_map;
}
private:
bool CheckPreparsedJsCachingEnabled() const;
@ -290,6 +297,10 @@ class CONTENT_EXPORT RendererBlinkPlatformImpl : public BlinkPlatformImpl {
// std::numeric_limits<uint32_t>::max()] range.
uint32_t next_frame_sink_id_;
// Maps WebUI resource URLs to the resource ID of their associated bundled
// code cache.
base::flat_map<GURL, int> webui_resource_to_code_cache_id_map_;
THREAD_CHECKER(main_thread_checker_);
// Used for callbacks.

@ -2,6 +2,9 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//build/buildflag_header.gni")
import("//ui/webui/webui_features.gni")
static_library("webui") {
sources = [
"mojo_web_ui_controller.cc",
@ -47,6 +50,12 @@ static_library("webui") {
}
}
buildflag_header("buildflags") {
header = "buildflags.h"
flags =
[ "ENABLE_WEBUI_GENERATE_CODE_CACHE=$enable_webui_generate_code_cache" ]
}
source_set("test_support") {
testonly = true