Support StoragePartitionConfig setting on WebContents creation. (#31761)

This commit is contained in:
Aleksei Khoroshilov
2025-11-11 17:24:48 +07:00
committed by GitHub
parent 04a6877680
commit f488494374
17 changed files with 685 additions and 1 deletions
+22
View File
@@ -0,0 +1,22 @@
# Copyright (c) 2025 The Brave Authors. All rights reserved.
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at https://mozilla.org/MPL/2.0/. */
import("//brave/components/containers/buildflags/buildflags.gni")
assert(enable_containers)
source_set("browser_tests") {
testonly = true
sources = [ "containers_browsertest.cc" ]
deps = [
"//brave/components/containers/core/common:features",
"//chrome/browser",
"//chrome/test:test_support",
]
defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ]
}
@@ -0,0 +1,465 @@
/* Copyright (c) 2025 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at https://mozilla.org/MPL/2.0/. */
#include "brave/components/containers/core/common/features.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_navigator.h"
#include "chrome/browser/ui/browser_navigator_params.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "services/network/public/cpp/network_switches.h"
#include "third_party/abseil-cpp/absl/strings/str_format.h"
#include "url/gurl.h"
namespace containers {
class ContainersBrowserTest : public InProcessBrowserTest {
public:
ContainersBrowserTest() : https_server_(net::EmbeddedTestServer::TYPE_HTTPS) {
feature_list_.InitAndEnableFeature(features::kContainers);
https_server_.SetSSLConfig(net::EmbeddedTestServer::CERT_TEST_NAMES);
// Register a request handler for serving test HTML content
https_server_.AddDefaultHandlers(
base::FilePath(FILE_PATH_LITERAL("brave/test/data")));
EXPECT_TRUE(https_server_.Start());
}
~ContainersBrowserTest() override = default;
void SetUpCommandLine(base::CommandLine* command_line) override {
InProcessBrowserTest::SetUpCommandLine(command_line);
command_line->AppendSwitchASCII(
network::switches::kHostResolverRules,
absl::StrFormat("MAP *:443 127.0.0.1:%d", https_server_.port()));
}
void SetUpOnMainThread() override {
InProcessBrowserTest::SetUpOnMainThread();
host_resolver()->AddRule("*", "127.0.0.1");
}
// JavaScript helper to set a cookie
std::string SetCookieJS(const std::string& name, const std::string& value) {
return absl::StrFormat(
"document.cookie = `%s=%s; path=/; SameSite=None; Secure; expires=Wed "
"Jan 01 2038 00:00:00 GMT`; "
"document.cookie;",
name, value);
}
// JavaScript helper to get all cookies
std::string GetCookiesJS() { return "document.cookie;"; }
// JavaScript helper to set localStorage item
std::string SetLocalStorageJS(const std::string& key,
const std::string& value) {
return content::JsReplace(
"localStorage.setItem($1, $2); "
"localStorage.getItem($1);",
key, value);
}
// JavaScript helper to get localStorage item
std::string GetLocalStorageJS(const std::string& key) {
return content::JsReplace("localStorage.getItem($1);", key);
}
// JavaScript helper to set sessionStorage item
std::string SetSessionStorageJS(const std::string& key,
const std::string& value) {
return content::JsReplace(
"sessionStorage.setItem($1, $2); "
"sessionStorage.getItem($1);",
key, value);
}
// JavaScript helper to get sessionStorage item
std::string GetSessionStorageJS(const std::string& key) {
return content::JsReplace("sessionStorage.getItem($1);", key);
}
// JavaScript helper to set IndexedDB item
std::string SetIndexedDBJS(const std::string& key, const std::string& value) {
return content::JsReplace(
"new Promise((resolve, reject) => {"
" const request = indexedDB.open('testDB', 1);"
" request.onerror = (e) => reject(e.target.error);"
" request.onsuccess = () => {"
" const db = request.result;"
" const transaction = db.transaction(['testStore'], 'readwrite');"
" const store = transaction.objectStore('testStore');"
" const putRequest = store.put($1, $2);"
" putRequest.onsuccess = () => resolve(true);"
" putRequest.onerror = (e) => reject(e.target.error);"
" };"
" request.onupgradeneeded = () => {"
" const db = request.result;"
" if (!db.objectStoreNames.contains('testStore')) {"
" db.createObjectStore('testStore');"
" }"
" };"
"});",
value, key);
}
// JavaScript helper to get IndexedDB item
std::string GetIndexedDBJS(const std::string& key) {
return content::JsReplace(
"new Promise((resolve, reject) => {"
" const request = indexedDB.open('testDB', 1);"
" request.onerror = (e) => reject(e.target.error);"
" request.onsuccess = () => {"
" const db = request.result;"
" const transaction = db.transaction(['testStore'], 'readonly');"
" const store = transaction.objectStore('testStore');"
" const getRequest = store.get($1);"
" getRequest.onsuccess = () => resolve(getRequest.result || null);"
" getRequest.onerror = (e) => reject(e.target.error);"
" };"
" request.onupgradeneeded = () => {"
" const db = request.result;"
" if (!db.objectStoreNames.contains('testStore')) {"
" db.createObjectStore('testStore');"
" }"
" };"
"});",
key);
}
// JavaScript helper to clear all storage
std::string ClearAllStorageJS() {
return "localStorage.clear(); sessionStorage.clear(); 'cleared';";
}
// JavaScript helper to register a service worker
std::string RegisterServiceWorkerJS(const std::string& script_url,
const std::string& scope) {
return content::JsReplace(
"new Promise((resolve, reject) => {"
" navigator.serviceWorker.register($1, {scope: $2})"
" .then(registration => {"
" console.log('Service worker registered:', registration);"
" resolve('registered');"
" })"
" .catch(error => {"
" console.error('Service worker registration failed:', error);"
" reject(error.toString());"
" });"
"});",
script_url, scope);
}
// JavaScript helper to check if a service worker is registered
std::string CheckServiceWorkerRegisteredJS(const std::string& scope) {
return content::JsReplace(
"new Promise((resolve) => {"
" navigator.serviceWorker.getRegistrations().then(registrations => {"
" const matching = registrations.filter(reg => reg.scope === $1);"
" resolve(matching.length > 0 ? 'registered' : 'not_registered');"
" });"
"});",
scope);
}
// JavaScript helper to get service worker registration count
std::string GetServiceWorkerRegistrationCountJS() {
return "new Promise((resolve) => {"
" navigator.serviceWorker.getRegistrations().then(registrations => "
"{"
" resolve(registrations.length);"
" });"
"});";
}
// JavaScript helper to unregister all service workers
std::string UnregisterAllServiceWorkersJS() {
return "new Promise((resolve) => {"
" navigator.serviceWorker.getRegistrations().then(registrations => "
"{"
" const promises = registrations.map(reg => reg.unregister());"
" Promise.all(promises).then(() => resolve('unregistered'));"
" });"
"});";
}
protected:
base::test::ScopedFeatureList feature_list_;
net::EmbeddedTestServer https_server_;
};
IN_PROC_BROWSER_TEST_F(ContainersBrowserTest, IsolateCookiesAndStorage) {
const GURL url("https://a.test/simple.html");
// Navigate to URL without container
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
content::WebContents* web_contents_default =
browser()->tab_strip_model()->GetActiveWebContents();
ASSERT_TRUE(web_contents_default);
// Set storage data in the default storage partition
EXPECT_TRUE(content::ExecJs(web_contents_default,
SetCookieJS("test_cookie", "value_a")));
EXPECT_TRUE(content::ExecJs(web_contents_default,
SetLocalStorageJS("test_key", "value_a")));
EXPECT_TRUE(content::ExecJs(web_contents_default,
SetSessionStorageJS("test_key", "value_a")));
// Set IndexedDB data in the default storage partition
EXPECT_TRUE(content::ExecJs(web_contents_default,
SetIndexedDBJS("test_key", "value_a")));
// Verify storage data is set correctly in the default storage partition
content::EvalJsResult cookie_result =
content::EvalJs(web_contents_default, GetCookiesJS());
EXPECT_TRUE(cookie_result.ExtractString().find("test_cookie=value_a") !=
std::string::npos);
EXPECT_EQ("value_a", content::EvalJs(web_contents_default,
GetLocalStorageJS("test_key")));
EXPECT_EQ("value_a", content::EvalJs(web_contents_default,
GetSessionStorageJS("test_key")));
EXPECT_EQ("value_a",
content::EvalJs(web_contents_default, GetIndexedDBJS("test_key")));
// Open a new tab with a different storage partition
NavigateParams params(browser(), url, ui::PAGE_TRANSITION_LINK);
params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
params.storage_partition_config = content::StoragePartitionConfig::Create(
browser()->profile(), "default", "container-a",
browser()->profile()->IsOffTheRecord());
ui_test_utils::NavigateToURL(&params);
content::WebContents* web_contents_container_a =
browser()->tab_strip_model()->GetActiveWebContents();
ASSERT_TRUE(web_contents_container_a);
// Verify that the new container doesn't have access to the first container's
// storage
content::EvalJsResult cookie_result_a =
content::EvalJs(web_contents_container_a, GetCookiesJS());
EXPECT_TRUE(cookie_result_a.ExtractString().find("test_cookie=value_a") ==
std::string::npos);
EXPECT_EQ(base::Value(), content::EvalJs(web_contents_container_a,
GetLocalStorageJS("test_key")));
EXPECT_EQ(base::Value(), content::EvalJs(web_contents_container_a,
GetSessionStorageJS("test_key")));
EXPECT_EQ(base::Value(), content::EvalJs(web_contents_container_a,
GetIndexedDBJS("test_key")));
// Set different storage data in the container
EXPECT_TRUE(content::ExecJs(web_contents_container_a,
SetCookieJS("test_cookie", "value_b")));
EXPECT_TRUE(content::ExecJs(web_contents_container_a,
SetLocalStorageJS("test_key", "value_b")));
EXPECT_TRUE(content::ExecJs(web_contents_container_a,
SetSessionStorageJS("test_key", "value_b")));
EXPECT_TRUE(content::ExecJs(web_contents_container_a,
SetIndexedDBJS("test_key", "value_b")));
// Verify container has its own data
cookie_result_a = content::EvalJs(web_contents_container_a, GetCookiesJS());
EXPECT_TRUE(cookie_result_a.ExtractString().find("test_cookie=value_b") !=
std::string::npos);
EXPECT_EQ("value_b", content::EvalJs(web_contents_container_a,
GetLocalStorageJS("test_key")));
EXPECT_EQ("value_b", content::EvalJs(web_contents_container_a,
GetSessionStorageJS("test_key")));
EXPECT_EQ("value_b", content::EvalJs(web_contents_container_a,
GetIndexedDBJS("test_key")));
// Check the data in default tab to container and verify its data is unchanged
content::EvalJsResult cookie_result_default =
content::EvalJs(web_contents_default, GetCookiesJS());
EXPECT_TRUE(cookie_result_default.ExtractString().find(
"test_cookie=value_a") != std::string::npos);
EXPECT_EQ("value_a", content::EvalJs(web_contents_default,
GetLocalStorageJS("test_key")));
EXPECT_EQ("value_a", content::EvalJs(web_contents_default,
GetSessionStorageJS("test_key")));
EXPECT_EQ("value_a",
content::EvalJs(web_contents_default, GetIndexedDBJS("test_key")));
// Verify default storage partition doesn't have access to container's data
EXPECT_TRUE(cookie_result_default.ExtractString().find(
"test_cookie=value_b") == std::string::npos);
// Open a new tab with a different storage partition
NavigateParams params_b(browser(), url, ui::PAGE_TRANSITION_LINK);
params_b.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
params_b.storage_partition_config = content::StoragePartitionConfig::Create(
browser()->profile(), "default", "container-b",
browser()->profile()->IsOffTheRecord());
ui_test_utils::NavigateToURL(&params_b);
content::WebContents* web_contents_container_b =
browser()->tab_strip_model()->GetActiveWebContents();
ASSERT_TRUE(web_contents_container_b);
// Verify that the new container doesn't have access to the first container's
// storage
content::EvalJsResult cookie_result_b =
content::EvalJs(web_contents_container_b, GetCookiesJS());
EXPECT_TRUE(cookie_result_b.ExtractString().find("test_cookie=value_a") ==
std::string::npos);
EXPECT_EQ(base::Value(), content::EvalJs(web_contents_container_b,
GetLocalStorageJS("test_key")));
EXPECT_EQ(base::Value(), content::EvalJs(web_contents_container_b,
GetSessionStorageJS("test_key")));
EXPECT_EQ(base::Value(), content::EvalJs(web_contents_container_b,
GetIndexedDBJS("test_key")));
}
IN_PROC_BROWSER_TEST_F(ContainersBrowserTest, IsolateServiceWorkers) {
const GURL url("https://a.test/containers/container_test.html");
const GURL worker_url("https://a.test/containers/container_worker.js");
const std::string scope = "https://a.test/containers/";
// Navigate to URL without container
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
content::WebContents* web_contents_default =
browser()->tab_strip_model()->GetActiveWebContents();
ASSERT_TRUE(web_contents_default);
// Register service worker in default storage partition
EXPECT_TRUE(content::ExecJs(
web_contents_default, RegisterServiceWorkerJS(worker_url.spec(), scope)));
// Verify service worker is registered in default partition
EXPECT_EQ("registered",
content::EvalJs(web_contents_default,
CheckServiceWorkerRegisteredJS(scope)));
// Verify we have exactly 1 service worker registration
EXPECT_EQ(1, content::EvalJs(web_contents_default,
GetServiceWorkerRegistrationCountJS()));
// Open a new tab with a different storage partition (container-a)
NavigateParams params(browser(), url, ui::PAGE_TRANSITION_LINK);
params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
params.storage_partition_config = content::StoragePartitionConfig::Create(
browser()->profile(), "default", "container-a",
browser()->profile()->IsOffTheRecord());
ui_test_utils::NavigateToURL(&params);
content::WebContents* web_contents_container_a =
browser()->tab_strip_model()->GetActiveWebContents();
ASSERT_TRUE(web_contents_container_a);
// Verify that the container doesn't see the service worker from default
// partition
EXPECT_EQ("not_registered",
content::EvalJs(web_contents_container_a,
CheckServiceWorkerRegisteredJS(scope)));
// Verify container has 0 service worker registrations
EXPECT_EQ(0, content::EvalJs(web_contents_container_a,
GetServiceWorkerRegistrationCountJS()));
// Register a different service worker in the container
EXPECT_TRUE(
content::ExecJs(web_contents_container_a,
RegisterServiceWorkerJS(worker_url.spec(), scope)));
// Verify service worker is registered in container partition
EXPECT_EQ("registered",
content::EvalJs(web_contents_container_a,
CheckServiceWorkerRegisteredJS(scope)));
// Verify container has exactly 1 service worker registration
EXPECT_EQ(1, content::EvalJs(web_contents_container_a,
GetServiceWorkerRegistrationCountJS()));
// Verify default partition still has its service worker
EXPECT_EQ("registered",
content::EvalJs(web_contents_default,
CheckServiceWorkerRegisteredJS(scope)));
// Verify default partition still has exactly 1 service worker registration
EXPECT_EQ(1, content::EvalJs(web_contents_default,
GetServiceWorkerRegistrationCountJS()));
// Open another container (container-b)
NavigateParams params_b(browser(), url, ui::PAGE_TRANSITION_LINK);
params_b.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
params_b.storage_partition_config = content::StoragePartitionConfig::Create(
browser()->profile(), "default", "container-b",
browser()->profile()->IsOffTheRecord());
ui_test_utils::NavigateToURL(&params_b);
content::WebContents* web_contents_container_b =
browser()->tab_strip_model()->GetActiveWebContents();
ASSERT_TRUE(web_contents_container_b);
// Verify that container_b doesn't see service workers from other partitions
EXPECT_EQ("not_registered",
content::EvalJs(web_contents_container_b,
CheckServiceWorkerRegisteredJS(scope)));
// Verify container_b has 0 service worker registrations
EXPECT_EQ(0, content::EvalJs(web_contents_container_b,
GetServiceWorkerRegistrationCountJS()));
// Register service worker in container_b
EXPECT_TRUE(
content::ExecJs(web_contents_container_b,
RegisterServiceWorkerJS(worker_url.spec(), scope)));
// Verify service worker is registered in container_b partition
EXPECT_EQ("registered",
content::EvalJs(web_contents_container_b,
CheckServiceWorkerRegisteredJS(scope)));
// Verify container_b has exactly 1 service worker registration
EXPECT_EQ(1, content::EvalJs(web_contents_container_b,
GetServiceWorkerRegistrationCountJS()));
// Verify other partitions are unaffected
EXPECT_EQ("registered",
content::EvalJs(web_contents_default,
CheckServiceWorkerRegisteredJS(scope)));
EXPECT_EQ(1, content::EvalJs(web_contents_default,
GetServiceWorkerRegistrationCountJS()));
EXPECT_EQ("registered",
content::EvalJs(web_contents_container_a,
CheckServiceWorkerRegisteredJS(scope)));
EXPECT_EQ(1, content::EvalJs(web_contents_container_a,
GetServiceWorkerRegistrationCountJS()));
// Test unregistering service worker in one container doesn't affect others
EXPECT_TRUE(content::ExecJs(web_contents_container_a,
UnregisterAllServiceWorkersJS()));
// Verify container_a no longer has service workers
EXPECT_EQ("not_registered",
content::EvalJs(web_contents_container_a,
CheckServiceWorkerRegisteredJS(scope)));
EXPECT_EQ(0, content::EvalJs(web_contents_container_a,
GetServiceWorkerRegistrationCountJS()));
// Verify other partitions still have their service workers
EXPECT_EQ("registered",
content::EvalJs(web_contents_default,
CheckServiceWorkerRegisteredJS(scope)));
EXPECT_EQ(1, content::EvalJs(web_contents_default,
GetServiceWorkerRegistrationCountJS()));
EXPECT_EQ("registered",
content::EvalJs(web_contents_container_b,
CheckServiceWorkerRegisteredJS(scope)));
EXPECT_EQ(1, content::EvalJs(web_contents_container_b,
GetServiceWorkerRegistrationCountJS()));
}
} // namespace containers
+6
View File
@@ -36,11 +36,17 @@ group("ui_public_dependencies") {
":brave_tab_features",
":brave_tab_prefs",
"//brave/components/brave_wayback_machine/buildflags",
"//brave/components/containers/buildflags",
"//brave/components/playlist/core/common/buildflags",
"//brave/components/speedreader/common/buildflags",
]
}
group("browser_navigator_params_headers_public_dependencies") {
visibility = [ "//chrome/browser/ui:browser_navigator_params_headers" ]
public_deps = [ "//brave/components/containers/buildflags" ]
}
source_set("ui") {
# Depend on //chrome/browser/ui instead of //brave/browser/ui.
visibility = [
@@ -0,0 +1,3 @@
include_rules = [
"+brave/components/containers/buildflags",
]
@@ -0,0 +1,18 @@
/* Copyright (c) 2025 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at https://mozilla.org/MPL/2.0/. */
#include "brave/components/containers/buildflags/buildflags.h"
#include "chrome/browser/tab_contents/tab_util.h"
#if BUILDFLAG(ENABLE_CONTAINERS)
#define GetSiteInstanceForNewTab(profile, url) \
GetSiteInstanceForNewTab(profile, url, std::nullopt)
#endif // BUILDFLAG(ENABLE_CONTAINERS)
#include <chrome/browser/password_manager/password_change_delegate_impl.cc>
#if BUILDFLAG(ENABLE_CONTAINERS)
#undef GetSiteInstanceForNewTab
#endif // BUILDFLAG(ENABLE_CONTAINERS)
@@ -0,0 +1,3 @@
include_rules = [
"+brave/components/containers/buildflags",
]
@@ -0,0 +1,30 @@
/* Copyright (c) 2025 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at https://mozilla.org/MPL/2.0/. */
#include "chrome/browser/tab_contents/tab_util.h"
#include "brave/components/containers/buildflags/buildflags.h"
#if BUILDFLAG(ENABLE_CONTAINERS)
#define GetSiteInstanceForNewTab(...) \
GetSiteInstanceForNewTab( \
__VA_ARGS__, \
std::optional<content::StoragePartitionConfig> storage_partition_config)
#define BRAVE_GET_SITE_INSTANCE_FOR_NEW_TAB \
if (storage_partition_config) { \
return SiteInstance::CreateForFixedStoragePartition( \
profile, url, *storage_partition_config); \
}
#else
#define BRAVE_GET_SITE_INSTANCE_FOR_NEW_TAB
#endif // BUILDFLAG(ENABLE_CONTAINERS)
#include <chrome/browser/tab_contents/tab_util.cc> // IWYU pragma: export
#if BUILDFLAG(ENABLE_CONTAINERS)
#undef GetSiteInstanceForNewTab
#undef BRAVE_GET_SITE_INSTANCE_FOR_NEW_TAB
#endif // BUILDFLAG(ENABLE_CONTAINERS)
@@ -0,0 +1,25 @@
/* Copyright (c) 2025 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at https://mozilla.org/MPL/2.0/. */
#ifndef BRAVE_CHROMIUM_SRC_CHROME_BROWSER_TAB_CONTENTS_TAB_UTIL_H_
#define BRAVE_CHROMIUM_SRC_CHROME_BROWSER_TAB_CONTENTS_TAB_UTIL_H_
#include "brave/components/containers/buildflags/buildflags.h"
#include "content/public/browser/storage_partition_config.h"
#if BUILDFLAG(ENABLE_CONTAINERS)
#define GetSiteInstanceForNewTab(...) \
GetSiteInstanceForNewTab( \
__VA_ARGS__, \
std::optional<content::StoragePartitionConfig> storage_partition_config)
#endif // BUILDFLAG(ENABLE_CONTAINERS)
#include <chrome/browser/tab_contents/tab_util.h> // IWYU pragma: export
#if BUILDFLAG(ENABLE_CONTAINERS)
#undef GetSiteInstanceForNewTab
#endif // BUILDFLAG(ENABLE_CONTAINERS)
#endif // BRAVE_CHROMIUM_SRC_CHROME_BROWSER_TAB_CONTENTS_TAB_UTIL_H_
+1
View File
@@ -5,6 +5,7 @@ include_rules += [
"+brave/components/vector_icons",
"+brave/components/commander/common",
"+brave/components/constants",
"+brave/components/containers/buildflags",
"+brave/components/omnibox/browser",
"+brave/components/tor/buildflags",
]
@@ -5,6 +5,8 @@
#include <string_view>
#include "brave/components/containers/buildflags/buildflags.h"
#include "chrome/browser/tab_contents/tab_util.h"
#include "chrome/browser/ui/browser_navigator_params.h"
#include "content/public/common/url_constants.h"
#include "url/gurl.h"
@@ -22,5 +24,16 @@ void UpdateBraveScheme(NavigateParams* params) {
} // namespace
#define BRAVE_ADJUST_NAVIGATE_PARAMS_FOR_URL UpdateBraveScheme(params);
#if BUILDFLAG(ENABLE_CONTAINERS)
#define GetSiteInstanceForNewTab(...) \
GetSiteInstanceForNewTab(__VA_ARGS__, params.storage_partition_config)
#endif // BUILDFLAG(ENABLE_CONTAINERS)
#include <chrome/browser/ui/browser_navigator.cc>
#if BUILDFLAG(ENABLE_CONTAINERS)
#undef GetSiteInstanceForNewTab
#endif // BUILDFLAG(ENABLE_CONTAINERS)
#undef BRAVE_ADJUST_NAVIGATE_PARAMS_FOR_URL
@@ -0,0 +1,24 @@
// Copyright (c) 2025 The Brave Authors. All rights reserved.
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at https://mozilla.org/MPL/2.0/.
#ifndef BRAVE_CHROMIUM_SRC_CHROME_BROWSER_UI_BROWSER_NAVIGATOR_PARAMS_H_
#define BRAVE_CHROMIUM_SRC_CHROME_BROWSER_UI_BROWSER_NAVIGATOR_PARAMS_H_
#include "brave/components/containers/buildflags/buildflags.h"
#include "content/public/browser/storage_partition_config.h"
#if BUILDFLAG(ENABLE_CONTAINERS)
#define blob_url_loader_factory \
blob_url_loader_factory; \
std::optional<content::StoragePartitionConfig> storage_partition_config
#endif
#include <chrome/browser/ui/browser_navigator_params.h> // IWYU pragma: export
#if BUILDFLAG(ENABLE_CONTAINERS)
#undef blob_url_loader_factory
#endif
#endif // BRAVE_CHROMIUM_SRC_CHROME_BROWSER_UI_BROWSER_NAVIGATOR_PARAMS_H_
@@ -9,16 +9,29 @@
#include "brave/browser/ui/tabs/brave_tab_strip_model.h"
#include "brave/browser/ui/tabs/features.h"
#include "brave/browser/ui/tabs/public/constants.h"
#include "brave/components/containers/buildflags/buildflags.h"
#include "chrome/browser/ui/tab_ui_helper.h"
#include "chrome/browser/ui/tabs/public/tab_features.h"
#include "content/public/browser/browser_context.h"
#if BUILDFLAG(ENABLE_CONTAINERS)
#include "chrome/browser/tab_contents/tab_util.h"
#define AddRestoredTab AddRestoredTab_ChromiumImpl
#define ReplaceRestoredTab ReplaceRestoredTab_ChromiumImpl
#define GetSiteInstanceForNewTab(...) \
GetSiteInstanceForNewTab(__VA_ARGS__, std::nullopt)
#endif // BUILDFLAG(ENABLE_CONTAINERS)
#include <chrome/browser/ui/browser_tabrestore.cc>
#undef ReplaceRestoredTab
#undef AddRestoredTab
#if BUILDFLAG(ENABLE_CONTAINERS)
#undef GetSiteInstanceForNewTab
#endif // BUILDFLAG(ENABLE_CONTAINERS)
namespace chrome {
@@ -0,0 +1,12 @@
diff --git a/chrome/browser/tab_contents/tab_util.cc b/chrome/browser/tab_contents/tab_util.cc
index 4ccf096e97dafd9add0bb46c01397f294d4a6b84..209abdfe6cda1a01eb425a27af3a2aaf375918d7 100644
--- a/chrome/browser/tab_contents/tab_util.cc
+++ b/chrome/browser/tab_contents/tab_util.cc
@@ -48,6 +48,7 @@ scoped_refptr<SiteInstance> GetSiteInstanceForNewTab(Profile* profile,
if (!SiteInstance::ShouldAssignSiteForURL(url))
return nullptr;
+ BRAVE_GET_SITE_INSTANCE_FOR_NEW_TAB
return SiteInstance::CreateForURL(profile, url);
}
+9 -1
View File
@@ -1,5 +1,5 @@
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index f4531197ae5e1438c35a101d2c86c9b6edd1953f..e103798ae941c3e810611122c7d3cab5b0173551 100644
index f4531197ae5e1438c35a101d2c86c9b6edd1953f..bf350e756272986f853eb42b9de8f64445f65b43 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -769,6 +769,7 @@ static_library("ui") {
@@ -38,3 +38,11 @@ index f4531197ae5e1438c35a101d2c86c9b6edd1953f..e103798ae941c3e810611122c7d3cab5
}
source_set("url_identity") {
@@ -5515,6 +5521,7 @@ source_set("browser_navigator_params_headers") {
"//url",
]
deps = []
+ public_deps += [ "//brave/browser/ui:browser_navigator_params_headers_public_dependencies" ]
}
if (!is_android) {
+4
View File
@@ -1109,6 +1109,10 @@ test("brave_browser_tests") {
deps += [ "//chrome/app/theme:chrome_unscaled_resources_grit" ]
}
if (enable_containers) {
deps += [ "//brave/browser/containers:browser_tests" ]
}
defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ]
if (toolkit_views) {
+17
View File
@@ -0,0 +1,17 @@
<!doctype html>
<html>
<head>
<title>Container Service Worker Test</title>
</head>
<body>
<h1>Container Service Worker Test Page</h1>
<p>This page is used to test service worker isolation in containers.</p>
<div id="status">Loading...</div>
<script>
// Display current page info
document.getElementById('status').textContent =
'Page loaded at: ' + new Date().toISOString()
</script>
</body>
</html>
+20
View File
@@ -0,0 +1,20 @@
// Copyright (c) 2025 The Brave Authors. All rights reserved.
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at https://mozilla.org/MPL/2.0/.
// Service worker for container isolation testing
self.addEventListener('install', (event) => {
console.log('Container service worker installing')
self.skipWaiting()
})
self.addEventListener('activate', (event) => {
console.log('Container service worker activated')
event.waitUntil(self.clients.claim())
})
self.addEventListener('fetch', (event) => {
// Simple pass-through for testing
event.respondWith(fetch(event.request))
})