Skip to content

Commit 6af0f4f

Browse files
committed
Support contained tabs session restore and sync.
1 parent 29ac726 commit 6af0f4f

File tree

48 files changed

+1076
-55
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+1076
-55
lines changed

browser/DEPS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ include_rules += [
4545
"+brave/components/brave_wallet/browser",
4646
"+brave/components/brave_wallet/common",
4747
"+brave/components/containers/buildflags",
48+
"+brave/components/containers/content/browser",
4849
"+brave/components/containers/core/browser",
4950
"+brave/components/containers/core/common",
5051
"+brave/components/containers/core/mojom",

browser/brave_content_browser_client.cc

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ using extensions::ChromeContentBrowserClientExtensionsPart;
225225
#endif
226226

227227
#if BUILDFLAG(ENABLE_CONTAINERS)
228+
#include "brave/components/containers/content/browser/storage_partition_utils.h"
228229
#include "brave/components/containers/core/common/features.h"
229230
#include "brave/components/containers/core/mojom/containers.mojom.h"
230231
#endif
@@ -1533,6 +1534,18 @@ bool BraveContentBrowserClient::IsWindowsRecallDisabled() {
15331534
#endif
15341535
}
15351536

1537+
bool BraveContentBrowserClient::ShouldInheritStoragePartition(
1538+
const content::StoragePartitionConfig& partition_config) const {
1539+
#if BUILDFLAG(ENABLE_CONTAINERS)
1540+
if (base::FeatureList::IsEnabled(containers::features::kContainers)) {
1541+
return containers::IsContainersStoragePartition(partition_config);
1542+
}
1543+
return false;
1544+
#else
1545+
return false;
1546+
#endif // BUILDFLAG(ENABLE_CONTAINERS)
1547+
}
1548+
15361549
bool BraveContentBrowserClient::AllowSignedExchange(
15371550
content::BrowserContext* context) {
15381551
// This override has been introduced due to the deletion of the flag

browser/brave_content_browser_client.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,9 @@ class BraveContentBrowserClient : public ChromeContentBrowserClient {
188188

189189
bool IsWindowsRecallDisabled() override;
190190

191+
bool ShouldInheritStoragePartition(
192+
const content::StoragePartitionConfig& partition_config) const override;
193+
191194
bool AllowSignedExchange(content::BrowserContext* context) override;
192195

193196
private:

browser/containers/BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ source_set("browser_tests") {
1313
sources = [ "containers_browsertest.cc" ]
1414

1515
deps = [
16+
"//brave/components/containers/content/browser",
1617
"//brave/components/containers/core/browser",
1718
"//brave/components/containers/core/common:features",
1819
"//brave/components/containers/core/mojom",

browser/containers/containers_browsertest.cc

Lines changed: 231 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* You can obtain one at https://mozilla.org/MPL/2.0/. */
55

66
#include "brave/browser/ui/browser_commands.h"
7-
#include "brave/components/containers/core/browser/storage_partition_constants.h"
7+
#include "brave/components/containers/content/browser/storage_partition_utils.h"
88
#include "brave/components/containers/core/common/features.h"
99
#include "brave/components/containers/core/mojom/containers.mojom.h"
1010
#include "chrome/browser/profiles/profile.h"
@@ -243,7 +243,7 @@ IN_PROC_BROWSER_TEST_F(ContainersBrowserTest, IsolateCookiesAndStorage) {
243243
NavigateParams params(browser(), url, ui::PAGE_TRANSITION_LINK);
244244
params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
245245
params.storage_partition_config = content::StoragePartitionConfig::Create(
246-
browser()->profile(), "default", "container-a",
246+
browser()->profile(), kContainersStoragePartitionDomain, "container-a",
247247
browser()->profile()->IsOffTheRecord());
248248
ui_test_utils::NavigateToURL(&params);
249249

@@ -306,7 +306,7 @@ IN_PROC_BROWSER_TEST_F(ContainersBrowserTest, IsolateCookiesAndStorage) {
306306
NavigateParams params_b(browser(), url, ui::PAGE_TRANSITION_LINK);
307307
params_b.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
308308
params_b.storage_partition_config = content::StoragePartitionConfig::Create(
309-
browser()->profile(), "default", "container-b",
309+
browser()->profile(), kContainersStoragePartitionDomain, "container-b",
310310
browser()->profile()->IsOffTheRecord());
311311
ui_test_utils::NavigateToURL(&params_b);
312312

@@ -328,7 +328,164 @@ IN_PROC_BROWSER_TEST_F(ContainersBrowserTest, IsolateCookiesAndStorage) {
328328
GetIndexedDBJS("test_key")));
329329
}
330330

331-
IN_PROC_BROWSER_TEST_F(ContainersBrowserTest, IsolateServiceWorkers) {
331+
IN_PROC_BROWSER_TEST_F(ContainersBrowserTest,
332+
PRE_StoragePersistenceAcrossSessions) {
333+
const GURL url("https://a.test/simple.html");
334+
335+
// Navigate to the page
336+
NavigateParams params(browser(), url, ui::PAGE_TRANSITION_LINK);
337+
params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
338+
params.storage_partition_config = content::StoragePartitionConfig::Create(
339+
browser()->profile(), kContainersStoragePartitionDomain, "container",
340+
browser()->profile()->IsOffTheRecord());
341+
ui_test_utils::NavigateToURL(&params);
342+
343+
content::WebContents* web_contents =
344+
browser()->tab_strip_model()->GetActiveWebContents();
345+
ASSERT_TRUE(web_contents);
346+
347+
// Set persistent storage data
348+
EXPECT_TRUE(content::ExecJs(
349+
web_contents, SetCookieJS("persistent_cookie", "persistent_value")));
350+
EXPECT_TRUE(content::ExecJs(
351+
web_contents, SetLocalStorageJS("persistent_key", "persistent_value")));
352+
353+
EXPECT_TRUE(content::ExecJs(
354+
web_contents, SetIndexedDBJS("persistent_key", "persistent_value")));
355+
356+
// Verify data is set
357+
content::EvalJsResult cookie_result =
358+
content::EvalJs(web_contents, GetCookiesJS());
359+
EXPECT_TRUE(cookie_result.ExtractString().find(
360+
"persistent_cookie=persistent_value") != std::string::npos);
361+
362+
EXPECT_EQ("persistent_value",
363+
content::EvalJs(web_contents, GetLocalStorageJS("persistent_key")));
364+
EXPECT_EQ("persistent_value",
365+
content::EvalJs(web_contents, GetIndexedDBJS("persistent_key")));
366+
}
367+
368+
IN_PROC_BROWSER_TEST_F(ContainersBrowserTest,
369+
StoragePersistenceAcrossSessions) {
370+
const GURL url("https://a.test/simple.html");
371+
372+
// Navigate to the page
373+
NavigateParams params(browser(), url, ui::PAGE_TRANSITION_LINK);
374+
params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
375+
params.storage_partition_config = content::StoragePartitionConfig::Create(
376+
browser()->profile(), kContainersStoragePartitionDomain, "container",
377+
browser()->profile()->IsOffTheRecord());
378+
ui_test_utils::NavigateToURL(&params);
379+
380+
content::WebContents* web_contents_reloaded =
381+
browser()->tab_strip_model()->GetActiveWebContents();
382+
ASSERT_TRUE(web_contents_reloaded);
383+
384+
// Verify persistent data is still available after reload
385+
content::EvalJsResult cookie_result_reloaded =
386+
content::EvalJs(web_contents_reloaded, GetCookiesJS());
387+
EXPECT_TRUE(cookie_result_reloaded.ExtractString().find(
388+
"persistent_cookie=persistent_value") != std::string::npos);
389+
390+
EXPECT_EQ("persistent_value",
391+
content::EvalJs(web_contents_reloaded,
392+
GetLocalStorageJS("persistent_key")));
393+
EXPECT_EQ(
394+
"persistent_value",
395+
content::EvalJs(web_contents_reloaded, GetIndexedDBJS("persistent_key")));
396+
}
397+
398+
IN_PROC_BROWSER_TEST_F(ContainersBrowserTest,
399+
LinkNavigationInheritsContainerStoragePartition) {
400+
const GURL url("https://a.test/simple.html");
401+
402+
// Navigate to base URL with a container
403+
NavigateParams params(browser(), url, ui::PAGE_TRANSITION_LINK);
404+
params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
405+
params.storage_partition_config = content::StoragePartitionConfig::Create(
406+
browser()->profile(), kContainersStoragePartitionDomain,
407+
"container-for-links", browser()->profile()->IsOffTheRecord());
408+
ui_test_utils::NavigateToURL(&params);
409+
410+
content::WebContents* container_web_contents =
411+
browser()->tab_strip_model()->GetActiveWebContents();
412+
ASSERT_TRUE(container_web_contents);
413+
414+
EXPECT_TRUE(
415+
content::ExecJs(container_web_contents,
416+
SetCookieJS("container_cookie", "container_value")));
417+
EXPECT_TRUE(
418+
content::ExecJs(container_web_contents,
419+
SetLocalStorageJS("container_key", "container_value")));
420+
EXPECT_TRUE(
421+
content::ExecJs(container_web_contents,
422+
SetSessionStorageJS("container_key", "container_value")));
423+
EXPECT_TRUE(
424+
content::ExecJs(container_web_contents,
425+
SetIndexedDBJS("container_key", "container_value")));
426+
427+
// Inject a link that opens in new tab
428+
std::string inject_new_tab_link_js = content::JsReplace(
429+
"const link = document.createElement('a');"
430+
"link.href = $1;"
431+
"link.textContent = 'New Tab Link';"
432+
"link.id = 'new-tab-link';"
433+
"link.target = '_blank';"
434+
"document.body.appendChild(link);"
435+
"link.click();",
436+
url);
437+
438+
content::WebContentsAddedObserver new_tab_observer;
439+
EXPECT_TRUE(content::ExecJs(container_web_contents, inject_new_tab_link_js));
440+
content::WebContents* new_tab_contents = new_tab_observer.GetWebContents();
441+
ASSERT_TRUE(new_tab_contents);
442+
443+
ASSERT_NE(new_tab_contents, container_web_contents);
444+
445+
// Wait for the new tab to load
446+
EXPECT_TRUE(content::WaitForLoadStop(new_tab_contents));
447+
448+
// Verify the new tab is on the correct URL
449+
EXPECT_EQ(url, new_tab_contents->GetLastCommittedURL());
450+
451+
// Verify the new tab has access to the same container storage partition
452+
content::EvalJsResult cookie_result =
453+
content::EvalJs(new_tab_contents, GetCookiesJS());
454+
EXPECT_TRUE(cookie_result.ExtractString().find(
455+
"container_cookie=container_value") != std::string::npos);
456+
EXPECT_EQ(
457+
"container_value",
458+
content::EvalJs(new_tab_contents, GetLocalStorageJS("container_key")));
459+
EXPECT_EQ(
460+
base::Value(),
461+
content::EvalJs(new_tab_contents, GetSessionStorageJS("container_key")));
462+
EXPECT_EQ("container_value",
463+
content::EvalJs(new_tab_contents, GetIndexedDBJS("container_key")));
464+
465+
// Verify that setting storage in the new tab affects the container
466+
EXPECT_TRUE(content::ExecJs(new_tab_contents,
467+
SetCookieJS("new_tab_cookie", "new_tab_value")));
468+
EXPECT_TRUE(content::ExecJs(
469+
new_tab_contents, SetLocalStorageJS("new_tab_key", "new_tab_value")));
470+
EXPECT_TRUE(content::ExecJs(
471+
new_tab_contents, SetSessionStorageJS("new_tab_key", "new_tab_value")));
472+
EXPECT_TRUE(content::ExecJs(new_tab_contents,
473+
SetIndexedDBJS("new_tab_key", "new_tab_value")));
474+
475+
// Verify the original container tab can see the new storage
476+
cookie_result = content::EvalJs(container_web_contents, GetCookiesJS());
477+
EXPECT_TRUE(cookie_result.ExtractString().find(
478+
"new_tab_cookie=new_tab_value") != std::string::npos);
479+
EXPECT_EQ("new_tab_value", content::EvalJs(container_web_contents,
480+
GetLocalStorageJS("new_tab_key")));
481+
EXPECT_EQ(base::Value(), content::EvalJs(container_web_contents,
482+
GetSessionStorageJS("new_tab_key")));
483+
EXPECT_EQ("new_tab_value", content::EvalJs(container_web_contents,
484+
GetIndexedDBJS("new_tab_key")));
485+
}
486+
487+
IN_PROC_BROWSER_TEST_F(ContainersBrowserTest,
488+
IsolateServiceWorkersBetweenContainers) {
332489
const GURL url("https://a.test/containers/container_test.html");
333490
const GURL worker_url("https://a.test/containers/container_worker.js");
334491
const std::string scope = "https://a.test/containers/";
@@ -352,11 +509,11 @@ IN_PROC_BROWSER_TEST_F(ContainersBrowserTest, IsolateServiceWorkers) {
352509
EXPECT_EQ(1, content::EvalJs(web_contents_default,
353510
GetServiceWorkerRegistrationCountJS()));
354511

355-
// Open a new tab with a different storage partition (container-a)
512+
// Open a new tab with a different storage partition (container_a)
356513
NavigateParams params(browser(), url, ui::PAGE_TRANSITION_LINK);
357514
params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
358515
params.storage_partition_config = content::StoragePartitionConfig::Create(
359-
browser()->profile(), "default", "container-a",
516+
browser()->profile(), kContainersStoragePartitionDomain, "container-a",
360517
browser()->profile()->IsOffTheRecord());
361518
ui_test_utils::NavigateToURL(&params);
362519

@@ -397,11 +554,11 @@ IN_PROC_BROWSER_TEST_F(ContainersBrowserTest, IsolateServiceWorkers) {
397554
EXPECT_EQ(1, content::EvalJs(web_contents_default,
398555
GetServiceWorkerRegistrationCountJS()));
399556

400-
// Open another container (container-b)
557+
// Open another container (container_b)
401558
NavigateParams params_b(browser(), url, ui::PAGE_TRANSITION_LINK);
402559
params_b.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
403560
params_b.storage_partition_config = content::StoragePartitionConfig::Create(
404-
browser()->profile(), "default", "container-b",
561+
browser()->profile(), kContainersStoragePartitionDomain, "container-b",
405562
browser()->profile()->IsOffTheRecord());
406563
ui_test_utils::NavigateToURL(&params_b);
407564

@@ -762,4 +919,70 @@ IN_PROC_BROWSER_TEST_F(ContainersBrowserTest,
762919
// container
763920
}
764921

922+
IN_PROC_BROWSER_TEST_F(ContainersBrowserTest,
923+
PRE_ServiceWorkerPersistenceAcrossSessions) {
924+
const GURL url("https://a.test/containers/container_test.html");
925+
const GURL worker_url("https://a.test/containers/container_worker.js");
926+
const std::string scope = "https://a.test/containers/";
927+
928+
// Navigate to the page with a container
929+
NavigateParams params(browser(), url, ui::PAGE_TRANSITION_LINK);
930+
params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
931+
params.storage_partition_config = content::StoragePartitionConfig::Create(
932+
browser()->profile(), kContainersStoragePartitionDomain,
933+
"persistent-container", browser()->profile()->IsOffTheRecord());
934+
ui_test_utils::NavigateToURL(&params);
935+
936+
content::WebContents* web_contents =
937+
browser()->tab_strip_model()->GetActiveWebContents();
938+
ASSERT_TRUE(web_contents);
939+
940+
// Register service worker
941+
EXPECT_TRUE(content::ExecJs(
942+
web_contents, RegisterServiceWorkerJS(worker_url.spec(), scope)));
943+
944+
// Verify service worker is registered
945+
EXPECT_EQ(
946+
"registered",
947+
content::EvalJs(web_contents, CheckServiceWorkerRegisteredJS(scope)));
948+
949+
// Set some persistent storage data that the service worker might use
950+
EXPECT_TRUE(content::ExecJs(
951+
web_contents, SetLocalStorageJS("sw_data", "persistent_value")));
952+
EXPECT_TRUE(content::ExecJs(web_contents,
953+
SetCookieJS("sw_cookie", "persistent_cookie")));
954+
}
955+
956+
IN_PROC_BROWSER_TEST_F(ContainersBrowserTest,
957+
ServiceWorkerPersistenceAcrossSessions) {
958+
const GURL url("https://a.test/containers/container_test.html");
959+
const std::string scope = "https://a.test/containers/";
960+
961+
// Navigate to the page with the same container
962+
NavigateParams params(browser(), url, ui::PAGE_TRANSITION_LINK);
963+
params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
964+
params.storage_partition_config = content::StoragePartitionConfig::Create(
965+
browser()->profile(), kContainersStoragePartitionDomain,
966+
"persistent-container", browser()->profile()->IsOffTheRecord());
967+
ui_test_utils::NavigateToURL(&params);
968+
969+
content::WebContents* web_contents_reloaded =
970+
browser()->tab_strip_model()->GetActiveWebContents();
971+
ASSERT_TRUE(web_contents_reloaded);
972+
973+
// Verify service worker is still registered after browser restart
974+
EXPECT_EQ("registered",
975+
content::EvalJs(web_contents_reloaded,
976+
CheckServiceWorkerRegisteredJS(scope)));
977+
978+
// Verify persistent storage data is still available
979+
EXPECT_EQ("persistent_value", content::EvalJs(web_contents_reloaded,
980+
GetLocalStorageJS("sw_data")));
981+
982+
content::EvalJsResult cookie_result =
983+
content::EvalJs(web_contents_reloaded, GetCookiesJS());
984+
EXPECT_TRUE(cookie_result.ExtractString().find(
985+
"sw_cookie=persistent_cookie") != std::string::npos);
986+
}
987+
765988
} // namespace containers

browser/sources.gni

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,7 @@ if (enable_ai_chat && is_android) {
388388

389389
if (enable_containers) {
390390
brave_chrome_browser_deps += [
391+
"//brave/components/containers/content/browser",
391392
"//brave/components/containers/core/browser",
392393
"//brave/components/containers/core/common",
393394
]

browser/ui/BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1432,6 +1432,7 @@ source_set("ui") {
14321432

14331433
if (enable_containers) {
14341434
deps += [
1435+
"//brave/components/containers/content/browser",
14351436
"//brave/components/containers/core/browser",
14361437
"//brave/components/containers/core/common",
14371438
"//brave/components/containers/core/mojom",

browser/ui/browser_commands.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@
126126
#endif
127127

128128
#if BUILDFLAG(ENABLE_CONTAINERS)
129-
#include "brave/components/containers/core/browser/storage_partition_constants.h"
129+
#include "brave/components/containers/content/browser/storage_partition_utils.h"
130130
#include "brave/components/containers/core/mojom/containers.mojom.h"
131131
#endif
132132

browser/ui/tabs/BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ source_set("tab_menu") {
9191
]
9292
deps += [
9393
"//brave/browser/ui/containers",
94+
"//brave/components/containers/content/browser",
9495
"//brave/components/containers/core/browser",
9596
"//brave/components/containers/core/common",
9697
"//components/tabs:public",

0 commit comments

Comments
 (0)