diff --git a/DEPS b/DEPS
index 01b86e7..c8bbafc 100644
--- a/DEPS
+++ b/DEPS
@@ -269,7 +269,7 @@
   'screen_ai_windows_386': 'version:140.02',
 
   # siso CIPD package version.
-  'siso_version': 'git_revision:33e71490533f445467879650036b6af7940455f3',
+  'siso_version': 'git_revision:e5fa67c5a456c1ab932f440ddfb195a8a33c235b',
 
   # download libaom test data
   'download_libaom_testdata': False,
@@ -295,11 +295,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': 'f248eba5e8d7d4828c0fd5390c5d5f29bb99f5be',
+  'skia_revision': 'eb9266cce6c1235d0303ee37d8a86f69c1195e49',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'v8_revision': 'ca21aab0e75ca67982d39bf021cbe33f997983a5',
+  'v8_revision': 'a6a3f1889b2fb25054f7b7476931f6818e12c9ff',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ANGLE
   # and whatever else without interference from each other.
@@ -379,7 +379,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling devtools-frontend
   # and whatever else without interference from each other.
-  'devtools_frontend_revision': '5911b6c9376c9eb6f430bcbc8490371b9d7e6f78',
+  'devtools_frontend_revision': '1c5bdf525e5d042bdd526e3d9c0774d84a747ca9',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libprotobuf-mutator
   # and whatever else without interference from each other.
@@ -403,7 +403,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'dawn_revision': 'd3409072e549a8f36d9c8e16b112bd1fb064b60f',
+  'dawn_revision': '4306d3c04b77dad4f9cd3d23bfd1068a6bb191bb',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -507,11 +507,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling llvm-libc
   # and whatever else without interference from each other.
-  'llvm_libc_revision':    'dd12cc11284e7845727f333a4a0c5274c161c541',
+  'llvm_libc_revision':    'f24be5deb774fae412aae70877b47fa6fcf19d28',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling llvm-libc
   # and whatever else without interference from each other.
-  'compiler_rt_revision': 'f6df13f71224eb80e35d67e67cfbfa4fb00831b9',
+  'compiler_rt_revision': '2396bb92b4c76ab74e11474ac7ed1b13b292f6e7',
 
   # If you change this, also update the libc++ revision in
   # //buildtools/deps_revisions.gni.
@@ -1581,7 +1581,7 @@
     'packages': [
       {
         'package': 'chromium/chrome/test/data/variations/cipd',
-        'version': 'PmZhzMo5UAfR4sL6uwGkPQm87IJ9MCr53OI7dSEKR9oC',
+        'version': 'Iu8wt3jloi9OpJ1eK0Tz2Xc87ZYDq5XPHBZthsMTKT0C',
       },
     ],
     'dep_type': 'cipd',
@@ -1592,7 +1592,7 @@
 
   'src/clank': {
     'url': Var('chrome_git') + '/clank/internal/apps.git' + '@' +
-    'b4f8c32a7394401015d4d5e47795851678fe4caf',
+    'd59dd8427adcc49e55c04f8929d7721357f9c5a9',
     'condition': 'checkout_android and checkout_src_internal',
   },
 
@@ -2983,7 +2983,7 @@
     Var('chromium_git') + '/webpagereplay.git' + '@' + Var('webpagereplay_revision'),
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '10a1bbbf89dd5a037f99dcce418e0709604eb21a',
+    Var('webrtc_git') + '/src.git' + '@' + '732523e79fd5c0b726ed48e62bbdf675c583f4aa',
 
   # Wuffs' canonical repository is at github.com/google/wuffs, but we use
   # Skia's mirror of Wuffs, the same as in upstream Skia's DEPS file.
@@ -3127,7 +3127,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/media_app/app',
-        'version': 'iadpq9xkZzskzo4527RON4ryhi-qxMqS8wLVmfQ6-SUC',
+        'version': 'p-fj0LlP_AkU7Rp70uvHRR785QzgluzOjES-Biw-A6wC',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
@@ -3160,7 +3160,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/projector_app/app',
-        'version': 'ZzrVCBLmlTVGn5C2efRhqSmY6WxTnft8edU-AnCDdhAC',
+        'version': 'a0nKCWUWTFv7JsxBrSOzy2M61wGu4HyLmiD_JRFZ-FIC',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
@@ -3746,7 +3746,7 @@
 
   'src/ios_internal':  {
       'url': Var('chrome_git') + '/chrome/ios_internal.git' + '@' +
-        'dcebd8470fac682ca9ff14c7ca0f4333e532c58e',
+        '827a716dc8d91ec9f5d8ce70e0fb6f7ebcd60566',
       'condition': 'checkout_ios and checkout_src_internal',
   },
 
diff --git a/android_webview/common/crash_reporter/crash_keys.cc b/android_webview/common/crash_reporter/crash_keys.cc
index c639a44f..ab3f481f 100644
--- a/android_webview/common/crash_reporter/crash_keys.cc
+++ b/android_webview/common/crash_reporter/crash_keys.cc
@@ -170,7 +170,6 @@
 
     // sandbox/linux
     "seccomp-sigsys",
-    "seccomp-sigsys-ioctl",
 
     kWeblayerWebViewCompatMode,
 
diff --git a/ash/accelerators/accelerator_commands.cc b/ash/accelerators/accelerator_commands.cc
index 498369de..97f3b6f 100644
--- a/ash/accelerators/accelerator_commands.cc
+++ b/ash/accelerators/accelerator_commands.cc
@@ -1063,17 +1063,17 @@
 }
 
 void NewIncognitoWindow() {
-  NewWindowDelegate::GetPrimary()->NewWindow(
+  NewWindowDelegate::GetInstance()->NewWindow(
       /*is_incognito=*/true,
       /*should_trigger_session_restore=*/false);
 }
 
 void NewTab() {
-  NewWindowDelegate::GetPrimary()->NewTab();
+  NewWindowDelegate::GetInstance()->NewTab();
 }
 
 void NewWindow() {
-  NewWindowDelegate::GetPrimary()->NewWindow(
+  NewWindowDelegate::GetInstance()->NewWindow(
       /*is_incognito=*/false,
       /*should_trigger_session_restore=*/false);
 }
@@ -1178,7 +1178,7 @@
 }
 
 void RestoreTab() {
-  NewWindowDelegate::GetPrimary()->RestoreTab();
+  NewWindowDelegate::GetInstance()->RestoreTab();
 }
 
 void RotateActiveWindow() {
diff --git a/ash/birch/birch_item.cc b/ash/birch/birch_item.cc
index 1236e08d..3584af7 100644
--- a/ash/birch/birch_item.cc
+++ b/ash/birch/birch_item.cc
@@ -301,7 +301,7 @@
     return;
   }
   RecordActionMetrics();
-  NewWindowDelegate::GetPrimary()->OpenUrl(
+  NewWindowDelegate::GetInstance()->OpenUrl(
       calendar_url_, NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       NewWindowDelegate::Disposition::kNewForegroundTab);
 }
@@ -314,7 +314,7 @@
   // TODO(jamescook): Decide if we want differerent metrics for secondary
   // actions.
   RecordActionMetrics();
-  NewWindowDelegate::GetPrimary()->OpenUrl(
+  NewWindowDelegate::GetInstance()->OpenUrl(
       conference_url_, NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       NewWindowDelegate::Disposition::kNewForegroundTab);
 }
@@ -433,7 +433,7 @@
     LOG(ERROR) << "No valid URL for attachment item";
   }
   RecordActionMetrics();
-  NewWindowDelegate::GetPrimary()->OpenUrl(
+  NewWindowDelegate::GetInstance()->OpenUrl(
       file_url_, NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       NewWindowDelegate::Disposition::kNewForegroundTab);
 }
@@ -501,7 +501,7 @@
 
 void BirchFileItem::PerformAction() {
   RecordActionMetrics();
-  NewWindowDelegate::GetPrimary()->OpenFile(file_path_);
+  NewWindowDelegate::GetInstance()->OpenFile(file_path_);
 }
 
 void BirchFileItem::LoadIcon(LoadIconCallback callback) const {
@@ -564,7 +564,7 @@
   RecordActionMetrics();
   // TODO(jamescook): Localize the query string.
   GURL url("https://google.com/search?q=weather");
-  NewWindowDelegate::GetPrimary()->OpenUrl(
+  NewWindowDelegate::GetInstance()->OpenUrl(
       url, NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       NewWindowDelegate::Disposition::kNewForegroundTab);
 }
@@ -676,7 +676,7 @@
     return;
   }
   RecordActionMetrics();
-  NewWindowDelegate::GetPrimary()->OpenUrl(
+  NewWindowDelegate::GetInstance()->OpenUrl(
       url_, NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       NewWindowDelegate::Disposition::kSwitchToTab);
 }
@@ -748,7 +748,7 @@
     return;
   }
   RecordActionMetrics();
-  NewWindowDelegate::GetPrimary()->OpenUrl(
+  NewWindowDelegate::GetInstance()->OpenUrl(
       page_url_, NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       NewWindowDelegate::Disposition::kSwitchToTab);
 }
@@ -822,7 +822,7 @@
     return;
   }
   RecordActionMetrics();
-  NewWindowDelegate::GetPrimary()->OpenUrl(
+  NewWindowDelegate::GetInstance()->OpenUrl(
       page_url_, NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       NewWindowDelegate::Disposition::kSwitchToTab);
 }
@@ -892,7 +892,7 @@
     activation_callback_.Run();
   }
   RecordActionMetrics();
-  NewWindowDelegate::GetPrimary()->OpenUrl(
+  NewWindowDelegate::GetInstance()->OpenUrl(
       url_, NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       NewWindowDelegate::Disposition::kSwitchToTab);
 }
@@ -1023,7 +1023,7 @@
     return;
   }
   RecordActionMetrics();
-  NewWindowDelegate::GetPrimary()->OpenUrl(
+  NewWindowDelegate::GetInstance()->OpenUrl(
       url_, NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       NewWindowDelegate::Disposition::kNewForegroundTab);
 }
diff --git a/ash/capture_mode/capture_mode_controller.cc b/ash/capture_mode/capture_mode_controller.cc
index 5e4679b..7b6a6af 100644
--- a/ash/capture_mode/capture_mode_controller.cc
+++ b/ash/capture_mode/capture_mode_controller.cc
@@ -255,7 +255,7 @@
 // Called when the "Share to YouTube" button is pressed to
 // open the YouTube share video page.
 void OnShareToYouTubeButtonPressed() {
-  NewWindowDelegate::GetPrimary()->OpenUrl(
+  NewWindowDelegate::GetInstance()->OpenUrl(
       GURL(kShareToYouTubeURL),
       NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       NewWindowDelegate::Disposition::kNewForegroundTab);
diff --git a/ash/capture_mode/capture_mode_session.cc b/ash/capture_mode/capture_mode_session.cc
index 21b334c8..9340f24 100644
--- a/ash/capture_mode/capture_mode_session.cc
+++ b/ash/capture_mode/capture_mode_session.cc
@@ -1698,7 +1698,7 @@
 }
 
 void CaptureModeSession::OnDisclaimerLinkPressed(const char* url) {
-  NewWindowDelegate::GetPrimary()->OpenUrl(
+  NewWindowDelegate::GetInstance()->OpenUrl(
       GURL(url), NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       NewWindowDelegate::Disposition::kNewForegroundTab);
 
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc
index dbdece1e..d71d5dd2 100644
--- a/ash/constants/ash_features.cc
+++ b/ash/constants/ash_features.cc
@@ -3732,10 +3732,6 @@
 #endif  // BUILDFLAG(GOOGLE_CHROME_BRANDING);
 }
 
-bool IsForestFeatureEnabled() {
-  return base::FeatureList::IsEnabled(kForestFeature);
-}
-
 bool IsFullscreenAfterUnlockAllowed() {
   return base::FeatureList::IsEnabled(kFullscreenAfterUnlockAllowed);
 }
diff --git a/ash/constants/ash_features.h b/ash/constants/ash_features.h
index 486e88d..6511484a 100644
--- a/ash/constants/ash_features.h
+++ b/ash/constants/ash_features.h
@@ -1169,7 +1169,6 @@
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsFloatingWorkspaceV2Enabled();
 COMPONENT_EXPORT(ASH_CONSTANTS)
 bool ShouldForceEnableServerSideSpeechRecognition();
-COMPONENT_EXPORT(ASH_CONSTANTS) bool IsForestFeatureEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsEcheLauncherEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsEcheLauncherListViewEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsEcheNetworkConnectionStateEnabled();
diff --git a/ash/dbus/url_handler_service_provider.cc b/ash/dbus/url_handler_service_provider.cc
index c3eea6bc..62e072e3 100644
--- a/ash/dbus/url_handler_service_provider.cc
+++ b/ash/dbus/url_handler_service_provider.cc
@@ -80,7 +80,7 @@
 
   VLOG(1) << "Opening url now";
 
-  NewWindowDelegate::GetPrimary()->OpenUrl(
+  NewWindowDelegate::GetInstance()->OpenUrl(
       gurl, NewWindowDelegate::OpenUrlFrom::kUnspecified,
       NewWindowDelegate::Disposition::kNewForegroundTab);
   std::move(response_sender).Run(dbus::Response::FromMethodCall(method_call));
diff --git a/ash/drag_drop/tab_drag_drop_delegate.cc b/ash/drag_drop/tab_drag_drop_delegate.cc
index f192b36..36a14de 100644
--- a/ash/drag_drop/tab_drag_drop_delegate.cc
+++ b/ash/drag_drop/tab_drag_drop_delegate.cc
@@ -161,7 +161,7 @@
 
   auto closure = base::BindOnce(&TabDragDropDelegate::OnNewBrowserWindowCreated,
                                 base::Owned(this), location_in_screen);
-  NewWindowDelegate::GetPrimary()->NewWindowForDetachingTab(
+  NewWindowDelegate::GetInstance()->NewWindowForDetachingTab(
       source_window_, drop_data, std::move(closure));
 }
 
diff --git a/ash/game_dashboard/game_dashboard_main_menu_view.cc b/ash/game_dashboard/game_dashboard_main_menu_view.cc
index 2fde27e1..f6ae02a3 100644
--- a/ash/game_dashboard/game_dashboard_main_menu_view.cc
+++ b/ash/game_dashboard/game_dashboard_main_menu_view.cc
@@ -991,7 +991,7 @@
 }
 
 void GameDashboardMainMenuView::OnHelpButtonPressed() {
-  NewWindowDelegate::GetPrimary()->OpenUrl(
+  NewWindowDelegate::GetInstance()->OpenUrl(
       GURL(kHelpUrl), NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       NewWindowDelegate::Disposition::kNewForegroundTab);
   RecordGameDashboardFunctionTriggered(context_->app_id(),
diff --git a/ash/glanceables/classroom/glanceables_classroom_student_view.cc b/ash/glanceables/classroom/glanceables_classroom_student_view.cc
index b133c80..39e3e0c 100644
--- a/ash/glanceables/classroom/glanceables_classroom_student_view.cc
+++ b/ash/glanceables/classroom/glanceables_classroom_student_view.cc
@@ -269,7 +269,7 @@
 }
 
 void GlanceablesClassroomStudentView::OpenUrl(const GURL& url) const {
-  NewWindowDelegate::GetPrimary()->OpenUrl(
+  NewWindowDelegate::GetInstance()->OpenUrl(
       url, NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       NewWindowDelegate::Disposition::kNewForegroundTab);
 }
diff --git a/ash/glanceables/tasks/glanceables_tasks_view.cc b/ash/glanceables/tasks/glanceables_tasks_view.cc
index f642817..f5d440c 100644
--- a/ash/glanceables/tasks/glanceables_tasks_view.cc
+++ b/ash/glanceables/tasks/glanceables_tasks_view.cc
@@ -643,7 +643,7 @@
     RecordUserWithNoTasksRedictedToTasksUI();
   }
   RecordTasksLaunchSource(source);
-  NewWindowDelegate::GetPrimary()->OpenUrl(
+  NewWindowDelegate::GetInstance()->OpenUrl(
       target_url, NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       NewWindowDelegate::Disposition::kNewForegroundTab);
 }
diff --git a/ash/public/cpp/new_window_delegate.cc b/ash/public/cpp/new_window_delegate.cc
index 090227347..b59efacd 100644
--- a/ash/public/cpp/new_window_delegate.cc
+++ b/ash/public/cpp/new_window_delegate.cc
@@ -17,11 +17,6 @@
   return g_new_window_delegate;
 }
 
-// static
-NewWindowDelegate* NewWindowDelegate::GetPrimary() {
-  return g_new_window_delegate;
-}
-
 NewWindowDelegate::NewWindowDelegate() {
   CHECK(!g_new_window_delegate);
   g_new_window_delegate = this;
diff --git a/ash/public/cpp/new_window_delegate.h b/ash/public/cpp/new_window_delegate.h
index 33b4cdd1..b7be4808 100644
--- a/ash/public/cpp/new_window_delegate.h
+++ b/ash/public/cpp/new_window_delegate.h
@@ -41,11 +41,6 @@
   // Returns an instance connected to ash-chrome.
   static NewWindowDelegate* GetInstance();
 
-  // DEPRECATED: This method is no longer useful after Lacros deprecation. This
-  // now returns the same value as `GetInstance` but will be removed soon.
-  // TODO(b/367844818): Remove this.
-  static NewWindowDelegate* GetPrimary();
-
   // Invoked when the user uses Ctrl+T to open a new tab.
   virtual void NewTab() = 0;
 
diff --git a/ash/quick_insert/quick_insert_controller.cc b/ash/quick_insert/quick_insert_controller.cc
index 6b226c6..da1873d 100644
--- a/ash/quick_insert/quick_insert_controller.cc
+++ b/ash/quick_insert/quick_insert_controller.cc
@@ -223,13 +223,13 @@
 }
 
 void OpenLink(const GURL& url) {
-  NewWindowDelegate::GetPrimary()->OpenUrl(
+  NewWindowDelegate::GetInstance()->OpenUrl(
       url, NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       NewWindowDelegate::Disposition::kNewForegroundTab);
 }
 
 void OpenFile(const base::FilePath& path) {
-  NewWindowDelegate::GetPrimary()->OpenFile(path);
+  NewWindowDelegate::GetInstance()->OpenFile(path);
 }
 
 GURL GetUrlForNewWindow(QuickInsertNewWindowResult::Type type) {
diff --git a/ash/quick_pair/companion_app/companion_app_broker_impl.cc b/ash/quick_pair/companion_app/companion_app_broker_impl.cc
index 06f16f15..5bb43e6 100644
--- a/ash/quick_pair/companion_app/companion_app_broker_impl.cc
+++ b/ash/quick_pair/companion_app/companion_app_broker_impl.cc
@@ -137,7 +137,7 @@
                                  << ": No Play store link or installed app. "
                                     "Opening companion web page.";
 
-    NewWindowDelegate::GetPrimary()->OpenUrl(
+    NewWindowDelegate::GetInstance()->OpenUrl(
         GURL(ash::features::kFastPairPwaCompanionInstallUri.Get()),
         NewWindowDelegate::OpenUrlFrom::kUserInteraction,
         NewWindowDelegate::Disposition::kNewForegroundTab);
diff --git a/ash/quick_pair/ui/fast_pair/fast_pair_presenter_impl.cc b/ash/quick_pair/ui/fast_pair/fast_pair_presenter_impl.cc
index d4c275f..b5b7cdf1 100644
--- a/ash/quick_pair/ui/fast_pair/fast_pair_presenter_impl.cc
+++ b/ash/quick_pair/ui/fast_pair/fast_pair_presenter_impl.cc
@@ -264,7 +264,7 @@
 
 void FastPairPresenterImpl::OnDiscoveryLearnMoreClicked(
     DiscoveryCallback callback) {
-  NewWindowDelegate::GetPrimary()->OpenUrl(
+  NewWindowDelegate::GetInstance()->OpenUrl(
       GURL(kDiscoveryLearnMoreLink),
       NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       NewWindowDelegate::Disposition::kNewForegroundTab);
@@ -419,7 +419,7 @@
 
 void FastPairPresenterImpl::OnAssociateAccountLearnMoreClicked(
     AssociateAccountCallback callback) {
-  NewWindowDelegate::GetPrimary()->OpenUrl(
+  NewWindowDelegate::GetInstance()->OpenUrl(
       GURL(kAssociateAccountLearnMoreLink),
       NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       NewWindowDelegate::Disposition::kNewForegroundTab);
diff --git a/ash/shelf/shelf_context_menu_model.cc b/ash/shelf/shelf_context_menu_model.cc
index e991613..27adc6b 100644
--- a/ash/shelf/shelf_context_menu_model.cc
+++ b/ash/shelf/shelf_context_menu_model.cc
@@ -123,7 +123,7 @@
       // Record entry point metric to Personalization Hub through Home Screen.
       base::UmaHistogramEnumeration(kPersonalizationEntryPointHistogramName,
                                     PersonalizationEntryPoint::kHomeScreen);
-      NewWindowDelegate::GetPrimary()->OpenPersonalizationHub();
+      NewWindowDelegate::GetInstance()->OpenPersonalizationHub();
       break;
     case MENU_HIDE_CONTINUE_SECTION:
       DCHECK(is_tablet_mode);
diff --git a/ash/system/input_device_settings/input_device_settings_notification_controller.cc b/ash/system/input_device_settings/input_device_settings_notification_controller.cc
index 4723133..7e6fb658 100644
--- a/ash/system/input_device_settings/input_device_settings_notification_controller.cc
+++ b/ash/system/input_device_settings/input_device_settings_notification_controller.cc
@@ -498,7 +498,7 @@
 }
 
 void OnLearnMoreClicked() {
-  NewWindowDelegate::GetPrimary()->OpenUrl(
+  NewWindowDelegate::GetInstance()->OpenUrl(
       GURL(kKeyboardSettingsLearnMoreLink),
       NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       NewWindowDelegate::Disposition::kNewForegroundTab);
diff --git a/ash/system/keyboard_brightness/unified_keyboard_brightness_slider_controller.cc b/ash/system/keyboard_brightness/unified_keyboard_brightness_slider_controller.cc
index 6aefa06..8e27737 100644
--- a/ash/system/keyboard_brightness/unified_keyboard_brightness_slider_controller.cc
+++ b/ash/system/keyboard_brightness/unified_keyboard_brightness_slider_controller.cc
@@ -114,7 +114,7 @@
     base::UmaHistogramEnumeration(
         kPersonalizationEntryPointHistogramName,
         PersonalizationEntryPoint::kKeyboardBrightnessSlider);
-    NewWindowDelegate* primary_delegate = NewWindowDelegate::GetPrimary();
+    NewWindowDelegate* primary_delegate = NewWindowDelegate::GetInstance();
     primary_delegate->OpenPersonalizationHub();
     return;
   }
diff --git a/ash/system/mahi/mahi_content_source_button.cc b/ash/system/mahi/mahi_content_source_button.cc
index 6899f44..40b2614c 100644
--- a/ash/system/mahi/mahi_content_source_button.cc
+++ b/ash/system/mahi/mahi_content_source_button.cc
@@ -96,7 +96,7 @@
   }
 
   // Opens or switches to the URL.
-  NewWindowDelegate::GetPrimary()->OpenUrl(
+  NewWindowDelegate::GetInstance()->OpenUrl(
       content_source_url_, NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       NewWindowDelegate::Disposition::kSwitchToTab);
 }
diff --git a/ash/system/mahi/mahi_panel_view.cc b/ash/system/mahi/mahi_panel_view.cc
index 77e5e1d0..646b3b93 100644
--- a/ash/system/mahi/mahi_panel_view.cc
+++ b/ash/system/mahi/mahi_panel_view.cc
@@ -949,7 +949,7 @@
 }
 
 void MahiPanelView::OnLearnMoreLinkClicked() {
-  NewWindowDelegate::GetPrimary()->OpenUrl(
+  NewWindowDelegate::GetInstance()->OpenUrl(
       GURL(chrome::kHelpMeReadWriteLearnMoreURL),
       NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       NewWindowDelegate::Disposition::kNewForegroundTab);
diff --git a/ash/system/pcie_peripheral/pcie_peripheral_notification_controller.cc b/ash/system/pcie_peripheral/pcie_peripheral_notification_controller.cc
index 79db4f86..84b6d5f3 100644
--- a/ash/system/pcie_peripheral/pcie_peripheral_notification_controller.cc
+++ b/ash/system/pcie_peripheral/pcie_peripheral_notification_controller.cc
@@ -102,7 +102,7 @@
       UpdateNotificationPrefCount(/*clicked_settings=*/true);
       break;
     case ButtonIndex::kLearnMore:
-      NewWindowDelegate::GetPrimary()->OpenUrl(
+      NewWindowDelegate::GetInstance()->OpenUrl(
           GURL(kLearnMoreHelpUrl),
           NewWindowDelegate::OpenUrlFrom::kUserInteraction,
           NewWindowDelegate::Disposition::kNewForegroundTab);
@@ -112,7 +112,7 @@
 }
 
 void OnGuestNotificationClicked(bool is_thunderbolt_only) {
-  NewWindowDelegate::GetPrimary()->OpenUrl(
+  NewWindowDelegate::GetInstance()->OpenUrl(
       GURL(kLearnMoreHelpUrl), NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       NewWindowDelegate::Disposition::kNewForegroundTab);
 
@@ -125,14 +125,14 @@
 }
 
 void OnPeripheralBlockedNotificationClicked() {
-  NewWindowDelegate::GetPrimary()->OpenUrl(
+  NewWindowDelegate::GetInstance()->OpenUrl(
       GURL(kLearnMoreHelpUrl), NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       NewWindowDelegate::Disposition::kNewForegroundTab);
   RemoveNotification(kPciePeripheralDeviceBlockedNotificationId);
 }
 
 void OnBillboardNotificationClicked() {
-  NewWindowDelegate::GetPrimary()->OpenUrl(
+  NewWindowDelegate::GetInstance()->OpenUrl(
       GURL(kLearnMoreHelpUrl), NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       NewWindowDelegate::Disposition::kNewForegroundTab);
   RemoveNotification(kPciePeripheralBillboardDeviceNotificationId);
diff --git a/ash/system/phonehub/app_stream_connection_error_dialog.cc b/ash/system/phonehub/app_stream_connection_error_dialog.cc
index 23571382..1cb5eae 100644
--- a/ash/system/phonehub/app_stream_connection_error_dialog.cc
+++ b/ash/system/phonehub/app_stream_connection_error_dialog.cc
@@ -167,7 +167,7 @@
             base::Unretained(this),
             base::BindRepeating(
                 &NewWindowDelegate::OpenUrl,
-                base::Unretained(NewWindowDelegate::GetPrimary()),
+                base::Unretained(NewWindowDelegate::GetInstance()),
                 GURL(phonehub::kPhoneHubLearnMoreLink),
                 NewWindowDelegate::OpenUrlFrom::kUserInteraction,
                 NewWindowDelegate::Disposition::kNewForegroundTab)));
diff --git a/ash/system/phonehub/bluetooth_disabled_view.cc b/ash/system/phonehub/bluetooth_disabled_view.cc
index 7f504a2..8e8111ca 100644
--- a/ash/system/phonehub/bluetooth_disabled_view.cc
+++ b/ash/system/phonehub/bluetooth_disabled_view.cc
@@ -65,7 +65,7 @@
 
 void BluetoothDisabledView::LearnMoreButtonPressed() {
   LogInterstitialScreenEvent(InterstitialScreenEvent::kLearnMore);
-  NewWindowDelegate::GetPrimary()->OpenUrl(
+  NewWindowDelegate::GetInstance()->OpenUrl(
       GURL(phonehub::kPhoneHubLearnMoreLink),
       NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       NewWindowDelegate::Disposition::kNewForegroundTab);
diff --git a/ash/system/phonehub/continue_browsing_chip.cc b/ash/system/phonehub/continue_browsing_chip.cc
index 4e06321..27b3c83 100644
--- a/ash/system/phonehub/continue_browsing_chip.cc
+++ b/ash/system/phonehub/continue_browsing_chip.cc
@@ -146,7 +146,7 @@
   phone_hub_metrics::LogTabContinuationChipClicked(index_);
   user_action_recorder_->RecordBrowserTabOpened();
 
-  NewWindowDelegate::GetPrimary()->OpenUrl(
+  NewWindowDelegate::GetInstance()->OpenUrl(
       url_, NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       NewWindowDelegate::Disposition::kNewForegroundTab);
 
diff --git a/ash/system/phonehub/phone_disconnected_view.cc b/ash/system/phonehub/phone_disconnected_view.cc
index 2d5d845..f53911c 100644
--- a/ash/system/phonehub/phone_disconnected_view.cc
+++ b/ash/system/phonehub/phone_disconnected_view.cc
@@ -51,7 +51,7 @@
           InterstitialScreenEvent::kLearnMore,
           base::BindRepeating(
               &NewWindowDelegate::OpenUrl,
-              base::Unretained(NewWindowDelegate::GetPrimary()),
+              base::Unretained(NewWindowDelegate::GetInstance()),
               GURL(phonehub::kPhoneHubLearnMoreLink),
               NewWindowDelegate::OpenUrlFrom::kUserInteraction,
               NewWindowDelegate::Disposition::kNewForegroundTab)),
diff --git a/ash/system/privacy_hub/privacy_hub_notification_controller.cc b/ash/system/privacy_hub/privacy_hub_notification_controller.cc
index a6d2519..4a2af83 100644
--- a/ash/system/privacy_hub/privacy_hub_notification_controller.cc
+++ b/ash/system/privacy_hub/privacy_hub_notification_controller.cc
@@ -357,7 +357,7 @@
           privacy_hub_metrics::PrivacyHubLearnMoreSensor::kGeolocation);
       return;
   }
-  NewWindowDelegate::GetPrimary()->OpenUrl(
+  NewWindowDelegate::GetInstance()->OpenUrl(
       GURL(kLearnMoreUrl), NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       NewWindowDelegate::Disposition::kNewForegroundTab);
 }
diff --git a/ash/webui/camera_app_ui/camera_app_helper_impl.cc b/ash/webui/camera_app_ui/camera_app_helper_impl.cc
index 3efb6d1..3c76ae66 100644
--- a/ash/webui/camera_app_ui/camera_app_helper_impl.cc
+++ b/ash/webui/camera_app_ui/camera_app_helper_impl.cc
@@ -343,7 +343,7 @@
 }
 
 void CameraAppHelperImpl::OpenUrlInBrowser(const GURL& url) {
-  NewWindowDelegate::GetPrimary()->OpenUrl(
+  NewWindowDelegate::GetInstance()->OpenUrl(
       url, NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       NewWindowDelegate::Disposition::kNewForegroundTab);
 }
diff --git a/ash/wm/desks/desk_action_view.cc b/ash/wm/desks/desk_action_view.cc
index 478bf1bb..608fc0a 100644
--- a/ash/wm/desks/desk_action_view.cc
+++ b/ash/wm/desks/desk_action_view.cc
@@ -40,19 +40,12 @@
   // merged into the desk action context menu, behind the a feature flag. Thus,
   // we replace the combine desks button with a button to open the context menu
   // if the feature is enabled.
-  if (features::IsForestFeatureEnabled()) {
-    context_menu_button_ = AddChildView(std::make_unique<DeskActionButton>(
-        // The tooltip for the context menu button will be set by the button
-        // itself, as its tooltip is constant.
-        std::u16string(), DeskActionButton::Type::kContextMenu,
-        std::move(context_menu_callback), this));
-    context_menu_button_->AddObserver(this);
-  } else {
-    combine_desks_button_ = AddChildView(std::make_unique<DeskActionButton>(
-        combine_desks_target_name, DeskActionButton::Type::kCombineDesk,
-        std::move(combine_desks_callback), this));
-    combine_desks_button_->AddObserver(this);
-  }
+  context_menu_button_ = AddChildView(std::make_unique<DeskActionButton>(
+      // The tooltip for the context menu button will be set by the button
+      // itself, as its tooltip is constant.
+      std::u16string(), DeskActionButton::Type::kContextMenu,
+      std::move(context_menu_callback), this));
+  context_menu_button_->AddObserver(this);
 
   close_all_button_ = AddChildView(std::make_unique<DeskActionButton>(
       close_all_target_name, DeskActionButton::Type::kCloseDesk,
@@ -61,19 +54,12 @@
 }
 
 DeskActionView::~DeskActionView() {
-  if (features::IsForestFeatureEnabled()) {
-    context_menu_button_->RemoveObserver(this);
-  } else {
-    combine_desks_button_->RemoveObserver(this);
-  }
+  context_menu_button_->RemoveObserver(this);
   close_all_button_->RemoveObserver(this);
 }
 
 bool DeskActionView::ChildHasFocus() const {
-  return (features::IsForestFeatureEnabled()
-              ? context_menu_button_->HasFocus()
-              : combine_desks_button_->HasFocus()) ||
-         close_all_button_->HasFocus();
+  return context_menu_button_->HasFocus() || close_all_button_->HasFocus();
 }
 
 void DeskActionView::OnViewFocused(views::View* observed) {
diff --git a/ash/wm/desks/desk_bar_view_base.cc b/ash/wm/desks/desk_bar_view_base.cc
index 47442a2..3f7f7c6 100644
--- a/ash/wm/desks/desk_bar_view_base.cc
+++ b/ash/wm/desks/desk_bar_view_base.cc
@@ -119,7 +119,7 @@
   auto* layer = view->layer();
   layer->SetFillsBoundsOpaquely(false);
 
-  if (features::IsForestFeatureEnabled() && !type_is_desk_button) {
+  if (!type_is_desk_button) {
     // Forest feature needs a transparent desks bar background. Still needs the
     // view layer to perform animations.
     return;
@@ -819,10 +819,7 @@
       if (state == State::kZero) {
         height = kDeskBarZeroStateHeight;
       } else {
-        height = DeskPreviewView::GetHeight(root) +
-                 (features::IsForestFeatureEnabled()
-                      ? kExpandedDeskBarHeight
-                      : kDeskBarNonPreviewAllocatedHeight);
+        height = DeskPreviewView::GetHeight(root) + kExpandedDeskBarHeight;
       }
       break;
   }
@@ -1924,19 +1921,10 @@
 
     int desk_index = desk_controller->GetDeskIndex(desk);
     auto* desk_action_view = mini_view->desk_action_view();
-    const std::u16string combine_desk_tooltip =
-        desk_controller->GetCombineDesksTargetName(desk);
     const std::u16string close_desk_tooltip =
         desk->name().empty() && desk_index != -1
             ? desk_controller->GetDeskDefaultName(desk_index)
             : desk->name();
-    // The combine desks button only exists if the feature is disabled. The
-    // context menu button that would appear in its place does not need to
-    // update its tooltip as it doesn't use a formatted string.
-    if (!features::IsForestFeatureEnabled()) {
-      desk_action_view->combine_desks_button()->UpdateTooltip(
-          combine_desk_tooltip);
-    }
     desk_action_view->close_all_button()->UpdateTooltip(close_desk_tooltip);
   }
 }
diff --git a/ash/wm/desks/desk_mini_view.cc b/ash/wm/desks/desk_mini_view.cc
index b0ada94..06f8728c 100644
--- a/ash/wm/desks/desk_mini_view.cc
+++ b/ash/wm/desks/desk_mini_view.cc
@@ -300,12 +300,6 @@
   CHECK(desk_);
 
   auto get_visible = [this]() -> bool {
-    // If revamp is enabled, then we still want to show the save desk options,
-    // even if we can't remove the desk.
-    if (!features::IsForestFeatureEnabled() &&
-        !DesksController::Get()->CanRemoveDesks()) {
-      return false;
-    }
     if (owner_bar_->dragged_item_over_bar()) {
       return false;
     }
@@ -343,16 +337,8 @@
 
   const bool visible = get_visible();
 
-  // Only show the combine desks button if there are app windows in the desk,
-  // or if the desk is active and there are windows that should be visible on
-  // all desks.
-  if (features::IsForestFeatureEnabled()) {
-    auto* context_menu_button = desk_action_view_->context_menu_button();
-    context_menu_button->SetVisible(context_menu_button->CanShow());
-  } else {
-    auto* combine_desks_button = desk_action_view_->combine_desks_button();
-    combine_desks_button->SetVisible(combine_desks_button->CanShow());
-  }
+  auto* context_menu_button = desk_action_view_->context_menu_button();
+  context_menu_button->SetVisible(context_menu_button->CanShow());
   auto* close_all_button = desk_action_view_->close_all_button();
   close_all_button->SetVisible(close_all_button->CanShow());
   desk_action_view_->SetVisible(visible);
@@ -511,11 +497,7 @@
 
   // Holdback metrics for the Saved Desk UI revamp.
   if (ShouldRecordSavedDesksOptionsHistogram(desk_, owner_bar_.get())) {
-    if (features::IsForestFeatureEnabled()) {
-      base::UmaHistogramBoolean(kSavedDeskMenuOptionsShownHistogramName, true);
-    } else {
-      base::UmaHistogramBoolean(kSavedDeskButtonsShownHistogramName, true);
-    }
+    base::UmaHistogramBoolean(kSavedDeskMenuOptionsShownHistogramName, true);
   }
 
   desk_preview_->SetHighlightOverlayVisibility(true);
diff --git a/ash/wm/desks/desks_unittests.cc b/ash/wm/desks/desks_unittests.cc
index 7acf681..ee723f5 100644
--- a/ash/wm/desks/desks_unittests.cc
+++ b/ash/wm/desks/desks_unittests.cc
@@ -1407,16 +1407,11 @@
   TestDeskObserver desk_1_observer;
   desk_1->AddObserver(&desk_1_observer);
 
-  if (features::IsForestFeatureEnabled()) {
-    views::MenuItemView* menu_item =
-        DesksTestApi::OpenDeskContextMenuAndGetMenuItem(
-            Shell::GetPrimaryRootWindow(), DeskBarViewBase::Type::kOverview,
-            /*index=*/0u, DeskActionContextMenu::CommandId::kCombineDesks);
-    LeftClickOn(menu_item);
-  } else {
-    // This will combine `desk_1` into `desk_4`.
-    CloseDeskFromMiniView(mini_view, GetEventGenerator());
-  }
+  views::MenuItemView* menu_item =
+      DesksTestApi::OpenDeskContextMenuAndGetMenuItem(
+          Shell::GetPrimaryRootWindow(), DeskBarViewBase::Type::kOverview,
+          /*index=*/0u, DeskActionContextMenu::CommandId::kCombineDesks);
+  LeftClickOn(menu_item);
 
   EXPECT_EQ(0, desk_1_observer.notify_counts());
   EXPECT_EQ(1, desk_4_observer.notify_counts());
@@ -1513,16 +1508,11 @@
   TestDeskObserver desk_2_observer;
   desk_2->AddObserver(&desk_2_observer);
 
-  if (features::IsForestFeatureEnabled()) {
-    views::MenuItemView* menu_item =
-        DesksTestApi::OpenDeskContextMenuAndGetMenuItem(
-            Shell::GetPrimaryRootWindow(), DeskBarViewBase::Type::kOverview,
-            /*index=*/1u, DeskActionContextMenu::CommandId::kCombineDesks);
-    LeftClickOn(menu_item);
-  } else {
-    // This will combine `desk_2` into `desk_1`.
-    CloseDeskFromMiniView(mini_view, GetEventGenerator());
-  }
+  views::MenuItemView* menu_item =
+      DesksTestApi::OpenDeskContextMenuAndGetMenuItem(
+          Shell::GetPrimaryRootWindow(), DeskBarViewBase::Type::kOverview,
+          /*index=*/1u, DeskActionContextMenu::CommandId::kCombineDesks);
+  LeftClickOn(menu_item);
 
   EXPECT_EQ(1, desk_1_observer.notify_counts());
   EXPECT_EQ(0, desk_2_observer.notify_counts());
@@ -8357,16 +8347,7 @@
   EnterOverview();
   ASSERT_TRUE(OverviewController::Get()->InOverviewSession());
 
-  DeskMiniView* mini_view = GetPrimaryRootDesksBarView()->mini_views()[0];
   auto* event_generator = GetEventGenerator();
-  if (!features::IsForestFeatureEnabled()) {
-    // We need to hover over the desk preview to properly check the combine
-    // desks button's visibility.
-    event_generator->MoveMouseTo(
-        mini_view->desk_preview()->GetBoundsInScreen().CenterPoint());
-    EXPECT_FALSE(
-        mini_view->desk_action_view()->combine_desks_button()->GetVisible());
-  }
 
   // We need to open the context menu to trigger its creation.
   OpenContextMenuForMiniView(0);
@@ -8383,27 +8364,14 @@
   DesksController::Get()->SendToDeskAtIndex(window.get(), 0);
   EnterOverview();
   ASSERT_TRUE(OverviewController::Get()->InOverviewSession());
-  mini_view = GetPrimaryRootDesksBarView()->mini_views()[0];
 
-  if (!features::IsForestFeatureEnabled()) {
-    event_generator->MoveMouseTo(
-        mini_view->desk_preview()->GetBoundsInScreen().CenterPoint());
-    EXPECT_TRUE(
-        mini_view->desk_action_view()->combine_desks_button()->GetVisible());
-  }
   OpenContextMenuForMiniView(0);
 
-  if (features::IsForestFeatureEnabled()) {
-    // The saved desk is part of the context menu with this feature on, although
-    // it may be disabled.
-    EXPECT_EQ(3u, DesksTestApi::GetContextMenuModelForDesk(
-                      DeskBarViewBase::Type::kOverview, 0)
-                      .GetItemCount());
-  } else {
-    EXPECT_EQ(2u, DesksTestApi::GetContextMenuModelForDesk(
-                      DeskBarViewBase::Type::kOverview, 0)
-                      .GetItemCount());
-  }
+  // The saved desk is part of the context menu with this feature on, although
+  // it may be disabled.
+  EXPECT_EQ(3u, DesksTestApi::GetContextMenuModelForDesk(
+                    DeskBarViewBase::Type::kOverview, 0)
+                    .GetItemCount());
 }
 
 TEST_P(DesksCloseAllTest, AccessibleName) {
@@ -8589,148 +8557,6 @@
   EXPECT_FALSE(highlight_overlay->GetVisible());
 }
 
-// Checks that the combine desks tooltip's validity is maintained whenever the
-// user adds a desk, closes a desk, moves a desk, or changes the name of a desk.
-TEST_P(DesksCloseAllTest, CombineDesksTooltipIsUpdatedOnUserActions) {
-  if (features::IsForestFeatureEnabled()) {
-    GTEST_SKIP()
-        << "Save desk buttons have been moved to the desk context menu. The "
-           "associated context menu item has text so it doesn't need a tooltip";
-  }
-  // Possible sources for tooltip updates.
-  enum class UpdateSource {
-    kAddDesk,
-    kCloseDesk,
-    kMoveActiveDesk,
-    kMoveNonActiveDesk,
-    kChangeActiveDeskName,
-    kChangeNonActiveDeskName,
-  };
-
-  struct {
-    const std::string scope_trace;
-    const UpdateSource source;
-
-    // The desk name that we expect `desk_1` in the test case to point to as the
-    // target for its combine desks operation after the test is performed.
-    const std::u16string expected_target_1;
-
-    // The desk name that we expect `desk_2` in the test case to point to as the
-    // target for its combine desks operation after the test is performed.
-    const std::u16string expected_target_2;
-  } kTestCases[] = {
-      {"Adding desk", UpdateSource::kAddDesk, u"Desk 2", u"Desk 1"},
-      {"Closing desk", UpdateSource::kCloseDesk, u"Desk 2", u"Desk 1"},
-      {"Moving active desk", UpdateSource::kMoveActiveDesk, u"Desk 1",
-       u"Desk 2"},
-      {"Moving non-active desk", UpdateSource::kMoveNonActiveDesk, u"Desk 2",
-       u"Desk 1"},
-      {"Changing active desk name", UpdateSource::kChangeActiveDeskName,
-       u"Desk 2", u"goo"},
-      {"Changing non-active desk name", UpdateSource::kChangeNonActiveDeskName,
-       u"gle", u"goo"},
-  };
-
-  // We need to make the display this large so that the mini views are
-  // draggable.
-  UpdateDisplay("1366x768");
-  auto* controller = DesksController::Get();
-
-  // Create two initial desks with one window each.
-  NewDesk();
-  ASSERT_EQ(2u, controller->desks().size());
-  Desk* desk_1 = controller->GetDeskAtIndex(0);
-  Desk* desk_2 = controller->GetDeskAtIndex(1);
-
-  WindowHolder win1(CreateAppWindow());
-  WindowHolder win2(CreateAppWindow());
-  controller->SendToDeskAtIndex(win1.window(), 0);
-  controller->SendToDeskAtIndex(win2.window(), 1);
-  ASSERT_EQ(1u, desk_1->windows().size());
-  ASSERT_EQ(1u, desk_2->windows().size());
-
-  EnterOverview();
-  ASSERT_TRUE(OverviewController::Get()->InOverviewSession());
-
-  const DeskBarViewBase* desks_bar_view = GetPrimaryRootDesksBarView();
-
-  // Cache the mini views and their name views and combine desks buttons.
-  DeskMiniView* mini_view_1 = desks_bar_view->mini_views()[0];
-  DeskMiniView* mini_view_2 = desks_bar_view->mini_views()[1];
-  DeskNameView* desk_name_view_1 = mini_view_1->desk_name_view();
-  DeskNameView* desk_name_view_2 = mini_view_2->desk_name_view();
-  const CloseButton* combine_desks_button_1 =
-      mini_view_1->desk_action_view()->combine_desks_button();
-  const CloseButton* combine_desks_button_2 =
-      mini_view_2->desk_action_view()->combine_desks_button();
-
-  const std::u16string tooltip_prefix = u"Combine with ";
-  auto* event_generator = GetEventGenerator();
-  for (const auto& test_case : kTestCases) {
-    SCOPED_TRACE(test_case.scope_trace);
-
-    ASSERT_TRUE(OverviewController::Get()->InOverviewSession());
-    ASSERT_EQ(tooltip_prefix + controller->GetCombineDesksTargetName(desk_1),
-              combine_desks_button_1->GetTooltipText());
-    ASSERT_EQ(tooltip_prefix + controller->GetCombineDesksTargetName(desk_2),
-              combine_desks_button_2->GetTooltipText());
-
-    switch (test_case.source) {
-      case UpdateSource::kAddDesk:
-        NewDesk();
-        break;
-      case UpdateSource::kCloseDesk:
-        ASSERT_EQ(3u, controller->desks().size());
-        RemoveDesk(controller->GetDeskAtIndex(2));
-        break;
-      case UpdateSource::kMoveActiveDesk:
-        ASSERT_TRUE(controller->GetDeskAtIndex(0)->is_active());
-        StartDragDeskPreview(mini_view_1, event_generator);
-        ASSERT_TRUE(desks_bar_view->IsDraggingDesk());
-        event_generator->MoveMouseTo(
-            mini_view_2->GetPreviewBoundsInScreen().CenterPoint());
-        event_generator->ReleaseLeftButton();
-        RunScheduledLayoutForAllOverviewDeskBars();
-        break;
-      case UpdateSource::kMoveNonActiveDesk:
-        ASSERT_FALSE(controller->GetDeskAtIndex(0)->is_active());
-        StartDragDeskPreview(mini_view_2, event_generator);
-        EXPECT_TRUE(desks_bar_view->IsDraggingDesk());
-        event_generator->MoveMouseTo(
-            mini_view_1->GetPreviewBoundsInScreen().CenterPoint());
-        event_generator->ReleaseLeftButton();
-        RunScheduledLayoutForAllOverviewDeskBars();
-        break;
-      case UpdateSource::kChangeActiveDeskName:
-        ASSERT_TRUE(controller->GetDeskAtIndex(0)->is_active());
-        event_generator->MoveMouseTo(
-            desk_name_view_1->GetBoundsInScreen().CenterPoint());
-        event_generator->ClickLeftButton();
-        PressAndReleaseKey(ui::VKEY_G);
-        PressAndReleaseKey(ui::VKEY_O);
-        PressAndReleaseKey(ui::VKEY_O);
-        PressAndReleaseKey(ui::VKEY_RETURN);
-        RunScheduledLayoutForAllOverviewDeskBars();
-        break;
-      case UpdateSource::kChangeNonActiveDeskName:
-        ASSERT_EQ(u"goo", mini_view_1->desk()->name());
-        ASSERT_FALSE(controller->GetDeskAtIndex(1)->is_active());
-        LeftClickOn(desk_name_view_2);
-        PressAndReleaseKey(ui::VKEY_G);
-        PressAndReleaseKey(ui::VKEY_L);
-        PressAndReleaseKey(ui::VKEY_E);
-        PressAndReleaseKey(ui::VKEY_RETURN);
-        RunScheduledLayoutForAllOverviewDeskBars();
-        break;
-    }
-
-    EXPECT_EQ(tooltip_prefix + test_case.expected_target_1,
-              combine_desks_button_1->GetTooltipText());
-    EXPECT_EQ(tooltip_prefix + test_case.expected_target_2,
-              combine_desks_button_2->GetTooltipText());
-  }
-}
-
 // Test metrics are being recorded in close all case.
 TEST_P(DesksCloseAllTest, TestMetricsRecordingWhenCloseAllWindows) {
   struct {
@@ -9385,8 +9211,6 @@
   void CombineDeskWithMenu(size_t index,
                            aura::Window* root,
                            DeskBarViewBase::Type bar_type) {
-    CHECK(features::IsForestFeatureEnabled());
-
     // Get the menu option to save the desk as a template and click it.
     views::MenuItemView* menu_item =
         DesksTestApi::OpenDeskContextMenuAndGetMenuItem(
@@ -9480,8 +9304,7 @@
 TEST_P(DeskBarTest, Basic) {
   UpdateDisplay("800x600");
 
-  const int expected_expanded_overview_height =
-      features::IsForestFeatureEnabled() ? 114 : 98;
+  const int expected_expanded_overview_height = 114;
 
   const DeskBarTestBasicCase tests[] = {
       {.test_name = "single desk + bottom shelf + saved desks",
@@ -9618,8 +9441,7 @@
   auto* desk_bar_widget = desk_bar_view->GetWidget();
   ASSERT_TRUE(desk_bar_widget);
 
-  const int expected_expanded_overview_height =
-      features::IsForestFeatureEnabled() ? 114 : 98;
+  const int expected_expanded_overview_height = 114;
 
   if (bar_type_ == DeskBarViewBase::Type::kOverview) {
     EXPECT_THAT(desk_bar_widget->GetWindowBoundsInScreen(),
@@ -9691,15 +9513,9 @@
     event_generator->MoveMouseTo(
         mini_view->desk_preview()->GetBoundsInScreen().CenterPoint());
 
-    if (features::IsForestFeatureEnabled()) {
-      EXPECT_TRUE(mini_view->desk_action_view()->context_menu_button());
-      EXPECT_TRUE(
-          mini_view->desk_action_view()->context_menu_button()->GetVisible());
-    } else {
-      EXPECT_TRUE(mini_view->desk_action_view()->combine_desks_button());
-      EXPECT_TRUE(
-          mini_view->desk_action_view()->combine_desks_button()->GetVisible());
-    }
+    EXPECT_TRUE(mini_view->desk_action_view()->context_menu_button());
+    EXPECT_TRUE(
+        mini_view->desk_action_view()->context_menu_button()->GetVisible());
 
     EXPECT_TRUE(
         mini_view->desk_action_view()->close_all_button()->GetVisible());
@@ -10215,15 +10031,9 @@
     if (i == 0) {
       PressAndReleaseKey(ui::VKEY_TAB);
 
-      if (features::IsForestFeatureEnabled()) {
-        ASSERT_TRUE(mini_view->desk_action_view()->context_menu_button());
-        ASSERT_TRUE(
-            mini_view->desk_action_view()->context_menu_button()->HasFocus());
-      } else {
-        ASSERT_TRUE(mini_view->desk_action_view()->combine_desks_button());
-        ASSERT_TRUE(
-            mini_view->desk_action_view()->combine_desks_button()->HasFocus());
-      }
+      ASSERT_TRUE(mini_view->desk_action_view()->context_menu_button());
+      ASSERT_TRUE(
+          mini_view->desk_action_view()->context_menu_button()->HasFocus());
     }
 
     PressAndReleaseKey(ui::VKEY_TAB);
@@ -10301,15 +10111,9 @@
     if (i == 0) {
       PressAndReleaseKey(ui::VKEY_TAB, ui::EF_SHIFT_DOWN);
 
-      if (features::IsForestFeatureEnabled()) {
-        ASSERT_TRUE(mini_view->desk_action_view()->context_menu_button());
-        ASSERT_TRUE(
-            mini_view->desk_action_view()->context_menu_button()->HasFocus());
-      } else {
-        ASSERT_TRUE(mini_view->desk_action_view()->combine_desks_button());
-        ASSERT_TRUE(
-            mini_view->desk_action_view()->combine_desks_button()->HasFocus());
-      }
+      ASSERT_TRUE(mini_view->desk_action_view()->context_menu_button());
+      ASSERT_TRUE(
+          mini_view->desk_action_view()->context_menu_button()->HasFocus());
     }
 
     // The shortcut view only appears on the first 8 desks in the desk button
@@ -10559,12 +10363,7 @@
 
   // Combine desks.
   auto* root_window = Shell::Get()->GetPrimaryRootWindow();
-  if (features::IsForestFeatureEnabled()) {
-    CombineDeskWithMenu(/*index=*/0, root_window, bar_type_);
-  } else {
-    CloseDeskWithButton(/*index=*/0, /*close_all=*/false, root_window,
-                        bar_type_);
-  }
+  CombineDeskWithMenu(/*index=*/0, root_window, bar_type_);
 
   histogram_tester.ExpectTotalCount(
       bar_type_ == DeskBarViewBase::Type::kDeskButton
@@ -10629,12 +10428,7 @@
   OpenDeskBar();
 
   // Combine desks.
-  if (features::IsForestFeatureEnabled()) {
-    CombineDeskWithMenu(/*index=*/0, root_window, bar_type_);
-  } else {
-    CloseDeskWithButton(/*index=*/0, /*close_all=*/false, root_window,
-                        bar_type_);
-  }
+  CombineDeskWithMenu(/*index=*/0, root_window, bar_type_);
 
   histogram_tester.ExpectBucketCount(
       kDeskSwitchHistogramName,
@@ -10677,18 +10471,12 @@
 
   // Long press doesn't register if there have been touch events on the desk bar
   // prior to trying to long press. Close and reopen the desk bar.
-  if (features::IsForestFeatureEnabled()) {
-    CloseDeskBar();
-  }
+  CloseDeskBar();
+
   OpenDeskBar();
 
   // Combine desks.
-  if (features::IsForestFeatureEnabled()) {
-    CombineDeskWithMenu(/*index=*/0, root_window, bar_type_);
-  } else {
-    CloseDeskWithButton(/*index=*/0, /*close_all=*/false, root_window,
-                        bar_type_);
-  }
+  CombineDeskWithMenu(/*index=*/0, root_window, bar_type_);
 
   histogram_tester.ExpectBucketCount(
       kRemoveDeskHistogramName,
@@ -10829,15 +10617,9 @@
   views::test::RunScheduledLayout(desk_bar_view);
   auto* desk_action_view = desk_bar_view->mini_views()[1]->desk_action_view();
 
-  if (features::IsForestFeatureEnabled()) {
-    EXPECT_TRUE(desk_action_view->context_menu_button());
-    EXPECT_THAT(desk_action_view->context_menu_button()->GetTooltipText(),
-                u"Open context menu");
-  } else {
-    EXPECT_TRUE(desk_action_view->combine_desks_button());
-    EXPECT_THAT(desk_action_view->combine_desks_button()->GetTooltipText(),
-                u"Combine with Desk 1");
-  }
+  EXPECT_TRUE(desk_action_view->context_menu_button());
+  EXPECT_THAT(desk_action_view->context_menu_button()->GetTooltipText(),
+              u"Open context menu");
 
   EXPECT_THAT(desk_action_view->close_all_button()->GetTooltipText(),
               u"Close Desk 2 and windows");
@@ -10848,15 +10630,9 @@
   PressAndReleaseKey(ui::VKEY_RETURN);
   views::test::RunScheduledLayout(desk_bar_view);
 
-  if (features::IsForestFeatureEnabled()) {
-    EXPECT_TRUE(desk_action_view->context_menu_button());
-    EXPECT_THAT(desk_action_view->context_menu_button()->GetTooltipText(),
-                u"Open context menu");
-  } else {
-    EXPECT_TRUE(desk_action_view->combine_desks_button());
-    EXPECT_THAT(desk_action_view->combine_desks_button()->GetTooltipText(),
-                u"Combine with Desk 1");
-  }
+  EXPECT_TRUE(desk_action_view->context_menu_button());
+  EXPECT_THAT(desk_action_view->context_menu_button()->GetTooltipText(),
+              u"Open context menu");
 
   EXPECT_THAT(desk_action_view->close_all_button()->GetTooltipText(),
               u"Close D2 and windows");
diff --git a/ash/wm/desks/templates/saved_desk_util.cc b/ash/wm/desks/templates/saved_desk_util.cc
index 92952a5d3..1a7f8fb9 100644
--- a/ash/wm/desks/templates/saved_desk_util.cc
+++ b/ash/wm/desks/templates/saved_desk_util.cc
@@ -88,10 +88,6 @@
 }
 
 bool ShouldShowSavedDesksOptionsForDesk(Desk* desk, DeskBarViewBase* bar_view) {
-  if (!features::IsForestFeatureEnabled()) {
-    return false;
-  }
-
   if (display::Screen::GetScreen()->InTabletMode()) {
     return false;
   }
diff --git a/ash/wm/overview/overview_grid.cc b/ash/wm/overview/overview_grid.cc
index 1fa7d7a..c08ee98 100644
--- a/ash/wm/overview/overview_grid.cc
+++ b/ash/wm/overview/overview_grid.cc
@@ -128,10 +128,6 @@
 constexpr int kNoItemsIndicatorRoundingDp = 16;
 constexpr int kNoItemsIndicatorVerticalPaddingDp = 8;
 
-// Distance from the bottom of the save desk as template button to the top of
-// the first overview item.
-constexpr int kSaveDeskAsTemplateOverviewItemSpacingDp = 45;
-
 // Distance from the bottom of the last overview item to the top of the split
 // view setup view toast widget.
 constexpr int kSplitViewSetupToastSpacingDp = 40;
@@ -304,37 +300,6 @@
   OverviewExitMetricsTracker metrics_tracker_;
 };
 
-// Creates `save_desk_button_container_widget_`. It contains SaveDeskAsTemplate
-// button and save for later button.
-std::unique_ptr<views::Widget> CreateSaveDeskButtonContainerWidget(
-    aura::Window* root_window) {
-  views::Widget::InitParams params(
-      views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET,
-      views::Widget::InitParams::TYPE_POPUP);
-  params.activatable = views::Widget::InitParams::Activatable::kYes;
-  params.opacity = views::Widget::InitParams::WindowOpacity::kTranslucent;
-  params.name = "SaveDeskButtonContainerWidget";
-  params.accept_events = true;
-  // This widget is hidden during window dragging, but will become visible on
-  // mouse/touch release. Place it in the active desk container so it remains
-  // beneath the dragged window when it is animating back to the overview grid.
-  params.parent = desks_util::GetActiveDeskContainerForRoot(root_window);
-  params.init_properties_container.SetProperty(kHideInDeskMiniViewKey, true);
-  // This should not show up in the MRU list. Otherwise, it will be treated as
-  // unsupported crostini app.
-  params.init_properties_container.SetProperty(kOverviewUiKey, true);
-
-  auto widget = std::make_unique<views::Widget>();
-  widget->set_focus_on_creation(false);
-  widget->Init(std::move(params));
-  // Turn off default widget animations.
-  widget->SetVisibilityAnimationTransition(views::Widget::ANIMATE_NONE);
-
-  aura::Window* window = widget->GetNativeWindow();
-  window->parent()->StackChildAtBottom(window);
-  return widget;
-}
-
 float GetWantedDropTargetOpacity(
     SplitViewDragIndicators::WindowDraggingState window_dragging_state) {
   switch (window_dragging_state) {
@@ -2399,113 +2364,9 @@
   // viable to be shown, then we want to record a histogram for holdback
   // purposes.
   if (target_visible && visibility_changed) {
-    if (features::IsForestFeatureEnabled()) {
-      base::UmaHistogramBoolean(kShowSavedDeskButtonsRevampEnabledHistogramName,
-                                true);
-    } else {
-      base::UmaHistogramBoolean(
-          kShowSavedDeskButtonsRevampDisabledHistogramName, true);
-    }
+    base::UmaHistogramBoolean(kShowSavedDeskButtonsRevampEnabledHistogramName,
+                              true);
   }
-
-  // If the UI revamp is enabled, we return as the buttons will not be shown.
-  if (features::IsForestFeatureEnabled()) {
-    return;
-  }
-
-  // Adds or removes the widget from the accessibility focus order when exiting
-  // the scope. Skip the update if the widget's visibility hasn't changed.
-  absl::Cleanup update_accessibility_focus = [this, visibility_changed] {
-    if (visibility_changed) {
-      overview_session_->UpdateAccessibilityFocus();
-    }
-  };
-
-  if (!target_visible) {
-    if (visibility_changed && save_desk_button_container_widget_) {
-      PerformFadeOutLayer(
-          save_desk_button_container_widget_->GetLayer(),
-          /*animate=*/true,
-          base::BindOnce(&OverviewGrid::OnSaveDeskButtonContainerFadedOut,
-                         weak_ptr_factory_.GetWeakPtr()));
-    }
-    return;
-  }
-
-  // Create `save_desk_button_container_widget_`.
-  if (!save_desk_button_container_widget_) {
-    save_desk_button_container_widget_ =
-        CreateSaveDeskButtonContainerWidget(root_window_);
-    save_desk_button_container_widget_->SetContentsView(
-        std::make_unique<SavedDeskSaveDeskButtonContainer>(
-            base::BindRepeating(
-                &OverviewGrid::OnSaveDeskAsTemplateButtonPressed,
-                weak_ptr_factory_.GetWeakPtr()),
-            base::BindRepeating(&OverviewGrid::OnSaveDeskForLaterButtonPressed,
-                                weak_ptr_factory_.GetWeakPtr())));
-  }
-
-  // If a desk animation is in progress, we don't want to animate
-  // `save_desk_button_container_widget_`.
-  const bool in_desk_animation = DesksController::Get()->animation();
-
-  // There may be an existing animation in progress triggered by
-  // `PerformFadeOutLayer()` above, which animates a widget to 0.f before
-  // calling `OnSaveDeskButtonContainerFadedOut()` to hide the widget on
-  // animation end. Stop animating so that the callbacks associated get fired,
-  // otherwise we may end up trying to show a widget that's already shown.
-  // `StopAnimating()` is a no-op if there is no animation in progress.
-  if (visibility_changed) {
-    save_desk_button_container_widget_->GetLayer()
-        ->GetAnimator()
-        ->StopAnimating();
-    save_desk_button_container_widget_->ShowInactive();
-    PerformFadeInLayer(save_desk_button_container_widget_->GetLayer(),
-                       /*animate=*/!in_desk_animation);
-  }
-
-  // Enable/disable button and update tooltip.
-  auto* container = views::AsViewClass<SavedDeskSaveDeskButtonContainer>(
-      save_desk_button_container_widget_->GetContentsView());
-  CHECK(container);
-
-  SaveDeskOptionStatus template_status =
-      GetEnableStateAndTooltipIDForTemplateType(DeskTemplateType::kTemplate);
-  SaveDeskOptionStatus save_later_status =
-      GetEnableStateAndTooltipIDForTemplateType(
-          DeskTemplateType::kSaveAndRecall);
-
-  container->UpdateButtonEnableStateAndTooltip(DeskTemplateType::kTemplate,
-                                               template_status);
-  container->UpdateButtonEnableStateAndTooltip(DeskTemplateType::kSaveAndRecall,
-                                               save_later_status);
-
-  // Set the widget position above the overview item window and default width
-  // and height.
-  gfx::RectF first_overview_item_bounds;
-  if (item_list_.front()->animating_to_close()) {
-    CHECK_GT(item_list_.size(), 1u);
-    first_overview_item_bounds = item_list_[1]->target_bounds();
-  } else {
-    first_overview_item_bounds = item_list_.front()->target_bounds();
-  }
-
-  // Animate the widget so it moves with the items. The widget's size isn't
-  // changing, so its ok to use a bounds animation as opposed to a transform
-  // animation. If the visibility has changed, skip the bounds animation and use
-  // the fade animation from above. Align the widget so it is visually aligned
-  // with the first overview item.
-  ScopedOverviewAnimationSettings settings(
-      visibility_changed || in_desk_animation
-          ? OVERVIEW_ANIMATION_NONE
-          : OVERVIEW_ANIMATION_LAYOUT_OVERVIEW_ITEMS_IN_OVERVIEW,
-      save_desk_button_container_widget_->GetNativeWindow());
-  gfx::Point available_origin =
-      gfx::ToRoundedPoint(first_overview_item_bounds.origin()) +
-      gfx::Vector2d(0, -kSaveDeskAsTemplateOverviewItemSpacingDp);
-  save_desk_button_container_widget_->SetBounds(gfx::Rect(
-      available_origin, save_desk_button_container_widget_->GetContentsView()
-                            ->GetPreferredSize()));
 }
 
 void OverviewGrid::EnableSaveDeskButtonContainer() {
diff --git a/ash/wm/overview/overview_utils.cc b/ash/wm/overview/overview_utils.cc
index e961173..753c061 100644
--- a/ash/wm/overview/overview_utils.cc
+++ b/ash/wm/overview/overview_utils.cc
@@ -292,19 +292,14 @@
     const HotseatState hotseat_state =
         Shelf::ForWindow(target_root)->shelf_layout_manager()->hotseat_state();
 
-    const bool hotseat_extended = hotseat_state == HotseatState::kExtended;
     const bool show_home_launcher =
         hotseat_state == HotseatState::kShownHomeLauncher;
 
-    const bool forest_enabled = features::IsForestFeatureEnabled();
-
     const int hotseat_bottom_inset =
         ShelfConfig::Get()->GetHotseatSize(HotseatDensity::kNormal) +
         ShelfConfig::Get()->hotseat_bottom_padding();
 
-    if (!forest_enabled && hotseat_extended) {
-      bounds.Inset(gfx::Insets::TLBR(0, 0, hotseat_bottom_inset, 0));
-    } else if (forest_enabled && show_home_launcher) {
+    if (show_home_launcher) {
       // If the home launcher is shown, add some extra spacing between the birch
       // bar and the hotseat. Subtract the in app shelf size since it is already
       // factored in the work area calculations.
diff --git a/ash/wm/window_restore/window_restore_util.cc b/ash/wm/window_restore/window_restore_util.cc
index 482bd186..927a382c 100644
--- a/ash/wm/window_restore/window_restore_util.cc
+++ b/ash/wm/window_restore/window_restore_util.cc
@@ -65,16 +65,14 @@
       static_cast<int>(full_restore::RestoreOption::kAskEveryTime),
       user_prefs::PrefRegistrySyncable::SYNCABLE_OS_PREF);
 
-  if (features::IsForestFeatureEnabled()) {
-    // TODO(crbug.com/432562252): Fix tests that fail when this value is true.
-    registry->RegisterBooleanPref(prefs::kShowInformedRestoreOnboarding,
-                                  !for_test);
-    registry->RegisterIntegerPref(prefs::kInformedRestoreNudgeShownCount, 0);
-    registry->RegisterTimePref(prefs::kInformedRestoreNudgeLastShown,
-                               base::Time());
-    registry->RegisterStringPref(prefs::kInformedRestoreLastVersion,
-                                 std::string());
-  }
+  // TODO(crbug.com/432562252): Fix tests that fail when this value is true.
+  registry->RegisterBooleanPref(prefs::kShowInformedRestoreOnboarding,
+                                !for_test);
+  registry->RegisterIntegerPref(prefs::kInformedRestoreNudgeShownCount, 0);
+  registry->RegisterTimePref(prefs::kInformedRestoreNudgeLastShown,
+                             base::Time());
+  registry->RegisterStringPref(prefs::kInformedRestoreLastVersion,
+                               std::string());
 }
 
 bool HasRestorePref(PrefService* prefs) {
diff --git a/base/allocator/partition_allocator/src/partition_alloc/partition_alloc-inl.h b/base/allocator/partition_allocator/src/partition_alloc/partition_alloc-inl.h
index 050d696..7d36a1c 100644
--- a/base/allocator/partition_allocator/src/partition_alloc/partition_alloc-inl.h
+++ b/base/allocator/partition_allocator/src/partition_alloc/partition_alloc-inl.h
@@ -89,6 +89,41 @@
   return UntagPtr(slot_start);
 }
 
+// In order to resolve circular dependencies, define template method:
+// GetMetadataOffset() here and SlotSpanMetadata::FromAddr(),
+// SuperPageExtentEntry's SuperPageBeginFromExtent() ... use it.
+template <typename T>
+std::ptrdiff_t GetMetadataOffset([[maybe_unused]] const T* root) {
+#if PA_CONFIG(MOVE_METADATA_OUT_OF_GIGACAGE)
+#if PA_BUILDFLAG(DCHECKS_ARE_ON)
+  PA_DCHECK(root);
+#endif  // PA_BUILDFLAG(DCHECKS_ARE_ON)
+  return static_cast<std::ptrdiff_t>(root->MetadataOffset());
+#else
+  return static_cast<std::ptrdiff_t>(SystemPageSize());
+#endif  // PA_CONFIG(MOVE_METADATA_OUT_OF_GIGACAGE)
+}
+
+PA_ALWAYS_INLINE uintptr_t
+PartitionSuperPageToMetadataPage(uintptr_t super_page,
+                                 [[maybe_unused]] std::ptrdiff_t offset) {
+#if PA_CONFIG(MOVE_METADATA_OUT_OF_GIGACAGE)
+  return super_page + static_cast<uintptr_t>(offset);
+#else
+  return super_page + SystemPageSize();
+#endif  // PA_CONFIG(MOVE_METADATA_OUT_OF_GIGACAGE)
+}
+
+PA_ALWAYS_INLINE uintptr_t
+PartitionMetadataPageToSuperPage(uintptr_t metadata_page,
+                                 [[maybe_unused]] std::ptrdiff_t offset) {
+#if PA_CONFIG(MOVE_METADATA_OUT_OF_GIGACAGE)
+  return metadata_page - static_cast<uintptr_t>(offset);
+#else
+  return metadata_page - SystemPageSize();
+#endif  // PA_CONFIG(MOVE_METADATA_OUT_OF_GIGACAGE)
+}
+
 }  // namespace partition_alloc::internal
 
 #endif  // PARTITION_ALLOC_PARTITION_ALLOC_INL_H_
diff --git a/base/allocator/partition_allocator/src/partition_alloc/partition_page.h b/base/allocator/partition_allocator/src/partition_alloc/partition_page.h
index 26ada30..b9908e6 100644
--- a/base/allocator/partition_allocator/src/partition_alloc/partition_page.h
+++ b/base/allocator/partition_allocator/src/partition_alloc/partition_page.h
@@ -12,6 +12,7 @@
 #include "partition_alloc/build_config.h"
 #include "partition_alloc/buildflags.h"
 #include "partition_alloc/partition_address_space.h"
+#include "partition_alloc/partition_alloc-inl.h"
 #include "partition_alloc/partition_alloc_base/bits.h"
 #include "partition_alloc/partition_alloc_base/compiler_specific.h"
 #include "partition_alloc/partition_alloc_base/component_export.h"
@@ -135,14 +136,62 @@
   // |slot_span| pointer may be the result of an offset calculation and
   // therefore cannot be trusted. The objective of these functions is to
   // sanitize this input.
+
+  // If metadata is outside of GigaCage, the following methods:
+  //  ToSlotSpanStart(), FromAddr(), FromSlotStart(), FromObject(),
+  //  FromObjectInnerAddr(), and FromObjectInnerAddr()
+  // are much slower, because:
+  // (1) need to find `pool` from the given address,
+  // (2) need to obtain `offset` from the `pool`.
+  // If `PartitionRoot` is known or metadata offset is known, it is much better
+  // to use methods with `root` or `offset`.
+  // For example, `FromAddr(uintptr_t address)` is slow and not recommended.
+  // `FromAddr(uintptr_t address, const PartitionRoot*)` takes a `root`
+  // parameter and `FromAddr(uintptr_t address, std::ptrdiff offset)` takes an
+  // `offset` parameter, which are recommended 146-147.
   PA_ALWAYS_INLINE static uintptr_t ToSlotSpanStart(
-      const SlotSpanMetadata* slot_span);
+      const SlotSpanMetadata* slot_span,
+      [[maybe_unused]] const PartitionRoot* root = nullptr);
+  PA_ALWAYS_INLINE static uintptr_t ToSlotSpanStart(
+      const SlotSpanMetadata* slot_span,
+      [[maybe_unused]] std::ptrdiff_t offset);
+
   PA_ALWAYS_INLINE static SlotSpanMetadata* FromAddr(uintptr_t address);
+  PA_ALWAYS_INLINE static SlotSpanMetadata* FromAddr(
+      uintptr_t address,
+      [[maybe_unused]] const PartitionRoot* root);
+  PA_ALWAYS_INLINE static SlotSpanMetadata* FromAddr(
+      uintptr_t address,
+      [[maybe_unused]] std::ptrdiff_t offset);
+
   PA_ALWAYS_INLINE static SlotSpanMetadata* FromSlotStart(uintptr_t slot_start);
+  PA_ALWAYS_INLINE static SlotSpanMetadata* FromSlotStart(
+      uintptr_t slot_start,
+      [[maybe_unused]] const PartitionRoot* root);
+  PA_ALWAYS_INLINE static SlotSpanMetadata* FromSlotStart(
+      uintptr_t slot_start,
+      [[maybe_unused]] std::ptrdiff_t offset);
+
   PA_ALWAYS_INLINE static SlotSpanMetadata* FromObject(const void* object);
+  PA_ALWAYS_INLINE static SlotSpanMetadata* FromObject(
+      const void* object,
+      [[maybe_unused]] const PartitionRoot* root);
+  PA_ALWAYS_INLINE static SlotSpanMetadata* FromObject(
+      const void* object,
+      [[maybe_unused]] std::ptrdiff_t offset);
+
   PA_ALWAYS_INLINE static SlotSpanMetadata* FromObjectInnerAddr(
-      uintptr_t address);
-  PA_ALWAYS_INLINE static SlotSpanMetadata* FromObjectInnerPtr(const void* ptr);
+      uintptr_t address,
+      [[maybe_unused]] const PartitionRoot* root);
+  PA_ALWAYS_INLINE static SlotSpanMetadata* FromObjectInnerAddr(
+      uintptr_t address,
+      [[maybe_unused]] std::ptrdiff_t offset);
+  PA_ALWAYS_INLINE static SlotSpanMetadata* FromObjectInnerPtr(
+      const void* ptr,
+      [[maybe_unused]] const PartitionRoot* root = nullptr);
+  PA_ALWAYS_INLINE static SlotSpanMetadata* FromObjectInnerPtr(
+      const void* ptr,
+      [[maybe_unused]] std::ptrdiff_t offset);
 
   PA_ALWAYS_INLINE PartitionSuperPageExtentEntry* ToSuperPageExtent() const;
 
@@ -315,7 +364,12 @@
   bool has_valid_span_after_this : 1;
   uint8_t unused;
 
-  PA_ALWAYS_INLINE static PartitionPageMetadata* FromAddr(uintptr_t address);
+  PA_ALWAYS_INLINE static PartitionPageMetadata* FromAddr(
+      uintptr_t address,
+      [[maybe_unused]] const PartitionRoot* root = nullptr);
+  PA_ALWAYS_INLINE static PartitionPageMetadata* FromAddr(
+      uintptr_t address,
+      [[maybe_unused]] std::ptrdiff_t offet);
 };
 #pragma pack(pop)
 static_assert(sizeof(PartitionPageMetadata) == kPageMetadataSize,
@@ -339,16 +393,26 @@
 #endif
 
 PA_ALWAYS_INLINE PartitionPageMetadata* PartitionSuperPageToMetadataArea(
-    uintptr_t super_page) {
+    uintptr_t super_page,
+    [[maybe_unused]] std::ptrdiff_t offset) {
   // This can't be just any super page, but it has to be the first super page of
   // the reservation, as we assume here that the metadata is near its beginning.
   PA_DCHECK(
       ReservationOffsetTable::Get(super_page).IsReservationStart(super_page));
   PA_DCHECK(!(super_page & kSuperPageOffsetMask));
+  uintptr_t address = PartitionSuperPageToMetadataPage(super_page, offset);
+#if !PA_CONFIG(MOVE_METADATA_OUT_OF_GIGACAGE)
   // The metadata area is exactly one system page (the guard page) into the
   // super page.
-  return reinterpret_cast<PartitionPageMetadata*>(super_page +
-                                                  SystemPageSize());
+  PA_DCHECK(super_page + SystemPageSize() == address);
+#endif
+  return reinterpret_cast<PartitionPageMetadata*>(address);
+}
+
+PA_ALWAYS_INLINE PartitionPageMetadata* PartitionSuperPageToMetadataArea(
+    uintptr_t super_page,
+    [[maybe_unused]] const PartitionRoot* root = nullptr) {
+  return PartitionSuperPageToMetadataArea(super_page, GetMetadataOffset(root));
 }
 
 PA_ALWAYS_INLINE const SubsequentPageMetadata* GetSubsequentPageMetadata(
@@ -362,10 +426,17 @@
 }
 
 PA_ALWAYS_INLINE PartitionSuperPageExtentEntry* PartitionSuperPageToExtent(
-    uintptr_t super_page) {
+    uintptr_t super_page,
+    [[maybe_unused]] std::ptrdiff_t offset) {
   // The very first entry of the metadata is the super page extent entry.
   return reinterpret_cast<PartitionSuperPageExtentEntry*>(
-      PartitionSuperPageToMetadataArea(super_page));
+      PartitionSuperPageToMetadataArea(super_page, offset));
+}
+
+PA_ALWAYS_INLINE PartitionSuperPageExtentEntry* PartitionSuperPageToExtent(
+    uintptr_t super_page,
+    [[maybe_unused]] const PartitionRoot* root = nullptr) {
+  return PartitionSuperPageToExtent(super_page, GetMetadataOffset(root));
 }
 
 PA_ALWAYS_INLINE PAGE_ALLOCATOR_CONSTANTS_DECLARE_CONSTEXPR size_t
@@ -397,8 +468,11 @@
 
 PA_ALWAYS_INLINE PartitionSuperPageExtentEntry*
 SlotSpanMetadata::ToSuperPageExtent() const {
-  uintptr_t super_page = reinterpret_cast<uintptr_t>(this) & kSuperPageBaseMask;
-  return PartitionSuperPageToExtent(super_page);
+  // SlotSpanMetadata and SuperPageExtentEntry are always in the same cage.
+  // But the memory layout is different from GigaCage.
+  uintptr_t super_page =
+      reinterpret_cast<uintptr_t>(this) & SystemPageBaseMask();
+  return reinterpret_cast<PartitionSuperPageExtentEntry*>(super_page);
 }
 
 // Returns whether the pointer lies within the super page's payload area (i.e.
@@ -422,7 +496,14 @@
 // care has to be taken with direct maps that span multiple super pages. This
 // function's behavior is undefined if |ptr| lies in a subsequent super page.
 PA_ALWAYS_INLINE PartitionPageMetadata* PartitionPageMetadata::FromAddr(
-    uintptr_t address) {
+    uintptr_t address,
+    [[maybe_unused]] const PartitionRoot* root) {
+  return PartitionPageMetadata::FromAddr(address, GetMetadataOffset(root));
+}
+
+PA_ALWAYS_INLINE PartitionPageMetadata* PartitionPageMetadata::FromAddr(
+    uintptr_t address,
+    [[maybe_unused]] std::ptrdiff_t metadata_offset) {
   uintptr_t super_page = address & kSuperPageBaseMask;
 
 #if PA_BUILDFLAG(DCHECKS_ARE_ON)
@@ -439,16 +520,36 @@
   // for other exclusions.
   PA_DCHECK(partition_page_index);
   PA_DCHECK(partition_page_index < NumPartitionPagesPerSuperPage() - 1);
-  return PartitionSuperPageToMetadataArea(super_page) + partition_page_index;
+  return PartitionSuperPageToMetadataArea(super_page, metadata_offset) +
+         partition_page_index;
 }
 
 // Converts from a pointer to the SlotSpanMetadata object (within a super
 // pages's metadata) into a pointer to the beginning of the slot span. This
 // works on direct maps too.
 PA_ALWAYS_INLINE uintptr_t
-SlotSpanMetadata::ToSlotSpanStart(const SlotSpanMetadata* slot_span) {
-  uintptr_t pointer_as_uint = reinterpret_cast<uintptr_t>(slot_span);
-  uintptr_t super_page_offset = (pointer_as_uint & kSuperPageOffsetMask);
+SlotSpanMetadata::ToSlotSpanStart(const SlotSpanMetadata* slot_span,
+                                  [[maybe_unused]] const PartitionRoot* root) {
+  return ToSlotSpanStart(slot_span, GetMetadataOffset(root));
+}
+
+PA_ALWAYS_INLINE uintptr_t
+SlotSpanMetadata::ToSlotSpanStart(const SlotSpanMetadata* slot_span,
+                                  [[maybe_unused]] std::ptrdiff_t offset) {
+  uintptr_t slot_span_addr = reinterpret_cast<uintptr_t>(slot_span);
+#if PA_CONFIG(MOVE_METADATA_OUT_OF_GIGACAGE)
+  uintptr_t partition_page_index =
+      (slot_span_addr & SystemPageOffsetMask()) >> kPageMetadataShift;
+  uintptr_t super_page_base =
+      PartitionMetadataPageToSuperPage(slot_span_addr, offset) &
+      kSuperPageBaseMask;
+#if PA_BUILDFLAG(DCHECKS_ARE_ON)
+  PA_DCHECK(PartitionAddressSpace::IsInMetadataRegion(slot_span_addr) ||
+            super_page_base == (slot_span_addr & kSuperPageBaseMask));
+#endif
+  return super_page_base + (partition_page_index << PartitionPageShift());
+#else
+  uintptr_t super_page_offset = (slot_span_addr & kSuperPageOffsetMask);
 
   // A valid |page| must be past the first guard System page and within
   // the following metadata region.
@@ -464,8 +565,9 @@
   // pages.
   PA_DCHECK(partition_page_index);
   PA_DCHECK(partition_page_index < NumPartitionPagesPerSuperPage() - 1);
-  uintptr_t super_page_base = (pointer_as_uint & kSuperPageBaseMask);
+  uintptr_t super_page_base = slot_span_addr & kSuperPageBaseMask;
   return super_page_base + (partition_page_index << PartitionPageShift());
+#endif  // PA_CONFIG(MOVE_METADATA_OUT_OF_GIGACAGE)
 }
 
 // Converts an address inside a slot span into a pointer to the SlotSpanMetadata
@@ -476,7 +578,39 @@
 // partition page.
 PA_ALWAYS_INLINE SlotSpanMetadata* SlotSpanMetadata::FromAddr(
     uintptr_t address) {
-  auto* page_metadata = PartitionPageMetadata::FromAddr(address);
+#if PA_CONFIG(MOVE_METADATA_OUT_OF_GIGACAGE)
+  std::ptrdiff_t metadata_offset =
+      PartitionAddressSpace::MetadataOffset(GetPool(address));
+#else
+  constexpr std::ptrdiff_t metadata_offset = 0;
+#endif  // PA_CONFIG(MOVE_METADATA_OUT_OF_GIGACAGE)
+  return FromAddr(address, metadata_offset);
+}
+
+PA_ALWAYS_INLINE SlotSpanMetadata* SlotSpanMetadata::FromAddr(
+    uintptr_t address,
+    [[maybe_unused]] const PartitionRoot* root) {
+  auto* page_metadata = PartitionPageMetadata::FromAddr(address, root);
+  PA_DCHECK(page_metadata->is_valid);
+  // Partition pages in the same slot span share the same SlotSpanMetadata
+  // object (located in the first PartitionPageMetadata object of that span).
+  // Adjust for that.
+  page_metadata -= page_metadata->slot_span_metadata_offset;
+  PA_DCHECK(page_metadata->is_valid);
+  PA_DCHECK(!page_metadata->slot_span_metadata_offset);
+  auto* slot_span = &page_metadata->slot_span_metadata;
+  PA_DCHECK(DeducedRootIsValid(slot_span));
+  // For direct map, if |address| doesn't point within the first partition page,
+  // |slot_span_metadata_offset| will be 0, |page_metadata| won't get shifted,
+  // leaving |slot_size| at 0.
+  PA_DCHECK(slot_span->bucket->slot_size);
+  return slot_span;
+}
+
+PA_ALWAYS_INLINE SlotSpanMetadata* SlotSpanMetadata::FromAddr(
+    uintptr_t address,
+    [[maybe_unused]] std::ptrdiff_t offset) {
+  auto* page_metadata = PartitionPageMetadata::FromAddr(address, offset);
   PA_DCHECK(page_metadata->is_valid);
   // Partition pages in the same slot span share the same SlotSpanMetadata
   // object (located in the first PartitionPageMetadata object of that span).
@@ -499,10 +633,28 @@
 // This works on direct maps too.
 PA_ALWAYS_INLINE SlotSpanMetadata* SlotSpanMetadata::FromSlotStart(
     uintptr_t slot_start) {
-  auto* slot_span = FromAddr(slot_start);
+#if PA_CONFIG(MOVE_METADATA_OUT_OF_GIGACAGE)
+  std::ptrdiff_t metadata_offset =
+      PartitionAddressSpace::MetadataOffset(GetPool(slot_start));
+#else
+  constexpr std::ptrdiff_t metadata_offset = 0;
+#endif  // PA_CONFIG(MOVE_METADATA_OUT_OF_GIGACAGE)
+  return FromSlotStart(slot_start, metadata_offset);
+}
+
+PA_ALWAYS_INLINE SlotSpanMetadata* SlotSpanMetadata::FromSlotStart(
+    uintptr_t slot_start,
+    [[maybe_unused]] const PartitionRoot* root) {
+  return FromSlotStart(slot_start, GetMetadataOffset(root));
+}
+
+PA_ALWAYS_INLINE SlotSpanMetadata* SlotSpanMetadata::FromSlotStart(
+    uintptr_t slot_start,
+    [[maybe_unused]] std::ptrdiff_t offset) {
+  auto* slot_span = FromAddr(slot_start, offset);
 #if PA_BUILDFLAG(DCHECKS_ARE_ON)
   // Checks that the pointer is a multiple of slot size.
-  uintptr_t slot_span_start = ToSlotSpanStart(slot_span);
+  uintptr_t slot_span_start = ToSlotSpanStart(slot_span, offset);
   PA_DCHECK(!((slot_start - slot_span_start) % slot_span->bucket->slot_size));
 #endif  // PA_BUILDFLAG(DCHECKS_ARE_ON)
   return slot_span;
@@ -513,6 +665,19 @@
 //
 // This works on direct maps too.
 PA_ALWAYS_INLINE SlotSpanMetadata* SlotSpanMetadata::FromObject(
+    const void* object,
+    [[maybe_unused]] const PartitionRoot* root) {
+  uintptr_t object_addr = ObjectPtr2Addr(object);
+  auto* slot_span = FromAddr(object_addr, root);
+  DCheckIsValidObjectAddress(slot_span, object_addr);
+  return slot_span;
+}
+
+// Like |FromAddr|, but asserts that |object| indeed points to the beginning of
+// an object. It doesn't check if the object is actually allocated.
+//
+// This works on direct maps too.
+PA_ALWAYS_INLINE SlotSpanMetadata* SlotSpanMetadata::FromObject(
     const void* object) {
   uintptr_t object_addr = ObjectPtr2Addr(object);
   auto* slot_span = FromAddr(object_addr);
@@ -526,11 +691,18 @@
 // CAUTION! For direct-mapped allocation, |address| has to be within the first
 // partition page.
 PA_ALWAYS_INLINE SlotSpanMetadata* SlotSpanMetadata::FromObjectInnerAddr(
-    uintptr_t address) {
-  auto* slot_span = FromAddr(address);
+    uintptr_t address,
+    [[maybe_unused]] const PartitionRoot* root) {
+  return FromObjectInnerAddr(address, GetMetadataOffset(root));
+}
+
+PA_ALWAYS_INLINE SlotSpanMetadata* SlotSpanMetadata::FromObjectInnerAddr(
+    uintptr_t address,
+    [[maybe_unused]] std::ptrdiff_t offset) {
+  auto* slot_span = FromAddr(address, offset);
 #if PA_BUILDFLAG(DCHECKS_ARE_ON)
   // Checks that the address is within the expected object boundaries.
-  uintptr_t slot_span_start = ToSlotSpanStart(slot_span);
+  uintptr_t slot_span_start = ToSlotSpanStart(slot_span, offset);
   uintptr_t shift_from_slot_start =
       (address - slot_span_start) % slot_span->bucket->slot_size;
   DCheckIsValidShiftFromSlotStart(slot_span, shift_from_slot_start);
@@ -539,8 +711,15 @@
 }
 
 PA_ALWAYS_INLINE SlotSpanMetadata* SlotSpanMetadata::FromObjectInnerPtr(
-    const void* ptr) {
-  return FromObjectInnerAddr(ObjectInnerPtr2Addr(ptr));
+    const void* ptr,
+    [[maybe_unused]] const PartitionRoot* root) {
+  return FromObjectInnerAddr(ObjectInnerPtr2Addr(ptr), root);
+}
+
+PA_ALWAYS_INLINE SlotSpanMetadata* SlotSpanMetadata::FromObjectInnerPtr(
+    const void* ptr,
+    [[maybe_unused]] std::ptrdiff_t offset) {
+  return FromObjectInnerAddr(ObjectInnerPtr2Addr(ptr), offset);
 }
 
 PA_ALWAYS_INLINE void SlotSpanMetadata::SetRawSize(size_t raw_size) {
@@ -771,19 +950,22 @@
  public:
   template <bool enforce = PA_CONFIG(ENFORCE_SLOT_STARTS)>
   PA_ALWAYS_INLINE static SlotStart FromUntaggedAddr(
-      uintptr_t untagged_slot_start) {
+      uintptr_t untagged_slot_start,
+      [[maybe_unused]] const PartitionRoot* root = nullptr) {
     auto result = SlotStart(untagged_slot_start);
     if constexpr (enforce) {
-      result.CheckIsSlotStart();
+      result.CheckIsSlotStart(root);
     }
     return result;
   }
 
   template <bool enforce = PA_CONFIG(ENFORCE_SLOT_STARTS)>
-  PA_ALWAYS_INLINE static SlotStart FromObject(const void* tagged_object) {
+  PA_ALWAYS_INLINE static SlotStart FromObject(
+      const void* tagged_object,
+      [[maybe_unused]] const PartitionRoot* root = nullptr) {
     uintptr_t untagged_slot_start =
         internal::UntagAddr(reinterpret_cast<uintptr_t>(tagged_object));
-    return SlotStart::FromUntaggedAddr<enforce>(untagged_slot_start);
+    return SlotStart::FromUntaggedAddr<enforce>(untagged_slot_start, root);
   }
 
   // Tagging objects is not free. Avoid calling this repeatedly.
@@ -792,9 +974,11 @@
   }
 
   PA_ALWAYS_INLINE
-  void CheckIsSlotStart() const {
-    auto* slot_span_metadata = SlotSpanMetadata::FromAddr(untagged_slot_start_);
-    uintptr_t slot_span = SlotSpanMetadata::ToSlotSpanStart(slot_span_metadata);
+  void CheckIsSlotStart([[maybe_unused]] const PartitionRoot* root) const {
+    auto* slot_span_metadata =
+        SlotSpanMetadata::FromAddr(untagged_slot_start_, root);
+    uintptr_t slot_span =
+        SlotSpanMetadata::ToSlotSpanStart(slot_span_metadata, root);
     PA_CHECK(!((untagged_slot_start_ - slot_span) %
                slot_span_metadata->bucket->slot_size));
   }
diff --git a/base/allocator/partition_allocator/src/partition_alloc/partition_root.h b/base/allocator/partition_allocator/src/partition_alloc/partition_root.h
index 0037cb1..5eb52ad 100644
--- a/base/allocator/partition_allocator/src/partition_alloc/partition_root.h
+++ b/base/allocator/partition_allocator/src/partition_alloc/partition_root.h
@@ -1237,7 +1237,7 @@
     if (!slot_start) [[unlikely]] {
       return 0;
     }
-    PA_DCHECK(slot_span == SlotSpanMetadata::FromSlotStart(slot_start));
+    PA_DCHECK(slot_span == SlotSpanMetadata::FromSlotStart(slot_start, this));
     PA_CHECK(DeducedRootIsValid(slot_span));
     // For direct mapped allocations, |bucket| is the sentinel.
     PA_DCHECK((slot_span->bucket == bucket) ||
diff --git a/base/allocator/partition_allocator/src/partition_alloc/partition_superpage_extent_entry.h b/base/allocator/partition_allocator/src/partition_alloc/partition_superpage_extent_entry.h
index 0b6187c..a7d08a1 100644
--- a/base/allocator/partition_allocator/src/partition_alloc/partition_superpage_extent_entry.h
+++ b/base/allocator/partition_allocator/src/partition_alloc/partition_superpage_extent_entry.h
@@ -9,6 +9,7 @@
 
 #include "partition_alloc/address_pool_manager.h"
 #include "partition_alloc/address_pool_manager_types.h"
+#include "partition_alloc/partition_alloc-inl.h"
 #include "partition_alloc/partition_alloc_constants.h"
 #include "partition_alloc/partition_alloc_forward.h"
 #include "partition_alloc/partition_dcheck_helper.h"
@@ -55,7 +56,8 @@
 PA_ALWAYS_INLINE uintptr_t
 SuperPagesBeginFromExtent(const PartitionSuperPageExtentEntry* extent) {
   PA_DCHECK(0 < extent->number_of_consecutive_super_pages);
-  uintptr_t extent_as_uintptr = reinterpret_cast<uintptr_t>(extent);
+  uintptr_t extent_as_uintptr = PartitionMetadataPageToSuperPage(
+      reinterpret_cast<uintptr_t>(extent), GetMetadataOffset(extent->root));
   PA_DCHECK(ReservationOffsetTable::Get(extent_as_uintptr)
                 .IsManagedByNormalBuckets(extent_as_uintptr));
   return base::bits::AlignDown(extent_as_uintptr, kSuperPageAlignment);
diff --git a/buildtools/third_party/libc++/libcxx_headers.gni b/buildtools/third_party/libc++/libcxx_headers.gni
index 0a67c9c..293bee7 100644
--- a/buildtools/third_party/libc++/libcxx_headers.gni
+++ b/buildtools/third_party/libc++/libcxx_headers.gni
@@ -543,6 +543,7 @@
   "//third_party/libc++/src/include/__locale_dir/time.h",
   "//third_party/libc++/src/include/__locale_dir/wbuffer_convert.h",
   "//third_party/libc++/src/include/__locale_dir/wstring_convert.h",
+  "//third_party/libc++/src/include/__log_hardening_failure",
   "//third_party/libc++/src/include/__math/abs.h",
   "//third_party/libc++/src/include/__math/copysign.h",
   "//third_party/libc++/src/include/__math/error_functions.h",
diff --git a/cc/mojo_embedder/async_layer_tree_frame_sink.cc b/cc/mojo_embedder/async_layer_tree_frame_sink.cc
index 560d70a0..a2511c501 100644
--- a/cc/mojo_embedder/async_layer_tree_frame_sink.cc
+++ b/cc/mojo_embedder/async_layer_tree_frame_sink.cc
@@ -432,6 +432,13 @@
   begin_frames_paused_ = paused;
   if (begin_frame_source_)
     begin_frame_source_->OnSetBeginFrameSourcePaused(paused);
+  if (use_internal_begin_frame_source_) {
+    if (paused) {
+      client_->SetBeginFrameSource(begin_frame_source_.get());
+    } else {
+      client_->SetBeginFrameSource(internal_begin_frame_source_.get());
+    }
+  }
 }
 
 void AsyncLayerTreeFrameSink::ReclaimResources(
@@ -531,7 +538,9 @@
       internal_begin_frame_source_->OnUpdateVSyncParameters(
           last_args.frame_time, last_args.interval);
     }
-    client_->SetBeginFrameSource(internal_begin_frame_source_.get());
+    if (!begin_frames_paused_) {
+      client_->SetBeginFrameSource(internal_begin_frame_source_.get());
+    }
     use_internal_begin_frame_source_ = true;
   } else {
     client_->SetBeginFrameSource(begin_frame_source_.get());
diff --git a/chrome/VERSION b/chrome/VERSION
index c46a21c..ae515bec 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=140
 MINOR=0
-BUILD=7321
+BUILD=7324
 PATCH=0
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ne.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ne.xtb
index 7afa59f..acf068b4 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ne.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ne.xtb
@@ -114,7 +114,7 @@
 <translation id="5161254044473106830">शीर्षक आवश्यक छ</translation>
 <translation id="524477996738997490">{AUTO_DELETE_DELAY,plural, =1{Chrome ले <ph name="AUTO_DELETE_DELAY_ONE" /> महिनापछि निष्क्रिय ट्याब र ट्याब समूहहरू स्वतः बन्द गर्ने छ। तपाईं सेटिङमा गई यो कुरा बदल्न सक्नुहुन्छ।}other{Chrome ले <ph name="AUTO_DELETE_DELAY_MANY" /> महिनापछि निष्क्रिय ट्याब र ट्याब समूहहरू स्वतः बन्द गर्ने छ। तपाईं सेटिङमा गई यो कुरा बदल्न सक्नुहुन्छ।}}</translation>
 <translation id="5339733443032484186">तपाईंको अन्तिम ट्याब</translation>
-<translation id="5380159289133845234">दोहोरिएका ट्याबहरू अभिलेखमा राख्नुहोस्</translation>
+<translation id="5380159289133845234">दोहोरिएका ट्याबहरू अर्काइभमा राख्नुहोस्</translation>
 <translation id="5400836586163650660">खरानी रङ्ग</translation>
 <translation id="5446043142172831860">ट्याब हटाउनुहोस् र समूह छाड्नुहोस्</translation>
 <translation id="5490235265819901748">ट्याब समूह विस्तृत गरियो</translation>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadController.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadController.java
index 91accce..2eeee1d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadController.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadController.java
@@ -6,12 +6,12 @@
 
 import android.Manifest.permission;
 
-import androidx.annotation.Nullable;
-
 import org.jni_zero.CalledByNative;
 import org.jni_zero.JniType;
 import org.jni_zero.NativeMethods;
 
+import org.chromium.build.annotations.NullMarked;
+import org.chromium.build.annotations.Nullable;
 import org.chromium.chrome.browser.pdf.PdfPage;
 import org.chromium.chrome.browser.pdf.PdfUtils;
 import org.chromium.chrome.browser.profiles.Profile;
@@ -28,6 +28,7 @@
 import org.chromium.url.GURL;
 
 /** Java counterpart of android DownloadController. Owned by native. */
+@NullMarked
 public class DownloadController {
     /**
      * Called to download the given URL triggered from a tab.
@@ -47,11 +48,14 @@
     @CalledByNative
     private static void onDownloadCompleted(
             @Nullable Tab tab, DownloadInfo downloadInfo, boolean isDownloadSafe) {
-        MediaStoreHelper.addImageToGalleryOnSDCard(
-                downloadInfo.getFilePath(), downloadInfo.getMimeType());
+        String fileName = downloadInfo.getFileName();
+        String filePath = downloadInfo.getFilePath();
+        String mimeType = downloadInfo.getMimeType();
+        assert fileName != null && filePath != null && mimeType != null;
+        MediaStoreHelper.addImageToGalleryOnSDCard(filePath, mimeType);
         if (tab == null
                 || !PdfUtils.shouldOpenPdfInline(tab.isIncognito())
-                || !downloadInfo.getMimeType().equals(MimeTypeUtils.PDF_MIME_TYPE)
+                || !mimeType.equals(MimeTypeUtils.PDF_MIME_TYPE)
                 || !downloadInfo.getIsTransient()) {
             return;
         }
@@ -62,9 +66,7 @@
         // The PdfPage may become a FrozenNativePage while downloading.
         // Need to check before cast to PdfPage.
         if (nativePage instanceof PdfPage) {
-            ((PdfPage) nativePage)
-                    .onDownloadComplete(
-                            downloadInfo.getFileName(), downloadInfo.getFilePath(), isDownloadSafe);
+            ((PdfPage) nativePage).onDownloadComplete(fileName, filePath, isDownloadSafe);
             tab.updateTitle();
         }
     }
@@ -75,7 +77,7 @@
      * @return true if allowed, or false otherwise.
      */
     @CalledByNative
-    private static boolean hasFileAccess(WindowAndroid windowAndroid) {
+    private static boolean hasFileAccess(@Nullable WindowAndroid windowAndroid) {
         if (DownloadCollectionBridge.supportsDownloadCollection()) return true;
         AndroidPermissionDelegate delegate = windowAndroid;
         return delegate == null ? false : delegate.hasPermission(permission.WRITE_EXTERNAL_STORAGE);
@@ -180,9 +182,10 @@
                 boolean granted,
                 @JniType("std::string") String permissionToUpdate);
 
-        void downloadUrl(@JniType("std::string") String url, WebContents webContents);
+        void downloadUrl(@JniType("std::string") String url, @Nullable WebContents webContents);
 
         void cancelDownload(
-                @JniType("Profile*") Profile profile, @JniType("std::string") String downloadGuid);
+                @JniType("Profile*") Profile profile,
+                @JniType("std::string") @Nullable String downloadGuid);
     }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadForegroundServiceImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadForegroundServiceImpl.java
index f4e5f27..ea4719c 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadForegroundServiceImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadForegroundServiceImpl.java
@@ -16,17 +16,19 @@
 import android.os.IBinder;
 
 import androidx.annotation.IntDef;
-import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
 import androidx.core.app.ServiceCompat;
 
 import org.chromium.base.Log;
+import org.chromium.build.annotations.NullMarked;
+import org.chromium.build.annotations.Nullable;
 import org.chromium.components.browser_ui.notifications.ForegroundServiceUtils;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
 /** Keep-alive foreground service for downloads. */
+@NullMarked
 public class DownloadForegroundServiceImpl extends DownloadForegroundService.Impl {
     private static final String TAG = "DownloadFg";
     private final IBinder mBinder = new LocalBinder();
@@ -66,7 +68,7 @@
             int newNotificationId,
             Notification newNotification,
             int oldNotificationId,
-            Notification oldNotification,
+            @Nullable Notification oldNotification,
             boolean killOldNotification) {
         Log.w(
                 TAG,
@@ -115,7 +117,7 @@
     public void stopDownloadForegroundService(
             @StopForegroundNotification int stopForegroundNotification,
             int pinnedNotificationId,
-            Notification pinnedNotification) {
+            @Nullable Notification pinnedNotification) {
         Log.w(
                 TAG,
                 "stopDownloadForegroundService status: "
@@ -141,7 +143,7 @@
     }
 
     @Override
-    public int onStartCommand(Intent intent, int flags, int startId) {
+    public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
         // In the case the service was restarted when the intent is null.
         if (intent == null) {
             DownloadNotificationUmaHelper.recordServiceStoppedHistogram(
@@ -178,9 +180,8 @@
         super.onLowMemory();
     }
 
-    @Nullable
     @Override
-    public IBinder onBind(Intent intent) {
+    public @Nullable IBinder onBind(Intent intent) {
         return mBinder;
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadForegroundServiceManager.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadForegroundServiceManager.java
index c5b009162..c97e41c 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadForegroundServiceManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadForegroundServiceManager.java
@@ -4,6 +4,8 @@
 
 package org.chromium.chrome.browser.download;
 
+import static org.chromium.build.NullUtil.assertNonNull;
+import static org.chromium.build.NullUtil.assumeNonNull;
 import static org.chromium.chrome.browser.download.DownloadSnackbarController.INVALID_NOTIFICATION_ID;
 
 import android.app.Notification;
@@ -21,6 +23,8 @@
 import org.chromium.base.ApplicationStatus;
 import org.chromium.base.ContextUtils;
 import org.chromium.base.Log;
+import org.chromium.build.annotations.NullMarked;
+import org.chromium.build.annotations.Nullable;
 import org.chromium.chrome.browser.download.DownloadNotificationService.DownloadStatus;
 import org.chromium.chrome.browser.notifications.NotificationUmaTracker;
 import org.chromium.chrome.browser.notifications.NotificationWrapperBuilderFactory;
@@ -32,6 +36,7 @@
  * Foreground service implementation of {@link DownloadContinuityManager} that starts and stops a
  * foreground service when there are active downloads. Only active for Android versions < U.
  */
+@NullMarked
 public class DownloadForegroundServiceManager extends DownloadContinuityManager {
     private static final String TAG = "DownloadFgsm";
     // Delay to ensure start/stop foreground doesn't happen too quickly (b/74236718).
@@ -62,13 +67,7 @@
     private boolean mStartForegroundCalled;
 
     // This is non-null when onServiceConnected has been called (aka service is active).
-    private DownloadForegroundServiceImpl mBoundService;
-
-    private static <T> void checkNotNull(T reference) {
-        if (reference == null) {
-            throw new NullPointerException();
-        }
-    }
+    private @Nullable DownloadForegroundServiceImpl mBoundService;
 
     public DownloadForegroundServiceManager() {}
 
@@ -235,7 +234,7 @@
     }
 
     // Creates an empty notification to feed to startForeground().
-    private Notification createEmptyNotification(int notificationId) {
+    private @Nullable Notification createEmptyNotification(int notificationId) {
         NotificationWrapperBuilder builder =
                 NotificationWrapperBuilderFactory.createNotificationWrapperBuilder(
                         ChromeChannelDefinitions.ChannelId.DOWNLOADS,
@@ -250,7 +249,7 @@
     @VisibleForTesting
     void stopAndUnbindService(@DownloadNotificationService.DownloadStatus int downloadStatus) {
         Log.w(TAG, "stopAndUnbindService status: " + downloadStatus);
-        checkNotNull(mBoundService);
+        assertNonNull(mBoundService);
         mIsServiceBound = false;
 
         @DownloadForegroundServiceImpl.StopForegroundNotification int stopForegroundNotification;
@@ -279,7 +278,8 @@
     void stopAndUnbindServiceInternal(
             @DownloadForegroundServiceImpl.StopForegroundNotification int stopForegroundStatus,
             int pinnedNotificationId,
-            Notification pinnedNotification) {
+            @Nullable Notification pinnedNotification) {
+        assumeNonNull(mBoundService);
         mBoundService.stopDownloadForegroundService(
                 stopForegroundStatus, pinnedNotificationId, pinnedNotification);
         ContextUtils.getApplicationContext().unbindService(mConnection);
diff --git a/chrome/android/profiles/arm.newest.txt b/chrome/android/profiles/arm.newest.txt
index 6976e47..c30eb1a 100644
--- a/chrome/android/profiles/arm.newest.txt
+++ b/chrome/android/profiles/arm.newest.txt
@@ -1 +1 @@
-chromeos-chrome-arm-140.0.7318.0_pre1492031_rc-r1-merged.afdo.bz2
+chromeos-chrome-arm-140.0.7320.0_pre1492415_rc-r1-merged.afdo.bz2
diff --git a/chrome/app/resources/chromium_strings_lt.xtb b/chrome/app/resources/chromium_strings_lt.xtb
index cbdbb6a0..b0a192d9 100644
--- a/chrome/app/resources/chromium_strings_lt.xtb
+++ b/chrome/app/resources/chromium_strings_lt.xtb
@@ -48,6 +48,7 @@
 <translation id="1607715478322902680">{COUNT,plural, =0{Administratorius reikalauja paleisti „Chromium“ iš naujo, kad būtų galima pritaikyti naujinį}=1{Administratorius reikalauja paleisti „Chromium“ iš naujo, kad būtų galima pritaikyti naujinį. Inkognito langas nebus atidarytas iš naujo.}one{Administratorius reikalauja paleisti „Chromium“ iš naujo, kad būtų galima pritaikyti naujinį. # inkognito langas nebus atidarytas iš naujo.}few{Administratorius reikalauja paleisti „Chromium“ iš naujo, kad būtų galima pritaikyti naujinį. # inkognito langai nebus atidaryti iš naujo.}many{Administratorius reikalauja paleisti „Chromium“ iš naujo, kad būtų galima pritaikyti naujinį. # inkognito lango nebus atidaryta iš naujo.}other{Administratorius reikalauja paleisti „Chromium“ iš naujo, kad būtų galima pritaikyti naujinį. # inkognito langų nebus atidaryta iš naujo.}}</translation>
 <translation id="1625909126243026060">Peržiūrėkite pagrindinius privatumo ir saugos valdiklius naršyklėje „Chromium“</translation>
 <translation id="1640672724030957280">Atsisiunčiama...</translation>
+<translation id="1680687534629375545">Klausti vaizdų paieškos apie šį puslapį</translation>
 <translation id="1709772298389099340">Suteikia „<ph name="BROWSER_NAME" />“ aukštesnio lygio privilegijas.</translation>
 <translation id="1715127912119967311">Kad padėtų tobulinti šias funkcijas, „Chromium“ siunčia jūsų sąveikas su jomis sistemai „Google“. Šiuos duomenis gali skaityti, apdoroti ir komentuoti tikrinantys žmonės.</translation>
 <translation id="1722488837206509557">Galėsite pasirinkti iš pasiekiamų įrenginių ir pateikti turinį juose.</translation>
@@ -143,6 +144,7 @@
 <translation id="2785438272836277133">Šiame plėtinyje yra kenkėjiškų programų ir jis nesaugus. Pašalinkite jį iš „Chromium“, kad jis nebematytų ir negalėtų pakeisti jūsų duomenų svetainėse, kuriose lankotės, įskaitant jūsų asmens informaciją.</translation>
 <translation id="2799223571221894425">Paleisti iš naujo</translation>
 <translation id="2803971713792056305">Jūsų „Chromium“</translation>
+<translation id="2816462166102338036">Ieškoti šiame vaizdo įraše naudojant vaizdų paiešką</translation>
 <translation id="2841525013647267359">Versti iš</translation>
 <translation id="2846251086934905009">Diegimo klaida: diegimo programa neužbaigta. Diegimas nutrauktas.</translation>
 <translation id="2847479871509788944">Pašalinti iš „Chromium“...</translation>
@@ -190,6 +192,7 @@
 <translation id="3313189106987092621">„Chromium“ perspės jus prieš įkeliant bet kokią svetainę, kurioje naudojamas nesaugus ryšys</translation>
 <translation id="3316771292331273802">Būsite atjungti nuo daugelio svetainių, kai uždarysite visus „Chromium“ langus, išskyrus „Google“ paskyrą, jei esate prisijungę prie „Chromium“. Jei norite, kad svetainės jus prisimintų, <ph name="SETTINGS_LINK" />.</translation>
 <translation id="3352986031709923790">viršutinis dešinysis paieškos srities kampas: dešinė – <ph name="RIGHT" /> %, viršus – <ph name="TOP" /> %</translation>
+<translation id="3369405342922656244">Ieškoti šiame puslapyje naudojant vaizdų paiešką</translation>
 <translation id="3387527074123400161">„Chromium“ OS</translation>
 <translation id="3406848076815591792">Perjungti į esamą „Chromium“ profilį?</translation>
 <translation id="3412460710772753638">Slaptažodžių tvarkyklėje šiame įrenginyje</translation>
@@ -312,6 +315,7 @@
 <translation id="5224391634244552924">Nėra išsaugotų slaptažodžių. „Chromium“ gali tikrinti jūsų slaptažodžius, kai juos išsaugote.</translation>
 <translation id="5231355151045086930">Atsijungimas nuo „Chromium“</translation>
 <translation id="5234764350956374838">Atsisakyti</translation>
+<translation id="5254739261293693943">Klausti apie šį vaizdo įrašą</translation>
 <translation id="5277894862589591112">Norėdami pritaikyti pakeitimus, paleiskite „Chromium“ iš naujo</translation>
 <translation id="5286907366254680517">Aptikta</translation>
 <translation id="5294316920224716406">Kai naršysite inkognito režimu, „Chromium“ perspės jus prieš įkeliant svetainę, kurioje naudojamas nesaugus ryšys</translation>
@@ -390,6 +394,7 @@
 <translation id="6183079672144801177">Įsitikinkite, kad esate prisijungę prie „Chromium“ naudodami „<ph name="TARGET_DEVICE_NAME" />“, ir bandykite siųsti iš naujo.</translation>
 <translation id="6212496753309875659">Šiame kompiuteryje jau yra naujesnės versijos „Chromium“. Jei programinė įranga neveikia, pašalinkite „Chromium“ ir bandykite dar kartą.</translation>
 <translation id="6219195342503754812">{0,plural, =0{„Chromium“ bus paleista iš naujo dabar}=1{„Chromium“ bus paleista iš naujo po 1 sekundės}one{„Chromium“ bus paleista iš naujo po # sekundės}few{„Chromium“ bus paleista iš naujo po # sekundžių}many{„Chromium“ bus paleista iš naujo po # sekundės}other{„Chromium“ bus paleista iš naujo po # sekundžių}}</translation>
+<translation id="6239161312595354541">Klausti vaizdų paieškos apie šį vaizdo įrašą</translation>
 <translation id="6241367896540709610">„Chromium“ reikia prieigos prie saugyklos, kad būtų galima atsisiųsti failus</translation>
 <translation id="6245734527075554892">Tikrinami URL pagal nesaugių svetainių sąrašą, saugomą naršyklėje „Chromium“</translation>
 <translation id="6248213926982192922">Padaryti „Chromium“ numatytąja naršykle</translation>
@@ -451,11 +456,13 @@
 <translation id="6847869444787758381">„Chromium“ praneš, jei slaptažodžiai bus pažeisti</translation>
 <translation id="684888714667046800">Nepavyksta prisijungti prie interneto. Jei naudojate užkardą, įsitikinkite, kad „<ph name="PRODUCT_EXE_NAME" />“ yra leidžiamųjų sąraše.</translation>
 <translation id="6857782730669500492">„Chromium“ – „<ph name="PAGE_TITLE" />“</translation>
+<translation id="6862030660799253820">Ieškoti šio vaizdo naudojant vaizdų paiešką</translation>
 <translation id="6873893289264747459">„Chromium“ aptiko kenkėjišką programą plėtinyje „<ph name="EXTENSION_NAME" />“</translation>
 <translation id="6877155553248388166">apatinis dešinysis paieškos srities kampas: dešinė – <ph name="RIGHT" /> %, apačia – <ph name="BOTTOM" /> %</translation>
 <translation id="6896758677409633944">Kopijuoti</translation>
 <translation id="6901631050894301805">Nustatykite „Chromium“ kaip numatytąją naršyklę ir prisekite ją prie užduočių juostos</translation>
 <translation id="6929417474050522668">Naudojant šias bandomąsias versijas, Skelbimų vertinimas leidžia svetainėms, kuriose lankotės, prašyti „Chromium“ informacijos, padedančios įvertinti savo skelbimų našumą. Skelbimų vertinimas apriboja veiklos skirtingose svetainėse stebėjimą tarp svetainių perduodant kaip įmanoma mažiau informacijos.</translation>
+<translation id="6934579572334859869">Klausti vaizdų paieškos apie šį vaizdą</translation>
 <translation id="6940431691900807093">Vėliau svetainė, kurioje lankotės, gali paprašyti „Chromium“ peržiūrėti jūsų pomėgius, kad galėtų suasmeninti jums rodomus skelbimus. „Chromium“ gali bendrinti iki 3 pomėgių.</translation>
 <translation id="6964305034639999644">Atidaryti nuorodą „Chromium“ inko&amp;gnito lange</translation>
 <translation id="6965382102122355670">Gerai</translation>
@@ -525,6 +532,7 @@
 <translation id="7859018312476869945">Kai įvedate tekstą adreso juostoje ar paieškos laukelyje, „Chromium“ siunčia tai, ką įvedate, į numatytąjį paieškos variklį, kad gautų geresnių pasiūlymų. Ši funkcija inkognito režimu išjungta.</translation>
 <translation id="7867198900892795913">Nepavyko atnaujinti „Chromium“ į naujausią versiją, todėl nebus pasiekiamos naujos funkcijos ir saugos pataisos.</translation>
 <translation id="7872446069773932638">Atsisiunčiama... Liko <ph name="SECONDS" /> sek.</translation>
+<translation id="7877212753140190672">Klausti apie šį vaizdą</translation>
 <translation id="7888981273428720788">„Chromium“ nustatymas kaip numatytosios naršyklės</translation>
 <translation id="7934340546140346950">„Chromium“ automatiškai naujovina nesaugius ryšius į HTTPS, kai tai įmanoma</translation>
 <translation id="7937630085815544518">Buvote prisijungę prie „Chromium“ kaip <ph name="USER_EMAIL_ADDRESS" />. Prisijungdami vėl naudokite tą pačią paskyrą.</translation>
diff --git a/chrome/app/resources/generated_resources_lt.xtb b/chrome/app/resources/generated_resources_lt.xtb
index fa44465..8830926 100644
--- a/chrome/app/resources/generated_resources_lt.xtb
+++ b/chrome/app/resources/generated_resources_lt.xtb
@@ -858,6 +858,7 @@
 <translation id="1587275751631642843">&amp;„JavaScript“ pultas</translation>
 <translation id="1587907146729660231">Pirštu palieskite maitinimo mygtuką</translation>
 <translation id="1588438908519853928">Įprastas</translation>
+<translation id="1588772269240419305">Logotipo ir pavadinimo atnaujinimų peržiūra</translation>
 <translation id="1588870296199743671">Atidaryti nuorodą naudojant...</translation>
 <translation id="1588919647604819635">Spustelėkite kortelę dešiniuoju pelės klavišu</translation>
 <translation id="1589055389569595240">Rodyti rašybos ir gramatikos tikrinimą</translation>
@@ -1337,6 +1338,7 @@
 <translation id="1912867150686509584">Peržiūrėkite daugiau susitikimų Kalendoriuje</translation>
 <translation id="1913734973620799732">{NUM_TABS,plural, =1{Pristabdykite skirtuką, kuris lėtina naršyklę}one{Pristabdykite skirtukus, kurie lėtina naršyklę}few{Pristabdykite skirtukus, kurie lėtina naršyklę}many{Pristabdykite skirtukus, kurie lėtina naršyklę}other{Pristabdykite skirtukus, kurie lėtina naršyklę}}</translation>
 <translation id="1913749768968678106">Perdavimas, išsaugojimas ir bendrinimas</translation>
+<translation id="19147273405311768">Iš naujo nustatyti numatytuosius įrankių juostos nustatymus</translation>
 <translation id="1915073950770830761">canary</translation>
 <translation id="1915307458270490472">Baigti</translation>
 <translation id="1915734383465415025">Parduotuvės numeris</translation>
@@ -3020,6 +3022,7 @@
 <translation id="3060952009917586498">Keiskite įrenginio kalbą. Dabartinė kalba yra <ph name="LANGUAGE" />.</translation>
 <translation id="3060987956645097882">Nepavyko užmegzti ryšio su jūsų telefonu. Įsitikinkite, kad telefonas netoliese, atrakintas ir jame įjungtas „Bluetooth“ bei „Wi-Fi“ ryšys.</translation>
 <translation id="3061302636956643119">Tekstas bus išsiųstas apdoroti sistemai „Google“.</translation>
+<translation id="306166624240243643">Pavadinimo ir URL atnaujinimų peržiūra</translation>
 <translation id="3064871050034234884">Svetainėse galima leisti garsus</translation>
 <translation id="3065041951436100775">Atsiliepimai dėl uždaryto skirtuko.</translation>
 <translation id="3065522099314259755">Klaviatūros kartojimo delsa</translation>
@@ -3062,6 +3065,7 @@
 <translation id="3100071818310370858">Naudokite vietovės nustatymą. Leiskite programoms ir paslaugoms, turinčioms leidimą pasiekti vietovės duomenis, naudoti šio įrenginio vietovę. „Google“ gali periodiškai rinkti vietovių duomenis ir anonimiškai naudoti šią informaciją vietovės nustatymo tikslumui ir vietove pagrįstoms paslaugoms tobulinti. <ph name="BEGIN_LINK1" />Sužinokite daugiau apie vietovę<ph name="BEGIN_LINK1_END" />Sužinokite daugiau<ph name="END_LINK1" /></translation>
 <translation id="3101126716313987672">Pritemdyta šviesa</translation>
 <translation id="3101709781009526431">Data ir laikas</translation>
+<translation id="3102309003841389927">Logotipo atnaujinimo peržiūra</translation>
 <translation id="310297983047869047">Ankstesnė skaidrė</translation>
 <translation id="3103451787721578293">Įveskite šių duomenų įkėlimo priežastį.</translation>
 <translation id="3103512663951238230">„Alt“ + paspaudimas</translation>
@@ -6062,6 +6066,7 @@
 <translation id="5225324770654022472">Rodyti spartųjį programų klavišą</translation>
 <translation id="52254442782792731">Matomumo nustatymas dar nenustatytas</translation>
 <translation id="5225463052809312700">Įjungti fotoaparatą</translation>
+<translation id="5226253862147382094">Logotipo ir URL atnaujinimų peržiūra</translation>
 <translation id="5226514125747186">Aplink svetainės piktogramas rodomas taškinis apskritimas. <ph name="BEGIN_LINK" />Sužinokite daugiau apie neaktyvius skirtukus<ph name="END_LINK" /></translation>
 <translation id="5226731562812684363">Svetainėms neleidžiama naudoti vietovės informacijos</translation>
 <translation id="5227679487546032910">Numatytasis tamsiai žydras pseudoportretas</translation>
@@ -7378,6 +7383,7 @@
 <translation id="6180389074227570449">{NUM_EXTENSIONS,plural, =1{Pašalinti plėtinį?}one{Pašalinti # plėtinį?}few{Pašalinti # plėtinius?}many{Pašalinti # plėtinio?}other{Pašalinti # plėtinių?}}</translation>
 <translation id="6180510783007738939">Linijos įrankis</translation>
 <translation id="6180550893222597997">Kurį „passkey“ norite naudoti su „<ph name="APP_NAME" />“?</translation>
+<translation id="6181218116951226898">Programos kartais atnaujina savo prekės ženklą. Peržiūrėkite visus pakeitimus, kad įsitikintumėte, jog esate patenkinti jais, prieš atnaujindami.</translation>
 <translation id="6181431612547969857">Atsisiuntimas užblokuotas</translation>
 <translation id="6183369864942961155">Automatinė šviesioji / tamsioji tema</translation>
 <translation id="6184099524311454384">Ieškoti skirtukų</translation>
@@ -7451,6 +7457,7 @@
 <translation id="6234108445915742946">Kovo 31 d. bus pakeistos „Chrome“ paslaugų teikimo sąlygos</translation>
 <translation id="6234474535228214774">Laukiama, kol bus įdiegta</translation>
 <translation id="6235208551686043831">Įrenginio fotoaparatas įjungtas. Padėkite „eSIM“ kortelės QR kodą prieš fotoaparatą.</translation>
+<translation id="6237256594069101884">URL atnaujinimo peržiūra</translation>
 <translation id="6237342324375264347"><ph name="SHARE_STATE" /> grupė „<ph name="GROUP_NAME" />“ – <ph name="GROUP_CONTENTS" /> – <ph name="COLLAPSED_STATE" /></translation>
 <translation id="6237474966939441970">Užrašų rašymo rašikliu programa</translation>
 <translation id="6237481151388361546">Pakeiskite interneto ryšį ir pasirinkite „Bandyti dar kartą“ arba pasirinkite „Atidaryti pagrindinėje redagavimo priemonėje“, kad galėtumėte naudoti ribotas peržiūros ir redagavimo parinktis.</translation>
@@ -8310,6 +8317,7 @@
 <translation id="6840155290835956714">Klausti prieš siunčiant</translation>
 <translation id="6840184929775541289">Nėra sertifikavimo institucija</translation>
 <translation id="6840214587087739194">Adresas ištrintas</translation>
+<translation id="6841076158433142214">Jums nebus pranešta, kai šios programos bus naudojamos ekrano turiniui įrašyti:</translation>
 <translation id="6841143363521180029">Šifruota</translation>
 <translation id="6841186874966388268">Klaidos</translation>
 <translation id="6842135459748401207">Tik įrenginiai, kuriuose prisijungta prie <ph name="USER_EMAIL" /></translation>
@@ -8770,6 +8778,7 @@
 <translation id="7181329571386134105">Jei leidžiate vaikui (<ph name="CHILD_NAME" />) įdiegti būsimus plėtinius be jūsų patvirtinimo, atidarykite „Family Link“ programą įrenginyje ir atnaujinkite vaiko (<ph name="CHILD_NAME" />) „Google Chrome“ nustatymus.</translation>
 <translation id="7181840534454431748">Prisijungimas prie skirtukų grupės su <ph name="OWNER_FIRST_NAME" />
             {NUM_OTHER_MEMBERS,plural, =0{Prisijungimas prie skirtukų grupės su <ph name="OWNER_FIRST_NAME" />}=1{Prisijungimas prie skirtukų grupės su <ph name="OWNER_FIRST_NAME" /> ir dar # asmeniu}one{Prisijungimas prie skirtukų grupės su <ph name="OWNER_FIRST_NAME" /> ir dar # asmeniu}few{Prisijungimas prie skirtukų grupės su <ph name="OWNER_FIRST_NAME" /> ir dar # asmenimis}many{Prisijungimas prie skirtukų grupės su <ph name="OWNER_FIRST_NAME" /> ir dar # asmens}other{Prisijungimas prie skirtukų grupės su <ph name="OWNER_FIRST_NAME" /> ir dar # asmenų}}</translation>
+<translation id="7181976109296206547">Logotipo, pavadinimo ir URL atnaujinimų peržiūra</translation>
 <translation id="7182051712900867547">Naudoti kitą paskyrą</translation>
 <translation id="7182063559013288142">Spartusis viešosios interneto prieigos taškas</translation>
 <translation id="7182791023900310535">Perkelti slaptažodį</translation>
@@ -8945,6 +8954,7 @@
 <translation id="7312040805247765153">Nepavyko įdiegti programos</translation>
 <translation id="7312210124139670355">Administratorius iš naujo nustato jūsų „eSIM“ kortelę. Tai gali užtrukti kelias minutes.</translation>
 <translation id="7313539585802573958">Klaviatūros foninio apšvietimo spalvos</translation>
+<translation id="7314865262803554456">Jums nebus pranešta, kai įrašymas prasidės.</translation>
 <translation id="7314989823816739632">Romantiška</translation>
 <translation id="7317342082064136423">Patvirtinkite paskyrą</translation>
 <translation id="7317831949569936035">Mokyklos registracija</translation>
@@ -11482,6 +11492,7 @@
 <translation id="9033765790910064284">Vis tiek tęsti</translation>
 <translation id="9033857511263905942">&amp;Įklijuoti</translation>
 <translation id="903480517321259405">Dar kartą įveskite PIN kodą</translation>
+<translation id="9035157477209989051">Gausite pranešimą, kai šios programos bus naudojamos ekrano turiniui įrašyti:</translation>
 <translation id="9036484080057916082">Pasirašyto sertifikato laiko žymių sąrašas</translation>
 <translation id="9037054491984310631">Prisijungta prie „Bluetooth“ įrenginio pavadinimu „<ph name="DEVICE" />“</translation>
 <translation id="9037640663275993951">Įrenginys neleidžiamas</translation>
diff --git a/chrome/app/resources/generated_resources_ml.xtb b/chrome/app/resources/generated_resources_ml.xtb
index 84bd3deb..3396bf7d 100644
--- a/chrome/app/resources/generated_resources_ml.xtb
+++ b/chrome/app/resources/generated_resources_ml.xtb
@@ -1360,6 +1360,7 @@
 <translation id="1931152874660185993">ഘടകങ്ങളൊന്നും ഇൻസ്റ്റാളുചെയ്‌തിട്ടില്ല.</translation>
 <translation id="1931410639376954712"><ph name="DEVICE_OS" /> ഇൻസ്റ്റാൾ ചെയ്യുന്നു</translation>
 <translation id="1932098463447129402">മുമ്പല്ല</translation>
+<translation id="1933070475689690969">Gemini ആപ്പുകളിലെ ആക്റ്റിവിറ്റി</translation>
 <translation id="1933489278505808700">വായിക്കാനും മാറ്റാനും അനുവാദമുണ്ട്</translation>
 <translation id="1935303383381416800">നിങ്ങളുടെ ലൊക്കേഷൻ കാണാൻ അനുവദിച്ചിരിക്കുന്നു</translation>
 <translation id="193565226207940518">പിന്തുണാ ടൂൾ</translation>
@@ -3495,6 +3496,7 @@
 <translation id="3435738964857648380">സുരക്ഷ</translation>
 <translation id="343578350365773421">പേപ്പറില്ല</translation>
 <translation id="3435896845095436175">തയ്യാറാക്കുക</translation>
+<translation id="3437072258256045988">നിങ്ങളുടെ Gemini ആപ്പുകളിലെ ആക്റ്റിവിറ്റി മാനേജ് ചെയ്യുക</translation>
 <translation id="3437397693214267762">നിങ്ങളുടെ Outlook കലണ്ടറും SharePoint-ഉം OneDrive ഫയലുകളും കാണുക</translation>
 <translation id="3438633801274389918">നിൻജ</translation>
 <translation id="3439153939049640737"><ph name="HOST" /> എന്നതിനെ നിങ്ങളുടെ മൈക്രോഫോൺ ആക്‌സസ് ചെയ്യാൻ എപ്പോഴും അനുവദിക്കുക</translation>
diff --git a/chrome/app/resources/generated_resources_ms.xtb b/chrome/app/resources/generated_resources_ms.xtb
index 8305cfb..1b802e8 100644
--- a/chrome/app/resources/generated_resources_ms.xtb
+++ b/chrome/app/resources/generated_resources_ms.xtb
@@ -1373,6 +1373,7 @@
 <translation id="1931152874660185993">Tiada komponen dipasang.</translation>
 <translation id="1931410639376954712">Memasang <ph name="DEVICE_OS" /></translation>
 <translation id="1932098463447129402">Bukan Sebelum</translation>
+<translation id="1933070475689690969">Aktiviti Apl Gemini</translation>
 <translation id="1933489278505808700">Dibenarkan untuk membaca &amp; menukar</translation>
 <translation id="1935303383381416800">Dibenarkan untuk melihat lokasi anda</translation>
 <translation id="193565226207940518">Alat Sokongan</translation>
@@ -3511,6 +3512,7 @@
 <translation id="3435738964857648380">Keselamatan</translation>
 <translation id="343578350365773421">Kehabisan kertas</translation>
 <translation id="3435896845095436175">Dayakan</translation>
+<translation id="3437072258256045988">Urus aktiviti Apl Gemini anda</translation>
 <translation id="3437397693214267762">Lihat Kalendar Outlook serta fail SharePoint dan OneDrive anda</translation>
 <translation id="3438633801274389918">Ninja</translation>
 <translation id="3439153939049640737">Sentiasa benarkan <ph name="HOST" /> mengakses mikrofon anda</translation>
diff --git a/chrome/app/resources/generated_resources_my.xtb b/chrome/app/resources/generated_resources_my.xtb
index e298669..d021eea 100644
--- a/chrome/app/resources/generated_resources_my.xtb
+++ b/chrome/app/resources/generated_resources_my.xtb
@@ -9156,7 +9156,7 @@
 <translation id="7465635034594602553">တစ်ခုခုမှားသွားသည်။ မိနစ်အနည်းငယ်စောင့်ပြီး <ph name="APP_NAME" /> ကို ထပ်ဖွင့်ကြည့်ပါ။</translation>
 <translation id="7465777686629334728">စီမံခန့်ခွဲထားသော ဆော့ဖ်ဝဲရေးဆွဲမှု ပတ်ဝန်းကျင် (<ph name="SPECIFIC_NAME" />) ကို ဖယ်ရှားရန်</translation>
 <translation id="7465778193084373987">Netscape လက်မှတ် ရုပ်သိမ်းမှု URL</translation>
-<translation id="7466431077154602932">ကျစ်ကျစ်လျစ်လျစ်ပြသခြင်း</translation>
+<translation id="7466431077154602932">ကျစ်လျစ်ပြကွက်</translation>
 <translation id="7466861475611330213">ပုဒ်ဖြတ်ပုဒ်ရပ် စတိုင်</translation>
 <translation id="746861123368584540">နောက်ဆက်တွဲကို ဖွင့်လိုက်ပါပြီ</translation>
 <translation id="7470131554696493512">Thunderbolt (သို့) USB4 ဆက်စပ်ပစ္စည်းများအား မှတ်ဉာဏ် (RAM) သုံးခြင်းနှင့် မျှဝေခြင်းမှ ပိတ်ထားရန်</translation>
diff --git a/chrome/app/resources/generated_resources_ne.xtb b/chrome/app/resources/generated_resources_ne.xtb
index 9ac8786..c8aad75 100644
--- a/chrome/app/resources/generated_resources_ne.xtb
+++ b/chrome/app/resources/generated_resources_ne.xtb
@@ -1898,7 +1898,7 @@
       <ph name="BR" />
       <ph name="BR" />
       <ph name="BEGIN_BOLD" />ख्याल गर्नुहोस्:<ph name="END_BOLD" />  यो प्रक्रियाका क्रममा सिस्टम रिबुट गरिने छ।</translation>
-<translation id="23030561267973084">"<ph name="EXTENSION_NAME" />" ले थप अनुमतिहरू अनुरोध गरेको छ।</translation>
+<translation id="23030561267973084">"<ph name="EXTENSION_NAME" />" ले थप अनुमति मागेको छ।</translation>
 <translation id="2304820083631266885">ग्रह</translation>
 <translation id="2306794767168143227">यो डिभाइसमार्फत <ph name="BRAND" /> मा सेभ गर्नुहोस्</translation>
 <translation id="2307553512430195144">तपाईंले यसमा सहमति जनाउनुभयो भने Google सहायक “Ok Google” भनेको कुरा पहिचान गर्न स्ट्यान्डबाई मोडमा तयार भएर बस्ने छ र यसले Voice Match को सहयोगले बोल्ने व्यक्ति <ph name="SUPERVISED_USER_NAME" /> हो भन्ने कुरा चिन्न सक्छ।
diff --git a/chrome/app/resources/generated_resources_th.xtb b/chrome/app/resources/generated_resources_th.xtb
index 28929752..9802420 100644
--- a/chrome/app/resources/generated_resources_th.xtb
+++ b/chrome/app/resources/generated_resources_th.xtb
@@ -1361,6 +1361,7 @@
 <translation id="1931152874660185993">ไม่มีคอมโพเนนต์ที่ได้รับการติดตั้ง</translation>
 <translation id="1931410639376954712">กำลังติดตั้ง <ph name="DEVICE_OS" /></translation>
 <translation id="1932098463447129402">หลังจาก</translation>
+<translation id="1933070475689690969">กิจกรรมบนแอป Gemini</translation>
 <translation id="1933489278505808700">ได้รับอนุญาตให้อ่านและเปลี่ยนแปลง</translation>
 <translation id="1935303383381416800">ได้รับอนุญาตให้ดูตำแหน่งของคุณ</translation>
 <translation id="193565226207940518">เครื่องมือการสนับสนุน</translation>
@@ -3492,6 +3493,7 @@
 <translation id="3435738964857648380">ความปลอดภัย</translation>
 <translation id="343578350365773421">กระดาษหมด</translation>
 <translation id="3435896845095436175">เปิดการใช้งาน</translation>
+<translation id="3437072258256045988">จัดการกิจกรรมบนแอป Gemini</translation>
 <translation id="3437397693214267762">ดูปฏิทิน Outlook และไฟล์ SharePoint และ OneDrive</translation>
 <translation id="3438633801274389918">นินจา</translation>
 <translation id="3439153939049640737">อนุญาตให้ <ph name="HOST" /> เข้าถึงไมโครโฟนของคุณเสมอ</translation>
diff --git a/chrome/app/resources/generated_resources_zh-CN.xtb b/chrome/app/resources/generated_resources_zh-CN.xtb
index 31feb10..8bfd012 100644
--- a/chrome/app/resources/generated_resources_zh-CN.xtb
+++ b/chrome/app/resources/generated_resources_zh-CN.xtb
@@ -1356,6 +1356,7 @@
 <translation id="1931152874660185993">没有安装任何组件。</translation>
 <translation id="1931410639376954712">正在安装 <ph name="DEVICE_OS" /></translation>
 <translation id="1932098463447129402">不早于</translation>
+<translation id="1933070475689690969">Gemini 应用活动记录</translation>
 <translation id="1933489278505808700">可以读取和更改</translation>
 <translation id="1935303383381416800">允许查看您的位置信息</translation>
 <translation id="193565226207940518">支持工具</translation>
@@ -3488,6 +3489,7 @@
 <translation id="3435738964857648380">安全</translation>
 <translation id="343578350365773421">纸张已用完</translation>
 <translation id="3435896845095436175">启用</translation>
+<translation id="3437072258256045988">管理 Gemini 应用活动记录</translation>
 <translation id="3437397693214267762">查看您的 Outlook 日历及 SharePoint 和 OneDrive 文件</translation>
 <translation id="3438633801274389918">忍者</translation>
 <translation id="3439153939049640737">始终允许 <ph name="HOST" /> 使用您的麦克风</translation>
diff --git a/chrome/app/resources/google_chrome_strings_lt.xtb b/chrome/app/resources/google_chrome_strings_lt.xtb
index 68a9e3c..95ca77f 100644
--- a/chrome/app/resources/google_chrome_strings_lt.xtb
+++ b/chrome/app/resources/google_chrome_strings_lt.xtb
@@ -197,6 +197,7 @@
 <translation id="3282568296779691940">Prisijungti prie „Chrome“</translation>
 <translation id="3286538390144397061">Paleisti iš naujo dabar</translation>
 <translation id="3292333338048274092">Tada turėsite iš naujo paleisti „Chrome“.</translation>
+<translation id="3324218984287646518">Klausti „Google Lens“ apie šį vaizdo įrašą</translation>
 <translation id="3327226547491422998">Vėliau „Chrome“ gali paklausti, ar norite naudoti išsaugotą informaciją automatiškai užpildydami formas</translation>
 <translation id="3352986031709923790">viršutinis dešinysis paieškos srities kampas: dešinė – <ph name="RIGHT" /> %, viršus – <ph name="TOP" /> %</translation>
 <translation id="3360895254066713204">„Chrome“ pagalbos priemonė</translation>
@@ -215,6 +216,7 @@
 <translation id="3576528680708590453">Sistemos administratorius sukonfigūravo „Google Chrome“ atidaryti alternatyvią naršyklę, norint pasiekti <ph name="TARGET_URL_HOSTNAME" />.</translation>
 <translation id="3582972582564653026">Sinchronizuokite ir suasmeninkite „Chrome“ skirtinguose įrenginiuose</translation>
 <translation id="3583751698304738917">Jau esate prisijungę kaip <ph name="USER_EMAIL_ADDRESS" /> kitame „Chrome“ profilyje</translation>
+<translation id="358381413217813387">Ieškoti šiame puslapyje naudojant „Google Lens“</translation>
 <translation id="3589519427766620380">Paklauskite „Google Lens“ apie šį puslapį</translation>
 <translation id="3595784445906693824">Prisijungti prie „Chrome“ naujame profilyje?</translation>
 <translation id="3596080736082218006">{COUNT,plural, =0{Administratorius reikalauja paleisti „Chrome“ iš naujo, kad būtų galima pritaikyti naujinį}=1{Administratorius reikalauja paleisti „Chrome“ iš naujo, kad būtų galima pritaikyti naujinį. Inkognito langas nebus atidarytas iš naujo.}one{Administratorius reikalauja paleisti „Chrome“ iš naujo, kad būtų galima pritaikyti naujinį. # inkognito langas nebus atidarytas iš naujo.}few{Administratorius reikalauja paleisti „Chrome“ iš naujo, kad būtų galima pritaikyti naujinį. # inkognito langai nebus atidaryti iš naujo.}many{Administratorius reikalauja paleisti „Chrome“ iš naujo, kad būtų galima pritaikyti naujinį. # inkognito lango nebus atidaryta iš naujo.}other{Administratorius reikalauja paleisti „Chrome“ iš naujo, kad būtų galima pritaikyti naujinį. # inkognito langų nebus atidaryta iš naujo.}}</translation>
@@ -295,9 +297,11 @@
 <translation id="4501471624619070934">Diegimas nepavyko, nes šioje šalyje prieiga ribojama.</translation>
 <translation id="4567424176335768812">Esate prisijungę kaip <ph name="USER_EMAIL_ADDRESS" />. Dabar galite pasiekti savo žymes, istoriją ir kitus nustatymus visuose įrenginiuose, kuriuose esate prisijungę.</translation>
 <translation id="4571503333518166079">Eiti į „Chrome“ pranešimų nustatymus</translation>
+<translation id="4592634244097223647">Klausti „Google“ apie šį vaizdą</translation>
 <translation id="459622048091363950">Kai „Chrome“ galės pasiekti duomenis, svetainės taip pat galės prašyti suteikti leidimą juos pasiekti.</translation>
 <translation id="4598116752460667024">Ieškokite bet kurio proceso iš sąrašo.</translation>
 <translation id="4600710005438004015">Nepavyko atnaujinti „Chrome“ į naujausią versiją, todėl nebus pasiekiamos naujos funkcijos ir saugos pataisos.</translation>
+<translation id="4608435347866444037">Ieškoti šiame vaizde naudojant „Google Lens“</translation>
 <translation id="4624065194742029982">„Chrome“ inkognito režimas</translation>
 <translation id="4627412468266359539">Pasirenkama: padėkite tobulinti „ChromeOS Flex“ funkcijas ir našumą automatiškai siųsdami diagnostikos ir naudojimo duomenis į sistemą „Google“.</translation>
 <translation id="4633000520311261472">Kad „Chrome“ padarytume saugesnę, išjungėme kai kuriuos plėtinius, kurių nėra „<ph name="IDS_EXTENSION_WEB_STORE_TITLE" />“ sąraše ir kurie galėjo būti pridėti be jūsų žinios.</translation>
@@ -487,6 +491,7 @@
 <translation id="7025789849649390912">Diegimas sustabdytas.</translation>
 <translation id="7025800014283535195">Čia galite perjungti „Chrome“ profilius</translation>
 <translation id="7059914902409643750">Suasmeninkite „Chrome“</translation>
+<translation id="7060643578009939353">Ieškoti šiame vaizdo įraše naudojant „Google Lens“</translation>
 <translation id="7071827361006050863">„Chrome“ netrukus ištrins naršymo duomenis</translation>
 <translation id="7085332316435785646">Pasirinkite, ar įtraukti „Chrome“ istoriją, kad būtų teikiamos labiau suasmenintos funkcijos „Google“ paslaugose</translation>
 <translation id="7088681679121566888">„Chrome“ atnaujinta</translation>
@@ -621,6 +626,7 @@
 <translation id="8712637175834984815">Supratau</translation>
 <translation id="8712767363896337380">Beveik atnaujinta! Paleiskite „Chrome“ iš naujo, kad būtų užbaigtas atnaujinimas.</translation>
 <translation id="8718062187489036808">Atsijungti nuo „Chrome“</translation>
+<translation id="8725440680697264016">Klausti „Google“ apie šį vaizdo įrašą</translation>
 <translation id="873133009373065397">„Google Chrome“ nepavyko aptikti arba nustatyti numatytosios naršyklės</translation>
 <translation id="8747073452963259673">apatinis kairysis paieškos srities kampas: kairė – <ph name="LEFT" /> %, apačia – <ph name="BOTTOM" /> %</translation>
 <translation id="8748735421235723888">„Chrome“ atlaisvina atminties iš neaktyvių skirtukų. Taip aktyviems skirtukams ir kitoms programoms suteikiama daugiau kompiuterio išteklių ir „Chrome“ veikia sparčiai. Neaktyvūs skirtukai automatiškai vėl tampa aktyvūs, kai grįžtate į juos. <ph name="BEGIN_LINK" />Sužinokite daugiau apie Atminties taupymo priemonę<ph name="END_LINK" /></translation>
@@ -637,6 +643,7 @@
 <translation id="8843516219908676469">„Chrome“ geriau supranta formas ir gali greičiau jas automatiškai užpildyti</translation>
 <translation id="8851180723659088381">{NUM_EXTENSIONS,plural, =1{„Chrome“ rekomenduoja tai pašalinti}one{„Chrome“ rekomenduoja tai pašalinti}few{„Chrome“ rekomenduoja tai pašalinti}many{„Chrome“ rekomenduoja tai pašalinti}other{„Chrome“ rekomenduoja tai pašalinti}}</translation>
 <translation id="8862326446509486874">Neturite reikiamų teisių sistemai įdiegti. Pamėginkite įdiegimo priemonę dar kartą paleisti kaip administratorius.</translation>
+<translation id="8883862939660515976">Klausti „Google Lens“ apie šį vaizdą</translation>
 <translation id="8914504000324227558">Iš naujo paleisti „Chrome“</translation>
 <translation id="8922193594870374009">Jei norite iš <ph name="ORIGIN" /> į „Android“ telefoną išsiųsti numerį, prisijunkite prie „Chrome“ abiejuose įrenginiuose.</translation>
 <translation id="8948460679427074738">Šis plėtinys nepaskelbė privatumo praktikos, pvz., kaip renka ir naudoja duomenis. „Chrome“ rekomenduoja jį pašalinti.</translation>
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index aa76b0c6..3b76d93 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -11245,8 +11245,7 @@
 
     {"prompt-api-for-gemini-nano",
      flag_descriptions::kPromptAPIForGeminiNanoName,
-     flag_descriptions::kPromptAPIForGeminiNanoDescription,
-     kOsDesktop,
+     flag_descriptions::kPromptAPIForGeminiNanoDescription, kOsDesktop,
      FEATURE_WITH_PARAMS_VALUE_TYPE(blink::features::kAIPromptAPI,
                                     kAILangsVariation,
                                     "kAIPromptAPI"),
@@ -11261,8 +11260,7 @@
 
     {"summarization-api-for-gemini-nano",
      flag_descriptions::kSummarizationAPIForGeminiNanoName,
-     flag_descriptions::kSummarizationAPIForGeminiNanoDescription,
-     kOsDesktop,
+     flag_descriptions::kSummarizationAPIForGeminiNanoDescription, kOsDesktop,
      FEATURE_WITH_PARAMS_VALUE_TYPE(blink::features::kAISummarizationAPI,
                                     kAILangsVariation,
                                     "kAISummarizationAPI"),
@@ -11270,8 +11268,7 @@
 
     {"writer-api-for-gemini-nano",
      flag_descriptions::kWriterAPIForGeminiNanoName,
-     flag_descriptions::kWriterAPIForGeminiNanoDescription,
-     kOsDesktop,
+     flag_descriptions::kWriterAPIForGeminiNanoDescription, kOsDesktop,
      FEATURE_WITH_PARAMS_VALUE_TYPE(blink::features::kAIWriterAPI,
                                     kAILangsVariation,
                                     "kAIWriterAPI"),
@@ -11279,8 +11276,7 @@
 
     {"rewriter-api-for-gemini-nano",
      flag_descriptions::kRewriterAPIForGeminiNanoName,
-     flag_descriptions::kRewriterAPIForGeminiNanoDescription,
-     kOsDesktop,
+     flag_descriptions::kRewriterAPIForGeminiNanoDescription, kOsDesktop,
      FEATURE_WITH_PARAMS_VALUE_TYPE(blink::features::kAIRewriterAPI,
                                     kAILangsVariation,
                                     "kAIRewriterAPI"),
@@ -11288,8 +11284,7 @@
 
     {"proofreader-api-for-gemini-nano",
      flag_descriptions::kProofreaderAPIForGeminiNanoName,
-     flag_descriptions::kProofreaderAPIForGeminiNanoDescription,
-     kOsDesktop,
+     flag_descriptions::kProofreaderAPIForGeminiNanoDescription, kOsDesktop,
      FEATURE_VALUE_TYPE(blink::features::kAIProofreadingAPI),
      flag_descriptions::kAIAPIsForGeminiNanoLinks},
 
diff --git a/chrome/browser/accessibility/tree_fixing/BUILD.gn b/chrome/browser/accessibility/tree_fixing/BUILD.gn
index 785aec4..77e43c52 100644
--- a/chrome/browser/accessibility/tree_fixing/BUILD.gn
+++ b/chrome/browser/accessibility/tree_fixing/BUILD.gn
@@ -27,7 +27,7 @@
   ]
 
   if (is_chromeos) {
-    deps += [ "//chrome/browser/ash/accessibility:accessibility" ]
+    deps += [ "//chrome/browser/ash/accessibility" ]
   }
 }
 
@@ -67,7 +67,7 @@
     "//components/paint_preview/browser",
     "//components/paint_preview/common",
     "//components/paint_preview/public",
-    "//content/public/browser:browser",
-    "//services/screen_ai/public/mojom:mojom",
+    "//content/public/browser",
+    "//services/screen_ai/public/mojom",
   ]
 }
diff --git a/chrome/browser/actor/BUILD.gn b/chrome/browser/actor/BUILD.gn
index 5522b8c..6a19b5a 100644
--- a/chrome/browser/actor/BUILD.gn
+++ b/chrome/browser/actor/BUILD.gn
@@ -51,7 +51,7 @@
     "//content/public/browser",
   ]
   if (enable_glic) {
-    public_deps += [ "//chrome/browser/glic:glic" ]
+    public_deps += [ "//chrome/browser/glic" ]
   }
 }
 
@@ -115,19 +115,18 @@
     "//chrome/browser/actor/ui",
     "//chrome/browser/actor/ui:event_dispatcher",
     "//chrome/browser/actor/ui:tool_request_variant",
-    "//chrome/browser/actor/ui:ui",
-    "//chrome/browser/optimization_guide:optimization_guide",
+    "//chrome/browser/optimization_guide",
     "//chrome/browser/page_content_annotations:fetcher",
     "//chrome/browser/profiles:profile",
     "//chrome/browser/safe_browsing",
     "//chrome/browser/ui:browser_navigator_params_headers",
-    "//chrome/browser/ui/browser_window:browser_window",
+    "//chrome/browser/ui/browser_window",
     "//chrome/browser/ui/tabs:tabs_public",
     "//chrome/common",
     "//components/lookalikes/core",
     "//components/safe_browsing:buildflags",
     "//components/safe_browsing/core/common:safe_browsing_prefs",
-    "//components/variations/service:service",
+    "//components/variations/service",
     "//content/public/browser",
     "//net",
     "//third_party/perfetto:libperfetto",
@@ -142,7 +141,7 @@
     "//chrome/browser/actor/ui:tool_request_variant",
   ]
   if (enable_glic) {
-    deps += [ "//chrome/browser/glic:glic" ]
+    deps += [ "//chrome/browser/glic" ]
   }
 }
 
@@ -158,7 +157,7 @@
   public_deps = [
     "//base",
     "//chrome/common:mojo_bindings",
-    "//ui/gfx/geometry:geometry",
+    "//ui/gfx/geometry",
   ]
   deps = [ "//third_party/abseil-cpp:absl" ]
 }
@@ -224,9 +223,9 @@
     "//base/test:test_support",
     "//chrome/browser/optimization_guide:test_support",
     "//chrome/browser/safe_browsing",
-    "//chrome/browser/ui:ui",
+    "//chrome/browser/ui",
     "//chrome/browser/ui:ui_features",
-    "//chrome/browser/ui/zoom:zoom",
+    "//chrome/browser/ui/zoom",
     "//chrome/test:test_support",
     "//chrome/test:test_support_ui",
     "//components/optimization_guide/core:bloomfilter",
@@ -255,6 +254,6 @@
       "tools/type_tool_browsertest.cc",
       "tools/wait_tool_browsertest.cc",
     ]
-    deps += [ "//chrome/browser/glic:glic" ]
+    deps += [ "//chrome/browser/glic" ]
   }
 }
diff --git a/chrome/browser/ai/BUILD.gn b/chrome/browser/ai/BUILD.gn
index e0a6664..4a5f995 100644
--- a/chrome/browser/ai/BUILD.gn
+++ b/chrome/browser/ai/BUILD.gn
@@ -40,16 +40,16 @@
     "//chrome/browser/ai:ai_utils",
     "//chrome/browser/optimization_guide",
     "//chrome/browser/profiles:profile",
-    "//components/component_updater:component_updater",
+    "//components/component_updater",
     "//components/optimization_guide/core",
-    "//components/update_client:update_client",
+    "//components/update_client",
     "//content/public/browser",
   ]
   if (enable_glic) {
-    public_deps += [ "//chrome/browser/glic:glic" ]
+    public_deps += [ "//chrome/browser/glic" ]
   }
   if (!is_android) {
-    public_deps += [ "//chrome/browser/actor:actor" ]
+    public_deps += [ "//chrome/browser/actor" ]
   }
 }
 
@@ -86,7 +86,7 @@
 
   public_deps = [
     "//chrome/browser:browser_public_dependencies",
-    "//chrome/browser/ui:ui",
+    "//chrome/browser/ui",
     "//components/content_extraction/content/browser",
   ]
   deps = [
@@ -97,13 +97,13 @@
     "//components/history_embeddings",
     "//components/language/core/common",
     "//components/optimization_guide/content/browser",
-    "//components/site_engagement/content:content",
+    "//components/site_engagement/content",
     "//pdf:buildflags",
     "//skia",
   ]
   if (!is_android) {
     deps += [
-      "//chrome/browser/ui/browser_window:browser_window",
+      "//chrome/browser/ui/browser_window",
       "//chrome/browser/ui/tabs:tab_group",
       "//chrome/browser/ui/tabs:tab_strip",
     ]
@@ -144,8 +144,8 @@
     "//chrome/test:test_support",
     "//components/component_updater:test_support",
     "//components/optimization_guide/core:test_support",
-    "//testing/gmock:gmock",
-    "//testing/gtest:gtest",
+    "//testing/gmock",
+    "//testing/gtest",
   ]
   deps = [ ":ai" ]
 }
diff --git a/chrome/browser/android/cookies/BUILD.gn b/chrome/browser/android/cookies/BUILD.gn
index 75ec56f..f9b88f26 100644
--- a/chrome/browser/android/cookies/BUILD.gn
+++ b/chrome/browser/android/cookies/BUILD.gn
@@ -40,7 +40,7 @@
     "//chrome/browser/profiles/android:java",
     "//third_party/hamcrest:hamcrest_java",
     "//third_party/jni_zero:gendeps_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
   ]
 }
diff --git a/chrome/browser/android/customtabs/branding/BUILD.gn b/chrome/browser/android/customtabs/branding/BUILD.gn
index 9cb6d064..ea034c6 100644
--- a/chrome/browser/android/customtabs/branding/BUILD.gn
+++ b/chrome/browser/android/customtabs/branding/BUILD.gn
@@ -126,7 +126,7 @@
     "//chrome/browser/ui/android/theme:java",
     "//content/public/test/android:content_java_test_support",
     "//third_party/androidx:androidx_test_runner_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//ui/android:ui_java",
     "//ui/android:ui_java_test_support",
   ]
diff --git a/chrome/browser/android/httpclient/BUILD.gn b/chrome/browser/android/httpclient/BUILD.gn
index bc6a0f9..cdfa717 100644
--- a/chrome/browser/android/httpclient/BUILD.gn
+++ b/chrome/browser/android/httpclient/BUILD.gn
@@ -38,7 +38,7 @@
   ]
 
   deps = [
-    "//base:base",
+    "//base",
     "//chrome/browser/profiles:profile",
     "//content/public/browser",
     "//net",
@@ -54,17 +54,17 @@
   sources = [ "http_client_unittest.cc" ]
   deps = [
     ":android",
-    "//base:base",
+    "//base",
     "//base/test:test_support",
     "//content/public/browser",
     "//content/test:test_support",
-    "//net:net",
+    "//net",
     "//net/traffic_annotation:test_support",
     "//services/network:test_support",
-    "//services/network/public/cpp:cpp",
+    "//services/network/public/cpp",
     "//services/network/public/mojom:url_loader_base",
     "//testing/gmock",
-    "//testing/gtest:gtest",
+    "//testing/gtest",
   ]
 }
 
@@ -81,7 +81,7 @@
     "//net/android:net_java",
     "//net/android:net_java_test_support",
     "//third_party/androidx:androidx_test_runner_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//url:gurl_java",
   ]
 }
@@ -98,7 +98,7 @@
     "//chrome/browser/profiles/android:java",
     "//net/android:net_java",
     "//third_party/jni_zero:jni_zero_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//url:gurl_java",
     "//url:gurl_junit_test_support",
diff --git a/chrome/browser/android/metrics/BUILD.gn b/chrome/browser/android/metrics/BUILD.gn
index 87a67c2..44ae3e0 100644
--- a/chrome/browser/android/metrics/BUILD.gn
+++ b/chrome/browser/android/metrics/BUILD.gn
@@ -50,7 +50,7 @@
       "//base",
       "//chrome/browser:browser_process",
       "//chrome/browser/android/metrics:test_jni_headers",
-      "//components/metrics_services_manager:metrics_services_manager",
+      "//components/metrics_services_manager",
       "//components/ukm",
     ]
   }
diff --git a/chrome/browser/android/vr/BUILD.gn b/chrome/browser/android/vr/BUILD.gn
index e9153ce..4c1fcc0 100644
--- a/chrome/browser/android/vr/BUILD.gn
+++ b/chrome/browser/android/vr/BUILD.gn
@@ -20,7 +20,7 @@
     "//device/vr:vr_base",
     "//device/vr:vr_util",
     "//device/vr/android:vr_android",
-    "//device/vr/buildflags:buildflags",
+    "//device/vr/buildflags",
   ]
 
   if (enable_arcore) {
@@ -62,8 +62,8 @@
     ":vr_android",
     "//base/test:test_support",
     "//chrome/browser",
-    "//components/translate/core/language_detection:language_detection",
-    "//components/webxr:webxr",
+    "//components/translate/core/language_detection",
+    "//components/webxr",
     "//device/vr:vr_fakes",
     "//device/vr/android:vr_android",
     "//device/vr/public/mojom:isolated_xr_service",
diff --git a/chrome/browser/android/webapk/BUILD.gn b/chrome/browser/android/webapk/BUILD.gn
index fe4749d..4e70d4cd 100644
--- a/chrome/browser/android/webapk/BUILD.gn
+++ b/chrome/browser/android/webapk/BUILD.gn
@@ -32,9 +32,9 @@
     "//chrome/browser/profiles:profile",
     "//chrome/browser/web_share_target",
     "//chrome/common:channel_info",
-    "//components/crx_file:crx_file",
+    "//components/crx_file",
     "//components/sync",
-    "//components/ukm:ukm",
+    "//components/ukm",
     "//components/webapps/browser",
     "//components/webapps/common",
     "//content/public/browser",
diff --git a/chrome/browser/apps/BUILD.gn b/chrome/browser/apps/BUILD.gn
index ee0cfd2..375327e 100644
--- a/chrome/browser/apps/BUILD.gn
+++ b/chrome/browser/apps/BUILD.gn
@@ -24,7 +24,7 @@
   deps = [
     "//base",
     "//chrome/browser/profiles:profile",
-    "//content/public/browser:browser",
+    "//content/public/browser",
   ]
 
   if (is_chromeos) {
diff --git a/chrome/browser/apps/app_discovery_service/recommended_arc_apps/BUILD.gn b/chrome/browser/apps/app_discovery_service/recommended_arc_apps/BUILD.gn
index 6b5b7924..5b9e2de3 100644
--- a/chrome/browser/apps/app_discovery_service/recommended_arc_apps/BUILD.gn
+++ b/chrome/browser/apps/app_discovery_service/recommended_arc_apps/BUILD.gn
@@ -67,7 +67,7 @@
     "//base",
     "//chrome/test:test_support",
     "//chromeos/ash/experiences/arc",
-    "//chromeos/crosapi/mojom:mojom",
+    "//chromeos/crosapi/mojom",
     "//components/user_manager",
     "//content/test:test_support",
     "//gpu/config",
diff --git a/chrome/browser/apps/app_service/BUILD.gn b/chrome/browser/apps/app_service/BUILD.gn
index bb960970..83cb6d2b 100644
--- a/chrome/browser/apps/app_service/BUILD.gn
+++ b/chrome/browser/apps/app_service/BUILD.gn
@@ -274,7 +274,7 @@
       "//chromeos/ash/experiences/arc/session",
       "//chromeos/ash/experiences/arc/session:connection_holder",
       "//chromeos/ash/experiences/system_web_apps/types",
-      "//chromeos/components/kiosk:kiosk",
+      "//chromeos/components/kiosk",
       "//chromeos/components/mgs",
       "//chromeos/crosapi/mojom",
       "//components/app_restore",
diff --git a/chrome/browser/apps/app_service/app_install/BUILD.gn b/chrome/browser/apps/app_service/app_install/BUILD.gn
index ac2921a..d6ee709 100644
--- a/chrome/browser/apps/app_service/app_install/BUILD.gn
+++ b/chrome/browser/apps/app_service/app_install/BUILD.gn
@@ -63,7 +63,7 @@
     "//chromeos/ash/experiences/arc/session",
     "//chromeos/ash/experiences/arc/session:connection_holder",
     "//chromeos/components/mgs",
-    "//chromeos/constants:constants",
+    "//chromeos/constants",
     "//chromeos/crosapi/mojom",
     "//components/metrics/structured:structured_events",
     "//components/services/app_service",
diff --git a/chrome/browser/apps/app_service/launch_utils.cc b/chrome/browser/apps/app_service/launch_utils.cc
index e3768dd..f105e35 100644
--- a/chrome/browser/apps/app_service/launch_utils.cc
+++ b/chrome/browser/apps/app_service/launch_utils.cc
@@ -332,9 +332,9 @@
       return;
     }
   }
-  CHECK(ash::NewWindowDelegate::GetPrimary());
+  CHECK(ash::NewWindowDelegate::GetInstance());
 
-  ash::NewWindowDelegate::GetPrimary()->OpenUrl(
+  ash::NewWindowDelegate::GetInstance()->OpenUrl(
       url, ash::NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       ash::NewWindowDelegate::Disposition::kNewForegroundTab);
 }
@@ -356,9 +356,9 @@
     }
   }
 
-  CHECK(ash::NewWindowDelegate::GetPrimary());
+  CHECK(ash::NewWindowDelegate::GetInstance());
 
-  ash::NewWindowDelegate::GetPrimary()->OpenUrl(
+  ash::NewWindowDelegate::GetInstance()->OpenUrl(
       url, ash::NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       ash::NewWindowDelegate::Disposition::kNewForegroundTab);
 }
diff --git a/chrome/browser/apps/app_shim/BUILD.gn b/chrome/browser/apps/app_shim/BUILD.gn
index 891f919..e12846f 100644
--- a/chrome/browser/apps/app_shim/BUILD.gn
+++ b/chrome/browser/apps/app_shim/BUILD.gn
@@ -40,7 +40,7 @@
     "//chrome/browser/ui:ui_features",
     "//chrome/browser/ui/profiles",
     "//chrome/browser/ui/web_applications",
-    "//chrome/browser/web_applications:web_applications",
+    "//chrome/browser/web_applications",
     "//chrome/common",
     "//chrome/common:app_mode_app_support",
     "//chrome/common:constants",
@@ -53,7 +53,7 @@
     "//components/webapps/common",
     "//content/public/browser",
     "//content/public/common",
-    "//services/preferences/public/cpp:cpp",
-    "//ui/views:views",
+    "//services/preferences/public/cpp",
+    "//ui/views",
   ]
 }
diff --git a/chrome/browser/apps/browser_instance/browser_app_instance_tracker.cc b/chrome/browser/apps/browser_instance/browser_app_instance_tracker.cc
index 73e9f2d..74b6eb0 100644
--- a/chrome/browser/apps/browser_instance/browser_app_instance_tracker.cc
+++ b/chrome/browser/apps/browser_instance/browser_app_instance_tracker.cc
@@ -16,6 +16,7 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_list.h"
 #include "chrome/browser/ui/browser_window.h"
+#include "chrome/browser/ui/browser_window/public/browser_window_interface.h"
 #include "chrome/browser/ui/tabs/tab_enums.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/web_applications/web_app_helpers.h"
@@ -253,8 +254,9 @@
   }
 }
 
-bool BrowserAppInstanceTracker::ShouldTrackBrowser(Browser* browser) {
-  return profile_->IsSameOrParent(browser->profile());
+bool BrowserAppInstanceTracker::ShouldTrackBrowser(
+    BrowserWindowInterface* browser) {
+  return profile_->IsSameOrParent(browser->GetProfile());
 }
 
 void BrowserAppInstanceTracker::OnBrowserAdded(Browser* browser) {
diff --git a/chrome/browser/apps/browser_instance/browser_app_instance_tracker.h b/chrome/browser/apps/browser_instance/browser_app_instance_tracker.h
index 87ac8ff5..8049133 100644
--- a/chrome/browser/apps/browser_instance/browser_app_instance_tracker.h
+++ b/chrome/browser/apps/browser_instance/browser_app_instance_tracker.h
@@ -87,7 +87,7 @@
       const TabStripSelectionChange& selection) override;
 
   // BrowserTabStripTrackerDelegate overrides:
-  bool ShouldTrackBrowser(Browser* browser) override;
+  bool ShouldTrackBrowser(BrowserWindowInterface* browser) override;
 
   // BrowserListObserver overrides:
   void OnBrowserAdded(Browser* browser) override;
diff --git a/chrome/browser/apps/link_capturing/BUILD.gn b/chrome/browser/apps/link_capturing/BUILD.gn
index 21b5e598..eb572e01 100644
--- a/chrome/browser/apps/link_capturing/BUILD.gn
+++ b/chrome/browser/apps/link_capturing/BUILD.gn
@@ -34,7 +34,7 @@
     "//components/keep_alive_registry",
     "//components/page_load_metrics/browser",
     "//components/page_load_metrics/google/browser",
-    "//components/webapps/common:common",
+    "//components/webapps/common",
     "//content/public/browser",
     "//third_party/abseil-cpp:absl",
     "//url",
@@ -95,8 +95,8 @@
     ":link_capturing",
     "//base/test:test_support",
     "//chrome/browser:test_support",
+    "//chrome/browser/web_applications",
     "//chrome/browser/web_applications:features",
-    "//chrome/browser/web_applications:web_applications",
     "//chrome/common:chrome_features",
     "//chrome/test:test_support",
     "//chrome/test:test_support_ui",
@@ -117,7 +117,7 @@
     "//chrome/test:test_support",
     "//content/test:test_support",
     "//testing/gtest",
-    "//ui/base:base",
+    "//ui/base",
     "//ui/display:test_support",
     "//url",
   ]
diff --git a/chrome/browser/apps/link_capturing/link_capturing_feature_test_support.cc b/chrome/browser/apps/link_capturing/link_capturing_feature_test_support.cc
index 2acd94f..53a9e322 100644
--- a/chrome/browser/apps/link_capturing/link_capturing_feature_test_support.cc
+++ b/chrome/browser/apps/link_capturing/link_capturing_feature_test_support.cc
@@ -258,14 +258,13 @@
         if (!has_function.is_ok() || !has_function.ExtractBool()) {
           // Sometimes the web contents is destroyed while evaluating this
           // javascript. That is fine.
-          DLOG_IF(INFO, !has_function.is_ok())
-              << "Got error: " << has_function.error;
+          DLOG_IF(INFO, !has_function.is_ok()) << "Got error: " << has_function;
           return;
         }
         content::EvalJsResult result =
             content::EvalJs(&web_contents, "resolveLaunchParamsFlush()");
         if (!result.is_ok()) {
-          errors.push_back(result.error);
+          errors.push_back(result.ExtractError());
         }
       }));
   if (!errors.empty()) {
diff --git a/chrome/browser/apps/platform_apps/BUILD.gn b/chrome/browser/apps/platform_apps/BUILD.gn
index aeb1c37..50eeb746 100644
--- a/chrome/browser/apps/platform_apps/BUILD.gn
+++ b/chrome/browser/apps/platform_apps/BUILD.gn
@@ -81,7 +81,7 @@
     "//extensions/common",
     "//extensions/common/api",
     "//net",
-    "//services/preferences/public/cpp:cpp",
+    "//services/preferences/public/cpp",
     "//ui/gfx",
   ]
 
diff --git a/chrome/browser/ash/accessibility/service/tts_client_impl.cc b/chrome/browser/ash/accessibility/service/tts_client_impl.cc
index cc2fbd4..01822c3 100644
--- a/chrome/browser/ash/accessibility/service/tts_client_impl.cc
+++ b/chrome/browser/ash/accessibility/service/tts_client_impl.cc
@@ -49,11 +49,10 @@
   }
 }
 
-// Self-owned, compare to TtsExtensionEventHandler.
+// Owned by TtsUtterance.
 class AtpTtsEventHandler : public content::UtteranceEventDelegate {
  public:
-  // static creator deals with "new" so clients don't have to think about it.
-  static AtpTtsEventHandler* Create() { return new AtpTtsEventHandler(); }
+  AtpTtsEventHandler() = default;
   ~AtpTtsEventHandler() override = default;
   AtpTtsEventHandler(const AtpTtsEventHandler&) = delete;
   AtpTtsEventHandler& operator=(const AtpTtsEventHandler&) = delete;
@@ -73,18 +72,12 @@
       mojom_event->error_message = error_message;
     }
     utterance_client_->OnEvent(std::move(mojom_event));
-    if (utterance->IsFinished()) {
-      // Expected to self-destroy on call to TtsEvent, see
-      // tts_utterance_impl.cc.
-      delete this;
-    }
   }
   mojo::PendingReceiver<ax::mojom::TtsUtteranceClient> PassReceiver() {
     return utterance_client_.BindNewPipeAndPassReceiver();
   }
 
  private:
-  AtpTtsEventHandler() = default;
   mojo::Remote<ax::mojom::TtsUtteranceClient> utterance_client_;
 };
 
@@ -157,9 +150,9 @@
     tts_utterance->SetEngineId(options->engine_id.value());
   }
   if (options->on_event) {
-    auto* atpTtsEventHandler = AtpTtsEventHandler::Create();
-    result->utterance_client = atpTtsEventHandler->PassReceiver();
-    tts_utterance->SetEventDelegate(atpTtsEventHandler);
+    auto atp_tts_event_handler = std::make_unique<AtpTtsEventHandler>();
+    result->utterance_client = atp_tts_event_handler->PassReceiver();
+    tts_utterance->SetEventDelegate(std::move(atp_tts_event_handler));
   }
   // Note: we don't need desired/required event types because they aren't
   // passed by ChromeVox or STS. We don't need an options_dict, it's redundant,
diff --git a/chrome/browser/ash/accessibility/spoken_feedback_browsertest.cc b/chrome/browser/ash/accessibility/spoken_feedback_browsertest.cc
index 6c0142d..df430e0 100644
--- a/chrome/browser/ash/accessibility/spoken_feedback_browsertest.cc
+++ b/chrome/browser/ash/accessibility/spoken_feedback_browsertest.cc
@@ -2728,103 +2728,6 @@
   sm()->Replay();
 }
 
-class DeskTemplatesSpokenFeedbackTest : public LoggedInSpokenFeedbackTest {
- public:
-  DeskTemplatesSpokenFeedbackTest() = default;
-  DeskTemplatesSpokenFeedbackTest(const DeskTemplatesSpokenFeedbackTest&) =
-      delete;
-  DeskTemplatesSpokenFeedbackTest& operator=(
-      const DeskTemplatesSpokenFeedbackTest&) = delete;
-  ~DeskTemplatesSpokenFeedbackTest() override = default;
-
-  void SetUpCommandLine(base::CommandLine* command_line) override {
-    LoggedInSpokenFeedbackTest::SetUpCommandLine(command_line);
-
-    scoped_feature_list_.InitWithFeatures({features::kDesksTemplates}, {});
-  }
-
- private:
-  base::test::ScopedFeatureList scoped_feature_list_;
-};
-
-// TODO(crbug.com/388867840): Add manifest v3 variant when migration is
-// complete.
-INSTANTIATE_TEST_SUITE_P(
-    ManifestV2,
-    DeskTemplatesSpokenFeedbackTest,
-    ::testing::Values(SpokenFeedbackTestConfig(ManifestVersion::kTwo)));
-
-IN_PROC_BROWSER_TEST_P(DeskTemplatesSpokenFeedbackTest, DeskTemplatesBasic) {
-  // TODO(http://b/350771229): This test tests clicking the "Save desk as
-  // template" button that will not be shown if the Forest feature is enabled.
-  // This test will be fixed before the button change is no longer hidden behind
-  // Forest.
-  if (ash::features::IsForestFeatureEnabled()) {
-    GTEST_SKIP() << "Skipping test body for Forest Feature.";
-  }
-
-  chromevox_test_utils()->EnableChromeVox();
-
-  // Enter overview first. This is how we reach the desk templates UI.
-  sm()->Call([this]() {
-    (PerformAcceleratorAction(AcceleratorAction::kToggleOverview));
-  });
-
-  sm()->ExpectSpeech(
-      "Entered window overview mode. Swipe to navigate, or press tab if using "
-      "a keyboard.");
-
-  // TODO(crbug.com/1360638): Remove the conditional here when the Save & Recall
-  // flag flip has landed since it will always be true.
-  if (saved_desk_util::ShouldShowSavedDesksOptions()) {
-    sm()->Call([this]() { SendKeyPressWithShift(ui::VKEY_TAB); });
-    sm()->ExpectSpeechPattern("Save desk for later");
-    sm()->ExpectSpeech("Button");
-  }
-
-  // Reverse tab to focus the save desk as template button.
-  sm()->Call([this]() { SendKeyPressWithShift(ui::VKEY_TAB); });
-  sm()->ExpectSpeechPattern("Save desk as a template");
-  sm()->ExpectSpeech("Button");
-
-  // Hit enter on the save desk as template button. It should take us to the
-  // templates grid, which triggers an accessibility alert. This should nudge
-  // the template name view but not say anything extra.
-  sm()->Call([this]() { SendKeyPress(ui::VKEY_RETURN); });
-  sm()->ExpectSpeech(
-      "Viewing saved desks and templates. Press tab to navigate.");
-
-  // The first item in the tab order is the template card, which is a button. It
-  // has the same name as the desk it was created from, in this case the default
-  // desk name is "Desk 1". The name view will be focused first, then we can go
-  // backwards to the template card, which is a button.
-  sm()->Call([this]() { SendKeyPressWithShift(ui::VKEY_TAB); });
-  sm()->ExpectSpeechPattern("Template, Desk 1");
-  sm()->ExpectSpeech("Button");
-  sm()->ExpectSpeech("Press Ctrl plus W to delete");
-  sm()->ExpectSpeech("Press Search plus Space to activate");
-
-  // The next item is the textfield inside the template card, which also has the
-  // same name as the desk it was created from.
-  sm()->Call([this]() { SendKeyPress(ui::VKEY_TAB); });
-  sm()->ExpectSpeechPattern("Desk 1");
-  sm()->ExpectSpeech("Edit text");
-
-  // Reverse tab to focus back on the template card.
-  sm()->Call([this]() { SendKeyPressWithShift(ui::VKEY_TAB); });
-
-  // Trigger a delete template dialog by pressing Ctrl+W.
-  sm()->Call([this]() { SendKeyPressWithControl(ui::VKEY_W); });
-  sm()->ExpectSpeech("Delete template?");
-  sm()->ExpectSpeech("Dialog");
-  sm()->ExpectSpeech("Delete");
-  sm()->ExpectSpeech("default");
-  sm()->ExpectSpeech("Button");
-  sm()->ExpectSpeech("Press Search plus Space to activate");
-
-  sm()->Replay();
-}
-
 class ShortcutsAppSpokenFeedbackTest : public LoggedInSpokenFeedbackTest {
  public:
   ShortcutsAppSpokenFeedbackTest() = default;
diff --git a/chrome/browser/ash/app_mode/test/kiosk_iwa_device_attributes_browsertest.cc b/chrome/browser/ash/app_mode/test/kiosk_iwa_device_attributes_browsertest.cc
index 3225d69..3a5565f 100644
--- a/chrome/browser/ash/app_mode/test/kiosk_iwa_device_attributes_browsertest.cc
+++ b/chrome/browser/ash/app_mode/test/kiosk_iwa_device_attributes_browsertest.cc
@@ -212,7 +212,7 @@
   for (const std::string& attribute : kDeviceAttributeNames) {
     content::EvalJsResult result =
         CallDeviceAttributesApi(web_contents(), attribute);
-    EXPECT_EQ(result.error, kNotAllowedOriginExpectedError);
+    EXPECT_EQ(result.ExtractError(), kNotAllowedOriginExpectedError);
   }
 }
 
diff --git a/chrome/browser/ash/arc/input_overlay/ui/editing_list.cc b/chrome/browser/ash/arc/input_overlay/ui/editing_list.cc
index d88dab26..44cda20b 100644
--- a/chrome/browser/ash/arc/input_overlay/ui/editing_list.cc
+++ b/chrome/browser/ash/arc/input_overlay/ui/editing_list.cc
@@ -455,7 +455,7 @@
 }
 
 void EditingList::OnHelpButtonPressed() {
-  ash::NewWindowDelegate::GetPrimary()->OpenUrl(
+  ash::NewWindowDelegate::GetInstance()->OpenUrl(
       GURL(kHelpUrl), ash::NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       ash::NewWindowDelegate::Disposition::kNewForegroundTab);
 }
diff --git a/chrome/browser/ash/arc/net/browser_url_opener_impl.cc b/chrome/browser/ash/arc/net/browser_url_opener_impl.cc
index 779de0f9..a53121b 100644
--- a/chrome/browser/ash/arc/net/browser_url_opener_impl.cc
+++ b/chrome/browser/ash/arc/net/browser_url_opener_impl.cc
@@ -9,7 +9,7 @@
 namespace arc {
 
 void BrowserUrlOpenerImpl::OpenUrl(GURL url) {
-  ash::NewWindowDelegate::GetPrimary()->OpenUrl(
+  ash::NewWindowDelegate::GetInstance()->OpenUrl(
       url, ash::NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       ash::NewWindowDelegate::Disposition::kNewForegroundTab);
 }
diff --git a/chrome/browser/ash/arc/session/arc_activation_necessity_checker.cc b/chrome/browser/ash/arc/session/arc_activation_necessity_checker.cc
index 4ae8843..add1f01 100644
--- a/chrome/browser/ash/arc/session/arc_activation_necessity_checker.cc
+++ b/chrome/browser/ash/arc/session/arc_activation_necessity_checker.cc
@@ -6,6 +6,7 @@
 
 #include <utility>
 
+#include "ash/constants/ash_features.h"
 #include "base/metrics/histogram_functions.h"
 #include "chrome/browser/ash/app_list/arc/arc_app_list_prefs.h"
 #include "chrome/browser/ash/arc/policy/arc_policy_util.h"
@@ -57,6 +58,13 @@
     return;
   }
 
+  // Activate ARC if Coral feature is enabled, since it depends on the on-device
+  // safety service which is powered inside arc.
+  if (ash::features::IsCoralFeatureEnabled()) {
+    OnChecked(std::move(callback), true);
+    return;
+  }
+
   // If ADB sideloading is enabled, activate ARC. Otherwise, no need to
   // activate.
   adb_sideloading_availability_delegate_->CanChangeAdbSideloading(
diff --git a/chrome/browser/ash/arc/session/arc_activation_necessity_checker_unittest.cc b/chrome/browser/ash/arc/session/arc_activation_necessity_checker_unittest.cc
index 399d0f88..c4efbf6 100644
--- a/chrome/browser/ash/arc/session/arc_activation_necessity_checker_unittest.cc
+++ b/chrome/browser/ash/arc/session/arc_activation_necessity_checker_unittest.cc
@@ -6,6 +6,7 @@
 
 #include <utility>
 
+#include "ash/constants/ash_features.h"
 #include "ash/constants/ash_switches.h"
 #include "base/command_line.h"
 #include "base/strings/stringprintf.h"
@@ -384,6 +385,18 @@
   EXPECT_TRUE(future.Get());
 }
 
+TEST_F(ArcActivationNecessityCheckerTest, CoralFeatureEnabled) {
+  base::test::ScopedFeatureList feature_list;
+  // Coral feature is enabled when both flags below are enabled.
+  feature_list.InitWithFeatures(
+      /* enabled_features */ {ash::features::kCoralFeature,
+                              ash::features::kCoralFeatureAllowed},
+      /* disabled_features */ {});
+  base::test::TestFuture<bool> future;
+  checker_->Check(future.GetCallback());
+  EXPECT_TRUE(future.Get());
+}
+
 }  // namespace
 
 }  // namespace arc
diff --git a/chrome/browser/ash/borealis/borealis_game_install_flow.cc b/chrome/browser/ash/borealis/borealis_game_install_flow.cc
index 10faf6b..1e0817f 100644
--- a/chrome/browser/ash/borealis/borealis_game_install_flow.cc
+++ b/chrome/browser/ash/borealis/borealis_game_install_flow.cc
@@ -56,7 +56,7 @@
   std::string url =
       base::StrCat({kSteamStoreUrlPrefix, base::NumberToString(steam_game_id)});
 
-  ash::NewWindowDelegate::GetPrimary()->OpenUrl(
+  ash::NewWindowDelegate::GetInstance()->OpenUrl(
       GURL(url), ash::NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       ash::NewWindowDelegate::Disposition::kNewForegroundTab);
 }
diff --git a/chrome/browser/ash/child_accounts/website_approval_notifier.cc b/chrome/browser/ash/child_accounts/website_approval_notifier.cc
index 6d7aa29..ac9764ca 100644
--- a/chrome/browser/ash/child_accounts/website_approval_notifier.cc
+++ b/chrome/browser/ash/child_accounts/website_approval_notifier.cc
@@ -60,7 +60,7 @@
 
 void OnNotificationClick(const GURL& url) {
   base::RecordAction(base::UserMetricsAction(kNotificationClickedActionName));
-  NewWindowDelegate::GetPrimary()->OpenUrl(
+  NewWindowDelegate::GetInstance()->OpenUrl(
       url, NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       NewWindowDelegate::Disposition::kNewForegroundTab);
 }
diff --git a/chrome/browser/ash/crosapi/files_app_launcher.cc b/chrome/browser/ash/crosapi/files_app_launcher.cc
index 53bce78..b3f244840 100644
--- a/chrome/browser/ash/crosapi/files_app_launcher.cc
+++ b/chrome/browser/ash/crosapi/files_app_launcher.cc
@@ -54,7 +54,7 @@
   // Launching traditional files.app and launching SWA files.app need quite
   // different procedure.
   // Use ash::NewWindowDelegate::OpenFileManager that handles the diff nicely.
-  ash::NewWindowDelegate::GetPrimary()->OpenFileManager();
+  ash::NewWindowDelegate::GetInstance()->OpenFileManager();
 }
 
 void FilesAppLauncher::OnAppUpdate(const apps::AppUpdate& update) {
diff --git a/chrome/browser/ash/eol/eol_notification.cc b/chrome/browser/ash/eol/eol_notification.cc
index 0b61261..38336c80 100644
--- a/chrome/browser/ash/eol/eol_notification.cc
+++ b/chrome/browser/ash/eol/eol_notification.cc
@@ -192,7 +192,7 @@
                            ? chrome::kEolNotificationURL
                            : chrome::kAutoUpdatePolicyURL);
         // Show eol link.
-        NewWindowDelegate::GetPrimary()->OpenUrl(
+        NewWindowDelegate::GetInstance()->OpenUrl(
             url, NewWindowDelegate::OpenUrlFrom::kUserInteraction,
             NewWindowDelegate::Disposition::kNewForegroundTab);
         break;
diff --git a/chrome/browser/ash/extended_updates/extended_updates_notification.cc b/chrome/browser/ash/extended_updates/extended_updates_notification.cc
index 760d538..af9b404 100644
--- a/chrome/browser/ash/extended_updates/extended_updates_notification.cc
+++ b/chrome/browser/ash/extended_updates/extended_updates_notification.cc
@@ -124,7 +124,7 @@
 }
 
 void ExtendedUpdatesNotification::OpenLearnMoreUrl() {
-  NewWindowDelegate::GetPrimary()->OpenUrl(
+  NewWindowDelegate::GetInstance()->OpenUrl(
       GURL(chrome::kDeviceExtendedUpdatesLearnMoreURL),
       NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       NewWindowDelegate::Disposition::kNewForegroundTab);
diff --git a/chrome/browser/ash/file_manager/open_with_browser.cc b/chrome/browser/ash/file_manager/open_with_browser.cc
index 17ba2a85..4c94b58 100644
--- a/chrome/browser/ash/file_manager/open_with_browser.cc
+++ b/chrome/browser/ash/file_manager/open_with_browser.cc
@@ -81,10 +81,10 @@
 bool OpenNewTab(const GURL& url) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
-  if (!ash::NewWindowDelegate::GetPrimary()) {
+  if (!ash::NewWindowDelegate::GetInstance()) {
     return false;
   }
-  ash::NewWindowDelegate::GetPrimary()->OpenUrl(
+  ash::NewWindowDelegate::GetInstance()->OpenUrl(
       url, ash::NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       ash::NewWindowDelegate::Disposition::kNewForegroundTab);
   return true;
diff --git a/chrome/browser/ash/file_suggest/file_suggest_keyed_service.cc b/chrome/browser/ash/file_suggest/file_suggest_keyed_service.cc
index ec99246..9ba0181 100644
--- a/chrome/browser/ash/file_suggest/file_suggest_keyed_service.cc
+++ b/chrome/browser/ash/file_suggest/file_suggest_keyed_service.cc
@@ -36,21 +36,11 @@
 
   proto_.Init();
 
-  if (features::IsLauncherContinueSectionWithRecentsEnabled() ||
-      features::IsForestFeatureEnabled()) {
-    drive_file_suggestion_provider_ =
-        std::make_unique<DriveRecentFileSuggestionProvider>(
-            profile, base::BindRepeating(
-                         &FileSuggestKeyedService::OnSuggestionProviderUpdated,
-                         weak_factory_.GetWeakPtr()));
-  } else {
-    drive_file_suggestion_provider_ =
-        std::make_unique<DriveFileSuggestionProvider>(
-            application_locale_storage, profile,
-            base::BindRepeating(
-                &FileSuggestKeyedService::OnSuggestionProviderUpdated,
-                weak_factory_.GetWeakPtr()));
-  }
+  drive_file_suggestion_provider_ =
+      std::make_unique<DriveRecentFileSuggestionProvider>(
+          profile, base::BindRepeating(
+                       &FileSuggestKeyedService::OnSuggestionProviderUpdated,
+                       weak_factory_.GetWeakPtr()));
 
   local_file_suggestion_provider_ =
       std::make_unique<LocalFileSuggestionProvider>(
diff --git a/chrome/browser/ash/file_suggest/file_suggest_keyed_service_browsertest.cc b/chrome/browser/ash/file_suggest/file_suggest_keyed_service_browsertest.cc
index f82a72f1..9034016 100644
--- a/chrome/browser/ash/file_suggest/file_suggest_keyed_service_browsertest.cc
+++ b/chrome/browser/ash/file_suggest/file_suggest_keyed_service_browsertest.cc
@@ -255,7 +255,7 @@
 IN_PROC_BROWSER_TEST_P(FileSuggestKeyedServiceBrowserTest,
                        QueryWithEmptyCache) {
   // TODO(http://b/349164737): Re-enable this test with forest feature enabled.
-  if (ash::features::IsForestFeatureEnabled() && !UseDriveRecents()) {
+  if (!UseDriveRecents()) {
     GTEST_SKIP() << "Skipping test body for Forest Feature enabled and Drive "
                     "Recents disabled.";
   }
@@ -313,7 +313,7 @@
 IN_PROC_BROWSER_TEST_P(FileSuggestKeyedServiceBrowserTest,
                        RespondToItemSuggestCacheUpdate) {
   // TODO(http://b/349164737): Re-enable this test with forest feature enabled.
-  if (ash::features::IsForestFeatureEnabled() && !UseDriveRecents()) {
+  if (!UseDriveRecents()) {
     GTEST_SKIP() << "Skipping test body for Forest Feature enabled and Drive "
                     "Recents disabled.";
   }
@@ -443,7 +443,7 @@
 IN_PROC_BROWSER_TEST_P(FileSuggestKeyedServiceBrowserTest,
                        RespondToItemSuggestCacheInvalidUpdate) {
   // TODO(http://b/349164737): Re-enable this test with forest feature enabled.
-  if (ash::features::IsForestFeatureEnabled() && !UseDriveRecents()) {
+  if (!UseDriveRecents()) {
     GTEST_SKIP() << "Skipping test body for Forest Feature enabled and Drive "
                     "Recents disabled.";
   }
@@ -524,7 +524,7 @@
 IN_PROC_BROWSER_TEST_P(FileSuggestKeyedServiceBrowserTest,
                        RespondToItemSuggestCachePartiallyInvalidUpdate) {
   // TODO(http://b/349164737): Re-enable this test with forest feature enabled.
-  if (ash::features::IsForestFeatureEnabled() && !UseDriveRecents()) {
+  if (!UseDriveRecents()) {
     GTEST_SKIP() << "Skipping test body for Forest Feature enabled and Drive "
                     "Recents disabled.";
   }
diff --git a/chrome/browser/ash/file_suggest/file_suggest_keyed_service_unittest.cc b/chrome/browser/ash/file_suggest/file_suggest_keyed_service_unittest.cc
index d977c7fe..f1a8d65 100644
--- a/chrome/browser/ash/file_suggest/file_suggest_keyed_service_unittest.cc
+++ b/chrome/browser/ash/file_suggest/file_suggest_keyed_service_unittest.cc
@@ -57,11 +57,9 @@
 
 TEST_F(FileSuggestKeyedServiceTest, GetSuggestData) {
   base::HistogramTester tester;
-  if (features::IsForestFeatureEnabled()) {
-    drive::DriveIntegrationServiceFactory::GetInstance()
-        ->GetForProfile(profile_)
-        ->SetEnabled(true);
-  }
+  drive::DriveIntegrationServiceFactory::GetInstance()
+      ->GetForProfile(profile_)
+      ->SetEnabled(true);
   FileSuggestKeyedServiceFactory::GetInstance()
       ->GetService(profile_)
       ->GetSuggestFileData(
@@ -73,20 +71,14 @@
   tester.ExpectBucketCount(
       "Ash.Search.DriveFileSuggestDataValidation.Status",
       /*sample=*/DriveSuggestValidationStatus::kDriveFSNotMounted,
-      /*expected_count=*/
-      (features::IsLauncherContinueSectionWithRecentsEnabled() ||
-       features::IsForestFeatureEnabled())
-          ? 0
-          : 1);
+      /*expected_count=*/0);
 }
 
 TEST_F(FileSuggestKeyedServiceTest, DisabledByPolicy) {
   base::HistogramTester tester;
-  if (features::IsForestFeatureEnabled()) {
-    drive::DriveIntegrationServiceFactory::GetInstance()
-        ->GetForProfile(profile_)
-        ->SetEnabled(true);
-  }
+  drive::DriveIntegrationServiceFactory::GetInstance()
+      ->GetForProfile(profile_)
+      ->SetEnabled(true);
   FileSuggestKeyedServiceFactory::GetInstance()
       ->GetService(profile_)
       ->GetSuggestFileData(
diff --git a/chrome/browser/ash/growth/open_url_action_performer.cc b/chrome/browser/ash/growth/open_url_action_performer.cc
index dd0f619..9c280e0 100644
--- a/chrome/browser/ash/growth/open_url_action_performer.cc
+++ b/chrome/browser/ash/growth/open_url_action_performer.cc
@@ -89,7 +89,7 @@
     return;
   }
 
-  ash::NewWindowDelegate::GetPrimary()->OpenUrl(
+  ash::NewWindowDelegate::GetInstance()->OpenUrl(
       open_url_param->url,
       ash::NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       open_url_param->disposition);
diff --git a/chrome/browser/ash/input_method/editor_system_actuator.cc b/chrome/browser/ash/input_method/editor_system_actuator.cc
index 808a538..a788704c 100644
--- a/chrome/browser/ash/input_method/editor_system_actuator.cc
+++ b/chrome/browser/ash/input_method/editor_system_actuator.cc
@@ -97,7 +97,7 @@
     mojo::ReportBadMessage("Invalid URL scheme. Only HTTPS is allowed.");
     return;
   }
-  ash::NewWindowDelegate::GetPrimary()->OpenUrl(
+  ash::NewWindowDelegate::GetInstance()->OpenUrl(
       url, ash::NewWindowDelegate::OpenUrlFrom::kUnspecified,
       ash::NewWindowDelegate::Disposition::kNewForegroundTab);
 }
diff --git a/chrome/browser/ash/integration_tests/web_handwriting_integration_test.cc b/chrome/browser/ash/integration_tests/web_handwriting_integration_test.cc
index a753cfe..2010dccf 100644
--- a/chrome/browser/ash/integration_tests/web_handwriting_integration_test.cc
+++ b/chrome/browser/ash/integration_tests/web_handwriting_integration_test.cc
@@ -95,9 +95,9 @@
 
   // The promise should have evaluated without errors. See the HTML files for
   // details.
-  std::string result_error =
-      content::EvalJs(web_contents, "window.resultPromise").error;
-  EXPECT_TRUE(result_error.empty()) << result_error;
+  content::EvalJsResult result =
+      content::EvalJs(web_contents, "window.resultPromise");
+  EXPECT_TRUE(result.is_ok()) << result;
 }
 
 }  // namespace
diff --git a/chrome/browser/ash/login/app_mode/test/web_kiosk_device_attributes_browsertest.cc b/chrome/browser/ash/login/app_mode/test/web_kiosk_device_attributes_browsertest.cc
index 983a746..50f86de 100644
--- a/chrome/browser/ash/login/app_mode/test/web_kiosk_device_attributes_browsertest.cc
+++ b/chrome/browser/ash/login/app_mode/test/web_kiosk_device_attributes_browsertest.cc
@@ -162,7 +162,7 @@
 
   // All methods should return the same error.
   for (const std::string& attribute : kAttributeNames) {
-    EXPECT_EQ(CallDeviceAttributesApi(web_contents, attribute).error,
+    EXPECT_EQ(CallDeviceAttributesApi(web_contents, attribute).ExtractError(),
               kNotAllowedOriginExpectedError);
   }
 }
@@ -236,7 +236,7 @@
   for (const std::string& attribute : kAttributeNames) {
     content::EvalJsResult result =
         CallDeviceAttributesApi(web_contents, attribute);
-    EXPECT_EQ(result.error, kNotTrustedOriginExpectedError);
+    EXPECT_EQ(result.ExtractError(), kNotTrustedOriginExpectedError);
   }
 }
 
diff --git a/chrome/browser/ash/login/demo_mode/demo_mode_idle_handler.cc b/chrome/browser/ash/login/demo_mode/demo_mode_idle_handler.cc
index 8a81947..9c8f437 100644
--- a/chrome/browser/ash/login/demo_mode/demo_mode_idle_handler.cc
+++ b/chrome/browser/ash/login/demo_mode/demo_mode_idle_handler.cc
@@ -177,7 +177,7 @@
           base::MakeRefCounted<message_center::HandleNotificationClickDelegate>(
               base::BindRepeating([](std::optional<int> button_index) {
                 if (button_index.has_value() && button_index.value() == 0) {
-                  ash::NewWindowDelegate::GetPrimary()->OpenUrl(
+                  ash::NewWindowDelegate::GetInstance()->OpenUrl(
                       GURL(kGooglePoliciesURL),
                       ash::NewWindowDelegate::OpenUrlFrom::kUserInteraction,
                       ash::NewWindowDelegate::Disposition::kNewForegroundTab);
diff --git a/chrome/browser/ash/magic_boost/magic_boost_controller_ash.cc b/chrome/browser/ash/magic_boost/magic_boost_controller_ash.cc
index 65794fd..c31e759 100644
--- a/chrome/browser/ash/magic_boost/magic_boost_controller_ash.cc
+++ b/chrome/browser/ash/magic_boost/magic_boost_controller_ash.cc
@@ -134,7 +134,7 @@
 }
 
 void MagicBoostControllerAsh::OnLinkPressed(const std::string& url) {
-  NewWindowDelegate::GetPrimary()->OpenUrl(
+  NewWindowDelegate::GetInstance()->OpenUrl(
       GURL(url), NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       NewWindowDelegate::Disposition::kNewForegroundTab);
 
diff --git a/chrome/browser/ash/policy/skyvault/migration_notification_manager.cc b/chrome/browser/ash/policy/skyvault/migration_notification_manager.cc
index 7f77a17..43ff640 100644
--- a/chrome/browser/ash/policy/skyvault/migration_notification_manager.cc
+++ b/chrome/browser/ash/policy/skyvault/migration_notification_manager.cc
@@ -76,7 +76,7 @@
                                       std::optional<int> button) {
   if (button.has_value() && button == 0) {
     file_manager::util::ShowItemInFolder(profile, path, base::DoNothing());
-    ash::NewWindowDelegate::GetPrimary()->OpenUrl(
+    ash::NewWindowDelegate::GetInstance()->OpenUrl(
         net::FilePathToFileURL(path),
         ash::NewWindowDelegate::OpenUrlFrom::kUserInteraction,
         ash::NewWindowDelegate::Disposition::kNewForegroundTab);
@@ -90,7 +90,7 @@
                                   const base::FilePath& path,
                                   std::optional<int> button) {
   if (button.has_value() && button == 0) {
-    ash::NewWindowDelegate::GetPrimary()->OpenUrl(
+    ash::NewWindowDelegate::GetInstance()->OpenUrl(
         net::FilePathToFileURL(path),
         ash::NewWindowDelegate::OpenUrlFrom::kUserInteraction,
         ash::NewWindowDelegate::Disposition::kNewForegroundTab);
diff --git a/chrome/browser/ash/scalable_iph/scalable_iph_delegate_impl.cc b/chrome/browser/ash/scalable_iph/scalable_iph_delegate_impl.cc
index 26377da..8dd0a439 100644
--- a/chrome/browser/ash/scalable_iph/scalable_iph_delegate_impl.cc
+++ b/chrome/browser/ash/scalable_iph/scalable_iph_delegate_impl.cc
@@ -207,7 +207,7 @@
                        scalable_iph::Logger* logger) {
   SCALABLE_IPH_LOG(logger) << "Opening a url with ash::NewWindowDelegate. Url: "
                            << url;
-  ash::NewWindowDelegate::GetPrimary()->OpenUrl(
+  ash::NewWindowDelegate::GetInstance()->OpenUrl(
       url, ash::NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       ash::NewWindowDelegate::Disposition::kNewWindow);
 }
@@ -644,7 +644,7 @@
       break;
     }
     case ActionType::kOpenFileManager: {
-      ash::NewWindowDelegate::GetPrimary()->OpenFileManager();
+      ash::NewWindowDelegate::GetInstance()->OpenFileManager();
       SCALABLE_IPH_LOG(GetLogger()) << "Opening file manager.";
       break;
     }
diff --git a/chrome/browser/ash/sharesheet/drive_share_action.cc b/chrome/browser/ash/sharesheet/drive_share_action.cc
index e2c5a47..9dab44cd 100644
--- a/chrome/browser/ash/sharesheet/drive_share_action.cc
+++ b/chrome/browser/ash/sharesheet/drive_share_action.cc
@@ -42,10 +42,10 @@
     apps::IntentPtr intent) {
   controller_ = controller;
   DCHECK(intent->drive_share_url.has_value());
-  if (!ash::NewWindowDelegate::GetPrimary()) {
+  if (!ash::NewWindowDelegate::GetInstance()) {
     return;
   }
-  ash::NewWindowDelegate::GetPrimary()->OpenUrl(
+  ash::NewWindowDelegate::GetInstance()->OpenUrl(
       intent->drive_share_url.value(),
       ash::NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       NewWindowDelegate::Disposition::kNewForegroundTab);
diff --git a/chrome/browser/ash/system/tray_accessibility_browsertest.cc b/chrome/browser/ash/system/tray_accessibility_browsertest.cc
index fd05faa..17795fb 100644
--- a/chrome/browser/ash/system/tray_accessibility_browsertest.cc
+++ b/chrome/browser/ash/system/tray_accessibility_browsertest.cc
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "ash/accessibility/accessibility_controller.h"
 #include "ash/constants/ash_pref_names.h"
 #include "ash/constants/ash_switches.h"
 #include "ash/public/cpp/ash_view_ids.h"
@@ -77,11 +78,7 @@
 }
 
 void EnableDictation(bool enabled) {
-  bool already_enabled = AccessibilityManager::Get()->IsDictationEnabled();
-  if (enabled == already_enabled) {
-    return;
-  }
-  AccessibilityManager::Get()->ToggleDictation();
+  AccessibilityManager::Get()->SetDictationEnabled(enabled);
   base::RunLoop().RunUntilIdle();
 }
 
@@ -159,6 +156,8 @@
   void SetUpOnMainThread() override {
     InProcessBrowserTest::SetUpOnMainThread();
     tray_test_api_ = ash::SystemTrayTestApi::Create();
+    ash::AccessibilityController::Get()
+        ->DisableSwitchAccessDisableConfirmationDialogTesting();
   }
 
   void SetUpInProcessBrowserTestFixture() override {
@@ -220,7 +219,7 @@
   std::unique_ptr<ash::SystemTrayTestApi> tray_test_api_;
 };
 
-IN_PROC_BROWSER_TEST_P(TrayAccessibilityTest, DISABLED_ShowMenu) {
+IN_PROC_BROWSER_TEST_P(TrayAccessibilityTest, ShowMenu) {
   SetShowAccessibilityOptionsInSystemTrayMenu(false);
 
   // Confirms that the menu is hidden.
@@ -389,9 +388,7 @@
   EXPECT_FALSE(IsMenuButtonVisible());
 }
 
-// Fails on linux-chromeos-dbg see crbug/1027919.
-IN_PROC_BROWSER_TEST_P(TrayAccessibilityTest,
-                       DISABLED_ShowMenuWithShowMenuOption) {
+IN_PROC_BROWSER_TEST_P(TrayAccessibilityTest, ShowMenuWithShowMenuOption) {
   SetShowAccessibilityOptionsInSystemTrayMenu(true);
 
   // Confirms that the menu is visible.
diff --git a/chrome/browser/ash/system_web_apps/apps/help_app/help_app_integration_browsertest.cc b/chrome/browser/ash/system_web_apps/apps/help_app/help_app_integration_browsertest.cc
index 5ee1cb9..9e7b412 100644
--- a/chrome/browser/ash/system_web_apps/apps/help_app/help_app_integration_browsertest.cc
+++ b/chrome/browser/ash/system_web_apps/apps/help_app/help_app_integration_browsertest.cc
@@ -380,58 +380,6 @@
 #endif
 }
 
-// Test that clicking the release notes notification opens Help App.
-IN_PROC_BROWSER_TEST_P(HelpAppIntegrationTest,
-                       HelpAppV2LaunchReleaseNotesFromNotification) {
-  // TODO(http://b/349164737): Re-enable this test with forest feature enabled.
-  if (ash::features::IsForestFeatureEnabled()) {
-    GTEST_SKIP() << "Skipping test body for Forest Feature.";
-  }
-
-  WaitForTestSystemAppInstall();
-  base::UserActionTester user_action_tester;
-  auto display_service =
-      std::make_unique<NotificationDisplayServiceTester>(/*profile=*/nullptr);
-  auto release_notes_notification =
-      std::make_unique<ReleaseNotesNotification>(profile());
-  auto release_notes_storage = std::make_unique<ReleaseNotesStorage>(profile());
-
-  // Force the release notes notification to show up.
-  profile()->GetPrefs()->SetInteger(
-      prefs::kHelpAppNotificationLastShownMilestone, 20);
-  release_notes_notification->MaybeShowReleaseNotes();
-  // Assert that the notification really is there.
-  auto notifications = display_service->GetDisplayedNotificationsForType(
-      NotificationHandler::Type::TRANSIENT);
-  ASSERT_EQ(1u, notifications.size());
-  ASSERT_EQ("show_release_notes_notification", notifications[0].id());
-
-  GURL expected_url = GURL("chrome://help-app/updates");
-  content::TestNavigationObserver navigation_observer(expected_url);
-  navigation_observer.StartWatchingNewWebContents();
-  // Then click.
-  display_service->SimulateClick(NotificationHandler::Type::TRANSIENT,
-                                 "show_release_notes_notification",
-                                 std::nullopt, std::nullopt);
-
-  EXPECT_EQ(
-      1, user_action_tester.GetActionCount("ReleaseNotes.NotificationShown"));
-  EXPECT_EQ(1, user_action_tester.GetActionCount(
-                   "ReleaseNotes.LaunchedNotification"));
-#if BUILDFLAG(ENABLE_CROS_HELP_APP)
-  EXPECT_NO_FATAL_FAILURE(navigation_observer.Wait());
-  // Help app should have opened at the expected page.
-  EXPECT_EQ(expected_url, GetActiveWebContents()->GetVisibleURL());
-  EXPECT_EQ(1,
-            user_action_tester.GetActionCount("ReleaseNotes.ShowReleaseNotes"));
-#else
-  // We just have the original browser. No new app opens.
-  EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
-  EXPECT_EQ(0,
-            user_action_tester.GetActionCount("ReleaseNotes.ShowReleaseNotes"));
-#endif
-}
-
 // Test that the background page can trigger the release notes notification.
 IN_PROC_BROWSER_TEST_P(HelpAppIntegrationTest,
                        HelpAppV2ReleaseNotesNotificationFromBackground) {
diff --git a/chrome/browser/autofill/BUILD.gn b/chrome/browser/autofill/BUILD.gn
index 5534118..763fb5b 100644
--- a/chrome/browser/autofill/BUILD.gn
+++ b/chrome/browser/autofill/BUILD.gn
@@ -53,7 +53,7 @@
     "//components/autofill/core/common",
     "//components/keyed_service/content",
     "//components/keyed_service/core",
-    "//components/signin/public/identity_manager:identity_manager",
+    "//components/signin/public/identity_manager",
     "//content/public/browser",
     "//services/network/public/cpp",
     "//ui/gfx",
@@ -144,10 +144,10 @@
   ]
 
   deps = [
-    "//chrome/browser/autofill:autofill",
+    "//chrome/browser/autofill",
     "//chrome/browser/profiles:profile",
     "//chrome/browser/ui/autofill",
-    "//components/autofill/content/browser:browser",
+    "//components/autofill/content/browser",
     "//components/autofill/content/common/mojom",
     "//components/autofill/core/browser:test_support",
     "//content/test:test_support",
diff --git a/chrome/browser/autofill/autofill_flow_test_util.cc b/chrome/browser/autofill/autofill_flow_test_util.cc
index 1b72f4b..515b356e 100644
--- a/chrome/browser/autofill/autofill_flow_test_util.cc
+++ b/chrome/browser/autofill/autofill_flow_test_util.cc
@@ -88,7 +88,7 @@
       e->c_str(), event_name.c_str(), event_name.c_str());
   content::EvalJsResult result = content::EvalJs(execution_target, script);
   if (!result.is_ok()) {
-    return AssertionFailure() << __func__ << "(): " << result.error;
+    return AssertionFailure() << __func__ << "(): " << result;
   } else if (false == result) {
     return AssertionFailure()
            << __func__ << "(): couldn't trigger " << event_name << " on " << *e;
diff --git a/chrome/browser/autofill/captured_sites_test_utils.cc b/chrome/browser/autofill/captured_sites_test_utils.cc
index 2f46221..d6d0cae 100644
--- a/chrome/browser/autofill/captured_sites_test_utils.cc
+++ b/chrome/browser/autofill/captured_sites_test_utils.cc
@@ -2208,7 +2208,7 @@
     *property = result.ExtractString();
     return true;
   }
-  *property = result.error;
+  *property = result.is_ok() ? "" : result.ExtractError();
   return false;
 }
 
@@ -2287,7 +2287,7 @@
     VLOG(1) << "Failed to focus element through script:"
             << (result.is_ok()
                     ? (result.is_bool() ? "Returned false" : "Not a valid bool")
-                    : result.error);
+                    : result.ExtractError());
 
     // Failing focusing on an element through script, use the less preferred
     // method of left mouse clicking the element.
diff --git a/chrome/browser/autofill/test/BUILD.gn b/chrome/browser/autofill/test/BUILD.gn
index b3f7b40..73bab36 100644
--- a/chrome/browser/autofill/test/BUILD.gn
+++ b/chrome/browser/autofill/test/BUILD.gn
@@ -28,7 +28,7 @@
     "//third_party/androidx:androidx_test_runner_java",
     "//third_party/google-truth:google_truth_java",
     "//third_party/hamcrest:hamcrest_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//url:gurl_java",
   ]
 }
diff --git a/chrome/browser/auxiliary_search/BUILD.gn b/chrome/browser/auxiliary_search/BUILD.gn
index 632ecbe..02ec6d57 100644
--- a/chrome/browser/auxiliary_search/BUILD.gn
+++ b/chrome/browser/auxiliary_search/BUILD.gn
@@ -152,7 +152,7 @@
     "//third_party/androidx:androidx_test_core_java",
     "//third_party/androidx:androidx_test_runner_java",
     "//third_party/jni_zero:gendeps_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_java",
     "//url:gurl_junit_test_support",
@@ -178,7 +178,7 @@
     "//third_party/androidx:androidx_appsearch_appsearch_java",
     "//third_party/androidx:androidx_appsearch_appsearch_platform_storage_java",
     "//third_party/androidx:androidx_test_runner_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_java_test_support",
   ]
diff --git a/chrome/browser/back_press/android/BUILD.gn b/chrome/browser/back_press/android/BUILD.gn
index 95e1c625..8b25fab 100644
--- a/chrome/browser/back_press/android/BUILD.gn
+++ b/chrome/browser/back_press/android/BUILD.gn
@@ -43,7 +43,7 @@
     "//components/browser_ui/widget/android:java",
     "//third_party/androidx:androidx_activity_activity_java",
     "//third_party/androidx:androidx_annotation_annotation_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
   ]
 }
diff --git a/chrome/browser/background/extensions/BUILD.gn b/chrome/browser/background/extensions/BUILD.gn
index 91581721..a4d397f 100644
--- a/chrome/browser/background/extensions/BUILD.gn
+++ b/chrome/browser/background/extensions/BUILD.gn
@@ -17,16 +17,16 @@
   deps = [
     "//base",
     "//chrome/browser/background",
-    "//chrome/browser/extensions:extensions",
+    "//chrome/browser/extensions",
     "//chrome/browser/profiles:profile_util",
-    "//chrome/browser/status_icons:status_icons",
+    "//chrome/browser/status_icons",
     "//chrome/browser/ui:browser_list",
-    "//components/prefs:prefs",
+    "//components/prefs",
     "//extensions/browser",
   ]
 
   if (!is_android) {
-    deps += [ "//components/keep_alive_registry:keep_alive_registry" ]
+    deps += [ "//components/keep_alive_registry" ]
   }
 }
 
@@ -55,17 +55,17 @@
     "//chrome/app/theme:chrome_unscaled_resources_grit",
     "//chrome/browser:browser_process",
     "//chrome/browser:browser_public_dependencies",
-    "//chrome/browser/apps/app_service:app_service",
+    "//chrome/browser/apps/app_service",
     "//chrome/browser/background",
-    "//chrome/browser/extensions:extensions",
+    "//chrome/browser/extensions",
     "//chrome/browser/lifetime:termination_notification",
     "//chrome/browser/profiles/keep_alive",
-    "//chrome/browser/status_icons:status_icons",
-    "//chrome/browser/ui:ui",
+    "//chrome/browser/status_icons",
+    "//chrome/browser/ui",
     "//chrome/browser/ui/extensions",
     "//chrome/browser/ui/profiles",
-    "//components/crx_file:crx_file",
-    "//components/prefs:prefs",
+    "//components/crx_file",
+    "//components/prefs",
     "//components/startup_metric_utils",
     "//content/public/browser",
     "//extensions/browser",
@@ -73,11 +73,11 @@
   ]
 
   if (!is_android) {
-    deps += [ "//components/keep_alive_registry:keep_alive_registry" ]
+    deps += [ "//components/keep_alive_registry" ]
   }
 
   if (enable_glic) {
-    deps += [ "//chrome/browser/glic:glic" ]
+    deps += [ "//chrome/browser/glic" ]
   }
 }
 
@@ -94,15 +94,15 @@
     "//base",
     "//chrome/browser:browser_process",
     "//chrome/browser/background",
-    "//chrome/browser/status_icons:status_icons",
+    "//chrome/browser/status_icons",
     "//chrome/test:test_support",
     "//components/policy/core/common:test_support",
-    "//components/sync_preferences:sync_preferences",
+    "//components/sync_preferences",
     "//content/public/browser",
     "//content/test:test_support",
     "//extensions:test_support",
     "//testing/gmock",
-    "//testing/gtest:gtest",
-    "//ui/message_center/public/cpp:cpp",
+    "//testing/gtest",
+    "//ui/message_center/public/cpp",
   ]
 }
diff --git a/chrome/browser/background/glic/BUILD.gn b/chrome/browser/background/glic/BUILD.gn
index 4ccfead..7b8543f 100644
--- a/chrome/browser/background/glic/BUILD.gn
+++ b/chrome/browser/background/glic/BUILD.gn
@@ -36,12 +36,12 @@
     "//chrome/app:generated_resources",
     "//chrome/browser:browser_process",
     "//chrome/browser:global_features",
-    "//chrome/browser/background:background",
+    "//chrome/browser/background",
     "//chrome/browser/glic",
     "//chrome/browser/glic/resources:browser_resources",
     "//chrome/browser/profiles:profile",
     "//chrome/browser/resources/glic:resources_grit",
-    "//chrome/browser/status_icons:status_icons",
+    "//chrome/browser/status_icons",
     "//chrome/browser/ui",
     "//chrome/browser/ui:browser_element_identifiers",
     "//chrome/browser/ui:browser_list",
@@ -63,12 +63,12 @@
     ":impl",
     "//base/test:test_support",
     "//chrome/browser:global_features",
-    "//chrome/browser/glic:glic",
+    "//chrome/browser/glic",
     "//chrome/browser/profiles",
-    "//chrome/browser/status_icons:status_icons",
+    "//chrome/browser/status_icons",
     "//chrome/browser/ui",
     "//chrome/browser/ui:ui_features",
-    "//chrome/browser/ui/webui/whats_new:whats_new",
+    "//chrome/browser/ui/webui/whats_new",
     "//chrome/common:chrome_features",
     "//chrome/test:test_support",
     "//testing/gtest",
@@ -90,12 +90,12 @@
     "//chrome/browser",
     "//chrome/browser:browser_process",
     "//chrome/browser:global_features",
-    "//chrome/browser/background:background",
+    "//chrome/browser/background",
     "//chrome/browser/glic",
     "//chrome/browser/glic:impl",
     "//chrome/browser/glic/fre",
     "//chrome/browser/glic/test_support",
-    "//chrome/browser/status_icons:status_icons",
+    "//chrome/browser/status_icons",
     "//chrome/common:chrome_features",
     "//chrome/test:test_support_ui",
     "//components/keep_alive_registry",
diff --git a/chrome/browser/banners/android/BUILD.gn b/chrome/browser/banners/android/BUILD.gn
index 497ed6b..df844f3 100644
--- a/chrome/browser/banners/android/BUILD.gn
+++ b/chrome/browser/banners/android/BUILD.gn
@@ -45,7 +45,7 @@
     "//third_party/androidx:androidx_test_runner_java",
     "//third_party/androidx:androidx_test_uiautomator_uiautomator_java",
     "//third_party/hamcrest:hamcrest_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_full_java",
     "//ui/android:ui_java_test_support",
diff --git a/chrome/browser/banners/app_banner_manager_desktop_browsertest.cc b/chrome/browser/banners/app_banner_manager_desktop_browsertest.cc
index 7b710a4b..3a03b68 100644
--- a/chrome/browser/banners/app_banner_manager_desktop_browsertest.cc
+++ b/chrome/browser/banners/app_banner_manager_desktop_browsertest.cc
@@ -21,7 +21,6 @@
 #include "chrome/browser/banners/app_banner_manager_browsertest_base.h"
 #include "chrome/browser/banners/test_app_banner_manager_desktop.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/ui/actions/chrome_action_id.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_command_controller.h"
 #include "chrome/browser/ui/browser_window.h"
@@ -259,13 +258,8 @@
   }
 
   // Install the app via the menu instead of the banner.
-  if (IsPageActionMigrated(PageActionIconType::kPwaInstall)) {
-    actions::ActionManager::Get().FindAction(kActionInstallPwa)->InvokeAction();
-  } else {
-    browser()->window()->ExecutePageActionIconForTesting(
-        PageActionIconType::kPwaInstall);
-  }
-
+  browser()->window()->ExecutePageActionIconForTesting(
+      PageActionIconType::kPwaInstall);
   manager->AwaitAppInstall();
 
   EXPECT_FALSE(manager->IsPromptAvailableForTesting());
diff --git a/chrome/browser/bluetooth/android/BUILD.gn b/chrome/browser/bluetooth/android/BUILD.gn
index 8c369235..e995e9d 100644
--- a/chrome/browser/bluetooth/android/BUILD.gn
+++ b/chrome/browser/bluetooth/android/BUILD.gn
@@ -57,7 +57,7 @@
     "//components/browser_ui/notifications/android:utils_java",
     "//components/url_formatter/android:url_formatter_java",
     "//third_party/jni_zero:jni_zero_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//url:gurl_java",
     "//url:gurl_junit_test_support",
diff --git a/chrome/browser/bookmarks/android/BUILD.gn b/chrome/browser/bookmarks/android/BUILD.gn
index ec45b35..eef6a1ba 100644
--- a/chrome/browser/bookmarks/android/BUILD.gn
+++ b/chrome/browser/bookmarks/android/BUILD.gn
@@ -15,7 +15,7 @@
     "//components/bookmarks/browser",
     "//components/bookmarks/common/android",
     "//components/bookmarks/managed",
-    "//components/power_bookmarks/core:core",
+    "//components/power_bookmarks/core",
     "//components/prefs",
     "//components/reading_list/core",
     "//components/signin/public/identity_manager",
@@ -30,7 +30,7 @@
     ":android",
     "//chrome/android:chrome_jni_headers",
     "//chrome/browser/commerce",
-    "//chrome/browser/profiles:profiles",
+    "//chrome/browser/profiles",
     "//chrome/browser/reading_list",
     "//chrome/browser/signin",
     "//components/query_parser",
diff --git a/chrome/browser/chrome_shared_array_buffer_browsertest.cc b/chrome/browser/chrome_shared_array_buffer_browsertest.cc
index 5f59050..a35cceb 100644
--- a/chrome/browser/chrome_shared_array_buffer_browsertest.cc
+++ b/chrome/browser/chrome_shared_array_buffer_browsertest.cc
@@ -173,9 +173,9 @@
         new WebAssembly.Memory({ shared:true, initial:1, maximum:1 }).buffer;
     g_iframe.contentWindow.postMessage(sab,"*");
   )");
-  EXPECT_THAT(
-      postSharedArrayBuffer.error,
-      testing::HasSubstr("Failed to execute 'postMessage' on 'Window': "));
+  EXPECT_THAT(postSharedArrayBuffer,
+              content::EvalJsResult::ErrorIs(testing::HasSubstr(
+                  "Failed to execute 'postMessage' on 'Window': ")));
 }
 
 }  // namespace policy
diff --git a/chrome/browser/chromeos/policy/dlp/clipboard_bubble.cc b/chrome/browser/chromeos/policy/dlp/clipboard_bubble.cc
index c8860e95..7003cb5dc 100644
--- a/chrome/browser/chromeos/policy/dlp/clipboard_bubble.cc
+++ b/chrome/browser/chromeos/policy/dlp/clipboard_bubble.cc
@@ -103,7 +103,7 @@
 };
 
 void OnLearnMoreLinkClicked() {
-  ash::NewWindowDelegate::GetPrimary()->OpenUrl(
+  ash::NewWindowDelegate::GetInstance()->OpenUrl(
       GURL(dlp::kDlpLearnMoreUrl),
       ash::NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       ash::NewWindowDelegate::Disposition::kNewForegroundTab);
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_clipboard_notifier.cc b/chrome/browser/chromeos/policy/dlp/dlp_clipboard_notifier.cc
index 46ebfcd..c2abc3d 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_clipboard_notifier.cc
+++ b/chrome/browser/chromeos/policy/dlp/dlp_clipboard_notifier.cc
@@ -89,7 +89,7 @@
 }
 
 void OnToastClicked() {
-  ash::NewWindowDelegate::GetPrimary()->OpenUrl(
+  ash::NewWindowDelegate::GetInstance()->OpenUrl(
       GURL(dlp::kDlpLearnMoreUrl),
       ash::NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       ash::NewWindowDelegate::Disposition::kNewForegroundTab);
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_files_utils.cc b/chrome/browser/chromeos/policy/dlp/dlp_files_utils.cc
index 874ce30e..1542056 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_files_utils.cc
+++ b/chrome/browser/chromeos/policy/dlp/dlp_files_utils.cc
@@ -61,7 +61,7 @@
 }
 
 void OpenLearnMore(const GURL& url) {
-  ash::NewWindowDelegate::GetPrimary()->OpenUrl(
+  ash::NewWindowDelegate::GetInstance()->OpenUrl(
       url, ash::NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       ash::NewWindowDelegate::Disposition::kNewForegroundTab);
 }
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_notification_helper.cc b/chrome/browser/chromeos/policy/dlp/dlp_notification_helper.cc
index 7c4da905..5260887 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_notification_helper.cc
+++ b/chrome/browser/chromeos/policy/dlp/dlp_notification_helper.cc
@@ -38,7 +38,7 @@
 constexpr char kDlpPolicyNotifierId[] = "policy.dlp";
 
 void OnNotificationClicked(const std::string id) {
-  ash::NewWindowDelegate::GetPrimary()->OpenUrl(
+  ash::NewWindowDelegate::GetInstance()->OpenUrl(
       GURL(dlp::kDlpLearnMoreUrl),
       ash::NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       ash::NewWindowDelegate::Disposition::kNewForegroundTab);
diff --git a/chrome/browser/chromeos/tablet_mode/BUILD.gn b/chrome/browser/chromeos/tablet_mode/BUILD.gn
index 965c8cd..d21561f 100644
--- a/chrome/browser/chromeos/tablet_mode/BUILD.gn
+++ b/chrome/browser/chromeos/tablet_mode/BUILD.gn
@@ -29,6 +29,7 @@
     "//chrome/browser/profiles:profile",
     "//chrome/browser/search",
     "//chrome/browser/ui:browser_list",
+    "//chrome/browser/ui/browser_window",
     "//chrome/browser/ui/tabs:tab_strip",
     "//chrome/browser/ui/webui/ash/system_web_dialog",
     "//chrome/common",
diff --git a/chrome/browser/chromeos/tablet_mode/tablet_mode_page_behavior.cc b/chrome/browser/chromeos/tablet_mode/tablet_mode_page_behavior.cc
index d6ff686..65b58957 100644
--- a/chrome/browser/chromeos/tablet_mode/tablet_mode_page_behavior.cc
+++ b/chrome/browser/chromeos/tablet_mode/tablet_mode_page_behavior.cc
@@ -48,7 +48,8 @@
   }
 }
 
-bool TabletModePageBehavior::ShouldTrackBrowser(Browser* browser) {
+bool TabletModePageBehavior::ShouldTrackBrowser(
+    BrowserWindowInterface* browser) {
   return display::Screen::GetScreen()->InTabletMode();
 }
 
diff --git a/chrome/browser/chromeos/tablet_mode/tablet_mode_page_behavior.h b/chrome/browser/chromeos/tablet_mode/tablet_mode_page_behavior.h
index 9452cd9..184c95a 100644
--- a/chrome/browser/chromeos/tablet_mode/tablet_mode_page_behavior.h
+++ b/chrome/browser/chromeos/tablet_mode/tablet_mode_page_behavior.h
@@ -32,7 +32,7 @@
   void OnDisplayTabletStateChanged(display::TabletState state) override;
 
   // BrowserTabStripTrackerDelegate:
-  bool ShouldTrackBrowser(Browser* browser) override;
+  bool ShouldTrackBrowser(BrowserWindowInterface* browser) override;
 
   // TabStripModelObserver:
   void OnTabStripModelChanged(
diff --git a/chrome/browser/collaboration/BUILD.gn b/chrome/browser/collaboration/BUILD.gn
index bc74e6c..1716ebc 100644
--- a/chrome/browser/collaboration/BUILD.gn
+++ b/chrome/browser/collaboration/BUILD.gn
@@ -131,7 +131,7 @@
       "//third_party/androidx:androidx_test_runner_java",
       "//third_party/hamcrest:hamcrest_core_java",
       "//third_party/hamcrest:hamcrest_library_java",
-      "//third_party/junit:junit",
+      "//third_party/junit",
     ]
   }
 
@@ -154,7 +154,7 @@
       "//third_party/androidx:androidx_test_runner_java",
       "//third_party/hamcrest:hamcrest_core_java",
       "//third_party/hamcrest:hamcrest_library_java",
-      "//third_party/junit:junit",
+      "//third_party/junit",
       "//url:url_java",
     ]
   }
@@ -209,7 +209,7 @@
       "//third_party/androidx:androidx_test_runner_java",
       "//third_party/hamcrest:hamcrest_core_java",
       "//third_party/hamcrest:hamcrest_library_java",
-      "//third_party/junit:junit",
+      "//third_party/junit",
     ]
   }
 }
diff --git a/chrome/browser/commerce/BUILD.gn b/chrome/browser/commerce/BUILD.gn
index 58f3fba..72c00fb 100644
--- a/chrome/browser/commerce/BUILD.gn
+++ b/chrome/browser/commerce/BUILD.gn
@@ -25,27 +25,27 @@
     ":commerce",
     "//chrome/browser:browser_process",
     "//chrome/browser/optimization_guide",
-    "//chrome/browser/persisted_state_db:persisted_state_db",
+    "//chrome/browser/persisted_state_db",
     "//chrome/browser/signin",
-    "//chrome/browser/sync:sync",
-    "//components/commerce/content/browser:browser",
+    "//chrome/browser/sync",
+    "//components/commerce/content/browser",
     "//components/commerce/core:commerce_constants",
     "//components/commerce/core:commerce_subscription_db_content_proto",
     "//components/commerce/core:feature_list",
     "//components/commerce/core:parcel_tracking_db_content_proto",
     "//components/commerce/core:proto",
     "//components/commerce/core:shopping_service",
-    "//components/commerce/core/product_specifications:product_specifications",
+    "//components/commerce/core/product_specifications",
     "//components/leveldb_proto",
-    "//components/prefs:prefs",
-    "//components/variations/service:service",
+    "//components/prefs",
+    "//components/variations/service",
     "//content/public/browser",
-    "//url:url",
+    "//url",
   ]
 
   if (!is_android) {
     deps += [
-      "//chrome/browser/ui:ui",
+      "//chrome/browser/ui",
       "//components/commerce/core:discounts_db_content_proto",
     ]
   }
@@ -63,6 +63,6 @@
     "//components/commerce/core:feature_utils",
     "//components/commerce/core:shopping_service_test_support",
     "//content/test:test_support",
-    "//testing/gtest:gtest",
+    "//testing/gtest",
   ]
 }
diff --git a/chrome/browser/commerce/android/BUILD.gn b/chrome/browser/commerce/android/BUILD.gn
index ea0d4ec..b060eb6 100644
--- a/chrome/browser/commerce/android/BUILD.gn
+++ b/chrome/browser/commerce/android/BUILD.gn
@@ -126,7 +126,7 @@
     "//third_party/androidx:androidx_preference_preference_java",
     "//third_party/androidx:androidx_recyclerview_recyclerview_java",
     "//third_party/androidx:androidx_test_runner_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_java_test_support",
     "//ui/android:ui_no_recycler_view_java",
@@ -152,7 +152,7 @@
     ":java",
     "//base:base_junit_test_support",
     "//components/browser_ui/bottomsheet/android:java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_no_recycler_view_java",
   ]
diff --git a/chrome/browser/commerce/coupons/android/BUILD.gn b/chrome/browser/commerce/coupons/android/BUILD.gn
index da27b2bf..02135c4 100644
--- a/chrome/browser/commerce/coupons/android/BUILD.gn
+++ b/chrome/browser/commerce/coupons/android/BUILD.gn
@@ -84,7 +84,7 @@
     "//third_party/androidx:androidx_preference_preference_java",
     "//third_party/androidx:androidx_recyclerview_recyclerview_java",
     "//third_party/androidx:androidx_test_runner_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_java_test_support",
     "//ui/android:ui_no_recycler_view_java",
@@ -120,7 +120,7 @@
     "//content/public/android:content_full_java",
     "//content/public/test/android:content_java_test_support",
     "//third_party/jni_zero:gendeps_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_java",
     "//ui/android:ui_no_recycler_view_java",
@@ -152,7 +152,7 @@
     "//third_party/androidx:androidx_test_runner_java",
     "//third_party/hamcrest:hamcrest_core_java",
     "//third_party/hamcrest:hamcrest_library_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_java_test_support",
     "//url:url_java",
diff --git a/chrome/browser/commerce/merchant_viewer/BUILD.gn b/chrome/browser/commerce/merchant_viewer/BUILD.gn
index 31f68f44..1ea5de7 100644
--- a/chrome/browser/commerce/merchant_viewer/BUILD.gn
+++ b/chrome/browser/commerce/merchant_viewer/BUILD.gn
@@ -13,15 +13,15 @@
   ]
 
   deps = [
-    "//base:base",
+    "//base",
     "//chrome/browser/commerce/merchant_viewer/android:jni_headers",
-    "//chrome/browser/persisted_state_db:persisted_state_db",
+    "//chrome/browser/persisted_state_db",
     "//components/commerce/core:merchant_signal_db_proto",
     "//components/commerce/core:persisted_state_db_content_proto",
     "//components/keyed_service/content",
     "//components/leveldb_proto",
-    "//components/session_proto_db:session_proto_db",
-    "//content/public/browser:browser",
+    "//components/session_proto_db",
+    "//content/public/browser",
     "//third_party/leveldatabase",
   ]
 }
@@ -36,8 +36,8 @@
 
   deps = [
     ":merchant_signal_db",
-    "//base:base",
-    "//chrome/browser/persisted_state_db:persisted_state_db",
+    "//base",
+    "//chrome/browser/persisted_state_db",
     "//chrome/browser/profiles",
     "//chrome/browser/profiles:profile",
     "//components/commerce/core:feature_list",
@@ -45,8 +45,8 @@
     "//components/commerce/core:persisted_state_db_content_proto",
     "//components/keyed_service/content",
     "//components/leveldb_proto",
-    "//components/session_proto_db:session_proto_db",
-    "//content/public/browser:browser",
+    "//components/session_proto_db",
+    "//content/public/browser",
     "//third_party/leveldatabase",
   ]
 }
diff --git a/chrome/browser/commerce/price_change/android/BUILD.gn b/chrome/browser/commerce/price_change/android/BUILD.gn
index c5c6a13..d48953c 100644
--- a/chrome/browser/commerce/price_change/android/BUILD.gn
+++ b/chrome/browser/commerce/price_change/android/BUILD.gn
@@ -94,7 +94,7 @@
     "//third_party/androidx:androidx_core_core_java",
     "//third_party/androidx:androidx_test_runner_java",
     "//third_party/jni_zero:jni_zero_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_junit_test_support",
     "//ui/android:ui_no_recycler_view_java",
diff --git a/chrome/browser/commerce/price_history/android/BUILD.gn b/chrome/browser/commerce/price_history/android/BUILD.gn
index 8bfd230..f92b80f 100644
--- a/chrome/browser/commerce/price_history/android/BUILD.gn
+++ b/chrome/browser/commerce/price_history/android/BUILD.gn
@@ -74,7 +74,7 @@
     "//content/public/android:content_full_java",
     "//content/public/test/android:content_java_test_support",
     "//third_party/jni_zero:gendeps_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_java",
     "//url:gurl_junit_test_support",
@@ -111,7 +111,7 @@
     "//third_party/androidx:androidx_appcompat_appcompat_resources_java",
     "//third_party/androidx:androidx_core_core_java",
     "//third_party/androidx:androidx_test_runner_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_java",
     "//ui/android:ui_java_test_support",
diff --git a/chrome/browser/commerce/price_insights/android/BUILD.gn b/chrome/browser/commerce/price_insights/android/BUILD.gn
index 254fa23..cc751d4c 100644
--- a/chrome/browser/commerce/price_insights/android/BUILD.gn
+++ b/chrome/browser/commerce/price_insights/android/BUILD.gn
@@ -94,7 +94,7 @@
     "//content/public/android:content_full_java",
     "//content/public/test/android:content_java_test_support",
     "//third_party/jni_zero:gendeps_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_java",
     "//url:gurl_junit_test_support",
@@ -127,7 +127,7 @@
     "//third_party/androidx:androidx_appcompat_appcompat_resources_java",
     "//third_party/androidx:androidx_core_core_java",
     "//third_party/androidx:androidx_test_runner_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_java_test_support",
     "//url:gurl_junit_test_support",
diff --git a/chrome/browser/commerce/price_tracking/android/BUILD.gn b/chrome/browser/commerce/price_tracking/android/BUILD.gn
index 403b344..e31d0e8 100644
--- a/chrome/browser/commerce/price_tracking/android/BUILD.gn
+++ b/chrome/browser/commerce/price_tracking/android/BUILD.gn
@@ -104,7 +104,7 @@
     "//content/public/android:content_full_java",
     "//content/public/test/android:content_java_test_support",
     "//third_party/jni_zero:gendeps_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_java",
     "//url:gurl_junit_test_support",
@@ -141,7 +141,7 @@
     "//third_party/androidx:androidx_appcompat_appcompat_resources_java",
     "//third_party/androidx:androidx_core_core_java",
     "//third_party/androidx:androidx_test_runner_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_java",
     "//ui/android:ui_java_test_support",
diff --git a/chrome/browser/companion/text_finder/BUILD.gn b/chrome/browser/companion/text_finder/BUILD.gn
index 43334d7..7863f9a 100644
--- a/chrome/browser/companion/text_finder/BUILD.gn
+++ b/chrome/browser/companion/text_finder/BUILD.gn
@@ -16,7 +16,7 @@
 
   deps = [
     "//base",
-    "//ui/gfx/geometry:geometry",
+    "//ui/gfx/geometry",
   ]
 
   if (!is_ios) {
diff --git a/chrome/browser/composeplate/android/BUILD.gn b/chrome/browser/composeplate/android/BUILD.gn
index b03d568..72455a2b 100644
--- a/chrome/browser/composeplate/android/BUILD.gn
+++ b/chrome/browser/composeplate/android/BUILD.gn
@@ -70,7 +70,7 @@
     "//chrome/browser/util:java",
     "//components/cached_flags:java",
     "//third_party/android_deps:org_mockito_mockito_core_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//ui/android:ui_no_recycler_view_java",
     "//url:url_java",
   ]
diff --git a/chrome/browser/contextual_cueing/BUILD.gn b/chrome/browser/contextual_cueing/BUILD.gn
index cc4fc78..957d5cb 100644
--- a/chrome/browser/contextual_cueing/BUILD.gn
+++ b/chrome/browser/contextual_cueing/BUILD.gn
@@ -48,7 +48,7 @@
     "//components/keyed_service/core",
     "//components/optimization_guide/content/browser",
     "//components/optimization_guide/content/browser:page_context_eligibility",
-    "//components/optimization_guide/core:core",
+    "//components/optimization_guide/core",
     "//components/optimization_guide/proto:optimization_guide_proto",
     "//components/pdf/common:constants",
     "//components/prefs",
diff --git a/chrome/browser/crash_upload_list/BUILD.gn b/chrome/browser/crash_upload_list/BUILD.gn
index 60ce3a5..ddaf5d3d 100644
--- a/chrome/browser/crash_upload_list/BUILD.gn
+++ b/chrome/browser/crash_upload_list/BUILD.gn
@@ -30,8 +30,8 @@
 
   deps = [
     "//chrome/common:constants",
-    "//components/crash/core/app:app",
-    "//components/crash/core/browser:browser",
+    "//components/crash/core/app",
+    "//components/crash/core/browser",
     "//components/upload_list",
   ]
 
diff --git a/chrome/browser/data_sharing/BUILD.gn b/chrome/browser/data_sharing/BUILD.gn
index eaed98b8..deaa5a0 100644
--- a/chrome/browser/data_sharing/BUILD.gn
+++ b/chrome/browser/data_sharing/BUILD.gn
@@ -204,7 +204,7 @@
       "//third_party/androidx:androidx_appcompat_appcompat_java",
       "//third_party/androidx:androidx_test_core_java",
       "//third_party/androidx:androidx_test_ext_junit_java",
-      "//third_party/junit:junit",
+      "//third_party/junit",
       "//third_party/mockito:mockito_java",
       "//ui/android:ui_java_test_support",
       "//ui/android:ui_no_recycler_view_java",
@@ -367,7 +367,7 @@
       "//third_party/androidx:androidx_annotation_annotation_java",
       "//third_party/androidx:androidx_test_core_java",
       "//third_party/androidx:androidx_test_ext_junit_java",
-      "//third_party/junit:junit",
+      "//third_party/junit",
       "//third_party/mockito:mockito_java",
       "//ui/android:ui_java_test_support",
       "//ui/android:ui_no_recycler_view_java",
@@ -401,7 +401,7 @@
       "//third_party/androidx:androidx_annotation_annotation_java",
       "//third_party/androidx:androidx_test_core_java",
       "//third_party/androidx:androidx_test_ext_junit_java",
-      "//third_party/junit:junit",
+      "//third_party/junit",
       "//third_party/mockito:mockito_java",
       "//ui/android:ui_java_test_support",
       "//ui/android:ui_no_recycler_view_java",
@@ -428,7 +428,7 @@
       "//third_party/androidx:androidx_test_runner_java",
       "//third_party/hamcrest:hamcrest_core_java",
       "//third_party/hamcrest:hamcrest_library_java",
-      "//third_party/junit:junit",
+      "//third_party/junit",
       "//third_party/mockito:mockito_java",
       "//ui/android:ui_java",
       "//ui/android:ui_java_test_support",
diff --git a/chrome/browser/device_api/managed_configuration_api_browsertest.cc b/chrome/browser/device_api/managed_configuration_api_browsertest.cc
index 094fc8b..60e6fe5 100644
--- a/chrome/browser/device_api/managed_configuration_api_browsertest.cc
+++ b/chrome/browser/device_api/managed_configuration_api_browsertest.cc
@@ -336,12 +336,11 @@
   EXPECT_EQ(api(), nullptr);
   // The JS API should return an error (but not cause a crash - it's a
   // regression test for b/231283325).
-  EXPECT_THAT(
-      GetValuesFromJsApi({kKey1}),
-      testing::Field("error", &content::EvalJsResult::error,
-                     Eq("a JavaScript error: \"NotAllowedError: Service "
-                        "connection error. This API is available only for "
-                        "managed apps.\"\n")));
+  EXPECT_THAT(GetValuesFromJsApi({kKey1}),
+              content::EvalJsResult::ErrorIs(
+                  Eq("a JavaScript error: \"NotAllowedError: Service "
+                     "connection error. This API is available only for "
+                     "managed apps.\"\n")));
 }
 
 #endif  // BUILDFLAG(IS_CHROMEOS)
diff --git a/chrome/browser/devtools/BUILD.gn b/chrome/browser/devtools/BUILD.gn
index 6a3e6ce5..15dc2692 100644
--- a/chrome/browser/devtools/BUILD.gn
+++ b/chrome/browser/devtools/BUILD.gn
@@ -128,14 +128,14 @@
     # Similar bandaid as the above. Since we cannot depend on
     # //chrome/browser:browser, we include indirect dependencies here.
     ":protocol_generated_sources",
-    "//chrome/browser/autofill:autofill",
+    "//chrome/browser/autofill",
     "//chrome/browser/profiles/keep_alive",
-    "//components/autofill/content/browser:browser",
-    "//components/autofill/core/browser:browser",
+    "//components/autofill/content/browser",
+    "//components/autofill/core/browser",
     "//components/enterprise/buildflags",
-    "//components/paint_preview/buildflags:buildflags",
-    "//components/variations/service:service",
-    "//components/webapps/common:common",
+    "//components/paint_preview/buildflags",
+    "//components/variations/service",
+    "//components/webapps/common",
     "//content/public/browser",
     "//net",
     "//services/metrics/public/cpp:ukm_builders",
@@ -240,9 +240,9 @@
       "//components/keyed_service/content",
       "//components/pref_registry",
       "//components/prefs",
-      "//components/search_engines:search_engines",
+      "//components/search_engines",
       "//components/sessions",
-      "//components/signin/public/identity_manager:identity_manager",
+      "//components/signin/public/identity_manager",
       "//components/sync/service",
       "//components/sync_preferences",
       "//components/web_modal",
@@ -337,8 +337,8 @@
       "//components/payments/content",
       "//components/privacy_sandbox/privacy_sandbox_attestations",
       "//components/security_state/content",
-      "//components/subresource_filter/content/browser:browser",
-      "//components/web_package:web_package",
+      "//components/subresource_filter/content/browser",
+      "//components/web_package",
       "//components/webapps/browser",
       "//third_party/blink/public/common:headers",
       "//third_party/inspector_protocol:crdtp",
diff --git a/chrome/browser/download/internal/android/BUILD.gn b/chrome/browser/download/internal/android/BUILD.gn
index b7342a0c..852e05ff 100644
--- a/chrome/browser/download/internal/android/BUILD.gn
+++ b/chrome/browser/download/internal/android/BUILD.gn
@@ -340,7 +340,7 @@
     "//content/public/test/android:content_java_test_support",
     "//third_party/androidx:androidx_core_core_java",
     "//third_party/jni_zero:jni_zero_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_full_java",
     "//url:gurl_java",
diff --git a/chrome/browser/educational_tip/BUILD.gn b/chrome/browser/educational_tip/BUILD.gn
index e29bf0e8..dfff03fb 100644
--- a/chrome/browser/educational_tip/BUILD.gn
+++ b/chrome/browser/educational_tip/BUILD.gn
@@ -125,7 +125,7 @@
     "//third_party/androidx:androidx_annotation_annotation_java",
     "//third_party/androidx:androidx_test_core_java",
     "//third_party/androidx:androidx_test_runner_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_java",
     "//ui/android:ui_junit_test_support",
diff --git a/chrome/browser/engagement/android/BUILD.gn b/chrome/browser/engagement/android/BUILD.gn
index 6f61309..3ca09b6 100644
--- a/chrome/browser/engagement/android/BUILD.gn
+++ b/chrome/browser/engagement/android/BUILD.gn
@@ -17,6 +17,6 @@
     "//content/public/android:content_java",
     "//content/public/test/android:content_java_test_support",
     "//third_party/androidx:androidx_test_runner_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
   ]
 }
diff --git a/chrome/browser/enterprise/connectors/analysis/BUILD.gn b/chrome/browser/enterprise/connectors/analysis/BUILD.gn
index 6047c02..d695ca9 100644
--- a/chrome/browser/enterprise/connectors/analysis/BUILD.gn
+++ b/chrome/browser/enterprise/connectors/analysis/BUILD.gn
@@ -17,8 +17,8 @@
   ]
 
   public_deps = [
-    "//base:base",
-    "//content/public/browser:browser",
+    "//base",
+    "//content/public/browser",
     "//third_party/content_analysis_sdk:liblcasdk",
   ]
 }
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/browser/commands/BUILD.gn b/chrome/browser/enterprise/connectors/device_trust/key_management/browser/commands/BUILD.gn
index 3fa5ccb..55c9624 100644
--- a/chrome/browser/enterprise/connectors/device_trust/key_management/browser/commands/BUILD.gn
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/browser/commands/BUILD.gn
@@ -25,8 +25,8 @@
   deps = [
     "//chrome/browser/enterprise/connectors/device_trust:features",
     "//chrome/browser/enterprise/connectors/device_trust/common",
+    "//components/enterprise/client_certificates/core",
     "//components/enterprise/client_certificates/core:cloud_management_delegate",
-    "//components/enterprise/client_certificates/core:core",
     "//components/enterprise/client_certificates/core:dm_server_client",
     "//components/enterprise/client_certificates/core:management_delegate",
     "//components/policy/core/common",
@@ -145,7 +145,7 @@
       "//chrome/browser/enterprise/connectors/device_trust/key_management/core/network:test_support",
       "//chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence:test_support",
       "//chrome/browser/enterprise/connectors/device_trust/key_management/installer:elevated_rotation",
-      "//components/enterprise:enterprise",
+      "//components/enterprise",
       "//components/enterprise:test_support",
       "//components/enterprise/client_certificates/core:cloud_management_delegate",
       "//components/enterprise/client_certificates/core:test_support",
diff --git a/chrome/browser/enterprise/connectors/device_trust/test/BUILD.gn b/chrome/browser/enterprise/connectors/device_trust/test/BUILD.gn
index d5946e8..7606dab 100644
--- a/chrome/browser/enterprise/connectors/device_trust/test/BUILD.gn
+++ b/chrome/browser/enterprise/connectors/device_trust/test/BUILD.gn
@@ -40,7 +40,7 @@
 
     public_deps += [
       "//base",
-      "//chrome/browser/enterprise/connectors/device_trust/key_management/core/network:network",
+      "//chrome/browser/enterprise/connectors/device_trust/key_management/core/network",
     ]
 
     deps += [
diff --git a/chrome/browser/enterprise/core/BUILD.gn b/chrome/browser/enterprise/core/BUILD.gn
index c4d6933..448a884 100644
--- a/chrome/browser/enterprise/core/BUILD.gn
+++ b/chrome/browser/enterprise/core/BUILD.gn
@@ -7,7 +7,7 @@
 
   public_deps = [
     "//base",
-    "//components/enterprise/core:core",
+    "//components/enterprise/core",
   ]
 }
 
diff --git a/chrome/browser/enterprise/watermark/BUILD.gn b/chrome/browser/enterprise/watermark/BUILD.gn
index 54281edd..6a91793 100644
--- a/chrome/browser/enterprise/watermark/BUILD.gn
+++ b/chrome/browser/enterprise/watermark/BUILD.gn
@@ -21,7 +21,7 @@
     "//components/policy/core/browser",
     "//components/prefs",
     "//components/strings:components_strings_grit",
-    "//components/version_info:version_info",
+    "//components/version_info",
     "//ui/views",
   ]
 }
@@ -40,11 +40,11 @@
     "//base",
     "//base/test:test_support",
     "//build/win:default_exe_manifest",
-    "//ui/base/metadata:metadata",
+    "//ui/base/metadata",
     "//ui/color:mixers",
-    "//ui/gfx:gfx",
+    "//ui/gfx",
     "//ui/resources:ui_test_pak",
-    "//ui/views:views",
+    "//ui/views",
     "//ui/views/examples:views_examples_lib",
     "//ui/views/examples:views_examples_proc",
   ]
diff --git a/chrome/browser/extensions/BUILD.gn b/chrome/browser/extensions/BUILD.gn
index 6e06ab1..95df759 100644
--- a/chrome/browser/extensions/BUILD.gn
+++ b/chrome/browser/extensions/BUILD.gn
@@ -955,14 +955,14 @@
       "//chrome/browser/resource_coordinator:mojo_bindings",
       "//chrome/browser/ui/tabs:tab_enums",
       "//chrome/browser/web_applications",
-      "//components/cbor:cbor",
+      "//components/cbor",
       "//components/commerce/core:pref_names",
       "//components/device_reauth",
       "//components/optimization_guide/core:features",
       "//components/security_interstitials/content:security_interstitial_page",
       "//components/security_state/content",
       "//components/site_engagement/core/mojom:mojo_bindings",
-      "//components/supervised_user/core/common:common",
+      "//components/supervised_user/core/common",
       "//components/webapps/browser",
       "//components/webapps/common",
       "//components/webauthn/json",
@@ -970,7 +970,7 @@
       # TODO(crbug.com/346472679): Remove this dependency:
       "//chrome/browser/web_applications/extensions",
       "//chrome/common/extensions/api:extensions_features",
-      "//chrome/services/file_util/public/mojom:mojom",
+      "//chrome/services/file_util/public/mojom",
       "//chrome/services/removable_storage_writer/public/mojom",
       "//components/affiliations/core/browser:affiliations",
       "//components/app_constants",
@@ -1007,7 +1007,7 @@
       "//components/navigation_interception",
       "//components/net_log",
       "//components/onc",
-      "//components/page_load_metrics/browser:browser",
+      "//components/page_load_metrics/browser",
       "//components/password_manager/content/browser",
       "//components/password_manager/core/browser",
       "//components/password_manager/core/browser/export",
@@ -1023,7 +1023,7 @@
       "//components/reading_list/core",
       "//components/resources",
       "//components/safe_browsing:buildflags",
-      "//components/safe_browsing/content/browser/web_ui:web_ui",
+      "//components/safe_browsing/content/browser/web_ui",
       "//components/safe_browsing/core/common/proto:csd_proto",
       "//components/search_engines",
       "//components/services/app_service",
@@ -1052,7 +1052,7 @@
       "//device/fido",
       "//extensions:extensions_resources",
       "//extensions/browser/api:extensions_api_client",
-      "//extensions/browser/api/content_settings:content_settings",
+      "//extensions/browser/api/content_settings",
       "//extensions/browser/api/system_display:display_info_provider",
       "//extensions/common:mojom",
       "//extensions/common/api",
@@ -1142,7 +1142,7 @@
         "//chromeos/components/quick_answers/public/cpp:prefs",
         "//chromeos/components/security_token_pin",
         "//chromeos/constants",
-        "//chromeos/dbus/missive:missive",
+        "//chromeos/dbus/missive",
         "//chromeos/dbus/power",
         "//chromeos/services/chromebox_for_meetings/public/cpp",
         "//chromeos/services/chromebox_for_meetings/public/mojom",
@@ -1182,7 +1182,7 @@
         "//chrome/browser/chromeos/drivefs:native_message_host_origins",
         "//chrome/browser/chromeos/extensions/file_system_provider",
         "//chrome/browser/chromeos/extensions/login_screen/login/cleanup",
-        "//chrome/browser/chromeos/extensions/smart_card_provider_private:smart_card_provider_private",
+        "//chrome/browser/chromeos/extensions/smart_card_provider_private",
 
         # TODO(crbug.com/40230380): Find an appropriate spot for vpn_provider.
         "//chrome/browser/chromeos/extensions/contact_center_insights",
@@ -1192,7 +1192,7 @@
         "//chromeos/components/quick_answers/public/cpp:prefs",
         "//chromeos/components/security_token_pin",
         "//chromeos/constants",
-        "//chromeos/dbus/missive:missive",
+        "//chromeos/dbus/missive",
         "//chromeos/dbus/power",
         "//chromeos/services/chromebox_for_meetings/public/cpp",
         "//chromeos/services/chromebox_for_meetings/public/mojom",
@@ -1341,7 +1341,7 @@
         "//chromeos/ash/components/cryptohome",
         "//chromeos/ash/components/dbus",
         "//chromeos/ash/components/dbus/attestation:attestation_proto",
-        "//chromeos/ash/components/dbus/cicerone:cicerone",
+        "//chromeos/ash/components/dbus/cicerone",
         "//chromeos/ash/components/dbus/cicerone:cicerone_proto",
         "//chromeos/ash/components/dbus/constants",
         "//chromeos/ash/components/dbus/cros_disks",
@@ -1362,7 +1362,7 @@
         "//chromeos/ash/components/proximity_auth",
         "//chromeos/ash/components/settings",
         "//chromeos/ash/components/system",
-        "//chromeos/ash/components/tether:tether",
+        "//chromeos/ash/components/tether",
         "//chromeos/ash/components/tpm",
         "//chromeos/ash/experiences/arc",
         "//chromeos/ash/experiences/arc:arc_app_constants",
@@ -1548,7 +1548,7 @@
     }
 
     if (enable_glic) {
-      deps += [ "//chrome/browser/glic:glic" ]
+      deps += [ "//chrome/browser/glic" ]
     }
 
     if (!is_android && !is_chromeos) {
diff --git a/chrome/browser/extensions/api/activity_log_private/BUILD.gn b/chrome/browser/extensions/api/activity_log_private/BUILD.gn
index c95f0452..f9cf0538 100644
--- a/chrome/browser/extensions/api/activity_log_private/BUILD.gn
+++ b/chrome/browser/extensions/api/activity_log_private/BUILD.gn
@@ -18,9 +18,9 @@
   deps = [
     "//base",
     "//chrome/browser:browser_process",
-    "//chrome/browser/extensions:extensions",
-    "//chrome/common/extensions/api:api",
-    "//components/prefs:prefs",
+    "//chrome/browser/extensions",
+    "//chrome/common/extensions/api",
+    "//components/prefs",
     "//extensions/browser",
   ]
 }
diff --git a/chrome/browser/extensions/api/autofill_private/BUILD.gn b/chrome/browser/extensions/api/autofill_private/BUILD.gn
index 39022df..c37e5376 100644
--- a/chrome/browser/extensions/api/autofill_private/BUILD.gn
+++ b/chrome/browser/extensions/api/autofill_private/BUILD.gn
@@ -26,24 +26,24 @@
   deps = [
     "//base",
     "//chrome/browser:browser_process",
-    "//chrome/browser/autofill:autofill",
-    "//chrome/browser/extensions:extensions",
+    "//chrome/browser/autofill",
+    "//chrome/browser/extensions",
     "//chrome/browser/profiles:profile",
-    "//chrome/browser/search_engines:search_engines",
-    "//chrome/browser/sync:sync",
+    "//chrome/browser/search_engines",
+    "//chrome/browser/sync",
     "//chrome/browser/ui/user_education",
-    "//chrome/common/extensions/api:api",
+    "//chrome/common/extensions/api",
     "//components/autofill/content/browser",
     "//components/autofill/core/browser",
     "//components/autofill/core/common:credit_card_number_validation",
-    "//components/device_reauth:device_reauth",
+    "//components/device_reauth",
     "//components/feature_engagement/public",
-    "//components/prefs:prefs",
+    "//components/prefs",
     "//components/strings:components_branded_strings_grit",
     "//components/strings:components_strings_grit",
-    "//components/sync/service:service",
-    "//components/variations/service:service",
-    "//extensions/browser:browser",
+    "//components/sync/service",
+    "//components/variations/service",
+    "//extensions/browser",
     "//skia",
     "//third_party/libaddressinput:util",
   ]
diff --git a/chrome/browser/extensions/api/bookmarks/test/BUILD.gn b/chrome/browser/extensions/api/bookmarks/test/BUILD.gn
index 9d4c4f0c..7ecff95c 100644
--- a/chrome/browser/extensions/api/bookmarks/test/BUILD.gn
+++ b/chrome/browser/extensions/api/bookmarks/test/BUILD.gn
@@ -8,7 +8,7 @@
   deps = [
     "//base",
     "//chrome/common/extensions/api",
-    "//components/bookmarks/browser:browser",
+    "//components/bookmarks/browser",
     "//testing/gmock",
   ]
 }
diff --git a/chrome/browser/extensions/api/crash_report_private/BUILD.gn b/chrome/browser/extensions/api/crash_report_private/BUILD.gn
index 969b8ae..012cf21 100644
--- a/chrome/browser/extensions/api/crash_report_private/BUILD.gn
+++ b/chrome/browser/extensions/api/crash_report_private/BUILD.gn
@@ -21,7 +21,7 @@
     "//chrome/browser/ui",
     "//chrome/browser/ui/web_applications",
     "//chrome/common",
-    "//components/crash/content/browser/error_reporting:error_reporting",
+    "//components/crash/content/browser/error_reporting",
     "//extensions/browser",
   ]
 }
diff --git a/chrome/browser/extensions/api/experimental_actor/BUILD.gn b/chrome/browser/extensions/api/experimental_actor/BUILD.gn
index 3b48fd3..31dbbd3 100644
--- a/chrome/browser/extensions/api/experimental_actor/BUILD.gn
+++ b/chrome/browser/extensions/api/experimental_actor/BUILD.gn
@@ -17,7 +17,7 @@
 
   deps = [
     "//base",
-    "//chrome/browser/actor:actor",
+    "//chrome/browser/actor",
     "//chrome/browser/ai",
     "//chrome/browser/extensions",
     "//chrome/browser/ui",
diff --git a/chrome/browser/extensions/api/runtime/BUILD.gn b/chrome/browser/extensions/api/runtime/BUILD.gn
index 079f20f3..9311af3 100644
--- a/chrome/browser/extensions/api/runtime/BUILD.gn
+++ b/chrome/browser/extensions/api/runtime/BUILD.gn
@@ -23,7 +23,7 @@
 
   deps = [
     "//build:chromeos_buildflags",
-    "//chrome/browser/devtools:devtools",
+    "//chrome/browser/devtools",
     "//chrome/browser/extensions",
     "//chrome/browser/profiles:profile",
     "//chrome/browser/ui",
diff --git a/chrome/browser/extensions/api/settings_overrides/BUILD.gn b/chrome/browser/extensions/api/settings_overrides/BUILD.gn
index 2df8477..e57ec820 100644
--- a/chrome/browser/extensions/api/settings_overrides/BUILD.gn
+++ b/chrome/browser/extensions/api/settings_overrides/BUILD.gn
@@ -24,7 +24,7 @@
   deps = [
     "//chrome/browser/prefs:util",
     "//chrome/browser/profiles:profile",
-    "//chrome/browser/search_engine_choice:search_engine_choice",
+    "//chrome/browser/search_engine_choice",
     "//chrome/browser/search_engines",
     "//chrome/common:constants",
     "//chrome/common/extensions",
diff --git a/chrome/browser/extensions/api/tab_groups/BUILD.gn b/chrome/browser/extensions/api/tab_groups/BUILD.gn
index f10288ae..34e58f8 100644
--- a/chrome/browser/extensions/api/tab_groups/BUILD.gn
+++ b/chrome/browser/extensions/api/tab_groups/BUILD.gn
@@ -21,18 +21,20 @@
   public_deps = [
     "//base",
     "//chrome/browser/profiles:profile",
-    "//chrome/browser/ui",
     "//chrome/browser/ui:browser_tab_strip",
     "//chrome/browser/ui/tabs:tab_strip_model_observer",
     "//chrome/common/extensions/api",
     "//components/tab_groups",
     "//extensions/browser",
+
+    # TODO(crbug.com/364501603) Remove this dependency when saved_tab_group_utils.h gets componentized.
+    "//chrome/browser/ui",
   ]
 
   deps = [
     "//chrome/browser/extensions",
     "//chrome/browser/ui:ui_features",
-    "//chrome/browser/ui/browser_window:browser_window",
+    "//chrome/browser/ui/browser_window",
     "//chrome/browser/ui/tabs:tab_group",
     "//chrome/browser/ui/tabs:tab_model",
     "//chrome/browser/ui/tabs:tab_strip",
diff --git a/chrome/browser/extensions/api/tab_groups/tab_groups_event_router.cc b/chrome/browser/extensions/api/tab_groups/tab_groups_event_router.cc
index d128349..a92e563 100644
--- a/chrome/browser/extensions/api/tab_groups/tab_groups_event_router.cc
+++ b/chrome/browser/extensions/api/tab_groups/tab_groups_event_router.cc
@@ -11,7 +11,7 @@
 #include "chrome/browser/extensions/extension_tab_util.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_window/public/browser_window_interface.h"
 #include "chrome/browser/ui/tabs/tab_group_model.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "components/tab_groups/tab_group_color.h"
@@ -62,9 +62,10 @@
   return;
 }
 
-bool TabGroupsEventRouter::ShouldTrackBrowser(Browser* browser) {
-  return profile_ == browser->profile() &&
-         ExtensionTabUtil::BrowserSupportsTabs(browser);
+bool TabGroupsEventRouter::ShouldTrackBrowser(BrowserWindowInterface* browser) {
+  return profile_ == browser->GetProfile() &&
+         ExtensionTabUtil::BrowserSupportsTabs(
+             browser->GetBrowserForMigrationOnly());
 }
 
 void TabGroupsEventRouter::DispatchGroupCreated(tab_groups::TabGroupId group) {
diff --git a/chrome/browser/extensions/api/tab_groups/tab_groups_event_router.h b/chrome/browser/extensions/api/tab_groups/tab_groups_event_router.h
index f80bd97..98f510a 100644
--- a/chrome/browser/extensions/api/tab_groups/tab_groups_event_router.h
+++ b/chrome/browser/extensions/api/tab_groups/tab_groups_event_router.h
@@ -37,7 +37,7 @@
   void OnTabGroupChanged(const TabGroupChange& change) override;
 
   // BrowserTabStripTrackerDelegate:
-  bool ShouldTrackBrowser(Browser* browser) override;
+  bool ShouldTrackBrowser(BrowserWindowInterface* browser) override;
 
  private:
   // Methods called from OnTabGroupChanged.
diff --git a/chrome/browser/extensions/api/tabs/tabs_event_router.cc b/chrome/browser/extensions/api/tabs/tabs_event_router.cc
index 65fa4cc..ca5bb784 100644
--- a/chrome/browser/extensions/api/tabs/tabs_event_router.cc
+++ b/chrome/browser/extensions/api/tabs/tabs_event_router.cc
@@ -26,6 +26,7 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_list.h"
 #include "chrome/browser/ui/browser_window/public/browser_window_features.h"
+#include "chrome/browser/ui/browser_window/public/browser_window_interface.h"
 #include "chrome/browser/ui/recently_audible_helper.h"
 #include "chrome/browser/ui/tabs/tab_group_model.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
@@ -211,9 +212,10 @@
   BrowserList::RemoveObserver(this);
 }
 
-bool TabsEventRouter::ShouldTrackBrowser(Browser* browser) {
-  return profile_->IsSameOrParent(browser->profile()) &&
-         ExtensionTabUtil::BrowserSupportsTabs(browser);
+bool TabsEventRouter::ShouldTrackBrowser(BrowserWindowInterface* browser) {
+  return profile_->IsSameOrParent(browser->GetProfile()) &&
+         ExtensionTabUtil::BrowserSupportsTabs(
+             browser->GetBrowserForMigrationOnly());
 }
 
 void TabsEventRouter::OnBrowserSetLastActive(Browser* browser) {
diff --git a/chrome/browser/extensions/api/tabs/tabs_event_router.h b/chrome/browser/extensions/api/tabs/tabs_event_router.h
index f954470..59694ff 100644
--- a/chrome/browser/extensions/api/tabs/tabs_event_router.h
+++ b/chrome/browser/extensions/api/tabs/tabs_event_router.h
@@ -55,7 +55,7 @@
   ~TabsEventRouter() override;
 
   // BrowserTabStripTrackerDelegate:
-  bool ShouldTrackBrowser(Browser* browser) override;
+  bool ShouldTrackBrowser(BrowserWindowInterface* browser) override;
 
   // BrowserListObserver:
   void OnBrowserSetLastActive(Browser* browser) override;
diff --git a/chrome/browser/extensions/api/web_authentication_proxy/web_authentication_proxy_apitest.cc b/chrome/browser/extensions/api/web_authentication_proxy/web_authentication_proxy_apitest.cc
index 0398e78..89485b8 100644
--- a/chrome/browser/extensions/api/web_authentication_proxy/web_authentication_proxy_apitest.cc
+++ b/chrome/browser/extensions/api/web_authentication_proxy/web_authentication_proxy_apitest.cc
@@ -127,9 +127,10 @@
               let err = await createPromise;
               return err;
             })();)";
-    return content::EvalJs(browser()->tab_strip_model()->GetActiveWebContents(),
-                           kMakeCredentialJs)
-               .error.find("AbortError") >= 0;
+    return testing::Value(
+        content::EvalJs(browser()->tab_strip_model()->GetActiveWebContents(),
+                        kMakeCredentialJs),
+        content::EvalJsResult::ErrorIs(testing::HasSubstr("AbortError")));
   }
 
   content::EvalJsResult NavigateAndCallGetAssertion() {
@@ -167,9 +168,10 @@
               let err = await getPromise;
               return err;
             })();)";
-    return content::EvalJs(browser()->tab_strip_model()->GetActiveWebContents(),
-                           kGetAssertionJs)
-               .error.find("AbortError") >= 0;
+    return testing::Value(
+        content::EvalJs(browser()->tab_strip_model()->GetActiveWebContents(),
+                        kGetAssertionJs),
+        content::EvalJsResult::ErrorIs(testing::HasSubstr("AbortError")));
   }
 
   bool ProxyIsActive() { return ProxyIsActiveForContext(profile()); }
diff --git a/chrome/browser/extensions/api/web_navigation/BUILD.gn b/chrome/browser/extensions/api/web_navigation/BUILD.gn
index 6877f2b7..4e0ffb3 100644
--- a/chrome/browser/extensions/api/web_navigation/BUILD.gn
+++ b/chrome/browser/extensions/api/web_navigation/BUILD.gn
@@ -22,7 +22,6 @@
   public_deps = [
     "//base",
     "//chrome/browser/profiles:profile",
-    "//chrome/browser/ui",
     "//chrome/browser/ui:browser_tab_strip",
     "//content/public/browser",
     "//extensions/browser",
@@ -33,6 +32,7 @@
   deps = [
     "//chrome/browser/extensions",
     "//chrome/browser/ui:browser_list",
+    "//chrome/browser/ui/browser_window",
     "//chrome/common",
     "//chrome/common/extensions/api",
     "//content/public/common",
@@ -48,7 +48,4 @@
       "//pdf:features",
     ]
   }
-
-  # //chrome/browser/ui and this target are co-dependent.
-  allow_circular_includes_from = [ "//chrome/browser/ui" ]
 }
diff --git a/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc b/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc
index 0985e698..2c5ef4d 100644
--- a/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc
+++ b/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc
@@ -12,8 +12,7 @@
 #include "chrome/browser/extensions/api/web_navigation/web_navigation_api_helpers.h"
 #include "chrome/browser/extensions/extension_tab_util.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/browser_list.h"
+#include "chrome/browser/ui/browser_window/public/browser_window_interface.h"
 #include "chrome/common/extensions/api/web_navigation.h"
 #include "content/public/browser/navigation_details.h"
 #include "content/public/browser/navigation_handle.h"
@@ -73,8 +72,9 @@
 
 WebNavigationEventRouter::~WebNavigationEventRouter() = default;
 
-bool WebNavigationEventRouter::ShouldTrackBrowser(Browser* browser) {
-  return profile_->IsSameOrParent(browser->profile());
+bool WebNavigationEventRouter::ShouldTrackBrowser(
+    BrowserWindowInterface* browser) {
+  return profile_->IsSameOrParent(browser->GetProfile());
 }
 
 void WebNavigationEventRouter::OnTabStripModelChanged(
diff --git a/chrome/browser/extensions/api/web_navigation/web_navigation_api.h b/chrome/browser/extensions/api/web_navigation/web_navigation_api.h
index 0936d48..b59fc423 100644
--- a/chrome/browser/extensions/api/web_navigation/web_navigation_api.h
+++ b/chrome/browser/extensions/api/web_navigation/web_navigation_api.h
@@ -155,7 +155,7 @@
   };
 
   // BrowserTabStripTrackerDelegate implementation.
-  bool ShouldTrackBrowser(Browser* browser) override;
+  bool ShouldTrackBrowser(BrowserWindowInterface* browser) override;
 
   // TabStripModelObserver implementation.
   void OnTabStripModelChanged(
diff --git a/chrome/browser/extensions/keyed_services/BUILD.gn b/chrome/browser/extensions/keyed_services/BUILD.gn
index 1c9e647..37de48f 100644
--- a/chrome/browser/extensions/keyed_services/BUILD.gn
+++ b/chrome/browser/extensions/keyed_services/BUILD.gn
@@ -26,6 +26,6 @@
     "//content/public/common:buildflags",
     "//extensions/buildflags",
     "//pdf:buildflags",
-    "//printing/buildflags:buildflags",
+    "//printing/buildflags",
   ]
 }
diff --git a/chrome/browser/facilitated_payments/ui/android/BUILD.gn b/chrome/browser/facilitated_payments/ui/android/BUILD.gn
index 166dded7..fda0c52 100644
--- a/chrome/browser/facilitated_payments/ui/android/BUILD.gn
+++ b/chrome/browser/facilitated_payments/ui/android/BUILD.gn
@@ -14,14 +14,14 @@
 
   deps = [
     ":jni_headers",
-    "//base:base",
+    "//base",
     "//chrome/android:chrome_jni_headers",
     "//chrome/browser/autofill",
     "//components/facilitated_payments/android",
     "//components/facilitated_payments/core/browser",
     "//components/facilitated_payments/core/utils",
-    "//content/public/browser:browser",
-    "//ui/android:android",
+    "//content/public/browser",
+    "//ui/android",
   ]
 }
 
@@ -36,9 +36,9 @@
     "//components/facilitated_payments/core/browser",
     "//components/facilitated_payments/core/browser:test_support",
     "//components/facilitated_payments/core/utils",
-    "//content/public/browser:browser",
+    "//content/public/browser",
     "//testing/gtest",
-    "//ui/android:android",
+    "//ui/android",
   ]
 }
 
diff --git a/chrome/browser/fast_checkout/BUILD.gn b/chrome/browser/fast_checkout/BUILD.gn
index f917e5a6..50ebf811 100644
--- a/chrome/browser/fast_checkout/BUILD.gn
+++ b/chrome/browser/fast_checkout/BUILD.gn
@@ -96,7 +96,7 @@
     "//chrome/test:test_support",
     "//components/autofill/content/browser:test_support",
     "//components/autofill/core/browser:test_support",
-    "//components/unified_consent:unified_consent",
+    "//components/unified_consent",
     "//services/network:test_support",
     "//testing/gmock",
     "//testing/gtest",
diff --git a/chrome/browser/favicon/BUILD.gn b/chrome/browser/favicon/BUILD.gn
index e107fc7..0c8299f 100644
--- a/chrome/browser/favicon/BUILD.gn
+++ b/chrome/browser/favicon/BUILD.gn
@@ -40,6 +40,6 @@
     "//ui/resources",
   ]
   if (is_chromeos) {
-    deps += [ "//ash/constants:constants" ]
+    deps += [ "//ash/constants" ]
   }
 }
diff --git a/chrome/browser/file_system_access/chrome_file_system_access_permission_context_browsertest.cc b/chrome/browser/file_system_access/chrome_file_system_access_permission_context_browsertest.cc
index 7db6c489..f789477 100644
--- a/chrome/browser/file_system_access/chrome_file_system_access_permission_context_browsertest.cc
+++ b/chrome/browser/file_system_access/chrome_file_system_access_permission_context_browsertest.cc
@@ -348,11 +348,9 @@
              R"(
       handle.move("test.swf");
   )"),
-      testing::Field(
-          &content::EvalJsResult::error,
-          testing::Eq(
-              "a JavaScript error: \"TypeError: Failed to execute 'move' on "
-              "'FileSystemFileHandle'\"\n")));
+      content::EvalJsResult::ErrorIs(testing::Eq(
+          "a JavaScript error: \"TypeError: Failed to execute 'move' on "
+          "'FileSystemFileHandle'\"\n")));
   // Checks that ConfirmSensitiveEntryAccess() is called again to verify the
   // move target file name.
   EXPECT_TRUE(permission_context.confirm_sensitive_entry_access());
diff --git a/chrome/browser/file_system_access/file_system_access_picker_requires_user_gesture_browsertest.cc b/chrome/browser/file_system_access/file_system_access_picker_requires_user_gesture_browsertest.cc
index 2eff3824..14ec1f62 100644
--- a/chrome/browser/file_system_access/file_system_access_picker_requires_user_gesture_browsertest.cc
+++ b/chrome/browser/file_system_access/file_system_access_picker_requires_user_gesture_browsertest.cc
@@ -192,8 +192,9 @@
 
   auto result = EvalJs(GetWebContents(), GetScript(),
                        content::EvalJsOptions::EXECUTE_SCRIPT_NO_USER_GESTURE);
-  EXPECT_TRUE(result.error.find(kUserGestureErrorMessage) != std::string::npos)
-      << result.error;
+  EXPECT_THAT(result, content::EvalJsResult::ErrorIs(
+                          testing::HasSubstr(kUserGestureErrorMessage)))
+      << result;
 }
 
 IN_PROC_BROWSER_TEST_P(FileSystemAccessPickerRequiresUserGestureTest,
@@ -222,8 +223,9 @@
 
   auto result = EvalJs(GetWebContents(), GetScript(),
                        content::EvalJsOptions::EXECUTE_SCRIPT_NO_USER_GESTURE);
-  EXPECT_TRUE(result.error.find(kUserGestureErrorMessage) != std::string::npos)
-      << result.error;
+  EXPECT_THAT(result, content::EvalJsResult::ErrorIs(
+                          testing::HasSubstr(kUserGestureErrorMessage)))
+      << result;
 }
 
 INSTANTIATE_TEST_SUITE_P(All,
diff --git a/chrome/browser/first_party_sets/BUILD.gn b/chrome/browser/first_party_sets/BUILD.gn
index 48b16b2a..f2affad 100644
--- a/chrome/browser/first_party_sets/BUILD.gn
+++ b/chrome/browser/first_party_sets/BUILD.gn
@@ -24,8 +24,8 @@
   deps = [
     "//base",
     "//chrome/browser:browser_process",
+    "//chrome/browser/profiles",
     "//chrome/browser/profiles:profile",
-    "//chrome/browser/profiles:profiles",
     "//components/keyed_service/content",
     "//components/policy:generated",
     "//components/policy:policy_code_generate",
@@ -33,8 +33,8 @@
     "//components/policy/core/browser",
     "//components/policy/proto",
     "//components/pref_registry",
-    "//components/prefs:prefs",
-    "//components/privacy_sandbox:privacy_sandbox",
+    "//components/prefs",
+    "//components/privacy_sandbox",
     "//components/privacy_sandbox:privacy_sandbox_prefs",
     "//components/strings:components_strings_grit",
   ]
diff --git a/chrome/browser/flags/BUILD.gn b/chrome/browser/flags/BUILD.gn
index 0e50bae..252fcbaf 100644
--- a/chrome/browser/flags/BUILD.gn
+++ b/chrome/browser/flags/BUILD.gn
@@ -46,7 +46,7 @@
     ":jni_headers",
     "//base",
     "//chrome/browser:browser_process",
-    "//components/prefs:prefs",
+    "//components/prefs",
     "//content/public/browser",
     "//content/public/common",
   ]
diff --git a/chrome/browser/media/webrtc/display_media_access_handler_browsertest.cc b/chrome/browser/media/webrtc/display_media_access_handler_browsertest.cc
index c775837..8d1c02c 100644
--- a/chrome/browser/media/webrtc/display_media_access_handler_browsertest.cc
+++ b/chrome/browser/media/webrtc/display_media_access_handler_browsertest.cc
@@ -138,13 +138,13 @@
 
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
-  EXPECT_THAT(content::EvalJs(web_contents->GetPrimaryMainFrame(),
-                              R"((async () => {
+  EXPECT_THAT(
+      content::EvalJs(web_contents->GetPrimaryMainFrame(),
+                      R"((async () => {
     return navigator.mediaDevices.getDisplayMedia({
         audio: true, systemAudio: 'include', video: false});
-  })())")
-                  .error,
-              testing::HasSubstr("Not supported"));
+  })())"),
+      content::EvalJsResult::ErrorIs(testing::HasSubstr("Not supported")));
   EXPECT_EQ(dialog_opened_, false);
 }
 
@@ -190,13 +190,13 @@
 
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
-  EXPECT_THAT(content::EvalJs(web_contents->GetPrimaryMainFrame(),
-                              R"((async () => {
+  EXPECT_THAT(
+      content::EvalJs(web_contents->GetPrimaryMainFrame(),
+                      R"((async () => {
     return navigator.mediaDevices.getDisplayMedia({
         audio: true, systemAudio: 'include', video: false});
-  })())")
-                  .error,
-              testing::HasSubstr("Not supported"));
+  })())"),
+      content::EvalJsResult::ErrorIs(testing::HasSubstr("Not supported")));
   EXPECT_EQ(dialog_opened_, false);
 }
 
@@ -217,13 +217,13 @@
 
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
-  EXPECT_THAT(content::EvalJs(web_contents->GetPrimaryMainFrame(),
-                              R"((async () => {
+  EXPECT_THAT(
+      content::EvalJs(web_contents->GetPrimaryMainFrame(),
+                      R"((async () => {
     return navigator.mediaDevices.getDisplayMedia({
         audio: true, systemAudio: 'exclude', video: false});
-  })())")
-                  .error,
-              testing::HasSubstr("Not supported"));
+  })())"),
+      content::EvalJsResult::ErrorIs(testing::HasSubstr("Not supported")));
   EXPECT_EQ(dialog_opened_, false);
 }
 
diff --git a/chrome/browser/nearby_sharing/nearby_sharing_service_impl.cc b/chrome/browser/nearby_sharing/nearby_sharing_service_impl.cc
index fded6ca..ac0b173 100644
--- a/chrome/browser/nearby_sharing/nearby_sharing_service_impl.cc
+++ b/chrome/browser/nearby_sharing/nearby_sharing_service_impl.cc
@@ -1066,7 +1066,7 @@
 
 void NearbySharingServiceImpl::OpenURL(GURL url) {
   DCHECK(profile_);
-  ash::NewWindowDelegate::GetPrimary()->OpenUrl(
+  ash::NewWindowDelegate::GetInstance()->OpenUrl(
       url, ash::NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       ash::NewWindowDelegate::Disposition::kNewForegroundTab);
 }
diff --git a/chrome/browser/net/cookie_policy_browsertest.cc b/chrome/browser/net/cookie_policy_browsertest.cc
index 1b9331b..becde52 100644
--- a/chrome/browser/net/cookie_policy_browsertest.cc
+++ b/chrome/browser/net/cookie_policy_browsertest.cc
@@ -129,7 +129,7 @@
                       const std::string& cookie) {
     content::EvalJsResult result =
         EvalJs(frame, base::StrCat({"document.cookie = '", cookie, "'"}));
-    ASSERT_TRUE(result.is_ok()) << result.error;
+    ASSERT_TRUE(result.is_ok()) << result;
   }
 
   std::string GetCookieViaJS(content::RenderFrameHost* frame) {
diff --git a/chrome/browser/net/reporting_browsertest.cc b/chrome/browser/net/reporting_browsertest.cc
index 5cbf029..3c04886 100644
--- a/chrome/browser/net/reporting_browsertest.cc
+++ b/chrome/browser/net/reporting_browsertest.cc
@@ -749,15 +749,11 @@
   EXPECT_TRUE(NavigateToURL(contents, main_url));
 
   // Use the crash reporting storage API, to collect some data about the current
-  // page. In this case, just the current origin and the window's outerHeight,
-  // to verify they come out on the other end of the crash report.
-  const int expected_outer_height =
-      content::EvalJs(contents, "window.outerHeight").ExtractInt();
-  EXPECT_TRUE(ExecJs(
-      contents->GetPrimaryMainFrame(),
-      "crashReport.set('self.origin', self.origin + "
-      "'/');crashReport.set('outer_height', "
-      "window.outerHeight);crashReport.set('custom_key', 'custom_value')"));
+  // page. In this case, just the current origin and a custom key, to verify
+  // they come out on the other end of the crash report.
+  EXPECT_TRUE(ExecJs(contents->GetPrimaryMainFrame(),
+                     "crashReport.set('self.origin', self.origin + "
+                     "'/');crashReport.set('custom_key', 'custom_value')"));
   EXPECT_TRUE(ExecJs(contents->GetPrimaryMainFrame(),
                      "crashReport.remove('custom_key')"));
 
@@ -780,7 +776,6 @@
   const base::Value::Dict* body = report.FindDict("body");
   const std::string* reason = body->FindString("reason");
   const std::string* self_origin = body->FindString("self.origin");
-  const std::string* outer_height = body->FindString("outer_height");
   const std::string* custom_key = body->FindString("custom_key");
 
   EXPECT_EQ("crash", *type);
@@ -789,7 +784,6 @@
   EXPECT_EQ(
       contents->GetPrimaryMainFrame()->GetLastCommittedOrigin().GetURL().spec(),
       *self_origin);
-  EXPECT_EQ(base::ToString(expected_outer_height), *outer_height);
   // Because `crashReport.remove('custom_key')` was called before the process
   // crashed, this value is not present in the report body.
   EXPECT_EQ(custom_key, nullptr);
diff --git a/chrome/browser/notifications/notification_permission_browsertest.cc b/chrome/browser/notifications/notification_permission_browsertest.cc
index c4214d09..39d9aefce 100644
--- a/chrome/browser/notifications/notification_permission_browsertest.cc
+++ b/chrome/browser/notifications/notification_permission_browsertest.cc
@@ -263,7 +263,7 @@
   EXPECT_EQ(
       "a JavaScript error: \"NotAllowedError: "
       "Registration failed - permission denied\"\n",
-      EvalJs(iframe, "requestPushPermission()").error);
+      EvalJs(iframe, "requestPushPermission()").ExtractError());
 }
 
 // Test that the Notifications.NonPersistentNotificationThirdPartyCount metric
diff --git a/chrome/browser/page_load_metrics/integration_tests/largest_contentful_paint_browsertest.cc b/chrome/browser/page_load_metrics/integration_tests/largest_contentful_paint_browsertest.cc
index 3b4b3aa..7e90a08 100644
--- a/chrome/browser/page_load_metrics/integration_tests/largest_contentful_paint_browsertest.cc
+++ b/chrome/browser/page_load_metrics/integration_tests/largest_contentful_paint_browsertest.cc
@@ -151,7 +151,7 @@
     waiter->AddMinimumLargestContentfulPaintImageExpectation(1);
 
     content::EvalJsResult result = EvalJs(web_contents(), test_name[i]);
-    EXPECT_EQ("", result.error);
+    EXPECT_TRUE(result.is_ok());
 
     const auto list = result.ExtractList();
     EXPECT_EQ(1u, list.size());
@@ -260,7 +260,7 @@
 
   content::EvalJsResult lcp_before_paint_preview =
       EvalJs(web_contents(), "block_for_next_lcp()");
-  EXPECT_EQ("", lcp_before_paint_preview.error);
+  EXPECT_TRUE(lcp_before_paint_preview.is_ok());
 
   paint_preview::PaintPreviewClient::CreateForWebContents(
       web_contents());  // Is a singleton.
@@ -290,7 +290,7 @@
 
   content::EvalJsResult lcp_after_paint_preview =
       EvalJs(web_contents(), "trigger_repaint_and_block_for_next_lcp()");
-  EXPECT_EQ("", lcp_after_paint_preview.error);
+  EXPECT_TRUE(lcp_after_paint_preview.is_ok());
 
   // When PaintPreview creates new LCP candidates, we compare the short text and
   // the long text here, which will fail. But in order to consistently get the
@@ -423,8 +423,8 @@
     }
     Start();
     Load(html_name);
-    EXPECT_EQ(EvalJs(web_contents()->GetPrimaryMainFrame(), "run_test()").error,
-              "");
+    EXPECT_TRUE(
+        EvalJs(web_contents()->GetPrimaryMainFrame(), "run_test()").is_ok());
 
     // Need to navigate away from the test html page to force metrics to get
     // flushed/synced.
@@ -579,17 +579,15 @@
   }
 
   void AddImage(const std::string& imgSrc) {
-    EXPECT_EQ(EvalJs(web_contents()->GetPrimaryMainFrame(),
-                     content::JsReplace("add_image($1)", imgSrc))
-                  .error,
-              "");
+    EXPECT_TRUE(EvalJs(web_contents()->GetPrimaryMainFrame(),
+                       content::JsReplace("add_image($1)", imgSrc))
+                    .is_ok());
   }
 
   void AddText(std::string_view text) {
-    EXPECT_EQ(EvalJs(web_contents()->GetPrimaryMainFrame(),
-                     content::JsReplace("add_text($1)", text))
-                  .error,
-              "");
+    EXPECT_TRUE(EvalJs(web_contents()->GetPrimaryMainFrame(),
+                       content::JsReplace("add_text($1)", text))
+                    .is_ok());
   }
 };
 
@@ -778,10 +776,9 @@
 
   std::string url = "/images/lcp-16x16.png";
   std::string element_id = "image";
-  EXPECT_EQ(EvalJs(web_contents()->GetPrimaryMainFrame(),
-                   content::JsReplace("addImage($1, $2)", url, element_id))
-                .error,
-            "");
+  EXPECT_TRUE(EvalJs(web_contents()->GetPrimaryMainFrame(),
+                     content::JsReplace("addImage($1, $2)", url, element_id))
+                  .is_ok());
   double web_exposed_lcp = EvalJs(web_contents()->GetPrimaryMainFrame(),
                                   content::JsReplace("getLCP($1)", element_id))
                                .ExtractDouble();
@@ -847,8 +844,8 @@
 
     // Execute script if any.
     if (!script.empty()) {
-      EXPECT_EQ(EvalJs(web_contents()->GetPrimaryMainFrame(), script).error,
-                "");
+      EXPECT_TRUE(
+          EvalJs(web_contents()->GetPrimaryMainFrame(), script).is_ok());
     }
 
     waiter0->Wait();
@@ -888,8 +885,8 @@
 
     // Execute script if any.
     if (!script.empty()) {
-      EXPECT_EQ(EvalJs(web_contents()->GetPrimaryMainFrame(), script).error,
-                "");
+      EXPECT_TRUE(
+          EvalJs(web_contents()->GetPrimaryMainFrame(), script).is_ok());
     }
 
     waiter1->Wait();
@@ -1191,10 +1188,9 @@
   const std::string url1 = "/images/lcp-16x16.png";
   const std::string element_id1 = "image";
 
-  EXPECT_EQ(EvalJs(web_contents()->GetPrimaryMainFrame(),
-                   content::JsReplace("addImage($1, $2)", url1, element_id1))
-                .error,
-            "");
+  EXPECT_TRUE(EvalJs(web_contents()->GetPrimaryMainFrame(),
+                     content::JsReplace("addImage($1, $2)", url1, element_id1))
+                  .is_ok());
 
   waiter->Wait();
 
@@ -1202,10 +1198,9 @@
 
   const std::string element_id2 = "text";
 
-  EXPECT_EQ(EvalJs(web_contents()->GetPrimaryMainFrame(),
-                   content::JsReplace("addText($1, $2)", element_id2))
-                .error,
-            "");
+  EXPECT_TRUE(EvalJs(web_contents()->GetPrimaryMainFrame(),
+                     content::JsReplace("addText($1, $2)", element_id2))
+                  .is_ok());
 
   waiter->Wait();
 
@@ -1246,10 +1241,9 @@
   // Load an image.
   const std::string url1 = "/images/lcp-16x16.png";
   const std::string element_id1 = "image";
-  EXPECT_EQ(EvalJs(web_contents()->GetPrimaryMainFrame(),
-                   content::JsReplace("addImage($1, $2)", url1, element_id1))
-                .error,
-            "");
+  EXPECT_TRUE(EvalJs(web_contents()->GetPrimaryMainFrame(),
+                     content::JsReplace("addImage($1, $2)", url1, element_id1))
+                  .is_ok());
 
   waiter->Wait();
 
@@ -1262,10 +1256,9 @@
   const std::string url2 = "/images/lcp-256x256.png";
   const std::string element_id2 = "larger_image";
 
-  EXPECT_EQ(EvalJs(web_contents()->GetPrimaryMainFrame(),
-                   content::JsReplace("addImage($1, $2)", url2, element_id2))
-                .error,
-            "");
+  EXPECT_TRUE(EvalJs(web_contents()->GetPrimaryMainFrame(),
+                     content::JsReplace("addImage($1, $2)", url2, element_id2))
+                  .is_ok());
 
   double web_exposed_lcp2 =
       EvalJs(web_contents()->GetPrimaryMainFrame(),
@@ -1328,8 +1321,8 @@
 
   Load("/lcp_detached_window.html");
 
-  EXPECT_EQ(EvalJs(web_contents()->GetPrimaryMainFrame(), "runTest()").error,
-            "");
+  EXPECT_TRUE(
+      EvalJs(web_contents()->GetPrimaryMainFrame(), "runTest()").is_ok());
 
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL("about:blank")));
 
diff --git a/chrome/browser/page_load_metrics/integration_tests/soft_navigation_metrics_browsertest.cc b/chrome/browser/page_load_metrics/integration_tests/soft_navigation_metrics_browsertest.cc
index 79958b6..d911852 100644
--- a/chrome/browser/page_load_metrics/integration_tests/soft_navigation_metrics_browsertest.cc
+++ b/chrome/browser/page_load_metrics/integration_tests/soft_navigation_metrics_browsertest.cc
@@ -352,17 +352,15 @@
   Start();
   Load("/soft_navigation.html");
 
-  EXPECT_EQ(
-      EvalJs(web_contents()->GetPrimaryMainFrame(), "setEventAndWait()").error,
-      "");
+  EXPECT_TRUE(EvalJs(web_contents()->GetPrimaryMainFrame(), "setEventAndWait()")
+                  .is_ok());
 
   SimulateMouseDownElementWithId("link");
 
   if (GetParam()) {
-    EXPECT_EQ(EvalJs(web_contents()->GetPrimaryMainFrame(),
-                     "waitForSoftNavigationEntry()")
-                  .error,
-              "");
+    EXPECT_TRUE(EvalJs(web_contents()->GetPrimaryMainFrame(),
+                       "waitForSoftNavigationEntry()")
+                    .is_ok());
   }
 
   waiter->Wait();
@@ -374,10 +372,9 @@
   SimulateMouseDownElementWithId("link");
 
   if (GetParam()) {
-    EXPECT_EQ(EvalJs(web_contents()->GetPrimaryMainFrame(),
-                     "waitForSoftNavigationEntry2()")
-                  .error,
-              "");
+    EXPECT_TRUE(EvalJs(web_contents()->GetPrimaryMainFrame(),
+                       "waitForSoftNavigationEntry2()")
+                    .is_ok());
   }
 
   waiter->Wait();
@@ -570,9 +567,8 @@
   Load("/soft_navigation.html");
 
   // Set up for soft navigation.
-  EXPECT_EQ(
-      EvalJs(web_contents()->GetPrimaryMainFrame(), "setEventAndWait()").error,
-      "");
+  EXPECT_TRUE(EvalJs(web_contents()->GetPrimaryMainFrame(), "setEventAndWait()")
+                  .is_ok());
 
   // Add event listener to change color on click.
   EXPECT_TRUE(ExecJs(web_contents(), "addChangeColorEventListener();"));
@@ -637,9 +633,8 @@
   waiter->Wait();
 
   // Set up for soft navigation.
-  EXPECT_EQ(
-      EvalJs(web_contents()->GetPrimaryMainFrame(), "setEventAndWait()").error,
-      "");
+  EXPECT_TRUE(EvalJs(web_contents()->GetPrimaryMainFrame(), "setEventAndWait()")
+                  .is_ok());
 
   // Trigger 1st soft navigation.
   TriggerSoftNavigation(waiter.get(), 1);
diff --git a/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc b/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc
index 4193717d..a9c6dd6 100644
--- a/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc
+++ b/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc
@@ -527,7 +527,7 @@
         }
       })
   )");
-  EXPECT_EQ("", result.error);
+  EXPECT_TRUE(result.is_ok());
 
   img_response->Send(kImgHttpResponseHeader);
   img_response->Send(file_contents);
@@ -547,7 +547,7 @@
      }))
      .observe({type: 'largest-contentful-paint', buffered: true});
  })})())");
-  EXPECT_EQ("", result2.error);
+  EXPECT_TRUE(result2.is_ok());
   waiter->Wait();
 
   // LCP is collected only at the end of the page lifecycle. Navigate to
@@ -653,7 +653,7 @@
   await new Promise(r => setTimeout(r, 50));
   return timestamp;
 })();)");
-    EXPECT_EQ("", result.error);
+    EXPECT_TRUE(result.is_ok());
     double timestamp = result.ExtractDouble();
 
     img_response->Send(second_frame);
@@ -673,7 +673,7 @@
      }))
      .observe({type: 'largest-contentful-paint', buffered: true});
  })})())");
-    EXPECT_EQ("", result2.error);
+    EXPECT_TRUE(result2.is_ok());
     waiter->Wait();
 
     // LCP is collected only at the end of the page lifecycle. Navigate to
diff --git a/chrome/browser/payments/payment_request_can_make_payment_browsertest.cc b/chrome/browser/payments/payment_request_can_make_payment_browsertest.cc
index 214148a..72a123a 100644
--- a/chrome/browser/payments/payment_request_can_make_payment_browsertest.cc
+++ b/chrome/browser/payments/payment_request_can_make_payment_browsertest.cc
@@ -168,18 +168,19 @@
                       content::JsReplace("checkCanMakePayment($1)", method)),
       testing::AnyOf(
           content::EvalJsResult::ErrorIs("a JavaScript error: \"false\"\n"),
-          content::EvalJsResult::IsOkAndHolds(false)));
+          content::EvalJsResult::IsOkAndHolds(testing::Eq(false))));
 
   // hasEnrolledInstrument() will either reject or resolve with "false",
   // depending on timing of when the browser completes the SSL check and when
   // the website calls hasEnrolledInstrument().
   // TODO(crbug.com/40858197): More consistent hasEnrolledInstrument() behavior.
-  EXPECT_THAT(content::EvalJs(
-                  GetActiveWebContents(),
-                  content::JsReplace("checkHasEnrolledInstrument($1)", method)),
-              testing::AnyOf(content::EvalJsResult::ErrorIs(
-                                 "a JavaScript error: \"false\"\n"),
-                             content::EvalJsResult::IsOkAndHolds(false)));
+  EXPECT_THAT(
+      content::EvalJs(
+          GetActiveWebContents(),
+          content::JsReplace("checkHasEnrolledInstrument($1)", method)),
+      testing::AnyOf(
+          content::EvalJsResult::ErrorIs("a JavaScript error: \"false\"\n"),
+          content::EvalJsResult::IsOkAndHolds(testing::Eq(false))));
 
   EXPECT_EQ("NotSupportedError: Invalid SSL certificate",
             content::EvalJs(GetActiveWebContents(),
diff --git a/chrome/browser/permissions/permissions_security_model_interactive_uitest.cc b/chrome/browser/permissions/permissions_security_model_interactive_uitest.cc
index 7384547b..5f51f57 100644
--- a/chrome/browser/permissions/permissions_security_model_interactive_uitest.cc
+++ b/chrome/browser/permissions/permissions_security_model_interactive_uitest.cc
@@ -61,7 +61,7 @@
 // ASSERT_* macros can only be used in functions returning void.
 void AssertResultIsString(const content::EvalJsResult& result) {
   // Verify no error.
-  ASSERT_EQ("", result.error);
+  ASSERT_TRUE(result.is_ok());
   // We could use result.value.is_string(), but this logs the actual type in
   // case of mismatch.
   std::ignore = result.ExtractString();
@@ -870,7 +870,7 @@
 
   content::EvalJsResult result = content::EvalJs(
       embedder_contents, "history.pushState({}, {}, 'https://chromium.org');");
-  EXPECT_EQ(std::string(), result.error);
+  EXPECT_TRUE(result.is_ok());
   EXPECT_EQ("https://chromium.org/", main_rfh->GetLastCommittedURL().spec());
   EXPECT_TRUE(main_rfh->GetLastCommittedOrigin().GetURL().SchemeIsFile());
 
@@ -915,7 +915,7 @@
 
   content::EvalJsResult result = content::EvalJs(
       embedder_contents, "history.pushState({}, {}, 'about:blank');");
-  EXPECT_EQ(std::string(), result.error);
+  EXPECT_TRUE(result.is_ok());
   EXPECT_EQ("about:blank", main_rfh->GetLastCommittedURL().spec());
   EXPECT_TRUE(main_rfh->GetLastCommittedURL().IsAboutBlank());
 
diff --git a/chrome/browser/predictors/preconnect_manager.h b/chrome/browser/predictors/preconnect_manager.h
index 2f6969e2..ee60acf 100644
--- a/chrome/browser/predictors/preconnect_manager.h
+++ b/chrome/browser/predictors/preconnect_manager.h
@@ -14,7 +14,11 @@
 #include "net/base/network_anonymization_key.h"
 #include "net/traffic_annotation/network_traffic_annotation.h"
 #include "services/network/public/mojom/connection_change_observer_client.mojom.h"
-#include "services/network/public/mojom/network_context.mojom.h"
+#include "url/gurl.h"
+
+namespace network::mojom {
+class NetworkContext;
+}
 
 namespace predictors {
 
diff --git a/chrome/browser/printing/web_api/web_printing_browsertest.cc b/chrome/browser/printing/web_api/web_printing_browsertest.cc
index 8d3e66f..3c1d6806 100644
--- a/chrome/browser/printing/web_api/web_printing_browsertest.cc
+++ b/chrome/browser/printing/web_api/web_printing_browsertest.cc
@@ -411,8 +411,9 @@
     })();
   )";
 
-  ASSERT_THAT(EvalJs(app_frame(), kGetPrintersScript).error,
-              testing::HasSubstr("User denied access"));
+  ASSERT_THAT(
+      EvalJs(app_frame(), kGetPrintersScript),
+      content::EvalJsResult::ErrorIs(testing::HasSubstr("User denied access")));
 }
 
 // Validate that further calls to printer's methods fail when content setting
@@ -445,8 +446,9 @@
       await printer.fetchAttributes();
     })();
   )";
-  ASSERT_THAT(EvalJs(app_frame(), kFetchAttributesScript).error,
-              testing::HasSubstr("User denied access"));
+  ASSERT_THAT(
+      EvalJs(app_frame(), kFetchAttributesScript),
+      content::EvalJsResult::ErrorIs(testing::HasSubstr("User denied access")));
 
   // Ensure that `printer.printJob()` reports access denied.
   constexpr std::string_view kPrintJobScript = R"(
@@ -469,8 +471,9 @@
       const printJob = await printer.printJob("Fail", { data: pdfBlob }, {});
     })();
   )";
-  ASSERT_THAT(EvalJs(app_frame(), kPrintJobScript).error,
-              testing::HasSubstr("User denied access"));
+  ASSERT_THAT(
+      EvalJs(app_frame(), kPrintJobScript),
+      content::EvalJsResult::ErrorIs(testing::HasSubstr("User denied access")));
 }
 
 IN_PROC_BROWSER_TEST_F(WebPrintingBrowserTest, CancelImmediately) {
diff --git a/chrome/browser/resources/settings/settings_main/settings_main.html b/chrome/browser/resources/settings/settings_main/settings_main.html
index 2f4806dc..e33bd57 100644
--- a/chrome/browser/resources/settings/settings_main/settings_main.html
+++ b/chrome/browser/resources/settings/settings_main/settings_main.html
@@ -67,14 +67,16 @@
     </div>
   </template>
 
-  <div slot="view" id="old">
-    <template is="dom-if" if="[[renderPlugin_(
-        routes_.PRIVACY, lastRoute_, inSearchMode_)]]">
-      <settings-basic-page class="cr-centered-card-container"
-          prefs="{{prefs}}" in-search-mode="[[inSearchMode_]]">
-      </settings-basic-page>
-    </template>
-  </div>
+  <template is="dom-if" if="[[showPage_(pageVisibility_.privacy)]]">
+    <div slot="view" id="privacy">
+      <template is="dom-if" if="[[renderPlugin_(
+          routes_.PRIVACY, lastRoute_, inSearchMode_)]]">
+        <settings-basic-page class="cr-centered-card-container"
+            prefs="{{prefs}}" in-search-mode="[[inSearchMode_]]">
+        </settings-basic-page>
+      </template>
+    </div>
+  </template>
 
   <template is="dom-if" if="[[showPage_(pageVisibility_.autofill)]]">
     <div slot="view" id="autofill">
diff --git a/chrome/browser/resources/settings/settings_main/settings_main.ts b/chrome/browser/resources/settings/settings_main/settings_main.ts
index 1fb97aa..5abd2dbc 100644
--- a/chrome/browser/resources/settings/settings_main/settings_main.ts
+++ b/chrome/browser/resources/settings/settings_main/settings_main.ts
@@ -182,16 +182,6 @@
 
     this.lastRoute_ = effectiveRoute;
 
-    if (!effectiveRoute.hasMigratedToPlugin) {
-      // Case where the requested section still resides within the old
-      // <settings-basic-page> element. Show that element, and let it handle
-      // showing the correct content.
-      this.$.switcher.switchView('old', 'no-animation', 'no-animation');
-      return;
-    }
-
-    // Case where the requested section has migrated to the new "plugin"
-    // architecture.
     const newSection = effectiveRoute.section;
     let sectionElement = this.$.switcher.querySelector(`#${newSection}`);
     if (!sectionElement) {
diff --git a/chrome/browser/safe_browsing/download_protection/deep_scanning_browsertest.cc b/chrome/browser/safe_browsing/download_protection/deep_scanning_browsertest.cc
index f87a5d7..c6f5941 100644
--- a/chrome/browser/safe_browsing/download_protection/deep_scanning_browsertest.cc
+++ b/chrome/browser/safe_browsing/download_protection/deep_scanning_browsertest.cc
@@ -1721,7 +1721,7 @@
   ASSERT_THAT(result, content::EvalJsResult::IsError());
 
   // TODO(crbug.com/407065784): Improve error message for SB checks.
-  EXPECT_EQ(result.error,
+  EXPECT_EQ(result.ExtractError(),
             "a JavaScript error: \"AbortError: Blocked by Safe Browsing.\"\n");
 
   // File is created but remains empty due to block.
diff --git a/chrome/browser/speech/extension_api/tts_extension_api.cc b/chrome/browser/speech/extension_api/tts_extension_api.cc
index eba60f2..bc7412ef 100644
--- a/chrome/browser/speech/extension_api/tts_extension_api.cc
+++ b/chrome/browser/speech/extension_api/tts_extension_api.cc
@@ -7,6 +7,7 @@
 #include <stddef.h>
 
 #include <memory>
+#include <set>
 #include <string>
 #include <utility>
 
@@ -114,75 +115,63 @@
 
 namespace extensions {
 
-// One of these is constructed for each utterance, and deleted
-// when the utterance gets any final event.
+namespace {
+
+// One of these is constructed for each utterance, and deleted when the
+// utterance gets any final event.
 class TtsExtensionEventHandler : public content::UtteranceEventDelegate {
  public:
-  explicit TtsExtensionEventHandler(const std::string& src_extension_id);
+  explicit TtsExtensionEventHandler(const std::string& extension_id)
+      : extension_id_(extension_id) {}
 
   void OnTtsEvent(content::TtsUtterance* utterance,
                   content::TtsEventType event_type,
                   int char_index,
                   int length,
-                  const std::string& error_message) override;
+                  const std::string& error_message) override {
+    if (utterance->GetSrcId() < 0) {
+      return;
+    }
+
+    const std::set<content::TtsEventType>& desired_event_types =
+        utterance->GetDesiredEventTypes();
+    if (!desired_event_types.empty() &&
+        desired_event_types.find(event_type) == desired_event_types.end()) {
+      return;
+    }
+
+    base::Value::Dict details;
+    if (char_index >= 0) {
+      details.Set(constants::kCharIndexKey, char_index);
+    }
+    if (length >= 0) {
+      details.Set(constants::kLengthKey, length);
+    }
+    details.Set(constants::kEventTypeKey, TtsEventTypeToString(event_type));
+    if (event_type == content::TTS_EVENT_ERROR) {
+      details.Set(constants::kErrorMessageKey, error_message);
+    }
+    details.Set(constants::kSrcIdKey, utterance->GetSrcId());
+    details.Set(constants::kIsFinalEventKey, utterance->IsFinished());
+
+    base::Value::List arguments;
+    arguments.Append(std::move(details));
+
+    auto event = std::make_unique<extensions::Event>(
+        ::extensions::events::TTS_ON_EVENT, ::events::kOnEvent,
+        std::move(arguments), utterance->GetBrowserContext());
+    event->event_url = utterance->GetSrcUrl();
+    extensions::EventRouter::Get(utterance->GetBrowserContext())
+        ->DispatchEventToExtension(extension_id_, std::move(event));
+  }
 
  private:
   // The extension ID of the extension that called speak() and should
   // receive events.
-  std::string src_extension_id_;
+  const std::string extension_id_;
 };
 
-TtsExtensionEventHandler::TtsExtensionEventHandler(
-    const std::string& src_extension_id)
-    : src_extension_id_(src_extension_id) {
-}
-
-void TtsExtensionEventHandler::OnTtsEvent(content::TtsUtterance* utterance,
-                                          content::TtsEventType event_type,
-                                          int char_index,
-                                          int length,
-                                          const std::string& error_message) {
-  if (utterance->GetSrcId() < 0) {
-    if (utterance->IsFinished())
-      delete this;
-    return;
-  }
-
-  const std::set<content::TtsEventType>& desired_event_types =
-      utterance->GetDesiredEventTypes();
-  if (!desired_event_types.empty() &&
-      desired_event_types.find(event_type) == desired_event_types.end()) {
-    if (utterance->IsFinished())
-      delete this;
-    return;
-  }
-
-  const char *event_type_string = TtsEventTypeToString(event_type);
-  base::Value::Dict details;
-  if (char_index >= 0)
-    details.Set(constants::kCharIndexKey, char_index);
-  if (length >= 0)
-    details.Set(constants::kLengthKey, length);
-  details.Set(constants::kEventTypeKey, event_type_string);
-  if (event_type == content::TTS_EVENT_ERROR) {
-    details.Set(constants::kErrorMessageKey, error_message);
-  }
-  details.Set(constants::kSrcIdKey, utterance->GetSrcId());
-  details.Set(constants::kIsFinalEventKey, utterance->IsFinished());
-
-  base::Value::List arguments;
-  arguments.Append(std::move(details));
-
-  auto event = std::make_unique<extensions::Event>(
-      ::extensions::events::TTS_ON_EVENT, ::events::kOnEvent,
-      std::move(arguments), utterance->GetBrowserContext());
-  event->event_url = utterance->GetSrcUrl();
-  extensions::EventRouter::Get(utterance->GetBrowserContext())
-      ->DispatchEventToExtension(src_extension_id_, std::move(event));
-
-  if (utterance->IsFinished())
-    delete this;
-}
+}  // namespace
 
 ExtensionFunction::ResponseAction TtsSpeakFunction::Run() {
   EXTENSION_FUNCTION_VALIDATE(args().size() >= 1);
@@ -326,8 +315,10 @@
   utterance->SetDesiredEventTypes(desired_event_types);
   utterance->SetEngineId(voice_extension_id);
   utterance->SetOptions(std::move(options));
-  if (extension())
-    utterance->SetEventDelegate(new TtsExtensionEventHandler(extension_id()));
+  if (extension()) {
+    utterance->SetEventDelegate(
+        std::make_unique<TtsExtensionEventHandler>(extension_id()));
+  }
 
   content::TtsController* controller = content::TtsController::GetInstance();
   controller->SpeakOrEnqueue(std::move(utterance));
diff --git a/chrome/browser/speech/extension_api/tts_extension_api.h b/chrome/browser/speech/extension_api/tts_extension_api.h
index 41f8448..55a7c7a 100644
--- a/chrome/browser/speech/extension_api/tts_extension_api.h
+++ b/chrome/browser/speech/extension_api/tts_extension_api.h
@@ -31,6 +31,7 @@
 class TtsSpeakFunction : public ExtensionFunction {
  private:
   ~TtsSpeakFunction() override = default;
+
   ResponseAction Run() override;
   DECLARE_EXTENSION_FUNCTION("tts.speak", TTS_SPEAK)
 };
diff --git a/chrome/browser/storage/shared_storage_browsertest.cc b/chrome/browser/storage/shared_storage_browsertest.cc
index 291e9af..2f177e60 100644
--- a/chrome/browser/storage/shared_storage_browsertest.cc
+++ b/chrome/browser/storage/shared_storage_browsertest.cc
@@ -1059,9 +1059,10 @@
 
   if (!SuccessExpected()) {
     // Shared Storage will be disabled.
-    EXPECT_TRUE(base::StartsWith(
-        result.error, GetSharedStorageAddModuleDisabledErrorMessage()));
-    VerifyDebugErrorMessage(result.error);
+    EXPECT_TRUE(
+        base::StartsWith(result.ExtractError(),
+                         GetSharedStorageAddModuleDisabledErrorMessage()));
+    VerifyDebugErrorMessage(result.ExtractError());
     EXPECT_EQ(0u, console_observer.messages().size());
 
     WaitForHistograms({kErrorTypeHistogram});
@@ -1130,9 +1131,9 @@
 
   if (!SuccessExpected()) {
     // Shared Storage will be disabled.
-    EXPECT_TRUE(base::StartsWith(run_op_result.error,
+    EXPECT_TRUE(base::StartsWith(run_op_result.ExtractError(),
                                  GetSharedStorageDisabledErrorMessage()));
-    VerifyDebugErrorMessage(run_op_result.error);
+    VerifyDebugErrorMessage(run_op_result.ExtractError());
 
     WaitForHistogramsWithSampleCounts(
         {std::make_tuple(kErrorTypeHistogram, 2)});
@@ -1236,9 +1237,9 @@
   if (!SuccessExpected()) {
     // Shared Storage will be disabled.
     EXPECT_TRUE(
-        base::StartsWith(run_url_op_result.error,
+        base::StartsWith(run_url_op_result.ExtractError(),
                          GetSharedStorageSelectURLDisabledErrorMessage()));
-    VerifyDebugErrorMessage(run_url_op_result.error);
+    VerifyDebugErrorMessage(run_url_op_result.ExtractError());
 
     WaitForHistogramsWithSampleCounts(
         {std::make_tuple(kErrorTypeHistogram, 2)});
@@ -1300,9 +1301,9 @@
 
   if (!SuccessExpected()) {
     // Shared Storage will be disabled.
-    EXPECT_TRUE(base::StartsWith(set_result.error,
+    EXPECT_TRUE(base::StartsWith(set_result.ExtractError(),
                                  GetSharedStorageDisabledErrorMessage()));
-    VerifyDebugErrorMessage(set_result.error);
+    VerifyDebugErrorMessage(set_result.ExtractError());
     return;
   }
 
@@ -1324,9 +1325,9 @@
 
   if (!SuccessExpected()) {
     // Shared Storage will be disabled.
-    EXPECT_TRUE(base::StartsWith(append_result.error,
+    EXPECT_TRUE(base::StartsWith(append_result.ExtractError(),
                                  GetSharedStorageDisabledErrorMessage()));
-    VerifyDebugErrorMessage(append_result.error);
+    VerifyDebugErrorMessage(append_result.ExtractError());
     return;
   }
 
@@ -1348,9 +1349,9 @@
 
   if (!SuccessExpected()) {
     // Shared Storage will be disabled.
-    EXPECT_TRUE(base::StartsWith(delete_result.error,
+    EXPECT_TRUE(base::StartsWith(delete_result.ExtractError(),
                                  GetSharedStorageDisabledErrorMessage()));
-    VerifyDebugErrorMessage(delete_result.error);
+    VerifyDebugErrorMessage(delete_result.ExtractError());
     return;
   }
 
@@ -1372,9 +1373,9 @@
 
   if (!SuccessExpected()) {
     // Shared Storage will be disabled.
-    EXPECT_TRUE(base::StartsWith(clear_result.error,
+    EXPECT_TRUE(base::StartsWith(clear_result.ExtractError(),
                                  GetSharedStorageDisabledErrorMessage()));
-    VerifyDebugErrorMessage(clear_result.error);
+    VerifyDebugErrorMessage(clear_result.ExtractError());
     return;
   }
 
@@ -2253,7 +2254,7 @@
                     "    at __const_std::string&_script__:1:24):\n",
                     "        {sharedStorage.worklet.addModule(\"", invalid_url,
                     "\")\n", "                               ^^^^^\n"}),
-      result.error);
+      result.ExtractError());
 
   WaitForHistograms({kErrorTypeHistogram});
   histogram_tester_.ExpectUniqueSample(
@@ -2274,7 +2275,7 @@
   EXPECT_EQ(
       base::StrCat({"a JavaScript error: \"OperationError: Failed to load ",
                     script_url.spec(), " HTTP status = 404 Not Found.\"\n"}),
-      result.error);
+      result.ExtractError());
 
   WaitForHistograms({kErrorTypeHistogram});
   histogram_tester_.ExpectUniqueSample(
@@ -2296,7 +2297,7 @@
       base::StrCat(
           {"a JavaScript error: \"OperationError: Unexpected redirect on ",
            script_url.spec(), ".\"\n"}),
-      result.error);
+      result.ExtractError());
 
   WaitForHistograms({kErrorTypeHistogram});
   histogram_tester_.ExpectUniqueSample(
@@ -2951,8 +2952,8 @@
           "sharedStorage.createWorklet($1, {dataOrigin: 'script-origin'})",
           script_url));
 
-  EXPECT_TRUE(base::StartsWith(
-      result.error, GetSharedStorageAddModuleDisabledErrorMessage()));
+  EXPECT_THAT(result, content::EvalJsResult::ErrorIs(testing::StartsWith(
+                          GetSharedStorageAddModuleDisabledErrorMessage())));
 
   EXPECT_EQ(0u, content::GetAttachedSharedStorageWorkletHostsCount(
                     GetActiveWebContents()
@@ -3030,7 +3031,7 @@
           script_url));
 
   EXPECT_TRUE(base::StartsWith(
-      result.error, GetSharedStorageAddModuleDisabledErrorMessage()));
+      result.ExtractError(), GetSharedStorageAddModuleDisabledErrorMessage()));
 
   EXPECT_EQ(0u, content::GetAttachedSharedStorageWorkletHostsCount(
                     GetActiveWebContents()
@@ -3084,7 +3085,7 @@
       )");
 
   EXPECT_TRUE(base::StartsWith(
-      result.error, GetSharedStorageSelectURLDisabledErrorMessage()));
+      result.ExtractError(), GetSharedStorageSelectURLDisabledErrorMessage()));
 
   WaitForHistograms({kErrorTypeHistogram});
   histogram_tester_.ExpectBucketCount(
@@ -3184,8 +3185,8 @@
         window.testWorklet.run('test-operation')
       )");
 
-  EXPECT_TRUE(
-      base::StartsWith(result.error, GetSharedStorageDisabledErrorMessage()));
+  EXPECT_TRUE(base::StartsWith(result.ExtractError(),
+                               GetSharedStorageDisabledErrorMessage()));
 
   WaitForHistograms({kErrorTypeHistogram});
   histogram_tester_.ExpectBucketCount(
@@ -3402,7 +3403,7 @@
       content::JsReplace("sharedStorage.createWorklet($1)", script_url));
 
   EXPECT_TRUE(base::StartsWith(
-      result.error, GetSharedStorageAddModuleDisabledErrorMessage()));
+      result.ExtractError(), GetSharedStorageAddModuleDisabledErrorMessage()));
 
   EXPECT_EQ(0u, content::GetAttachedSharedStorageWorkletHostsCount(
                     GetActiveWebContents()
@@ -3441,7 +3442,7 @@
                                                                  script_url));
 
   EXPECT_TRUE(base::StartsWith(
-      result.error, GetSharedStorageAddModuleDisabledErrorMessage()));
+      result.ExtractError(), GetSharedStorageAddModuleDisabledErrorMessage()));
 
   EXPECT_EQ(0u, content::GetAttachedSharedStorageWorkletHostsCount(
                     GetActiveWebContents()
@@ -3548,7 +3549,7 @@
           script_url));
 
   EXPECT_TRUE(base::StartsWith(
-      result.error, GetSharedStorageAddModuleDisabledErrorMessage()));
+      result.ExtractError(), GetSharedStorageAddModuleDisabledErrorMessage()));
 
   EXPECT_EQ(0u, content::GetAttachedSharedStorageWorkletHostsCount(
                     GetActiveWebContents()
@@ -3587,7 +3588,7 @@
                                                                  script_url));
 
   EXPECT_TRUE(base::StartsWith(
-      result.error, GetSharedStorageAddModuleDisabledErrorMessage()));
+      result.ExtractError(), GetSharedStorageAddModuleDisabledErrorMessage()));
 
   EXPECT_EQ(0u, content::GetAttachedSharedStorageWorkletHostsCount(
                     GetActiveWebContents()
@@ -3693,7 +3694,7 @@
       content::JsReplace("sharedStorage.worklet.addModule($1)", script_url));
 
   EXPECT_TRUE(base::StartsWith(
-      result.error, GetSharedStorageAddModuleDisabledErrorMessage()));
+      result.ExtractError(), GetSharedStorageAddModuleDisabledErrorMessage()));
 
   EXPECT_EQ(0u, content::GetAttachedSharedStorageWorkletHostsCount(
                     GetActiveWebContents()
@@ -3732,7 +3733,7 @@
       content::JsReplace("sharedStorage.worklet.addModule($1)", script_url));
 
   EXPECT_TRUE(base::StartsWith(
-      result.error, GetSharedStorageAddModuleDisabledErrorMessage()));
+      result.ExtractError(), GetSharedStorageAddModuleDisabledErrorMessage()));
 
   EXPECT_EQ(0u, content::GetAttachedSharedStorageWorkletHostsCount(
                     GetActiveWebContents()
@@ -3768,7 +3769,7 @@
       content::JsReplace("sharedStorage.worklet.addModule($1)", script_url));
 
   EXPECT_TRUE(base::StartsWith(
-      result.error, GetSharedStorageAddModuleDisabledErrorMessage()));
+      result.ExtractError(), GetSharedStorageAddModuleDisabledErrorMessage()));
 
   EXPECT_EQ(0u, content::GetAttachedSharedStorageWorkletHostsCount(
                     GetActiveWebContents()
@@ -4778,9 +4779,9 @@
     histogram_tester_.ExpectTotalCount(kTimingDocumentSetHistogram, 1);
   } else {
     // Shared Storage will be disabled.
-    EXPECT_TRUE(base::StartsWith(set_result.error,
+    EXPECT_TRUE(base::StartsWith(set_result.ExtractError(),
                                  GetSharedStorageDisabledErrorMessage()));
-    VerifyDebugErrorMessage(set_result.error);
+    VerifyDebugErrorMessage(set_result.ExtractError());
   }
 
   // Set up console observer.
@@ -4799,12 +4800,13 @@
     // Fenced storage read is disabled when untrusted network access is not
     // revoked.
     ASSERT_FALSE(get_result.is_ok());
-    EXPECT_TRUE(base::StartsWith(
-        get_result.error, GetFencedStorageReadWithoutRevokeNetworkMessage()));
+    EXPECT_TRUE(
+        base::StartsWith(get_result.ExtractError(),
+                         GetFencedStorageReadWithoutRevokeNetworkMessage()));
     EXPECT_TRUE(console_observer.messages().empty());
   } else if (!AllowThirdPartyCookies()) {
     // Fenced storage read is disabled. A JavaScript error is shown.
-    EXPECT_TRUE(base::StartsWith(get_result.error,
+    EXPECT_TRUE(base::StartsWith(get_result.ExtractError(),
                                  GetFencedStorageReadDisabledMessage()));
 
     // Fenced storage read is disabled when all third party cookies are blocked.
@@ -4817,7 +4819,7 @@
              EnforcementAndEnrollmentStatus::
                  kAttestationsEnforcedMainHostUnenrolled) {
     // Fenced storage read is disabled. A JavaScript error is shown.
-    EXPECT_TRUE(base::StartsWith(get_result.error,
+    EXPECT_TRUE(base::StartsWith(get_result.ExtractError(),
                                  GetFencedStorageReadDisabledMessage()));
 
     // Fenced storage read is disabled when the accessing site is not enrolled.
@@ -4831,7 +4833,7 @@
   } else {
     // Fenced storage read is disabled. A JavaScript error is shown.
     ASSERT_FALSE(EnablePrivacySandbox());
-    EXPECT_TRUE(base::StartsWith(get_result.error,
+    EXPECT_TRUE(base::StartsWith(get_result.ExtractError(),
                                  GetFencedStorageReadDisabledMessage()));
   }
 }
@@ -4862,9 +4864,9 @@
     histogram_tester_.ExpectTotalCount(kTimingDocumentSetHistogram, 1);
   } else {
     // Shared Storage will be disabled.
-    EXPECT_TRUE(base::StartsWith(set_result.error,
+    EXPECT_TRUE(base::StartsWith(set_result.ExtractError(),
                                  GetSharedStorageDisabledErrorMessage()));
-    VerifyDebugErrorMessage(set_result.error);
+    VerifyDebugErrorMessage(set_result.ExtractError());
   }
 
   // Set up console observer.
@@ -4893,7 +4895,7 @@
     histogram_tester_.ExpectTotalCount(kTimingDocumentGetHistogram, 1);
   } else if (!AllowThirdPartyCookies()) {
     // Fenced storage read is disabled. A JavaScript error is shown.
-    EXPECT_TRUE(base::StartsWith(get_result.error,
+    EXPECT_TRUE(base::StartsWith(get_result.ExtractError(),
                                  GetFencedStorageReadDisabledMessage()));
 
     // Fenced storage read is disabled when all third party cookies are blocked.
@@ -4906,7 +4908,7 @@
              EnforcementAndEnrollmentStatus::
                  kAttestationsEnforcedMainHostUnenrolled) {
     // Fenced storage read is disabled. A JavaScript error is shown.
-    EXPECT_TRUE(base::StartsWith(get_result.error,
+    EXPECT_TRUE(base::StartsWith(get_result.ExtractError(),
                                  GetFencedStorageReadDisabledMessage()));
 
     // Fenced storage read is disabled when the accessing site is not enrolled.
@@ -4921,7 +4923,7 @@
     // Fenced storage read is disabled. A JavaScript
     // error is shown.
     ASSERT_FALSE(EnablePrivacySandbox());
-    EXPECT_TRUE(base::StartsWith(get_result.error,
+    EXPECT_TRUE(base::StartsWith(get_result.ExtractError(),
                                  GetFencedStorageReadDisabledMessage()));
   }
 }
diff --git a/chrome/browser/tpcd/experiment/tpcd_mitigations_browsertest.cc b/chrome/browser/tpcd/experiment/tpcd_mitigations_browsertest.cc
index 98c7a63..da5e4074 100644
--- a/chrome/browser/tpcd/experiment/tpcd_mitigations_browsertest.cc
+++ b/chrome/browser/tpcd/experiment/tpcd_mitigations_browsertest.cc
@@ -114,12 +114,11 @@
                               "localStorage.getItem(\"UnpartitionedLocal\")"),
               "Hello");
   } else {
-    EXPECT_THAT(
-        content::EvalJs(GetChildFrame(),
-                        "localStorage.getItem(\"UnpartitionedLocal\")")
-            .error,
-        HasSubstr("Error: Failed to read the 'localStorage' property from "
-                  "'Window': Access is denied for this document."));
+    EXPECT_THAT(content::EvalJs(GetChildFrame(),
+                                "localStorage.getItem(\"UnpartitionedLocal\")"),
+                content::EvalJsResult::ErrorIs(HasSubstr(
+                    "Error: Failed to read the 'localStorage' property from "
+                    "'Window': Access is denied for this document.")));
   }
 }
 
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index 24f480b..af0a94c 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -1641,6 +1641,8 @@
       "//chrome/browser/ui/webui/util",
       "//chrome/browser/ui/webui/whats_new",
       "//chrome/browser/ui/webui/whats_new:impl",
+      "//chrome/browser/ui/webui_browser",
+      "//chrome/browser/ui/webui_browser:impl",
       "//chrome/browser/ui/window_sizer",
       "//chrome/browser/ui/window_sizer:impl",
       "//chrome/browser/web_applications",
@@ -1790,6 +1792,8 @@
       "//chrome/browser/ui/views/new_tab_footer",
       "//chrome/browser/ui/webui/searchbox",
       "//chrome/browser/ui/webui/top_chrome:impl",
+      "//chrome/browser/ui/webui_browser",
+      "//chrome/browser/ui/webui_browser:impl",
       "//chrome/browser/ui/search:impl",
 
       # TODO(crbug.com/382237520): Remove this once NTP code is modularized.
@@ -1917,7 +1921,10 @@
 
     public_deps += [ "//chrome/browser/ui/supervised_user" ]
 
-    deps += [ "//chromeos/ui/vector_icons" ]
+    deps += [
+      "//chrome/browser/extensions/api/web_navigation",
+      "//chromeos/ui/vector_icons",
+    ]
   }
 
   if (is_chromeos) {
diff --git a/chrome/browser/ui/README.md b/chrome/browser/ui/README.md
index 240d403..e6e20e8 100644
--- a/chrome/browser/ui/README.md
+++ b/chrome/browser/ui/README.md
@@ -14,6 +14,8 @@
             //chrome/browser/android.
 * webui - the WebUI parts of the browser UI. This includes things like the
           chrome://settings page and other WebUI pages.
+* webui_browser - an experimental browser UI written in WebUI. It still uses
+          views for windowing management and secondary UIs.
 
 Historically, the goal of this directory was to be platform agnostic, with
 platform-specific logic in the above sub-directories. This didn't work and
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_lt.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_lt.xtb
index bf9accd..a33f6a0d 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_lt.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_lt.xtb
@@ -1641,6 +1641,7 @@
 <translation id="8207867836430106322">{NUM_OTHER_MEMBERS,plural, =1{Prisijungimas prie skirtukų grupės su <ph name="OWNER_FIRST_NAME" /> ir dar <ph name="NUMBER_OF_OTHER_MEMBERS" /> asmeniu}one{Prisijungimas prie skirtukų grupės su <ph name="OWNER_FIRST_NAME" /> ir dar <ph name="NUMBER_OF_OTHER_MEMBERS" /> asmeniu}few{Prisijungimas prie skirtukų grupės su <ph name="OWNER_FIRST_NAME" /> ir dar <ph name="NUMBER_OF_OTHER_MEMBERS" /> asmenimis}many{Prisijungimas prie skirtukų grupės su <ph name="OWNER_FIRST_NAME" /> ir dar <ph name="NUMBER_OF_OTHER_MEMBERS" /> asmens}other{Prisijungimas prie skirtukų grupės su <ph name="OWNER_FIRST_NAME" /> ir dar <ph name="NUMBER_OF_OTHER_MEMBERS" /> asmenų}}</translation>
 <translation id="8209050860603202033">Atidaryti vaizdą</translation>
 <translation id="8210770465353466621">Čia rasite skirtukus</translation>
+<translation id="8212799748012101103">Atidaryti skirtukų paiešką</translation>
 <translation id="8215740705341534369">Šoninis lapas</translation>
 <translation id="8218622182176210845">Paskyros tvarkymas</translation>
 <translation id="8221401890884589479">Galite užblokuoti nepageidaujamas svetaines. „Chrome“ taip pat iš sąrašo automatiškai ištrina senesnes nei trisdešimt dienų svetaines. <ph name="BEGIN_LINK" />Sužinokite daugiau<ph name="END_LINK" /></translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_my.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_my.xtb
index fe25bb46..93bfe9e 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_my.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_my.xtb
@@ -1460,7 +1460,7 @@
 <translation id="7455988709578031708">သင်၏ကြည့်ရှုမှုမှတ်တမ်းကို အခြေခံထားသည်။ ဤဆက်တင်ကို ဖွင့်ထားသည်။</translation>
 <translation id="7456774706094330779">တိုးချဲ့ထားသော ကြိုဖွင့်မှု</translation>
 <translation id="7466328545712777810">ဝဘ်ဆိုက်တစ်ခုခုတွင် ဈေးကျသွားပါက အကြောင်းကြားချက် ရရှိပါမည်</translation>
-<translation id="7466431077154602932">ကျစ်ကျစ်လျစ်လျစ်ပြသခြင်း</translation>
+<translation id="7466431077154602932">ကျစ်လျစ်ပြကွက်</translation>
 <translation id="7474822150871987353">စာမျက်နှာမှမထွက်ဘဲ ဝဘ်ဆိုက်များရှိ အကြောင်းအရာများအကြောင်း လေ့လာနိုင်သည်။ စာမျက်နှာရှိ စကားလုံးတစ်လုံးနှင့်အထက်ကို ရှာဖွေရန် ရွေးနိုင်သည်။</translation>
 <translation id="7475192538862203634">သင်သည် ဒါကို မကြာခဏ မြင်နေရလျှင်၊ <ph name="BEGIN_LINK" />အကြံပြုချက်များ<ph name="END_LINK" />ကို စမ်းကြည့်ပါ။</translation>
 <translation id="7475688122056506577">SD ကတ် မတွေ့ပါ။ သင့်ဖိုင်အချို့ ပျောက်နေနိုင်ပါသည်။</translation>
diff --git a/chrome/browser/ui/ash/arc/arc_open_url_delegate_impl.cc b/chrome/browser/ui/ash/arc/arc_open_url_delegate_impl.cc
index 55e7600..702c405 100644
--- a/chrome/browser/ui/ash/arc/arc_open_url_delegate_impl.cc
+++ b/chrome/browser/ui/ash/arc/arc_open_url_delegate_impl.cc
@@ -231,7 +231,7 @@
   }
 
   GURL url_to_open = ConvertArcUrlToExternalFileUrlIfNeeded(url);
-  ash::NewWindowDelegate::GetPrimary()->OpenUrl(
+  ash::NewWindowDelegate::GetInstance()->OpenUrl(
       url_to_open, ash::NewWindowDelegate::OpenUrlFrom::kArc,
       ash::NewWindowDelegate::Disposition::kNewForegroundTab);
 }
diff --git a/chrome/browser/ui/ash/assistant/assistant_browser_delegate_impl.cc b/chrome/browser/ui/ash/assistant/assistant_browser_delegate_impl.cc
index 4eaa75e3..e6f498cb 100644
--- a/chrome/browser/ui/ash/assistant/assistant_browser_delegate_impl.cc
+++ b/chrome/browser/ui/ash/assistant/assistant_browser_delegate_impl.cc
@@ -303,7 +303,7 @@
   // such, the browser will always be instructed to open |url| in a new
   // browser tab and Assistant UI state will be updated downstream to respect
   // |in_background|.
-  ash::NewWindowDelegate::GetPrimary()->OpenUrl(
+  ash::NewWindowDelegate::GetInstance()->OpenUrl(
       url, ash::NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       ash::NewWindowDelegate::Disposition::kNewForegroundTab);
 }
diff --git a/chrome/browser/ui/ash/google_one/google_one_offer_iph_tab_helper.cc b/chrome/browser/ui/ash/google_one/google_one_offer_iph_tab_helper.cc
index dd43643..0b789243 100644
--- a/chrome/browser/ui/ash/google_one/google_one_offer_iph_tab_helper.cc
+++ b/chrome/browser/ui/ash/google_one/google_one_offer_iph_tab_helper.cc
@@ -50,7 +50,7 @@
       return;
     }
 
-    ash::NewWindowDelegate::GetPrimary()->OpenUrl(
+    ash::NewWindowDelegate::GetInstance()->OpenUrl(
         GURL(kGoogleOneOfferUrl),
         ash::NewWindowDelegate::OpenUrlFrom::kUserInteraction,
         ash::NewWindowDelegate::Disposition::kNewForegroundTab);
diff --git a/chrome/browser/ui/ash/network/network_portal_signin_controller.cc b/chrome/browser/ui/ash/network/network_portal_signin_controller.cc
index e639fc3..0ab3272b 100644
--- a/chrome/browser/ui/ash/network/network_portal_signin_controller.cc
+++ b/chrome/browser/ui/ash/network/network_portal_signin_controller.cc
@@ -303,7 +303,7 @@
 
 void NetworkPortalSigninController::ShowSigninWindow(const GURL& url) {
   // Calls NetworkPortalSigninWindow::Show in the appropriate browser.
-  ash::NewWindowDelegate::GetPrimary()->OpenCaptivePortalSignin(url);
+  ash::NewWindowDelegate::GetInstance()->OpenCaptivePortalSignin(url);
 }
 
 void NetworkPortalSigninController::ShowTab(Profile* profile, const GURL& url) {
@@ -324,7 +324,7 @@
 
 void NetworkPortalSigninController::ShowActiveProfileTab(const GURL& url) {
   // Opens a new tab the appropriate browser.
-  ash::NewWindowDelegate::GetPrimary()->OpenUrl(
+  ash::NewWindowDelegate::GetInstance()->OpenUrl(
       url, NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       NewWindowDelegate::Disposition::kNewForegroundTab);
 }
diff --git a/chrome/browser/ui/ash/projector/screencast_manager_browsertest.cc b/chrome/browser/ui/ash/projector/screencast_manager_browsertest.cc
index 7c48722..f2ecd709 100644
--- a/chrome/browser/ui/ash/projector/screencast_manager_browsertest.cc
+++ b/chrome/browser/ui/ash/projector/screencast_manager_browsertest.cc
@@ -421,7 +421,7 @@
       "a JavaScript error: \"Failed to fetch DriveFS file with video file "
       "id=%s and error code=%d\"\n",
       kVideoFileId, drive::FILE_ERROR_NOT_FOUND);
-  EXPECT_EQ(result.error, expected_error);
+  EXPECT_EQ(result.ExtractError(), expected_error);
 }
 
 // Tests a disk I/O error when trying to access the file handle in launch.js.
@@ -444,7 +444,7 @@
   const std::string& script = base::StringPrintf(kGetVideoScript, kVideoFileId);
   content::EvalJsResult result = EvalJs(app, script);
   EXPECT_EQ(
-      result.error,
+      result.ExtractError(),
       "a JavaScript error: \"NotFoundError: A requested file or directory "
       "could not be found at the time an operation was processed.\"\n");
 }
@@ -468,7 +468,8 @@
 
   const std::string& script = base::StringPrintf(kGetVideoScript, kVideoFileId);
   content::EvalJsResult result = EvalJs(app, script);
-  EXPECT_EQ(result.error, "a JavaScript error: \"NotAVideo: Not a video.\"\n");
+  EXPECT_EQ(result.ExtractError(),
+            "a JavaScript error: \"NotAVideo: Not a video.\"\n");
 }
 
 #endif  // !BUILDFLAG(ENABLE_CROS_PROJECTOR_APP)
diff --git a/chrome/browser/ui/ash/quick_answers/quick_answers_ui_controller.cc b/chrome/browser/ui/ash/quick_answers/quick_answers_ui_controller.cc
index 7d90b0c..07e4cdf1 100644
--- a/chrome/browser/ui/ash/quick_answers/quick_answers_ui_controller.cc
+++ b/chrome/browser/ui/ash/quick_answers/quick_answers_ui_controller.cc
@@ -52,7 +52,7 @@
 
 // Open the specified URL in a new tab with the specified profile
 void OpenUrl(Profile* profile, const GURL& url) {
-  ash::NewWindowDelegate::GetPrimary()->OpenUrl(
+  ash::NewWindowDelegate::GetInstance()->OpenUrl(
       url, ash::NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       ash::NewWindowDelegate::Disposition::kNewForegroundTab);
 }
@@ -384,7 +384,7 @@
 
   // TODO(b/229007013, crbug.com/374253370): Merge the logics after resolve the
   // deps cycle with //c/b/ui in ash chrome build.
-  ash::NewWindowDelegate::GetPrimary()->OpenFeedbackPage(
+  ash::NewWindowDelegate::GetInstance()->OpenFeedbackPage(
       ash::NewWindowDelegate::FeedbackSource::kFeedbackSourceQuickAnswers,
       feedback_template);
 }
diff --git a/chrome/browser/ui/ash/quick_answers/ui/quick_answers_util.cc b/chrome/browser/ui/ash/quick_answers/ui/quick_answers_util.cc
index 8f21d61..31fe7bb 100644
--- a/chrome/browser/ui/ash/quick_answers/ui/quick_answers_util.cc
+++ b/chrome/browser/ui/ash/quick_answers/ui/quick_answers_util.cc
@@ -75,10 +75,6 @@
           quick_answers::TtsEngineEvent::TTS_EVENT_OTHER);
       break;
   }
-
-  if (utterance->IsFinished()) {
-    delete this;
-  }
 }
 
 gfx::FontList GetFontList(TypographyToken token) {
@@ -232,7 +228,8 @@
   // TtsController will use the default TTS engine if the Google TTS engine
   // is not available.
   tts_utterance->SetEngineId(kGoogleTtsEngineId);
-  tts_utterance->SetEventDelegate(new QuickAnswersUtteranceEventDelegate());
+  tts_utterance->SetEventDelegate(
+      std::make_unique<QuickAnswersUtteranceEventDelegate>());
 
   tts_controller->SpeakOrEnqueue(std::move(tts_utterance));
 }
diff --git a/chrome/browser/ui/ash/sharesheet/sharesheet_bubble_view_unittest.cc b/chrome/browser/ui/ash/sharesheet/sharesheet_bubble_view_unittest.cc
index a1883b31..39efe80 100644
--- a/chrome/browser/ui/ash/sharesheet/sharesheet_bubble_view_unittest.cc
+++ b/chrome/browser/ui/ash/sharesheet/sharesheet_bubble_view_unittest.cc
@@ -590,7 +590,7 @@
 
   // Make sure the drive action was invoked.
   auto* delegate = static_cast<::TestNewWindowDelegate*>(
-      ash::NewWindowDelegate::GetPrimary());
+      ash::NewWindowDelegate::GetInstance());
   auto url = delegate->retrieve_url();
   ASSERT_TRUE(url.has_value());
   EXPECT_EQ(drive_share_url, *url);
diff --git a/chrome/browser/ui/ash/shell_delegate/chrome_shell_delegate.cc b/chrome/browser/ui/ash/shell_delegate/chrome_shell_delegate.cc
index b302f3cb..235c5e69 100644
--- a/chrome/browser/ui/ash/shell_delegate/chrome_shell_delegate.cc
+++ b/chrome/browser/ui/ash/shell_delegate/chrome_shell_delegate.cc
@@ -257,7 +257,7 @@
 }
 
 void ChromeShellDelegate::OpenKeyboardShortcutHelpPage() const {
-  ash::NewWindowDelegate::GetPrimary()->OpenUrl(
+  ash::NewWindowDelegate::GetInstance()->OpenUrl(
       GURL(kKeyboardShortcutHelpPageUrl),
       ash::NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       ash::NewWindowDelegate::Disposition::kNewForegroundTab);
diff --git a/chrome/browser/ui/ash/system/system_tray_client_impl.cc b/chrome/browser/ui/ash/system/system_tray_client_impl.cc
index b13ac30..2f8f28c 100644
--- a/chrome/browser/ui/ash/system/system_tray_client_impl.cc
+++ b/chrome/browser/ui/ash/system/system_tray_client_impl.cc
@@ -433,7 +433,7 @@
   // Settings/System Tray.
   ash::personalization_app::LogPersonalizationEntryPoint(
       ash::PersonalizationEntryPoint::kSystemTray);
-  ash::NewWindowDelegate::GetPrimary()->OpenPersonalizationHub();
+  ash::NewWindowDelegate::GetInstance()->OpenPersonalizationHub();
 }
 
 void SystemTrayClientImpl::ShowStorageSettings() {
@@ -902,7 +902,7 @@
 }
 
 void SystemTrayClientImpl::ShowEolInfoPage() {
-  ash::NewWindowDelegate::GetPrimary()->OpenUrl(
+  ash::NewWindowDelegate::GetInstance()->OpenUrl(
       GURL(chrome::kEolNotificationURL),
       ash::NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       ash::NewWindowDelegate::Disposition::kNewForegroundTab);
diff --git a/chrome/browser/ui/browser_tab_strip_tracker_delegate.h b/chrome/browser/ui/browser_tab_strip_tracker_delegate.h
index 66ef23a3..e32746f 100644
--- a/chrome/browser/ui/browser_tab_strip_tracker_delegate.h
+++ b/chrome/browser/ui/browser_tab_strip_tracker_delegate.h
@@ -5,12 +5,12 @@
 #ifndef CHROME_BROWSER_UI_BROWSER_TAB_STRIP_TRACKER_DELEGATE_H_
 #define CHROME_BROWSER_UI_BROWSER_TAB_STRIP_TRACKER_DELEGATE_H_
 
-class Browser;
+class BrowserWindowInterface;
 
 class BrowserTabStripTrackerDelegate {
  public:
   // Returns true if a TabStripModelObserver should be registered for |browser|.
-  virtual bool ShouldTrackBrowser(Browser* browser) = 0;
+  virtual bool ShouldTrackBrowser(BrowserWindowInterface* browser) = 0;
 
  protected:
   virtual ~BrowserTabStripTrackerDelegate() = default;
diff --git a/chrome/browser/ui/startup/default_browser_prompt/default_browser_prompt.cc b/chrome/browser/ui/startup/default_browser_prompt/default_browser_prompt.cc
index be9f414..28e608de 100644
--- a/chrome/browser/ui/startup/default_browser_prompt/default_browser_prompt.cc
+++ b/chrome/browser/ui/startup/default_browser_prompt/default_browser_prompt.cc
@@ -19,8 +19,7 @@
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
-#include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/browser_finder.h"
+#include "chrome/browser/ui/browser_window/public/browser_window_interface.h"
 #include "chrome/browser/ui/browser_window/public/browser_window_interface_iterator.h"
 #include "chrome/browser/ui/startup/default_browser_prompt/default_browser_infobar_delegate.h"
 #include "chrome/browser/ui/startup/default_browser_prompt/default_browser_prompt_manager.h"
diff --git a/chrome/browser/ui/startup/default_browser_prompt/default_browser_prompt_manager.cc b/chrome/browser/ui/startup/default_browser_prompt/default_browser_prompt_manager.cc
index 14f286e..aae9c84 100644
--- a/chrome/browser/ui/startup/default_browser_prompt/default_browser_prompt_manager.cc
+++ b/chrome/browser/ui/startup/default_browser_prompt/default_browser_prompt_manager.cc
@@ -14,10 +14,10 @@
 #include "base/timer/timer.h"
 #include "build/build_config.h"
 #include "chrome/browser/browser_process.h"
-#include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/browser_list.h"
+#include "chrome/browser/ui/browser_window/public/browser_window_interface.h"
 #include "chrome/browser/ui/startup/default_browser_prompt/default_browser_infobar_delegate.h"
 #include "chrome/browser/ui/startup/default_browser_prompt/default_browser_prompt_prefs.h"
+#include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/ui_features.h"
 #include "chrome/common/pref_names.h"
 #include "components/infobars/core/confirm_infobar_delegate.h"
@@ -170,10 +170,11 @@
   show_app_menu_item_ = show;
 }
 
-bool DefaultBrowserPromptManager::ShouldTrackBrowser(Browser* browser) {
-  return browser->is_type_normal() &&
-         !browser->profile()->IsIncognitoProfile() &&
-         !browser->profile()->IsGuestSession();
+bool DefaultBrowserPromptManager::ShouldTrackBrowser(
+    BrowserWindowInterface* browser) {
+  return browser->GetType() == BrowserWindowInterface::TYPE_NORMAL &&
+         !browser->GetProfile()->IsIncognitoProfile() &&
+         !browser->GetProfile()->IsGuestSession();
 }
 
 void DefaultBrowserPromptManager::OnTabStripModelChanged(
diff --git a/chrome/browser/ui/startup/default_browser_prompt/default_browser_prompt_manager.h b/chrome/browser/ui/startup/default_browser_prompt/default_browser_prompt_manager.h
index 14edf40e..41bfad19 100644
--- a/chrome/browser/ui/startup/default_browser_prompt/default_browser_prompt_manager.h
+++ b/chrome/browser/ui/startup/default_browser_prompt/default_browser_prompt_manager.h
@@ -64,7 +64,7 @@
   void SetAppMenuItemVisibility(bool show);
 
   // BrowserTabStripTrackerDelegate
-  bool ShouldTrackBrowser(Browser* browser) override;
+  bool ShouldTrackBrowser(BrowserWindowInterface* browser) override;
 
   // TabStripModelObserver:
   void OnTabStripModelChanged(
diff --git a/chrome/browser/ui/views/borealis/borealis_disallowed_dialog.cc b/chrome/browser/ui/views/borealis/borealis_disallowed_dialog.cc
index 87dc8e54..996b7588 100644
--- a/chrome/browser/ui/views/borealis/borealis_disallowed_dialog.cc
+++ b/chrome/browser/ui/views/borealis/borealis_disallowed_dialog.cc
@@ -127,7 +127,7 @@
       link_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
       link_label->SetCallback(base::BindRepeating(
           [](GURL url) {
-            ash::NewWindowDelegate::GetPrimary()->OpenUrl(
+            ash::NewWindowDelegate::GetInstance()->OpenUrl(
                 url, ash::NewWindowDelegate::OpenUrlFrom::kUserInteraction,
                 ash::NewWindowDelegate::Disposition::kNewForegroundTab);
           },
diff --git a/chrome/browser/ui/views/bruschetta/bruschetta_installer_view.cc b/chrome/browser/ui/views/bruschetta/bruschetta_installer_view.cc
index 13d54ee..a8984dd 100644
--- a/chrome/browser/ui/views/bruschetta/bruschetta_installer_view.cc
+++ b/chrome/browser/ui/views/bruschetta/bruschetta_installer_view.cc
@@ -220,7 +220,7 @@
   learn_more_url_ = bruschetta::GetLearnMoreUrl(profile_);
   link_label_->SetCallback(base::BindRepeating(
       [](GURL url) {
-        ash::NewWindowDelegate::GetPrimary()->OpenUrl(
+        ash::NewWindowDelegate::GetInstance()->OpenUrl(
             url, ash::NewWindowDelegate::OpenUrlFrom::kUserInteraction,
             ash::NewWindowDelegate::Disposition::kNewForegroundTab);
       },
diff --git a/chrome/browser/ui/views/frame/browser_window_factory.cc b/chrome/browser/ui/views/frame/browser_window_factory.cc
index 503a8e6..a0f3014 100644
--- a/chrome/browser/ui/views/frame/browser_window_factory.cc
+++ b/chrome/browser/ui/views/frame/browser_window_factory.cc
@@ -8,6 +8,8 @@
 #include "chrome/browser/ui/views/frame/browser_frame.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
 #include "chrome/browser/ui/views/frame/native_browser_frame_factory.h"
+#include "chrome/browser/ui/webui_browser/webui_browser.h"
+#include "chrome/browser/ui/webui_browser/webui_browser_window.h"
 #include "chrome/grit/branded_strings.h"
 #include "components/safe_browsing/core/browser/password_protection/metrics_util.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -34,6 +36,10 @@
     std::unique_ptr<Browser> browser,
     bool user_gesture,
     bool in_tab_dragging) {
+  if (webui_browser::IsWebUIBrowserEnabled()) {
+    return new WebUIBrowserWindow(std::move(browser));
+  }
+
 #if defined(USE_AURA)
   // Avoid generating too many occlusion tracking calculation events before this
   // function returns. The occlusion status will be computed only once once this
diff --git a/chrome/browser/ui/views/page_action/page_action_properties_provider.cc b/chrome/browser/ui/views/page_action/page_action_properties_provider.cc
index 0b016b0..3d0a1d0 100644
--- a/chrome/browser/ui/views/page_action/page_action_properties_provider.cc
+++ b/chrome/browser/ui/views/page_action/page_action_properties_provider.cc
@@ -71,7 +71,6 @@
             {
                 .histogram_name = "PwaInstall",
                 .type = PageActionIconType::kPwaInstall,
-                .element_identifier = kInstallPwaElementId,
             },
         },
         {
diff --git a/chrome/browser/ui/views/permissions/permission_bubble_interactive_uitest.cc b/chrome/browser/ui/views/permissions/permission_bubble_interactive_uitest.cc
index c6b3860..dea77e3a 100644
--- a/chrome/browser/ui/views/permissions/permission_bubble_interactive_uitest.cc
+++ b/chrome/browser/ui/views/permissions/permission_bubble_interactive_uitest.cc
@@ -5,6 +5,7 @@
 #include <memory>
 
 #include "base/run_loop.h"
+#include "base/test/run_until.h"
 #include "build/build_config.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
@@ -169,38 +170,13 @@
                        MAYBE_CmdWClosesWindow) {
   EXPECT_TRUE(browser()->window()->IsVisible());
 
-  class NoWidgetsWaiter : public views::WidgetObserver {
-   public:
-    NoWidgetsWaiter() {
-      EXPECT_NE(views::test::WidgetTest::GetAllWidgets().size(), 0U);
-      for (views::Widget* widget : views::test::WidgetTest::GetAllWidgets()) {
-        widget->AddObserver(this);
-      }
-    }
-
-    void Wait() {
-      run_loop_.Run();
-      EXPECT_EQ(views::test::WidgetTest::GetAllWidgets().size(), 0U);
-    }
-
-   private:
-    // views::WidgetObserver:
-    void OnWidgetDestroyed(views::Widget*) override {
-      if (views::test::WidgetTest::GetAllWidgets().empty()) {
-        run_loop_.Quit();
-      }
-    }
-
-    base::RunLoop run_loop_;
-  };
-
   // On Windows, the WM_NCDESTROY message triggering Widget destruction may not
   // have been processed by the time `SendAcceleratorSync` returns (only waits
   // for WM_KEYDOWN). For that reason, wait until there are no more widgets
   // instead of checking immediately that there are no more widgets.
-  NoWidgetsWaiter waiter;
   SendAcceleratorSync(ui::VKEY_W, false, false);
-  waiter.Wait();
+  EXPECT_TRUE(base::test::RunUntil(
+      [&] { return views::test::WidgetTest::GetAllWidgets().empty(); }));
 }
 
 #if BUILDFLAG(IS_MAC)
diff --git a/chrome/browser/ui/views/user_education/feature_promo_dialog_interactive_uitest.cc b/chrome/browser/ui/views/user_education/feature_promo_dialog_interactive_uitest.cc
index 3e620cac..1007756 100644
--- a/chrome/browser/ui/views/user_education/feature_promo_dialog_interactive_uitest.cc
+++ b/chrome/browser/ui/views/user_education/feature_promo_dialog_interactive_uitest.cc
@@ -17,7 +17,6 @@
 #include "chrome/browser/apps/app_service/app_registry_cache_waiter.h"
 #include "chrome/browser/banners/test_app_banner_manager_desktop.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/ui/actions/chrome_action_id.h"
 #include "chrome/browser/ui/test/test_browser_dialog.h"
 #include "chrome/browser/ui/ui_features.h"
 #include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h"
@@ -203,8 +202,10 @@
       webapps::TestAppBannerManagerDesktop::FromWebContents(web_contents);
   app_banner_manager->WaitForInstallableCheck();
   EXPECT_TRUE(BrowserView::GetBrowserViewForBrowser(browser())
-                  ->toolbar_button_provider()
-                  ->GetPageActionView(kActionInstallPwa)
+                  ->toolbar()
+                  ->location_bar()
+                  ->page_action_icon_controller()
+                  ->GetIconView(PageActionIconType::kPwaInstall)
                   ->GetVisible());
   browser()->window()->Activate();
   ui_test_utils::BrowserActivationWaiter(browser()).WaitForActivation();
diff --git a/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc b/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc
index d3cc4f80..9d0e451 100644
--- a/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc
+++ b/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc
@@ -57,14 +57,12 @@
 #include "chrome/browser/shell_integration.h"
 #include "chrome/browser/ui/actions/chrome_action_id.h"
 #include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/browser_actions.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/browser_list.h"
 #include "chrome/browser/ui/browser_window/public/browser_window_features.h"
 #include "chrome/browser/ui/exclusive_access/exclusive_access_manager.h"
 #include "chrome/browser/ui/intent_picker_tab_helper.h"
-#include "chrome/browser/ui/page_action/page_action_icon_type.h"
 #include "chrome/browser/ui/startup/startup_browser_creator.h"
 #include "chrome/browser/ui/startup/web_app_startup_utils.h"
 #include "chrome/browser/ui/ui_features.h"
@@ -1358,15 +1356,7 @@
   ASSERT_TRUE(pwa_install_view()->GetVisible());
   WebAppTestInstallWithOsHooksObserver install_observer(profile());
   install_observer.BeginListening();
-  if (IsPageActionMigrated(PageActionIconType::kPwaInstall)) {
-    actions::ActionManager::Get()
-        .FindAction(kActionInstallPwa,
-                    browser()->GetActions()->root_action_item())
-        ->InvokeAction();
-  } else {
-    browser()->window()->ExecutePageActionIconForTesting(
-        PageActionIconType::kPwaInstall);
-  }
+  pwa_install_view()->ExecuteForTesting();
 
   WaitForAndAcceptInstallDialogForSite(InstallableSiteToSite(site));
 
@@ -4723,11 +4713,11 @@
   return profiles;
 }
 
-IconLabelBubbleView* WebAppIntegrationTestDriver::pwa_install_view() {
-  IconLabelBubbleView* pwa_install_view =
+PageActionIconView* WebAppIntegrationTestDriver::pwa_install_view() {
+  PageActionIconView* pwa_install_view =
       BrowserView::GetBrowserViewForBrowser(browser())
           ->toolbar_button_provider()
-          ->GetPageActionView(kActionInstallPwa);
+          ->GetPageActionIconView(PageActionIconType::kPwaInstall);
   CHECK(pwa_install_view);
   return pwa_install_view;
 }
diff --git a/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.h b/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.h
index 338268f..7a72c97 100644
--- a/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.h
+++ b/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.h
@@ -40,7 +40,7 @@
 #endif
 
 class Browser;
-class IconLabelBubbleView;
+class PageActionIconView;
 
 namespace base {
 class CommandLine;
@@ -501,7 +501,7 @@
 
   Browser* app_browser() { return app_browser_; }
   WebAppProvider* provider() { return WebAppProvider::GetForTest(profile()); }
-  IconLabelBubbleView* pwa_install_view();
+  PageActionIconView* pwa_install_view();
   views::Button* intent_chip_view();
 
   const net::EmbeddedTestServer& GetTestServerForSiteMode(Site site_mode) const;
diff --git a/chrome/browser/ui/web_applications/pwa_install_page_action_browsertest.cc b/chrome/browser/ui/web_applications/pwa_install_page_action_browsertest.cc
index 2e307a4f..c0f1ca2 100644
--- a/chrome/browser/ui/web_applications/pwa_install_page_action_browsertest.cc
+++ b/chrome/browser/ui/web_applications/pwa_install_page_action_browsertest.cc
@@ -188,10 +188,6 @@
       enabled_features.push_back(
           {features::kPageActionsMigration,
            {{features::kPageActionsMigrationPwaInstall.name, "true"}}});
-    } else {
-      enabled_features.push_back(
-          {features::kPageActionsMigration,
-           {{features::kPageActionsMigrationPwaInstall.name, "false"}}});
     }
 
     features_.InitAndEnableFeaturesWithParameters(enabled_features, {});
diff --git a/chrome/browser/ui/web_applications/sub_apps_admin_policy_browsertest.cc b/chrome/browser/ui/web_applications/sub_apps_admin_policy_browsertest.cc
index d705879..e80bcd40 100644
--- a/chrome/browser/ui/web_applications/sub_apps_admin_policy_browsertest.cc
+++ b/chrome/browser/ui/web_applications/sub_apps_admin_policy_browsertest.cc
@@ -177,8 +177,9 @@
                     content::EvalJsOptions::EXECUTE_SCRIPT_NO_USER_GESTURE);
 
   // TODO
-  EXPECT_THAT(ret.error, HasSubstr("This API can only be called shortly "
-                                   "after a user activation."));
+  EXPECT_THAT(ret, content::EvalJsResult::ErrorIs(
+                       HasSubstr("This API can only be called shortly "
+                                 "after a user activation.")));
   EXPECT_THAT(GetAllSubAppIds(parent_app_id_), IsEmpty());
 }
 
@@ -246,8 +247,9 @@
                     content::EvalJsOptions::EXECUTE_SCRIPT_NO_USER_GESTURE);
 
   // TODO
-  EXPECT_THAT(ret.error, HasSubstr("This API can only be called shortly "
-                                   "after a user activation."));
+  EXPECT_THAT(ret, content::EvalJsResult::ErrorIs(
+                       HasSubstr("This API can only be called shortly "
+                                 "after a user activation.")));
   EXPECT_THAT(GetAllSubAppIds(parent_app_id_), IsEmpty());
 }
 
diff --git a/chrome/browser/ui/webui/ash/emoji/new_window_proxy.cc b/chrome/browser/ui/webui/ash/emoji/new_window_proxy.cc
index 9b5c938..a0936ba 100644
--- a/chrome/browser/ui/webui/ash/emoji/new_window_proxy.cc
+++ b/chrome/browser/ui/webui/ash/emoji/new_window_proxy.cc
@@ -15,7 +15,7 @@
 NewWindowProxy::~NewWindowProxy() = default;
 
 void NewWindowProxy::OpenUrl(const GURL& url) {
-  ash::NewWindowDelegate::GetPrimary()->OpenUrl(
+  ash::NewWindowDelegate::GetInstance()->OpenUrl(
       url, ash::NewWindowDelegate::OpenUrlFrom::kUnspecified,
       ash::NewWindowDelegate::Disposition::kNewForegroundTab);
 }
diff --git a/chrome/browser/ui/webui/ash/lobster/lobster_page_handler.cc b/chrome/browser/ui/webui/ash/lobster/lobster_page_handler.cc
index c5460d1..ea62958 100644
--- a/chrome/browser/ui/webui/ash/lobster/lobster_page_handler.cc
+++ b/chrome/browser/ui/webui/ash/lobster/lobster_page_handler.cc
@@ -136,7 +136,7 @@
     mojo::ReportBadMessage("Invalid URL scheme. Only HTTPS is allowed.");
     return;
   }
-  ash::NewWindowDelegate::GetPrimary()->OpenUrl(
+  ash::NewWindowDelegate::GetInstance()->OpenUrl(
       url, ash::NewWindowDelegate::OpenUrlFrom::kUnspecified,
       ash::NewWindowDelegate::Disposition::kNewForegroundTab);
 }
diff --git a/chrome/browser/ui/webui/ash/settings/pages/a11y/accessibility_handler.cc b/chrome/browser/ui/webui/ash/settings/pages/a11y/accessibility_handler.cc
index 5ab7586..2663469 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/a11y/accessibility_handler.cc
+++ b/chrome/browser/ui/webui/ash/settings/pages/a11y/accessibility_handler.cc
@@ -100,7 +100,7 @@
 
 void AccessibilityHandler::HandleShowBrowserAppearanceSettings(
     const base::Value::List& args) {
-  ash::NewWindowDelegate::GetPrimary()->OpenUrl(
+  ash::NewWindowDelegate::GetInstance()->OpenUrl(
       GURL(chrome::kChromeUISettingsURL).Resolve(chrome::kAppearanceSubPage),
       ash::NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       ash::NewWindowDelegate::Disposition::kSwitchToTab);
diff --git a/chrome/browser/ui/webui/ash/settings/pages/a11y/settings_with_tts_preview_handler.cc b/chrome/browser/ui/webui/ash/settings/pages/a11y/settings_with_tts_preview_handler.cc
index fa4903c..4729c206 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/a11y/settings_with_tts_preview_handler.cc
+++ b/chrome/browser/ui/webui/ash/settings/pages/a11y/settings_with_tts_preview_handler.cc
@@ -26,29 +26,46 @@
 
 namespace ash::settings {
 
+namespace {
+
+class TtsPreviewEventDelegate : public content::UtteranceEventDelegate {
+ public:
+  explicit TtsPreviewEventDelegate(
+      base::WeakPtr<SettingsWithTtsPreviewHandler> handler)
+      : handler_(handler) {}
+  ~TtsPreviewEventDelegate() override = default;
+
+  // content::UtteranceEventDelegate:
+  void OnTtsEvent(content::TtsUtterance* utterance,
+                  content::TtsEventType event_type,
+                  int char_index,
+                  int length,
+                  const std::string& error_message) override {
+    if (handler_ && (event_type == content::TTS_EVENT_END ||
+                     event_type == content::TTS_EVENT_INTERRUPTED ||
+                     event_type == content::TTS_EVENT_ERROR)) {
+      handler_->FireTtsPreviewEvent();
+    }
+  }
+
+ private:
+  base::WeakPtr<SettingsWithTtsPreviewHandler> handler_;
+};
+
+}  // namespace
+
 SettingsWithTtsPreviewHandler::SettingsWithTtsPreviewHandler() = default;
 
-SettingsWithTtsPreviewHandler::~SettingsWithTtsPreviewHandler() {
-  RemoveTtsControllerDelegates();
-}
+SettingsWithTtsPreviewHandler::~SettingsWithTtsPreviewHandler() = default;
 
 void SettingsWithTtsPreviewHandler::HandleGetAllTtsVoiceData(
     const base::Value::List& args) {
   OnVoicesChanged();
 }
 
-void SettingsWithTtsPreviewHandler::OnTtsEvent(
-    content::TtsUtterance* utterance,
-    content::TtsEventType event_type,
-    int char_index,
-    int length,
-    const std::string& error_message) {
-  if (event_type == content::TTS_EVENT_END ||
-      event_type == content::TTS_EVENT_INTERRUPTED ||
-      event_type == content::TTS_EVENT_ERROR) {
-    base::Value result(false /* preview stopped */);
-    FireWebUIListener("tts-preview-state-changed", result);
-  }
+void SettingsWithTtsPreviewHandler::FireTtsPreviewEvent() {
+  FireWebUIListener("tts-preview-state-changed",
+                    base::Value(/*preview_stopped=*/false));
 }
 
 void SettingsWithTtsPreviewHandler::HandlePreviewTtsVoice(
@@ -77,11 +94,12 @@
   utterance->SetVoiceName(name);
   utterance->SetEngineId(extension_id);
   utterance->SetSrcUrl(GetSourceURL());
-  utterance->SetEventDelegate(this);
+  utterance->SetEventDelegate(
+      std::make_unique<TtsPreviewEventDelegate>(weak_factory_.GetWeakPtr()));
   content::TtsController::GetInstance()->Stop();
 
-  base::Value result(true /* preview started */);
-  FireWebUIListener("tts-preview-state-changed", result);
+  FireWebUIListener("tts-preview-state-changed",
+                    base::Value(/*preview_started=*/true));
   content::TtsController::GetInstance()->SpeakOrEnqueue(std::move(utterance));
 }
 
@@ -112,7 +130,6 @@
 
 void SettingsWithTtsPreviewHandler::RemoveTtsControllerDelegates() {
   content::TtsController::GetInstance()->RemoveVoicesChangedDelegate(this);
-  content::TtsController::GetInstance()->RemoveUtteranceEventDelegate(this);
 }
 
 }  // namespace ash::settings
diff --git a/chrome/browser/ui/webui/ash/settings/pages/a11y/settings_with_tts_preview_handler.h b/chrome/browser/ui/webui/ash/settings/pages/a11y/settings_with_tts_preview_handler.h
index db06222..b0a4b59 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/a11y/settings_with_tts_preview_handler.h
+++ b/chrome/browser/ui/webui/ash/settings/pages/a11y/settings_with_tts_preview_handler.h
@@ -13,8 +13,7 @@
 
 // Parent Chrome OS TTS-related settings page handler.
 class SettingsWithTtsPreviewHandler : public ::settings::SettingsPageUIHandler,
-                                      public content::VoicesChangedDelegate,
-                                      public content::UtteranceEventDelegate {
+                                      public content::VoicesChangedDelegate {
  public:
   SettingsWithTtsPreviewHandler();
 
@@ -24,6 +23,8 @@
 
   ~SettingsWithTtsPreviewHandler() override;
 
+  void FireTtsPreviewEvent();
+
   void HandleGetAllTtsVoiceData(const base::Value::List& args);
   void HandlePreviewTtsVoice(const base::Value::List& args);
 
@@ -32,18 +33,12 @@
   void OnJavascriptAllowed() override;
   void OnJavascriptDisallowed() override;
 
-  // UtteranceEventDelegate implementation.
-  void OnTtsEvent(content::TtsUtterance* utterance,
-                  content::TtsEventType event_type,
-                  int char_index,
-                  int length,
-                  const std::string& error_message) override;
-
-  void RefreshTtsVoices(const base::Value::List& args);
-  void RemoveTtsControllerDelegates();
   virtual GURL GetSourceURL() const = 0;
 
  private:
+  void RefreshTtsVoices(const base::Value::List& args);
+  void RemoveTtsControllerDelegates();
+
   base::WeakPtrFactory<SettingsWithTtsPreviewHandler> weak_factory_{this};
 };
 
diff --git a/chrome/browser/ui/webui/ash/settings/pages/apps/app_notification_handler.cc b/chrome/browser/ui/webui/ash/settings/pages/apps/app_notification_handler.cc
index 3327925..0571f96 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/apps/app_notification_handler.cc
+++ b/chrome/browser/ui/webui/ash/settings/pages/apps/app_notification_handler.cc
@@ -109,7 +109,7 @@
 }
 
 void AppNotificationHandler::OpenBrowserNotificationSettings() {
-  ash::NewWindowDelegate::GetPrimary()->OpenUrl(
+  ash::NewWindowDelegate::GetInstance()->OpenUrl(
       GURL(chrome::kAppNotificationsBrowserSettingsURL),
       ash::NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       ash::NewWindowDelegate::Disposition::kSwitchToTab);
diff --git a/chrome/browser/ui/webui/ash/settings/pages/multidevice/multidevice_handler.cc b/chrome/browser/ui/webui/ash/settings/pages/multidevice/multidevice_handler.cc
index 2977cbe..91caaf1 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/multidevice/multidevice_handler.cc
+++ b/chrome/browser/ui/webui/ash/settings/pages/multidevice/multidevice_handler.cc
@@ -514,7 +514,7 @@
 
 void MultideviceHandler::HandleShowBrowserSyncSettings(
     const base::Value::List& args) {
-  ash::NewWindowDelegate::GetPrimary()->OpenUrl(
+  ash::NewWindowDelegate::GetInstance()->OpenUrl(
       GURL("chrome://settings/syncSetup/advanced"),
       ash::NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       ash::NewWindowDelegate::Disposition::kSwitchToTab);
diff --git a/chrome/browser/ui/webui/ash/settings/pages/people/os_sync_handler.cc b/chrome/browser/ui/webui/ash/settings/pages/people/os_sync_handler.cc
index 216faa4d..f15f0c4 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/people/os_sync_handler.cc
+++ b/chrome/browser/ui/webui/ash/settings/pages/people/os_sync_handler.cc
@@ -93,7 +93,7 @@
 
 void OSSyncHandler::HandleOpenBrowserSyncSettings(
     const base::Value::List& args) {
-  ash::NewWindowDelegate::GetPrimary()->OpenUrl(
+  ash::NewWindowDelegate::GetInstance()->OpenUrl(
       GURL(chrome::kChromeUISettingsURL).Resolve(chrome::kSyncSetupSubPage),
       ash::NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       ash::NewWindowDelegate::Disposition::kSwitchToTab);
diff --git a/chrome/browser/ui/webui/ash/settings/pages/people/parental_controls_handler.cc b/chrome/browser/ui/webui/ash/settings/pages/people/parental_controls_handler.cc
index da2ce43..25df197f 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/people/parental_controls_handler.cc
+++ b/chrome/browser/ui/webui/ash/settings/pages/people/parental_controls_handler.cc
@@ -83,7 +83,7 @@
   }
 
   // As a last resort, launch browser to the family link site.
-  NewWindowDelegate::GetPrimary()->OpenUrl(
+  NewWindowDelegate::GetInstance()->OpenUrl(
       GURL(kFamilyLinkSiteURL),
       NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       NewWindowDelegate::Disposition::kNewWindow);
diff --git a/chrome/browser/ui/webui/ash/settings/pages/printing/cups_printers_handler.cc b/chrome/browser/ui/webui/ash/settings/pages/printing/cups_printers_handler.cc
index a6e6c51..622f713 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/printing/cups_printers_handler.cc
+++ b/chrome/browser/ui/webui/ash/settings/pages/printing/cups_printers_handler.cc
@@ -594,7 +594,7 @@
   }
 
   PRINTER_LOG(DEBUG) << "PPD saved to " << ppd_file_path;
-  ash::NewWindowDelegate::GetPrimary()->OpenUrl(
+  ash::NewWindowDelegate::GetInstance()->OpenUrl(
       GURL(base::StringPrintf("file://%s", ppd_file_path.value().c_str())),
       ash::NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       ash::NewWindowDelegate::Disposition::kSwitchToTab);
diff --git a/chrome/browser/ui/webui/ash/settings/pages/privacy/app_permission_handler.cc b/chrome/browser/ui/webui/ash/settings/pages/privacy/app_permission_handler.cc
index 51852ed5..f7299226 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/privacy/app_permission_handler.cc
+++ b/chrome/browser/ui/webui/ash/settings/pages/privacy/app_permission_handler.cc
@@ -128,7 +128,7 @@
       NOTREACHED();
   }
 
-  ash::NewWindowDelegate::GetPrimary()->OpenUrl(
+  ash::NewWindowDelegate::GetInstance()->OpenUrl(
       url, ash::NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       ash::NewWindowDelegate::Disposition::kSwitchToTab);
 }
diff --git a/chrome/browser/ui/webui/ash/settings/pages/storage/device_storage_handler.cc b/chrome/browser/ui/webui/ash/settings/pages/storage/device_storage_handler.cc
index 02b76fd..ca7c8f8 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/storage/device_storage_handler.cc
+++ b/chrome/browser/ui/webui/ash/settings/pages/storage/device_storage_handler.cc
@@ -208,7 +208,7 @@
 
 void StorageHandler::HandleOpenBrowsingDataSettings(
     const base::Value::List& unused_args) {
-  ash::NewWindowDelegate::GetPrimary()->OpenUrl(
+  ash::NewWindowDelegate::GetInstance()->OpenUrl(
       GURL(chrome::kChromeUISettingsURL)
           .Resolve(chrome::kClearBrowserDataSubPage),
       ash::NewWindowDelegate::OpenUrlFrom::kUserInteraction,
diff --git a/chrome/browser/ui/webui/settings/about_handler.cc b/chrome/browser/ui/webui/settings/about_handler.cc
index fa86548..fa360630 100644
--- a/chrome/browser/ui/webui/settings/about_handler.cc
+++ b/chrome/browser/ui/webui/settings/about_handler.cc
@@ -819,7 +819,7 @@
 
 void AboutHandler::HandleOpenProductLicenseOther(
     const base::Value::List& args) {
-  ash::NewWindowDelegate::GetPrimary()->OpenUrl(
+  ash::NewWindowDelegate::GetInstance()->OpenUrl(
       GURL(chrome::kChromeUICreditsURL),
       ash::NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       ash::NewWindowDelegate::Disposition::kSwitchToTab);
diff --git a/chrome/browser/ui/webui/settings/search_engines_handler.cc b/chrome/browser/ui/webui/settings/search_engines_handler.cc
index 38879e9b..17b00f4 100644
--- a/chrome/browser/ui/webui/settings/search_engines_handler.cc
+++ b/chrome/browser/ui/webui/settings/search_engines_handler.cc
@@ -493,7 +493,7 @@
 #if BUILDFLAG(IS_CHROMEOS)
 void SearchEnginesHandler::HandleOpenBrowserSearchSettings(
     const base::Value::List& args) {
-  ash::NewWindowDelegate::GetPrimary()->OpenUrl(
+  ash::NewWindowDelegate::GetInstance()->OpenUrl(
       GURL(chrome::kChromeUISettingsURL).Resolve(chrome::kSearchSubPage),
       ash::NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       ash::NewWindowDelegate::Disposition::kSwitchToTab);
diff --git a/chrome/browser/ui/webui/tab_search/tab_search_page_handler.cc b/chrome/browser/ui/webui/tab_search/tab_search_page_handler.cc
index 43056c1f..4017ed7 100644
--- a/chrome/browser/ui/webui/tab_search/tab_search_page_handler.cc
+++ b/chrome/browser/ui/webui/tab_search/tab_search_page_handler.cc
@@ -1801,9 +1801,9 @@
   SetTabDeclutterController(tab_declutter_controller);
 }
 
-bool TabSearchPageHandler::ShouldTrackBrowser(Browser* browser) {
-  return browser->profile() == Profile::FromWebUI(web_ui_) &&
-         browser->type() == Browser::Type::TYPE_NORMAL;
+bool TabSearchPageHandler::ShouldTrackBrowser(BrowserWindowInterface* browser) {
+  return browser->GetProfile() == Profile::FromWebUI(web_ui_) &&
+         browser->GetType() == BrowserWindowInterface::TYPE_NORMAL;
 }
 
 void TabSearchPageHandler::SetTimerForTesting(
diff --git a/chrome/browser/ui/webui/tab_search/tab_search_page_handler.h b/chrome/browser/ui/webui/tab_search/tab_search_page_handler.h
index 47c6357..2248ba41 100644
--- a/chrome/browser/ui/webui/tab_search/tab_search_page_handler.h
+++ b/chrome/browser/ui/webui/tab_search/tab_search_page_handler.h
@@ -159,7 +159,7 @@
       std::map<GURL, std::vector<tabs::TabInterface*>> duplicate_tabs) override;
 
   // BrowserTabStripTrackerDelegate:
-  bool ShouldTrackBrowser(Browser* browser) override;
+  bool ShouldTrackBrowser(BrowserWindowInterface* browser) override;
 
   // Returns true if the WebContents hosting the WebUI is visible to the user
   // (in either a fully visible or partially occluded state).
diff --git a/chrome/browser/ui/webui_browser/BUILD.gn b/chrome/browser/ui/webui_browser/BUILD.gn
new file mode 100644
index 0000000..280f71c
--- /dev/null
+++ b/chrome/browser/ui/webui_browser/BUILD.gn
@@ -0,0 +1,26 @@
+# 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.
+
+source_set("webui_browser") {
+  sources = [
+    "webui_browser.h",
+    "webui_browser_window.h",
+  ]
+}
+
+source_set("impl") {
+  sources = [
+    "webui_browser.cc",
+    "webui_browser_window.cc",
+  ]
+
+  deps = [
+    ":webui_browser",
+    "//base",
+    "//components/input",
+    "//components/sharing_message",
+    "//content/public/browser",
+    "//ui/base",
+  ]
+}
diff --git a/chrome/browser/ui/webui_browser/OWNERS b/chrome/browser/ui/webui_browser/OWNERS
new file mode 100644
index 0000000..77a99e1
--- /dev/null
+++ b/chrome/browser/ui/webui_browser/OWNERS
@@ -0,0 +1,3 @@
+kerenzhu@chromium.org
+robliao@chromium.org
+tluk@chromium.org
diff --git a/chrome/browser/ui/webui_browser/webui_browser.cc b/chrome/browser/ui/webui_browser/webui_browser.cc
new file mode 100644
index 0000000..8e03fd9
--- /dev/null
+++ b/chrome/browser/ui/webui_browser/webui_browser.cc
@@ -0,0 +1,13 @@
+// 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_browser/webui_browser.h"
+
+namespace webui_browser {
+
+bool IsWebUIBrowserEnabled() {
+  return false;
+}
+
+}  // namespace webui_browser
diff --git a/chrome/browser/ui/webui_browser/webui_browser.h b/chrome/browser/ui/webui_browser/webui_browser.h
new file mode 100644
index 0000000..0220517c
--- /dev/null
+++ b/chrome/browser/ui/webui_browser/webui_browser.h
@@ -0,0 +1,14 @@
+// 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.
+
+#ifndef CHROME_BROWSER_UI_WEBUI_BROWSER_WEBUI_BROWSER_H_
+#define CHROME_BROWSER_UI_WEBUI_BROWSER_WEBUI_BROWSER_H_
+
+namespace webui_browser {
+
+bool IsWebUIBrowserEnabled();
+
+}  // namespace webui_browser
+
+#endif  // CHROME_BROWSER_UI_WEBUI_BROWSER_WEBUI_BROWSER_H_
diff --git a/chrome/browser/ui/webui_browser/webui_browser_window.cc b/chrome/browser/ui/webui_browser/webui_browser_window.cc
new file mode 100644
index 0000000..00510aa
--- /dev/null
+++ b/chrome/browser/ui/webui_browser/webui_browser_window.cc
@@ -0,0 +1,659 @@
+// 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_browser/webui_browser_window.h"
+
+#include "base/notimplemented.h"
+#include "components/input/native_web_keyboard_event.h"
+#include "components/sharing_message/sharing_dialog_data.h"
+#include "content/public/browser/keyboard_event_processing_result.h"
+
+WebUIBrowserWindow::WebUIBrowserWindow(std::unique_ptr<Browser> browser)
+    : browser_(std::move(browser)) {}
+
+WebUIBrowserWindow::~WebUIBrowserWindow() = default;
+
+void WebUIBrowserWindow::Show() {
+  NOTIMPLEMENTED();
+}
+
+void WebUIBrowserWindow::ShowInactive() {
+  NOTIMPLEMENTED();
+}
+
+void WebUIBrowserWindow::Hide() {
+  NOTIMPLEMENTED();
+}
+
+bool WebUIBrowserWindow::IsVisible() const {
+  NOTIMPLEMENTED();
+  return false;
+}
+
+void WebUIBrowserWindow::SetBounds(const gfx::Rect& bounds) {
+  NOTIMPLEMENTED();
+}
+
+void WebUIBrowserWindow::Close() {
+  NOTIMPLEMENTED();
+}
+
+void WebUIBrowserWindow::Activate() {
+  NOTIMPLEMENTED();
+}
+
+void WebUIBrowserWindow::Deactivate() {
+  NOTIMPLEMENTED();
+}
+
+bool WebUIBrowserWindow::IsActive() const {
+  NOTIMPLEMENTED();
+  return false;
+}
+
+void WebUIBrowserWindow::FlashFrame(bool flash) {
+  NOTIMPLEMENTED();
+}
+
+ui::ZOrderLevel WebUIBrowserWindow::GetZOrderLevel() const {
+  NOTIMPLEMENTED();
+  return ui::ZOrderLevel::kNormal;
+}
+
+void WebUIBrowserWindow::SetZOrderLevel(ui::ZOrderLevel order) {
+  NOTIMPLEMENTED();
+}
+
+gfx::NativeWindow WebUIBrowserWindow::GetNativeWindow() const {
+  NOTIMPLEMENTED();
+  return gfx::NativeWindow();
+}
+
+bool WebUIBrowserWindow::IsOnCurrentWorkspace() const {
+  NOTIMPLEMENTED();
+  return false;
+}
+
+bool WebUIBrowserWindow::IsVisibleOnScreen() const {
+  NOTIMPLEMENTED();
+  return false;
+}
+
+void WebUIBrowserWindow::SetTopControlsShownRatio(
+    content::WebContents* web_contents,
+    float ratio) {
+  NOTIMPLEMENTED();
+}
+
+bool WebUIBrowserWindow::DoBrowserControlsShrinkRendererSize(
+    const content::WebContents* contents) const {
+  NOTIMPLEMENTED();
+  return false;
+}
+
+ui::NativeTheme* WebUIBrowserWindow::GetNativeTheme() {
+  NOTIMPLEMENTED();
+  return nullptr;
+}
+
+const ui::ThemeProvider* WebUIBrowserWindow::GetThemeProvider() const {
+  NOTIMPLEMENTED();
+  return nullptr;
+}
+
+const ui::ColorProvider* WebUIBrowserWindow::GetColorProvider() const {
+  NOTIMPLEMENTED();
+  return nullptr;
+}
+
+ui::ElementContext WebUIBrowserWindow::GetElementContext() {
+  NOTIMPLEMENTED();
+  return ui::ElementContext();
+}
+
+int WebUIBrowserWindow::GetTopControlsHeight() const {
+  NOTIMPLEMENTED();
+  return 0;
+}
+
+void WebUIBrowserWindow::SetTopControlsGestureScrollInProgress(
+    bool in_progress) {
+  NOTIMPLEMENTED();
+}
+
+std::vector<StatusBubble*> WebUIBrowserWindow::GetStatusBubbles() {
+  NOTIMPLEMENTED();
+  return {};
+}
+
+void WebUIBrowserWindow::UpdateTitleBar() {
+  NOTIMPLEMENTED();
+}
+
+void WebUIBrowserWindow::BookmarkBarStateChanged(
+    BookmarkBar::AnimateChangeType change_type) {
+  NOTIMPLEMENTED();
+}
+
+void WebUIBrowserWindow::TemporarilyShowBookmarkBar(base::TimeDelta duration) {
+  NOTIMPLEMENTED();
+}
+
+void WebUIBrowserWindow::UpdateDevTools() {
+  NOTIMPLEMENTED();
+}
+
+void WebUIBrowserWindow::UpdateLoadingAnimations(bool is_visible) {
+  NOTIMPLEMENTED();
+}
+
+void WebUIBrowserWindow::SetStarredState(bool is_starred) {
+  NOTIMPLEMENTED();
+}
+
+bool WebUIBrowserWindow::IsTabModalPopupDeprecated() const {
+  NOTIMPLEMENTED();
+  return false;
+}
+
+void WebUIBrowserWindow::SetIsTabModalPopupDeprecated(
+    bool is_tab_modal_popup_deprecated) {
+  NOTIMPLEMENTED();
+}
+
+void WebUIBrowserWindow::OnActiveTabChanged(content::WebContents* old_contents,
+                                            content::WebContents* new_contents,
+                                            int index,
+                                            int reason) {
+  NOTIMPLEMENTED();
+}
+
+void WebUIBrowserWindow::OnTabDetached(content::WebContents* contents,
+                                       bool was_active) {
+  NOTIMPLEMENTED();
+}
+
+void WebUIBrowserWindow::ZoomChangedForActiveTab(bool can_show_bubble) {
+  NOTIMPLEMENTED();
+}
+
+bool WebUIBrowserWindow::ShouldHideUIForFullscreen() const {
+  NOTIMPLEMENTED();
+  return false;
+}
+
+bool WebUIBrowserWindow::IsFullscreenBubbleVisible() const {
+  NOTIMPLEMENTED();
+  return false;
+}
+
+bool WebUIBrowserWindow::IsForceFullscreen() const {
+  NOTIMPLEMENTED();
+  return false;
+}
+
+void WebUIBrowserWindow::SetForceFullscreen(bool force_fullscreen) {
+  NOTIMPLEMENTED();
+}
+
+gfx::Size WebUIBrowserWindow::GetContentsSize() const {
+  NOTIMPLEMENTED();
+  return gfx::Size();
+}
+
+void WebUIBrowserWindow::SetContentsSize(const gfx::Size& size) {
+  NOTIMPLEMENTED();
+}
+
+void WebUIBrowserWindow::UpdatePageActionIcon(PageActionIconType type) {
+  NOTIMPLEMENTED();
+}
+
+autofill::AutofillBubbleHandler*
+WebUIBrowserWindow::GetAutofillBubbleHandler() {
+  NOTIMPLEMENTED();
+  return nullptr;
+}
+
+void WebUIBrowserWindow::ExecutePageActionIconForTesting(
+    PageActionIconType type) {
+  NOTIMPLEMENTED();
+}
+
+LocationBar* WebUIBrowserWindow::GetLocationBar() const {
+  NOTIMPLEMENTED();
+  return nullptr;
+}
+
+void WebUIBrowserWindow::SetFocusToLocationBar(bool select_all) {
+  NOTIMPLEMENTED();
+}
+
+void WebUIBrowserWindow::UpdateReloadStopState(bool is_loading, bool force) {
+  NOTIMPLEMENTED();
+}
+
+void WebUIBrowserWindow::UpdateToolbar(content::WebContents* contents) {
+  NOTIMPLEMENTED();
+}
+
+bool WebUIBrowserWindow::UpdateToolbarSecurityState() {
+  NOTIMPLEMENTED();
+  return false;
+}
+
+void WebUIBrowserWindow::UpdateCustomTabBarVisibility(bool visible,
+                                                      bool animate) {
+  NOTIMPLEMENTED();
+}
+
+void WebUIBrowserWindow::SetContentScrimVisibility(bool visible) {
+  NOTIMPLEMENTED();
+}
+
+void WebUIBrowserWindow::SetDevToolsScrimVisibility(bool visible) {
+  NOTIMPLEMENTED();
+}
+
+void WebUIBrowserWindow::ResetToolbarTabState(content::WebContents* contents) {
+  NOTIMPLEMENTED();
+}
+
+void WebUIBrowserWindow::FocusToolbar() {
+  NOTIMPLEMENTED();
+}
+
+ExtensionsContainer* WebUIBrowserWindow::GetExtensionsContainer() {
+  NOTIMPLEMENTED();
+  return nullptr;
+}
+
+void WebUIBrowserWindow::ToolbarSizeChanged(bool is_animating) {
+  NOTIMPLEMENTED();
+}
+
+void WebUIBrowserWindow::TabDraggingStatusChanged(bool is_dragging) {
+  NOTIMPLEMENTED();
+}
+
+void WebUIBrowserWindow::LinkOpeningFromGesture(
+    WindowOpenDisposition disposition) {
+  NOTIMPLEMENTED();
+}
+
+void WebUIBrowserWindow::FocusAppMenu() {
+  NOTIMPLEMENTED();
+}
+
+void WebUIBrowserWindow::FocusBookmarksToolbar() {
+  NOTIMPLEMENTED();
+}
+
+void WebUIBrowserWindow::FocusInactivePopupForAccessibility() {
+  NOTIMPLEMENTED();
+}
+
+void WebUIBrowserWindow::RotatePaneFocus(bool forwards) {
+  NOTIMPLEMENTED();
+}
+
+void WebUIBrowserWindow::FocusWebContentsPane() {
+  NOTIMPLEMENTED();
+}
+
+bool WebUIBrowserWindow::IsBookmarkBarVisible() const {
+  NOTIMPLEMENTED();
+  return false;
+}
+
+bool WebUIBrowserWindow::IsBookmarkBarAnimating() const {
+  NOTIMPLEMENTED();
+  return false;
+}
+
+bool WebUIBrowserWindow::IsTabStripEditable() const {
+  NOTIMPLEMENTED();
+  return false;
+}
+
+void WebUIBrowserWindow::SetTabStripNotEditableForTesting() {
+  NOTIMPLEMENTED();
+}
+
+bool WebUIBrowserWindow::IsToolbarVisible() const {
+  NOTIMPLEMENTED();
+  return false;
+}
+
+bool WebUIBrowserWindow::IsToolbarShowing() const {
+  NOTIMPLEMENTED();
+  return false;
+}
+
+bool WebUIBrowserWindow::IsLocationBarVisible() const {
+  NOTIMPLEMENTED();
+  return false;
+}
+
+SharingDialog* WebUIBrowserWindow::ShowSharingDialog(
+    content::WebContents* contents,
+    SharingDialogData data) {
+  NOTIMPLEMENTED();
+  return nullptr;
+}
+
+void WebUIBrowserWindow::ShowUpdateChromeDialog() {
+  NOTIMPLEMENTED();
+}
+
+void WebUIBrowserWindow::ShowIntentPickerBubble(
+    std::vector<apps::IntentPickerAppInfo> app_info,
+    bool show_stay_in_chrome,
+    bool show_remember_selection,
+    apps::IntentPickerBubbleType bubble_type,
+    const std::optional<url::Origin>& initiating_origin,
+    IntentPickerResponse callback) {
+  NOTIMPLEMENTED();
+}
+
+void WebUIBrowserWindow::ShowBookmarkBubble(const GURL& url,
+                                            bool already_bookmarked) {
+  NOTIMPLEMENTED();
+}
+
+sharing_hub::ScreenshotCapturedBubble*
+WebUIBrowserWindow::ShowScreenshotCapturedBubble(content::WebContents* contents,
+                                                 const gfx::Image& image) {
+  NOTIMPLEMENTED();
+  return nullptr;
+}
+
+qrcode_generator::QRCodeGeneratorBubbleView*
+WebUIBrowserWindow::ShowQRCodeGeneratorBubble(content::WebContents* contents,
+                                              const GURL& url,
+                                              bool show_back_button) {
+  NOTIMPLEMENTED();
+  return nullptr;
+}
+
+send_tab_to_self::SendTabToSelfBubbleView*
+WebUIBrowserWindow::ShowSendTabToSelfDevicePickerBubble(
+    content::WebContents* contents) {
+  NOTIMPLEMENTED();
+  return nullptr;
+}
+
+send_tab_to_self::SendTabToSelfBubbleView*
+WebUIBrowserWindow::ShowSendTabToSelfPromoBubble(content::WebContents* contents,
+                                                 bool show_signin_button) {
+  NOTIMPLEMENTED();
+  return nullptr;
+}
+
+#if BUILDFLAG(IS_CHROMEOS)
+views::Button* WebUIBrowserWindow::GetSharingHubIconButton() {
+  NOTIMPLEMENTED();
+  return nullptr;
+}
+
+void WebUIBrowserWindow::ToggleMultitaskMenu() const {
+  NOTIMPLEMENTED();
+}
+#else
+sharing_hub::SharingHubBubbleView* WebUIBrowserWindow::ShowSharingHubBubble(
+    share::ShareAttempt attempt) {
+  NOTIMPLEMENTED();
+  return nullptr;
+}
+#endif  // BUILDFLAG(IS_CHROMEOS)
+
+ShowTranslateBubbleResult WebUIBrowserWindow::ShowTranslateBubble(
+    content::WebContents* contents,
+    translate::TranslateStep step,
+    const std::string& source_language,
+    const std::string& target_language,
+    translate::TranslateErrors error_type,
+    bool is_user_gesture) {
+  NOTIMPLEMENTED();
+  return ShowTranslateBubbleResult::BROWSER_WINDOW_NOT_VALID;
+}
+
+void WebUIBrowserWindow::StartPartialTranslate(
+    const std::string& source_language,
+    const std::string& target_language,
+    const std::u16string& text_selection) {
+  NOTIMPLEMENTED();
+}
+
+void WebUIBrowserWindow::ShowOneClickSigninConfirmation(
+    const std::u16string& email,
+    base::OnceCallback<void(bool)> confirmed_callback) {
+  NOTIMPLEMENTED();
+}
+
+views::View* WebUIBrowserWindow::GetTopContainer() {
+  NOTIMPLEMENTED();
+  return nullptr;
+}
+
+views::View* WebUIBrowserWindow::GetLensOverlayView() {
+  NOTIMPLEMENTED();
+  return nullptr;
+}
+
+DownloadBubbleUIController*
+WebUIBrowserWindow::GetDownloadBubbleUIController() {
+  NOTIMPLEMENTED();
+  return nullptr;
+}
+
+void WebUIBrowserWindow::ConfirmBrowserCloseWithPendingDownloads(
+    int download_count,
+    Browser::DownloadCloseType dialog_type,
+    base::OnceCallback<void(bool)> callback) {
+  NOTIMPLEMENTED();
+}
+
+void WebUIBrowserWindow::UserChangedTheme(
+    BrowserThemeChangeType theme_change_type) {
+  NOTIMPLEMENTED();
+}
+
+void WebUIBrowserWindow::ShowAppMenu() {
+  NOTIMPLEMENTED();
+}
+
+bool WebUIBrowserWindow::PreHandleMouseEvent(
+    const blink::WebMouseEvent& event) {
+  NOTIMPLEMENTED();
+  return false;
+}
+
+void WebUIBrowserWindow::PreHandleDragUpdate(const content::DropData& drop_data,
+                                             const gfx::PointF& point) {
+  NOTIMPLEMENTED();
+}
+
+void WebUIBrowserWindow::PreHandleDragExit() {
+  NOTIMPLEMENTED();
+}
+
+void WebUIBrowserWindow::HandleDragEnded() {
+  NOTIMPLEMENTED();
+}
+
+content::KeyboardEventProcessingResult
+WebUIBrowserWindow::PreHandleKeyboardEvent(
+    const input::NativeWebKeyboardEvent& event) {
+  NOTIMPLEMENTED();
+  return content::KeyboardEventProcessingResult::NOT_HANDLED;
+}
+
+bool WebUIBrowserWindow::HandleKeyboardEvent(
+    const input::NativeWebKeyboardEvent& event) {
+  NOTIMPLEMENTED();
+  return false;
+}
+
+std::unique_ptr<FindBar> WebUIBrowserWindow::CreateFindBar() {
+  NOTIMPLEMENTED();
+  return nullptr;
+}
+
+web_modal::WebContentsModalDialogHost*
+WebUIBrowserWindow::GetWebContentsModalDialogHost() {
+  NOTIMPLEMENTED();
+  return nullptr;
+}
+
+void WebUIBrowserWindow::ShowAvatarBubbleFromAvatarButton(
+    bool is_source_accelerator) {
+  NOTIMPLEMENTED();
+}
+
+void WebUIBrowserWindow::MaybeShowProfileSwitchIPH() {
+  NOTIMPLEMENTED();
+}
+
+void WebUIBrowserWindow::MaybeShowSupervisedUserProfileSignInIPH() {
+  NOTIMPLEMENTED();
+}
+
+void WebUIBrowserWindow::ShowHatsDialog(
+    const std::string& site_id,
+    const std::optional<std::string>& hats_histogram_name,
+    const std::optional<uint64_t> hats_survey_ukm_id,
+    base::OnceClosure success_callback,
+    base::OnceClosure failure_callback,
+    const SurveyBitsData& product_specific_bits_data,
+    const SurveyStringData& product_specific_string_data) {
+  NOTIMPLEMENTED();
+}
+
+ExclusiveAccessContext* WebUIBrowserWindow::GetExclusiveAccessContext() {
+  NOTIMPLEMENTED();
+  return nullptr;
+}
+
+std::string WebUIBrowserWindow::GetWorkspace() const {
+  NOTIMPLEMENTED();
+  return std::string();
+}
+
+bool WebUIBrowserWindow::IsVisibleOnAllWorkspaces() const {
+  NOTIMPLEMENTED();
+  return false;
+}
+
+void WebUIBrowserWindow::ShowEmojiPanel() {
+  NOTIMPLEMENTED();
+}
+
+std::unique_ptr<content::EyeDropper> WebUIBrowserWindow::OpenEyeDropper(
+    content::RenderFrameHost* frame,
+    content::EyeDropperListener* listener) {
+  NOTIMPLEMENTED();
+  return nullptr;
+}
+
+void WebUIBrowserWindow::ShowCaretBrowsingDialog() {
+  NOTIMPLEMENTED();
+}
+
+void WebUIBrowserWindow::CreateTabSearchBubble(
+    tab_search::mojom::TabSearchSection section,
+    tab_search::mojom::TabOrganizationFeature organization_feature) {
+  NOTIMPLEMENTED();
+}
+
+void WebUIBrowserWindow::CloseTabSearchBubble() {
+  NOTIMPLEMENTED();
+}
+
+void WebUIBrowserWindow::ShowIncognitoClearBrowsingDataDialog() {
+  NOTIMPLEMENTED();
+}
+
+void WebUIBrowserWindow::ShowIncognitoHistoryDisclaimerDialog() {
+  NOTIMPLEMENTED();
+}
+
+bool WebUIBrowserWindow::IsBorderlessModeEnabled() const {
+  NOTIMPLEMENTED();
+  return false;
+}
+
+void WebUIBrowserWindow::OnWebApiWindowResizableChanged() {
+  NOTIMPLEMENTED();
+}
+
+bool WebUIBrowserWindow::GetCanResize() {
+  NOTIMPLEMENTED();
+  return false;
+}
+
+ui::mojom::WindowShowState WebUIBrowserWindow::GetWindowShowState() const {
+  NOTIMPLEMENTED();
+  return ui::mojom::WindowShowState::kDefault;
+}
+
+void WebUIBrowserWindow::ShowChromeLabs() {
+  NOTIMPLEMENTED();
+}
+
+views::WebView* WebUIBrowserWindow::GetContentsWebView() {
+  NOTIMPLEMENTED();
+  return nullptr;
+}
+
+BrowserView* WebUIBrowserWindow::AsBrowserView() {
+  NOTIMPLEMENTED();
+  return nullptr;
+}
+
+gfx::Rect WebUIBrowserWindow::GetBounds() const {
+  NOTIMPLEMENTED();
+  return gfx::Rect();
+}
+
+bool WebUIBrowserWindow::IsMaximized() const {
+  NOTIMPLEMENTED();
+  return false;
+}
+
+bool WebUIBrowserWindow::IsMinimized() const {
+  NOTIMPLEMENTED();
+  return false;
+}
+
+bool WebUIBrowserWindow::IsFullscreen() const {
+  NOTIMPLEMENTED();
+  return false;
+}
+
+gfx::Rect WebUIBrowserWindow::GetRestoredBounds() const {
+  NOTIMPLEMENTED();
+  return gfx::Rect();
+}
+
+ui::mojom::WindowShowState WebUIBrowserWindow::GetRestoredState() const {
+  NOTIMPLEMENTED();
+  return ui::mojom::WindowShowState::kDefault;
+}
+
+void WebUIBrowserWindow::Maximize() {
+  NOTIMPLEMENTED();
+}
+
+void WebUIBrowserWindow::Minimize() {
+  NOTIMPLEMENTED();
+}
+
+void WebUIBrowserWindow::Restore() {
+  NOTIMPLEMENTED();
+}
+
+void WebUIBrowserWindow::DestroyBrowser() {
+  NOTIMPLEMENTED();
+}
diff --git a/chrome/browser/ui/webui_browser/webui_browser_window.h b/chrome/browser/ui/webui_browser/webui_browser_window.h
new file mode 100644
index 0000000..a6272d2
--- /dev/null
+++ b/chrome/browser/ui/webui_browser/webui_browser_window.h
@@ -0,0 +1,213 @@
+// 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.
+
+#ifndef CHROME_BROWSER_UI_WEBUI_BROWSER_WEBUI_BROWSER_WINDOW_H_
+#define CHROME_BROWSER_UI_WEBUI_BROWSER_WEBUI_BROWSER_WINDOW_H_
+
+#include <memory>
+
+#include "chrome/browser/ui/browser_window.h"
+
+class Browser;
+
+// A BrowserWindow implementation that uses WebUI for its primary UI. It still
+// uses views::Widget for windowing management.
+class WebUIBrowserWindow : public BrowserWindow {
+ public:
+  explicit WebUIBrowserWindow(std::unique_ptr<Browser> browser);
+  ~WebUIBrowserWindow() override;
+
+  // BrowserWindow:
+  gfx::NativeWindow GetNativeWindow() const override;
+  bool IsOnCurrentWorkspace() const override;
+  bool IsVisibleOnScreen() const override;
+  void SetTopControlsShownRatio(content::WebContents* web_contents,
+                                float ratio) override;
+  bool DoBrowserControlsShrinkRendererSize(
+      const content::WebContents* contents) const override;
+  ui::NativeTheme* GetNativeTheme() override;
+  const ui::ThemeProvider* GetThemeProvider() const override;
+  const ui::ColorProvider* GetColorProvider() const override;
+  ui::ElementContext GetElementContext() override;
+  int GetTopControlsHeight() const override;
+  void SetTopControlsGestureScrollInProgress(bool in_progress) override;
+  std::vector<StatusBubble*> GetStatusBubbles() override;
+  void UpdateTitleBar() override;
+  void BookmarkBarStateChanged(
+      BookmarkBar::AnimateChangeType change_type) override;
+  void TemporarilyShowBookmarkBar(base::TimeDelta duration) override;
+  void UpdateDevTools() override;
+  void UpdateLoadingAnimations(bool is_visible) override;
+  void SetStarredState(bool is_starred) override;
+  bool IsTabModalPopupDeprecated() const override;
+  void SetIsTabModalPopupDeprecated(
+      bool is_tab_modal_popup_deprecated) override;
+  void OnActiveTabChanged(content::WebContents* old_contents,
+                          content::WebContents* new_contents,
+                          int index,
+                          int reason) override;
+  void OnTabDetached(content::WebContents* contents, bool was_active) override;
+  void ZoomChangedForActiveTab(bool can_show_bubble) override;
+  bool ShouldHideUIForFullscreen() const override;
+  bool IsFullscreenBubbleVisible() const override;
+  bool IsForceFullscreen() const override;
+  void SetForceFullscreen(bool force_fullscreen) override;
+  gfx::Size GetContentsSize() const override;
+  void SetContentsSize(const gfx::Size& size) override;
+  void UpdatePageActionIcon(PageActionIconType type) override;
+  autofill::AutofillBubbleHandler* GetAutofillBubbleHandler() override;
+  void ExecutePageActionIconForTesting(PageActionIconType type) override;
+  LocationBar* GetLocationBar() const override;
+  void SetFocusToLocationBar(bool select_all) override;
+  void UpdateReloadStopState(bool is_loading, bool force) override;
+  void UpdateToolbar(content::WebContents* contents) override;
+  bool UpdateToolbarSecurityState() override;
+  void UpdateCustomTabBarVisibility(bool visible, bool animate) override;
+  void SetContentScrimVisibility(bool visible) override;
+  void SetDevToolsScrimVisibility(bool visible) override;
+  void ResetToolbarTabState(content::WebContents* contents) override;
+  void FocusToolbar() override;
+  ExtensionsContainer* GetExtensionsContainer() override;
+  void ToolbarSizeChanged(bool is_animating) override;
+  void TabDraggingStatusChanged(bool is_dragging) override;
+  void LinkOpeningFromGesture(WindowOpenDisposition disposition) override;
+  void FocusAppMenu() override;
+  void FocusBookmarksToolbar() override;
+  void FocusInactivePopupForAccessibility() override;
+  void RotatePaneFocus(bool forwards) override;
+  void FocusWebContentsPane() override;
+  bool IsBookmarkBarVisible() const override;
+  bool IsBookmarkBarAnimating() const override;
+  bool IsTabStripEditable() const override;
+  void SetTabStripNotEditableForTesting() override;
+  bool IsToolbarVisible() const override;
+  bool IsToolbarShowing() const override;
+  bool IsLocationBarVisible() const override;
+  SharingDialog* ShowSharingDialog(content::WebContents* contents,
+                                   SharingDialogData data) override;
+  void ShowUpdateChromeDialog() override;
+  void ShowIntentPickerBubble(
+      std::vector<apps::IntentPickerAppInfo> app_info,
+      bool show_stay_in_chrome,
+      bool show_remember_selection,
+      apps::IntentPickerBubbleType bubble_type,
+      const std::optional<url::Origin>& initiating_origin,
+      IntentPickerResponse callback) override;
+  void ShowBookmarkBubble(const GURL& url, bool already_bookmarked) override;
+  sharing_hub::ScreenshotCapturedBubble* ShowScreenshotCapturedBubble(
+      content::WebContents* contents,
+      const gfx::Image& image) override;
+  qrcode_generator::QRCodeGeneratorBubbleView* ShowQRCodeGeneratorBubble(
+      content::WebContents* contents,
+      const GURL& url,
+      bool show_back_button) override;
+  send_tab_to_self::SendTabToSelfBubbleView*
+  ShowSendTabToSelfDevicePickerBubble(content::WebContents* contents) override;
+  send_tab_to_self::SendTabToSelfBubbleView* ShowSendTabToSelfPromoBubble(
+      content::WebContents* contents,
+      bool show_signin_button) override;
+#if BUILDFLAG(IS_CHROMEOS)
+  views::Button* GetSharingHubIconButton() override;
+  void ToggleMultitaskMenu() const override;
+#else
+  sharing_hub::SharingHubBubbleView* ShowSharingHubBubble(
+      share::ShareAttempt attempt) override;
+#endif  // BUILDFLAG(IS_CHROMEOS)
+  ShowTranslateBubbleResult ShowTranslateBubble(
+      content::WebContents* contents,
+      translate::TranslateStep step,
+      const std::string& source_language,
+      const std::string& target_language,
+      translate::TranslateErrors error_type,
+      bool is_user_gesture) override;
+  void StartPartialTranslate(const std::string& source_language,
+                             const std::string& target_language,
+                             const std::u16string& text_selection) override;
+  void ShowOneClickSigninConfirmation(
+      const std::u16string& email,
+      base::OnceCallback<void(bool)> confirmed_callback) override;
+  views::View* GetTopContainer() override;
+  views::View* GetLensOverlayView() override;
+  DownloadBubbleUIController* GetDownloadBubbleUIController() override;
+  void ConfirmBrowserCloseWithPendingDownloads(
+      int download_count,
+      Browser::DownloadCloseType dialog_type,
+      base::OnceCallback<void(bool)> callback) override;
+  void UserChangedTheme(BrowserThemeChangeType theme_change_type) override;
+  void ShowAppMenu() override;
+  bool PreHandleMouseEvent(const blink::WebMouseEvent& event) override;
+  void PreHandleDragUpdate(const content::DropData& drop_data,
+                           const gfx::PointF& point) override;
+  void PreHandleDragExit() override;
+  void HandleDragEnded() override;
+  content::KeyboardEventProcessingResult PreHandleKeyboardEvent(
+      const input::NativeWebKeyboardEvent& event) override;
+  bool HandleKeyboardEvent(const input::NativeWebKeyboardEvent& event) override;
+  std::unique_ptr<FindBar> CreateFindBar() override;
+  web_modal::WebContentsModalDialogHost* GetWebContentsModalDialogHost()
+      override;
+  void ShowAvatarBubbleFromAvatarButton(bool is_source_accelerator) override;
+  void MaybeShowProfileSwitchIPH() override;
+  void MaybeShowSupervisedUserProfileSignInIPH() override;
+  void ShowHatsDialog(
+      const std::string& site_id,
+      const std::optional<std::string>& hats_histogram_name,
+      const std::optional<uint64_t> hats_survey_ukm_id,
+      base::OnceClosure success_callback,
+      base::OnceClosure failure_callback,
+      const SurveyBitsData& product_specific_bits_data,
+      const SurveyStringData& product_specific_string_data) override;
+  ExclusiveAccessContext* GetExclusiveAccessContext() override;
+  std::string GetWorkspace() const override;
+  bool IsVisibleOnAllWorkspaces() const override;
+  void ShowEmojiPanel() override;
+  std::unique_ptr<content::EyeDropper> OpenEyeDropper(
+      content::RenderFrameHost* frame,
+      content::EyeDropperListener* listener) override;
+  void ShowCaretBrowsingDialog() override;
+  void CreateTabSearchBubble(
+      tab_search::mojom::TabSearchSection section,
+      tab_search::mojom::TabOrganizationFeature organization_feature) override;
+  void CloseTabSearchBubble() override;
+  void ShowIncognitoClearBrowsingDataDialog() override;
+  void ShowIncognitoHistoryDisclaimerDialog() override;
+  bool IsBorderlessModeEnabled() const override;
+  void OnWebApiWindowResizableChanged() override;
+  bool GetCanResize() override;
+  ui::mojom::WindowShowState GetWindowShowState() const override;
+  void ShowChromeLabs() override;
+  views::WebView* GetContentsWebView() override;
+  BrowserView* AsBrowserView() override;
+
+  // ui::BaseWindow:
+  void Show() override;
+  void ShowInactive() override;
+  void Hide() override;
+  bool IsVisible() const override;
+  void SetBounds(const gfx::Rect& bounds) override;
+  void Close() override;
+  void Activate() override;
+  void Deactivate() override;
+  bool IsActive() const override;
+  gfx::Rect GetBounds() const override;
+  bool IsMaximized() const override;
+  bool IsMinimized() const override;
+  bool IsFullscreen() const override;
+  gfx::Rect GetRestoredBounds() const override;
+  ui::mojom::WindowShowState GetRestoredState() const override;
+  void Maximize() override;
+  void Minimize() override;
+  void Restore() override;
+  void FlashFrame(bool flash) override;
+  ui::ZOrderLevel GetZOrderLevel() const override;
+  void SetZOrderLevel(ui::ZOrderLevel order) override;
+
+ protected:
+  void DestroyBrowser() override;
+
+ private:
+  std::unique_ptr<Browser> browser_;
+};
+
+#endif  // CHROME_BROWSER_UI_WEBUI_BROWSER_WEBUI_BROWSER_WINDOW_H_
diff --git a/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_device_attributes_browsertest.cc b/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_device_attributes_browsertest.cc
index cb35820c..8a3fbcd 100644
--- a/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_device_attributes_browsertest.cc
+++ b/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_device_attributes_browsertest.cc
@@ -200,10 +200,10 @@
       EXPECT_EQ(kExpectedDeviceAttributeValues[i],
                 CallDeviceAttributesApi(app_frame, kDeviceAttributeNames[i]));
     } else {
-      EXPECT_THAT(
-          CallDeviceAttributesApi(app_frame, kDeviceAttributeNames[i]).error,
-          HasSubstr(IsFeatureFlagEnabled() ? kPermissionsPolicyError
-                                           : kAdminPolicyError));
+      EXPECT_THAT(CallDeviceAttributesApi(app_frame, kDeviceAttributeNames[i]),
+                  content::EvalJsResult::ErrorIs(
+                      HasSubstr(IsFeatureFlagEnabled() ? kPermissionsPolicyError
+                                                       : kAdminPolicyError)));
     }
   }
 }
@@ -232,8 +232,8 @@
   ASSERT_NE(iframe, nullptr);
 
   for (const std::string& attribute_name : kDeviceAttributeNames) {
-    EXPECT_THAT(CallDeviceAttributesApi(iframe, attribute_name).error,
-                HasSubstr(kChildFrameError));
+    EXPECT_THAT(CallDeviceAttributesApi(iframe, attribute_name),
+                content::EvalJsResult::ErrorIs(HasSubstr(kChildFrameError)));
   }
 }
 
diff --git a/chrome/build/android-desktop-x64.pgo.txt b/chrome/build/android-desktop-x64.pgo.txt
index ca27bdc..d94fc673 100644
--- a/chrome/build/android-desktop-x64.pgo.txt
+++ b/chrome/build/android-desktop-x64.pgo.txt
@@ -1 +1 @@
-chrome-android-desktop-x64-main-1753574358-ecf17a6ec7d69de6c510c082f505d256be83a672-2c3b089d273526f81ea961dad6ff1f05a7bc3f10.profdata
+chrome-android-desktop-x64-main-1753660600-f37ae7e8ec60744a36c44088c22dac68beb5dfc7-73892b39c2de3437b0936cbdb0cbc92af42d58b9.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt
index d066283..11eab603 100644
--- a/chrome/build/mac-arm.pgo.txt
+++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@
-chrome-mac-arm-main-1753550705-bbe12ba60dd1cbba6c662c2dfd6c41191910a8d1-30f689e99494d57ef7f6f16efcf1e86958c60fac.profdata
+chrome-mac-arm-main-1753660600-1db836c9ead8956bd629b7502713c3347a4cbdcf-73892b39c2de3437b0936cbdb0cbc92af42d58b9.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt
index 3403e1e5..1068f06 100644
--- a/chrome/build/mac.pgo.txt
+++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@
-chrome-mac-main-1753550705-973274449a236e3e8cfbbb700699e17bef76f77f-30f689e99494d57ef7f6f16efcf1e86958c60fac.profdata
+chrome-mac-main-1753660600-bab540cdb183590cc66cb35536316dcb93c691d0-73892b39c2de3437b0936cbdb0cbc92af42d58b9.profdata
diff --git a/chrome/build/win-arm64.pgo.txt b/chrome/build/win-arm64.pgo.txt
index d167cb9a..956015a7 100644
--- a/chrome/build/win-arm64.pgo.txt
+++ b/chrome/build/win-arm64.pgo.txt
@@ -1 +1 @@
-chrome-win-arm64-main-1753574358-5e53c0edfe360d6c32b00f61ca917f1a12af9f1e-2c3b089d273526f81ea961dad6ff1f05a7bc3f10.profdata
+chrome-win-arm64-main-1753660600-88e98170e0582ec4a9eb6bff1c13d5ff79ad88a9-73892b39c2de3437b0936cbdb0cbc92af42d58b9.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt
index 741bd91a..470b1fb 100644
--- a/chrome/build/win32.pgo.txt
+++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@
-chrome-win32-main-1753550705-1ad85fe6bf57237bc0cf5501b41954eaebceefc3-30f689e99494d57ef7f6f16efcf1e86958c60fac.profdata
+chrome-win32-main-1753649984-7a519a09a4afe9fa1b012da9842c171abfaaa449-ea0bf447cc6cb17b25dafebad3bd5e5e3134fb4d.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index 4b822e94..3838b2e 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-main-1753550705-62d9ed87fceab4d8b8742c5c75098fafb126e841-30f689e99494d57ef7f6f16efcf1e86958c60fac.profdata
+chrome-win64-main-1753649984-6468f98395855aefa7f711792320d5579d04e09b-ea0bf447cc6cb17b25dafebad3bd5e5e3134fb4d.profdata
diff --git a/chrome/test/data/webui/settings/settings_main_plugins_test.ts b/chrome/test/data/webui/settings/settings_main_plugins_test.ts
index ec8b0775..1744e67a 100644
--- a/chrome/test/data/webui/settings/settings_main_plugins_test.ts
+++ b/chrome/test/data/webui/settings/settings_main_plugins_test.ts
@@ -22,8 +22,19 @@
     return CrSettingsPrefs.initialized;
   });
 
-  function createSettingsMain() {
+  function createSettingsMain(overrides?: {[key: string]: any}) {
     document.body.innerHTML = window.trustedTypes!.emptyHTML;
+
+    loadTimeData.overrideValues(Object.assign(
+        {
+          isGuest: false,
+          showAiPage: false,
+          showResetProfileBanner: false,
+        },
+        overrides || {}));
+    resetPageVisibilityForTesting();
+    resetRouterForTesting();
+
     searchManager = new TestSearchManager();
     setSearchManagerForTesting(searchManager);
     Router.getInstance().navigateTo(routes.BASIC);
@@ -35,11 +46,6 @@
   }
 
   setup(function() {
-    loadTimeData.overrideValues({
-      isGuest: false,
-      showAiPage: false,
-      showResetProfileBanner: false,
-    });
     createSettingsMain();
   });
 
@@ -144,10 +150,7 @@
     assertVisibilityRespected();
 
     // Case2: Guest mode
-    loadTimeData.overrideValues({isGuest: true});
-    resetPageVisibilityForTesting();
-    // Create a new instance for the visibility to have an effect.
-    createSettingsMain();
+    createSettingsMain({isGuest: true});
     assertVisibilityRespected();
   });
 
@@ -155,10 +158,7 @@
     assertFalse(loadTimeData.getBoolean('showAiPage'));
     assertFalse(!!queryView('ai'));
 
-    loadTimeData.overrideValues({showAiPage: true});
-    resetPageVisibilityForTesting();
-    resetRouterForTesting();
-    createSettingsMain();
+    createSettingsMain({showAiPage: true});
     assertTrue(!!queryView('ai'));
   });
 
@@ -173,10 +173,8 @@
     assertEquals('people', active.id);
 
     // Case2: Guest mode.
-    loadTimeData.overrideValues({isGuest: true});
-    resetPageVisibilityForTesting();
-    // Create a new instance for the visibility to have an effect.
-    createSettingsMain();
+    createSettingsMain({isGuest: true});
+    await flushTasks();
     active = settingsMain.$.switcher.querySelector<HTMLElement>(
         '.active[slot=view]');
     assertTrue(!!active);
@@ -184,15 +182,14 @@
     assertEquals('search', active.id);
     // </if>
     // <if expr="is_chromeos">
-    assertEquals('old', active.id);
+    assertEquals('privacy', active.id);
     // </if>
   });
 
   test('ResetProfileBannerShown', function() {
     assertFalse(!!settingsMain.shadowRoot!.querySelector(
         'settings-reset-profile-banner'));
-    loadTimeData.overrideValues({showResetProfileBanner: true});
-    createSettingsMain();
+    createSettingsMain({showResetProfileBanner: true});
     assertTrue(!!settingsMain.shadowRoot!.querySelector(
         'settings-reset-profile-banner'));
   });
diff --git a/chrome/test/interaction/webcontents_interaction_test_util.cc b/chrome/test/interaction/webcontents_interaction_test_util.cc
index 7e6be93..e32f385 100644
--- a/chrome/test/interaction/webcontents_interaction_test_util.cc
+++ b/chrome/test/interaction/webcontents_interaction_test_util.cc
@@ -749,10 +749,10 @@
   auto result = EvalJsLocal(web_contents(), function);
   if (!result.is_ok()) {
     if (error_message) {
-      *error_message = result.error;
+      *error_message = result.ExtractError();
       return base::Value();
     } else {
-      NOTREACHED() << "Uncaught JS exception: " << result.error;
+      NOTREACHED() << "Uncaught JS exception: " << result;
     }
   }
 
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM
index f39280d..a8bbd91 100644
--- a/chromeos/CHROMEOS_LKGM
+++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@
-16362.0.0-1070542
\ No newline at end of file
+16363.0.0-1070563
\ No newline at end of file
diff --git a/chromeos/ash/services/assistant/test_support/scoped_assistant_browser_delegate.cc b/chromeos/ash/services/assistant/test_support/scoped_assistant_browser_delegate.cc
index d13d0fe..553d742 100644
--- a/chromeos/ash/services/assistant/test_support/scoped_assistant_browser_delegate.cc
+++ b/chromeos/ash/services/assistant/test_support/scoped_assistant_browser_delegate.cc
@@ -44,7 +44,7 @@
 }
 
 void ScopedAssistantBrowserDelegate::OpenUrl(GURL url) {
-  NewWindowDelegate::GetPrimary()->OpenUrl(
+  NewWindowDelegate::GetInstance()->OpenUrl(
       url, NewWindowDelegate::OpenUrlFrom::kUserInteraction,
       NewWindowDelegate::Disposition::kNewForegroundTab);
 }
diff --git a/chromeos/profiles/arm.afdo.newest.txt b/chromeos/profiles/arm.afdo.newest.txt
index 458b6bff..a6b4d4d 100644
--- a/chromeos/profiles/arm.afdo.newest.txt
+++ b/chromeos/profiles/arm.afdo.newest.txt
@@ -1 +1 @@
-chromeos-chrome-arm-none-140-7258.43-1753063931-benchmark-140.0.7318.0_pre1492031-r1-redacted.afdo.xz
+chromeos-chrome-arm-none-140-7258.43-1753063931-benchmark-140.0.7320.0_pre1492415-r1-redacted.afdo.xz
diff --git a/clank b/clank
index b4f8c32..d59dd84 160000
--- a/clank
+++ b/clank
@@ -1 +1 @@
-Subproject commit b4f8c32a7394401015d4d5e47795851678fe4caf
+Subproject commit d59dd8427adcc49e55c04f8929d7721357f9c5a9
diff --git a/components/certificate_transparency/data/log_list.json b/components/certificate_transparency/data/log_list.json
index 1d52f33..4c3c116 100644
--- a/components/certificate_transparency/data/log_list.json
+++ b/components/certificate_transparency/data/log_list.json
@@ -1,6 +1,6 @@
 {
-  "version": "59.17",
-  "log_list_timestamp": "2025-07-26T12:55:35Z",
+  "version": "59.18",
+  "log_list_timestamp": "2025-07-27T12:54:32Z",
   "operators": [
     {
       "name": "Google",
diff --git a/components/guest_contents/README.md b/components/guest_contents/README.md
new file mode 100644
index 0000000..dcb40a8d
--- /dev/null
+++ b/components/guest_contents/README.md
@@ -0,0 +1,293 @@
+`GuestContents` is an experimental component that allows you to embed an
+independent `content::WebContents` (a "guest") within an outer
+`content::WebContents`, which is typically a WebUI page. This is useful for
+displaying external web content inside your WebUI in a sandboxed way, similar to
+the functionality of the `<webview>` tag in Chrome Apps.
+
+The core mechanism involves swapping an `<iframe>` in the outer WebUI's renderer
+process with the main frame of the guest `WebContents` from the browser process.
+This process is orchestrated via the `GuestContentsHost` Mojo interfaces.
+
+`GuestContents` is **NOT** for production use due to privacy and security
+reasons. See [Security Considerations](#security-considerations).
+
+# Core Concepts
+
+-   **Guest `WebContents`**: The WebContents instance that you want to embed.
+
+-   **Outer `WebContents`**: The host WebContents, which is your WebUI page.
+
+-   `GuestContentsHandle`: A browser-side handle for the guest `WebContents`. It
+    assigns a unique `GuestId` to the guest and manages its attachment to an
+    outer `WebContents`. Its lifetime is tied to the guest `WebContents`.
+
+-   `guest_contents::mojom::GuestContentsHost`: A Mojo interface implemented in
+    the browser process. The outer WebUI's renderer calls this interface to
+    request the attachment of a guest. The WebUI's `WebUIController` handles the
+    binding of this interface via a `BindInterface()` method.
+
+-   `guest_contents::renderer::SwapRenderFrame`: A renderer-side C++ function
+    that initiates the guest attachment process by calling the
+    `GuestContentsHost` Mojo interface.
+
+# How-To Guide
+
+Here is a step-by-step guide to embedding a guest `WebContents` in your WebUI.
+[webui_examples](https://source.chromium.org/chromium/chromium/src/+/main:ui/webui/examples/README.md)
+uses this pattern and is a good example to follow.
+
+### 1. Browser-Side Setup
+
+In your WebUI's browser-side C++ code:
+
+-   **Register the `GuestContentsHost` interface** in `ContentBrowserClient` for
+    your `WebUIController`.
+
+    ```c++
+    // ui/webui/examples/browser/content_browser_client.cc
+    void ContentBrowserClient::RegisterBrowserInterfaceBindersForFrame(...) {
+      // ...
+      // `Browser` is a WebUIController.
+      RegisterWebUIControllerInterfaceBinder<
+          guest_contents::mojom::GuestContentsHost, Browser>(map);
+    }
+    ```
+
+-   **Bind the `GuestContentsHost` Mojo Interface**: Your WebUI controller must
+    expose the `GuestContentsHost` interface to its renderer.
+
+    ```c++
+    // ui/webui/examples/browser/ui/web/browser.h
+    class Browser : public ui::MojoWebUIController, ... {
+      // ...
+      void BindInterface(
+          mojo::PendingReceiver<guest_contents::mojom::GuestContentsHost> receiver);
+      // ...
+    };
+
+    // ui/webui/examples/browser/ui/web/browser.cc
+    void Browser::BindInterface(
+        mojo::PendingReceiver<guest_contents::mojom::GuestContentsHost> receiver) {
+      guest_contents::GuestContentsHostImpl::Create(web_ui()->GetWebContents(),
+                                                    std::move(receiver));
+    }
+    ```
+
+-   **Create and Own the Guest `WebContents`**: For example, in your
+    WebUIController's constructor, create the guest WebContents.
+
+    ```c++
+    // ui/webui/examples/browser/ui/web/browser.h
+    class Browser : public ui::MojoWebUIController, ... {
+      // ...
+      std::unique_ptr<content::WebContents> guest_contents_;
+    };
+
+    // ui/webui/examples/browser/ui/web/browser.cc
+    Browser::Browser(content::WebUI* web_ui)
+        : ui::MojoWebUIController(web_ui, false) {
+      content::BrowserContext* browser_context =
+          web_ui->GetWebContents()->GetBrowserContext();
+      // ...
+      content::WebContents::CreateParams params(browser_context);
+      guest_contents_ = content::WebContents::Create(params);
+      // ...
+    }
+    ```
+
+-   **Create a `GuestContentsHandle` and Pass its ID to the Frontend**: The
+    handle provides the unique ID needed to identify the guest. Pass this ID to
+    your frontend JavaScript, for example, using `loadTimeData` or via a Mojo
+    interface. The following example uses `loadTimeData`.
+
+    ```c++
+    // ui/webui/examples/browser/ui/web/browser.cc
+    Browser::Browser(content::WebUI* web_ui) : ... {
+      // ... (create guest_contents_)
+      guest_contents::GuestContentsHandle::CreateForWebContents(
+          guest_contents_.get());
+      auto* guest_handle = guest_contents::GuestContentsHandle::FromWebContents(
+          guest_contents_.get());
+      html_source->AddInteger("guest-contents-id", guest_handle->id());
+    }
+    ```
+
+### 2. Renderer-Side Setup (C++)
+
+To bridge the gap between your frontend JavaScript and the browser process, you
+need some C++ code in the renderer.
+
+-   **Expose C++ Bindings to JavaScript**: Inject functions into the renderer's
+    JavaScript context. The example uses a `RenderFrameObserver` to add a
+    `webshell` object with C++-backed functions when the WebUI is ready.
+
+    ```c++
+    // ui/webui/examples/renderer/render_frame_observer.cc
+    void RenderFrameObserver::ReadyToCommitNavigation(...) {
+      V8BinderContext binder_context(render_frame());
+      binder_context.CreateWebshellObject();
+      binder_context.AddCallbackToWebshellObject(
+          "attachIframeGuest", base::BindRepeating(&AttachIframeGuest));
+      // ...
+    }
+    ```
+
+-   **Implement the Binding**: The AttachIframeGuest function parses the
+    arguments from JavaScript, gets the `content::RenderFrame*` for the
+    `<iframe>`, and calls the `guest_contents` helper function.
+
+    ```c++
+    // ui/webui/examples/renderer/render_frame_observer.cc
+    void AttachIframeGuest(const v8::FunctionCallbackInfo<v8::Value>& args) {
+      // ... argument parsing ...
+      int guest_contents_id = args[0].As<v8::Int32>()->Value();
+      content::RenderFrame* render_frame = GetRenderFrame(args[1]);
+      // ...
+      guest_contents::renderer::SwapRenderFrame(render_frame, guest_contents_id);
+    }
+    ```
+
+This `SwapRenderFrame` function handles the final step of calling the
+[`GuestContentsHost.Attach`](https://source.chromium.org/chromium/chromium/src/+/main:components/guest_contents/common/guest_contents.mojom;l=16;drc=d6543287271f614b90e40373609a38a1092e3e63)
+Mojo method, which completes the attachment in the browser process.
+
+### 3. Renderer-Side Setup (TypeScript/HTML)
+
+In your WebUI's frontend code, add a placeholder element that will be swapped
+with the guest. An `<iframe>` is a good choice, although other frame-like
+element might also work. In the following example, `<webview>` is a custom web
+component that has a `<iframe>` child element.
+
+```html
+<!-- ui/webui/examples/resources/browser/index.html -->
+<webview id="webview"></webview>
+```
+
+In your TypeScript/JavaScript, get the `guest-contents-id` from `loadTimeData`.
+Then, call a C++ binding to trigger the attachment. The example uses a
+`webshell` object injected into the renderer for this communication.
+
+```typescript
+// ui/webui/examples/resources/browser/index.ts
+class WebviewElement extends HTMLElement {
+  public iframeElement: HTMLIFrameElement;
+  private guestContentsId: number;
+
+  constructor() {
+    super();
+    this.iframeElement = document.createElement('iframe');
+    this.appendChild(this.iframeElement);
+
+    this.guestContentsId = loadTimeData.getInteger('guest-contents-id');
+    const iframeContentWindow = this.iframeElement.contentWindow;
+
+    // This is the key call that triggers the C++ logic.
+    webshell.attachIframeGuest(this.guestContentsId,
+                               iframeContentWindow);
+  }
+  // ...
+}
+```
+
+### 4. Controlling the Guest
+
+`GuestContents` provides only basic embedding functionalities, including sizing,
+painting and event routing. The WebUI needs to provide their own implementation
+for additional controls over the guest.
+
+Navigation is a common and concrete example of additional control. To add
+support for navigation, you can:
+
+-   **Define a Mojo Interface**: Add methods like `Navigate`, `GoBack`, and
+    `GoForward` to your WebUI's page handler Mojo interface.
+
+-   **Implement in the Browser**: Implement these methods in your `PageHandler`
+    class. They should retrieve the guest `WebContents` from your WebUI
+    controller and use its `NavigationController`.
+
+-   **Call from the Frontend**: Call these Mojo methods from your TypeScript
+    code to control the guest's navigation, for example, from back/forward
+    button events.
+
+# GuestContents vs GuestView
+
+While both `GuestContents` and
+[`GuestView`](https://source.chromium.org/chromium/chromium/src/+/main:components/guest_view/README.md;l=1;drc=995605f8d603b59d99180674f304e595467d08dc)
+are used for embedding web content, they are designed for different use cases
+and have significant architectural differences, primarily due to the ongoing
+migration of `GuestView` to MPArch.
+
+### Core Distinction: Inner WebContents vs. MPArch
+
+The fundamental difference lies in how the guest content is hosted:
+
+*   **`GuestContents`** was created to explicitly **retain the use of inner
+    `WebContents`**. This allows the embedder to have direct access to the
+    guest's `WebContents` instance and its full API. This is critical for use
+    cases that need to attach `TabHelpers` (e.g., for autofill, permissions,
+    downloads) and interact deeply with the guest's state and navigation, such
+    as when embedding a full-featured browser tab.
+
+*   **`GuestView`** is migrating to MPArch (Multiple Page Architecture) and will
+    no longer use inner `WebContents`. Instead, the guest is hosted in a
+    `GuestPageHolder`. This abstracts the guest's `WebContents` away from the
+    embedder, providing stronger isolation but preventing the direct API access
+    that `GuestContents` allows.
+
+### Lifetime Management
+
+The ownership model for the guest `WebContents` is another key differentiator:
+
+*   In **`GuestContents`**, the lifetimes of the inner (guest) and outer
+    `WebContents` are **decoupled**. The client that creates the inner
+    `WebContents` is responsible for its lifetime. The outer `WebContents` does
+    not own the guest, which allows for flexible scenarios like detaching a
+    guest and re-attaching it elsewhere (e.g., dragging a tab out of a window).
+
+*   In **`GuestView`**, the outer `WebContents` typically **owns** the guest
+    `WebContents` after it is attached.
+
+### API and Complexity
+
+*   **`GuestContents`** offers a **simpler, more direct API** focused purely on
+    embedding.
+
+*   **`GuestView`** can be more complex, especially when used via extension's
+    `<webview>` tag, which brings in extension-specific concepts and
+    dependencies that may be unnecessary for non-extension use cases.
+
+# Security Considerations
+
+`GuestContents` inherits the security posture of the underlying primitives in
+`//content` and Blink. It is not inherently more or less secure than the
+pre-MPArch `GuestView` model, as both rely on the same complex mechanisms. This
+complexity can make security analysis difficult and may be a source of
+vulnerabilities.
+
+Under the hood,
+
+*   **At the `WebContents` level**: The guest and outer `WebContents` are
+    connected via `WebContentsTreeNode` after a call to
+    `WebContents::Attach(Unowned)InnerWebContents()`. This creates a
+    relationship (e.g., `WebContents::GetOuterWebContents()`) that adds
+    complexity where greater isolation would be ideal. This is used by
+    `GuestContents` and pre-MPArch `GuestView`.
+
+*   **At the frame level**: The outer `<iframe>` element and the guest's main
+    frame are connected by a
+    [`RenderFrameProxyHost`](https://source.chromium.org/chromium/chromium/src/+/main:content/browser/renderer_host/render_frame_proxy_host.h;drc=b156bea6f54b90c33f24d96f2f75925f8997044c).
+    In Blink, this is represented as a `blink::RemoteFrame`. This used by all
+    embedding techniques, including `GuestContents`, standard `<iframe>`, and
+    both pre- and post-MPArch `GuestView`.
+
+Reusing the general-purpose `<iframe>`-related primitives is considered a
+primary security risk. This IPC channel provides a much larger API surface than
+is strictly necessary for embedding a guest, including features like
+`window.opener` and `window.postMessage()`. Future changes to `<iframe>`
+implementation could unintentionally introduce vulnerabilities or break the
+security isolation between a guest and its embedder.
+
+The long-term goal (https://crbug.com/416609971) is to develop more minimal,
+purpose-built primitives for embedding that expose only the essential IPCs for
+painting, sizing, and event routing, thereby reducing the potential attack
+surface.
diff --git a/components/policy/resources/policy_templates_th.xtb b/components/policy/resources/policy_templates_th.xtb
index f7ee7995..6717f2ae 100644
--- a/components/policy/resources/policy_templates_th.xtb
+++ b/components/policy/resources/policy_templates_th.xtb
@@ -278,6 +278,7 @@
 <translation id="1202216683470826356">แสดงการ์ดในหน้าแท็บใหม่</translation>
 <translation id="1203676252390737801">การจัดการ IP ของ WebRTC ต่อ URL</translation>
 <translation id="1204263402976895730">เครื่องพิมพ์ขององค์กรที่มีการเปิดใช้</translation>
+<translation id="120513772363332049">กระบวนการอื่นๆ ทั้งหมดจะกำหนดเวลาในแกน CPU เดียวกันไม่ได้เมื่อกระบวนการแสดงผลดำเนินอยู่</translation>
 <translation id="1207301487141109411">ป้องกันไม่ให้เลือกรูปโปรไฟล์ของผู้ใช้จากระบบไฟล์ในเครื่อง กล้อง และโปรไฟล์ Google</translation>
 <translation id="1209096923317019235">กําหนดแอปเป็นตัวแฮนเดิลเริ่มต้นสําหรับนามสกุลไฟล์ที่ระบุ</translation>
 <translation id="120937472976628837">รายงานข้อมูลพัดลม</translation>
@@ -3734,6 +3735,15 @@
       การตั้งค่านโยบายเป็น "ปิดใช้" จะทำให้ใช้ Translator API ไม่ได้</translation>
 <translation id="366494444808132420">อนุญาตการผสานรวม Gemini</translation>
 <translation id="3665437376055221832">แสดงข้อความแจ้งผู้ใช้เฉพาะในกรณีที่ไม่มีใบรับรองตรงกับการเลือกอัตโนมัติ</translation>
+<translation id="3667089394451236198">รายการรูปแบบ URL คำขอที่เริ่มต้นมาจากเว็บไซต์ที่แสดงโดยต้นทางที่ตรงกันจะไม่ต้องมีการตรวจสอบ<ph name="LOCAL_NETWORK_ACCESS" />
+
+หากต้นทางครอบคลุมทั้งนโยบายนี้และ LocalNetworkAccessBlockedForUrls นโยบาย LocalNetworkAccessBlockedForUrls จะมีผลเหนือกว่า
+
+สำหรับต้นทางที่ไม่รวมอยู่ในรูปแบบที่ระบุไว้ที่นี่ ระบบจะใช้การกำหนดค่าส่วนตัวของผู้ใช้
+
+ดูข้อมูลโดยละเอียดเกี่ยวกับรูปแบบ URL ที่ถูกต้องได้ที่ https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns
+
+ดูข้อจำกัดของ <ph name="LOCAL_NETWORK_ACCESS" /> ได้ที่ https://wicg.github.io/local-network-access/</translation>
 <translation id="3671773704245936868">ปิดใช้การไฮไลต์โฟกัสแป้นพิมพ์</translation>
 <translation id="3674010627788940405">ไม่รองรับส่วนหัวของคำขอที่ไม่มีไวลด์การ์ดสำหรับ CORS</translation>
 <translation id="3675303748198647471">โดยทั่วไปแล้ว setTimeout(…, 0) จะใช้เพื่อแบ่งงาน JavaScript ที่ยาว
@@ -4292,6 +4302,17 @@
       หากไม่ตั้งค่า <ph name="DEFAULT_SEARCH_PROVIDER_KEYWORD_POLICY_NAME" /> จะไม่มีคีย์เวิร์ดใดเลยที่เปิดใช้งานผู้ให้บริการค้นหาดังกล่าว</translation>
 <translation id="4090088362777472639">แฮช SHA-256 ของ Ansible Playbook</translation>
 <translation id="4091040199847925434">ปิดใช้การรายงานข้อมูลระบบและเนื้อหาของหน้าซึ่งใช้เพื่อช่วยปรับปรุง Google Safe Browsing</translation>
+<translation id="4092882308219320847">รายการรูปแบบ URL คำขอที่เริ่มต้นมาจากเว็บไซต์ที่แสดงโดยต้นทางที่ตรงกันจะถูกบล็อกไม่ให้ออกคําขอ<ph name="LOCAL_NETWORK_ACCESS" />
+
+หากต้นทางครอบคลุมทั้งนโยบายนี้และ LocalNetworkAccessAllowedForUrls นโยบายนี้จะมีผลเหนือกว่า
+
+คุณอาจต้องเปิดใช้ LocalNetworkAccessRestrictionsEnabled ด้วยเพื่อให้นโยบายนี้บล็อกคำขอ<ph name="LOCAL_NETWORK_ACCESS" />ได้ ทั้งนี้ขึ้นอยู่กับขั้นตอนของการเปิดตัว<ph name="LOCAL_NETWORK_ACCESS" />
+
+สำหรับต้นทางที่ไม่รวมอยู่ในรูปแบบที่ระบุไว้ที่นี่ ระบบจะใช้การกำหนดค่าส่วนตัวของผู้ใช้
+
+ดูข้อมูลโดยละเอียดเกี่ยวกับรูปแบบ URL ที่ถูกต้องได้ที่ https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns
+
+ดูข้อจำกัดของ <ph name="LOCAL_NETWORK_ACCESS" /> ได้ที่ https://wicg.github.io/local-network-access/</translation>
 <translation id="4093058072421210667">ไม่อนุญาตให้ใช้รูปภาพในบรรทัด</translation>
 <translation id="4098920079809952737">อนุญาตการพิมพ์ทั้งกรณีที่มีและไม่มีกราฟิกพื้นหลัง</translation>
 <translation id="410061592404122032">ถามทุกครั้งที่เว็บไซต์ต้องการได้รับสิทธิ์การจัดการหน้าต่าง</translation>
@@ -6382,6 +6403,7 @@
 <translation id="5490462588616309068">หากตั้งค่านโยบายเป็น "จริง" หรือไม่ได้ตั้งค่าไว้ ระบบจะอนุญาตให้ใช้ตัวระบุเนื้อหาที่มีการคุ้มครอง ซึ่งจะช่วยให้เล่นเนื้อหาที่มีการคุ้มครองได้ในคุณภาพที่สูงขึ้น
 
 หากตั้งค่านโยบายเป็น "เท็จ" ระบบจะไม่อนุญาตให้ใช้ตัวระบุเนื้อหาที่มีการคุ้มครอง</translation>
+<translation id="5492713303272131731">กระบวนการอื่นๆ ทั้งหมดจะกำหนดเวลาในแกน CPU เดียวกันได้เมื่อกระบวนการแสดงผลดำเนินอยู่</translation>
 <translation id="5494322570831642650">ระบุว่าผู้ใช้จะเปิดหน้าด้วยโหมดไม่ระบุตัวตนใน <ph name="PRODUCT_NAME" /> หรือไม่
 
       หากเลือก "เปิดใช้" หรือไม่ได้ตั้งนโยบายไว้ หน้าอาจเปิดด้วยโหมดไม่ระบุตัวตน
@@ -8299,6 +8321,11 @@
 
 สำหรับ <ph name="PRODUCT_NAME" /> นโยบายนี้จะมีผลเมื่อลงทะเบียนเครื่องด้วย <ph name="CLOUD_MANAGEMENT_ENROLLMENT_TOKEN" /> เท่านั้น
 และสำหรับ <ph name="PRODUCT_OS_NAME" /> นโยบายนี้จะมีผลเสมอ</translation>
+<translation id="6720071484598746942">เมื่อตั้งค่านโยบายนี้เป็น "เปิดใช้" เมื่อใดก็ตามที่คำเตือนแสดงขึ้นใน <ph name="DEV_TOOLS_NAME" /> เนื่องจากการตรวจสอบ <ph name="LOCAL_NETWORK_ACCCESS" /> ล้มเหลว ระบบจะบล็อกคำขอหลักแทน
+
+เมื่อตั้งค่านโยบายนี้เป็น "ปิดใช้" หรือไม่ได้ตั้งค่า คำขอ <ph name="LOCAL_NETWORK_ACCESS" /> จะใช้การจัดการเริ่มต้นสำหรับคำขอเหล่านี้
+
+ดูข้อจำกัดของ <ph name="LOCAL_NETWORK_ACCESS" /> ได้ที่ https://wicg.github.io/local-network-access/</translation>
 <translation id="6720330829631914048">ชั่วโมงที่ผ่านไปตั้งแต่เริ่มวันใน (รูปแบบ 24 ชั่วโมง)</translation>
 <translation id="6721252203593581486">WebSQL ในบริบทของบุคคลที่สาม (เช่น iframe ข้ามเว็บไซต์) จะปิดอยู่โดยค่าเริ่มต้นตั้งแต่ M97 และจะถูกนำออกโดยสมบูรณ์ใน M101
           หากตั้งค่านโยบายนี้เป็น "เท็จ" หรือไม่ได้ตั้งค่า WebSQL ในบริบทของบุคคลที่สามจะยังคงปิดอยู่
@@ -10434,6 +10461,9 @@
 <translation id="8331479227794770304">เปิดใช้คีย์ติดหนึบ</translation>
 <translation id="8332822245414537447">ปิดใช้การตรวจสอบการใช้งานคีย์ RSA</translation>
 <translation id="8334685561819743286">ปิดใช้ฟีเจอร์การแก้ไขอัตโนมัติบนแป้นพิมพ์จริงเมื่อผู้ใช้พิมพ์</translation>
+<translation id="8336986243404088829">นโยบายนี้ช่วยลดการโจมตีหน่วยความจำข้ามกระบวนการฝั่งช่องโดยแยกกระบวนการแสดงผลในแกน CPU และป้องกันไม่ให้กระบวนการอื่นๆ แชร์แกนเดียวกัน การลดผลกระทบนี้รองรับใน <ph name="MS_WIN_NAME" /> 11 24H2 ขึ้นไป หากระบบปฏิบัติการไม่มีการรองรับการกำหนดเวลาที่จำเป็น นโยบายนี้จะไม่มีผล นโยบายนี้อาจทำให้ประสิทธิภาพช้าลงในบางสถานการณ์ที่ต้องใช้ทรัพยากรมาก ซึ่งคล้ายกับการปิดใช้ Hyperthreading ดูข้อมูลเพิ่มเติมได้ที่ refer https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-process_mitigation_side_channel_isolation_policy หากเปิดใช้นโยบายนี้ ระบบจะไม่กำหนดเวลาให้กระบวนการอื่นๆ ทั้งหมดในแกน CPU เดียวกันเมื่อกระบวนการแสดงผลดำเนินอยู่
+      หากปิดใช้นโยบายนี้ กระบวนการอื่นๆ ทั้งหมดจะกำหนดเวลาในแกน CPU เดียวกันได้หากกระบวนการแสดงผลดำเนินอยู่
+      หากไม่ได้ตั้งค่านโยบายนี้ กระบวนการอื่นๆ ทั้งหมดจะกำหนดเวลาในแกน CPU เดียวกันได้หากกระบวนการแสดงผลดำเนินอยู่ในแกนดังกล่าว ซึ่งอาจแตกต่างกันไปตามรุ่นของ <ph name="PRODUCT_NAME" /> การทดสอบในวงจำกัดที่ทำอยู่ในปัจจุบัน และแพลตฟอร์ม</translation>
 <translation id="8337114537412769126">หาก <ph name="DEFAULT_SEARCH_PROVIDER_ENABLED_POLICY_NAME" /> เปิดอยู่ การตั้งค่า <ph name="DEFAULT_SEARCH_PROVIDER_SUGGEST_URL_POST_PARAMS_POLICY_NAME" /> จะระบุพารามิเตอร์ระหว่างการค้นหาที่แนะนำด้วยเมธอด POST โดยจะประกอบด้วยคู่ชื่อ-ค่าที่คั่นด้วยจุลภาค หากมีค่าใดเป็นพารามิเตอร์เทมเพลต เช่น <ph name="SEARCH_TERM_MARKER" /> ข้อมูลข้อความค้นหาจริงจะแทนที่ค่าดังกล่าว
 
       การไม่ตั้งค่า <ph name="DEFAULT_SEARCH_PROVIDER_SUGGEST_URL_POST_PARAMS_POLICY_NAME" /> จะทำให้ระบบส่งคำขอการค้นหาที่แนะนำโดยใช้เมธอด GET</translation>
@@ -11673,6 +11703,7 @@
 <translation id="9162444960513782569">บังคับไม่ให้มีการควบคุมตัวจับเวลา JavaScript เบื้องหลัง</translation>
 <translation id="9164656078867027374">กำหนดโดเมนที่อนุญาตให้เข้าถึง <ph name="GOOGLE_WORKSPACE_PRODUCT_NAME" /></translation>
 <translation id="9165128017344777105">อนุญาตสิทธิ์สำหรับแบบอักษรในเครื่องในเว็บไซต์เหล่านี้</translation>
+<translation id="9165498643231979857">จำกัดการแชร์แกน CPU สำหรับกระบวนการแสดงผล</translation>
 <translation id="9166670902476893480">นโยบายนี้ควบคุมว่า <ph name="PRODUCT_NAME" /> จะส่งคำขอประเภทระเบียน DNS เพิ่มเติมเมื่อสร้างคำขอ DNS ที่ไม่ปลอดภัยได้หรือไม่ นโยบายนี้ไม่มีผลต่อคำขอ DNS ที่สร้างผ่าน DNS ที่ปลอดภัย ซึ่งจะส่งคำขอประเภท DNS เพิ่มเติมทุกครั้ง
 
       หากไม่ได้ตั้งค่านโยบายนี้หรือตั้งค่าเป็น "เปิดใช้" ระบบจะส่งคำขอประเภทเพิ่มเติม เช่น <ph name="DNS_TYPE_HTTPS" /> (DNS ประเภท 65) นอกเหนือไปจาก <ph name="DNS_TYPE_A" /> (DNS ประเภท 1) และ <ph name="DNS_TYPE_AAAA" /> (DNS ประเภท 28)
diff --git a/components/policy/resources/policy_templates_zh-CN.xtb b/components/policy/resources/policy_templates_zh-CN.xtb
index 8d0cbb5..a601015 100644
--- a/components/policy/resources/policy_templates_zh-CN.xtb
+++ b/components/policy/resources/policy_templates_zh-CN.xtb
@@ -278,6 +278,7 @@
 <translation id="1202216683470826356">在“新标签页”页面上显示卡片</translation>
 <translation id="1203676252390737801">WebRTC 网址级 IP 处理</translation>
 <translation id="1204263402976895730">已启用企业打印机</translation>
+<translation id="120513772363332049">当渲染程序进程在某个 CPU 核心上运行时,所有其他进程都不会被调度到该 CPU 核心上。</translation>
 <translation id="1207301487141109411">禁止从本地文件系统、相机和 Google 个人资料中选择用户头像</translation>
 <translation id="1209096923317019235">分配应用以用作所指定文件扩展名的默认处理程序</translation>
 <translation id="120937472976628837">报告风扇信息</translation>
@@ -3722,6 +3723,15 @@
       如果此政策已停用,系统将禁止使用 Translator API。</translation>
 <translation id="366494444808132420">允许集成 Gemini。</translation>
 <translation id="3665437376055221832">仅当没有任何证书与自动选择政策匹配时才提示用户。</translation>
+<translation id="3667089394451236198">以列表形式指定一系列网址格式。从匹配源所提供网站中发起的请求不会受到<ph name="LOCAL_NETWORK_ACCESS" />检查机制的约束。
+
+如果某个源同时受此政策和 LocalNetworkAccessBlockedForUrls 政策的约束,则优先适用 LocalNetworkAccessBlockedForUrls 政策。
+
+对于与此处所列格式不匹配的源,系统会应用用户的个人配置。
+
+如需详细了解有效网址格式,请访问 https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns。
+
+如需了解<ph name="LOCAL_NETWORK_ACCESS" />限制,请访问 https://wicg.github.io/local-network-access/。</translation>
 <translation id="3671773704245936868">禁止使用键盘焦点突出显示</translation>
 <translation id="3674010627788940405">不支持 CORS 非通配符式请求标头。</translation>
 <translation id="3675303748198647471">setTimeout(…, 0) 通常用于中断耗时较长的 JavaScript 任务。
@@ -4278,6 +4288,17 @@
       如果您不设置 <ph name="DEFAULT_SEARCH_PROVIDER_KEYWORD_POLICY_NAME" />,则意味着没有任何可用于查找此搜索服务提供商的关键字。</translation>
 <translation id="4090088362777472639">Ansible Playbook 的 SHA-256 哈希值。</translation>
 <translation id="4091040199847925434">禁止为帮助改进安全浏览功能而报告系统信息和网页内容</translation>
+<translation id="4092882308219320847">以列表形式指定一系列网址格式。从匹配源所提供网站中发起的请求将无法发出<ph name="LOCAL_NETWORK_ACCESS" />请求。
+
+如果源同时受此政策和 LocalNetworkAccessAllowedForUrls 政策的约束,则优先适用此政策。
+
+根据<ph name="LOCAL_NETWORK_ACCESS" />的推出阶段,可能还需要启用 LocalNetworkAccessRestrictionsEnabled,才能让此政策屏蔽<ph name="LOCAL_NETWORK_ACCESS" />请求。
+
+对于与此处所列格式不匹配的源,系统会应用用户的个人配置。
+
+如需详细了解有效网址格式,请访问 https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns。
+
+如需了解<ph name="LOCAL_NETWORK_ACCESS" />限制,请访问 https://wicg.github.io/local-network-access/。</translation>
 <translation id="4093058072421210667">不允许使用内嵌图片功能。</translation>
 <translation id="4098920079809952737">始终允许打印(无论是否有背景图片)</translation>
 <translation id="410061592404122032">每当网站想获得窗口管理权限时都询问</translation>
@@ -6353,6 +6374,7 @@
 <translation id="5490462588616309068">如果此政策设为 true 或未设置,则允许使用受保护内容标识符,这有助于提升受保护内容的播放质量。
 
 如果此政策设为 false,则不允许使用受保护内容标识符。</translation>
+<translation id="5492713303272131731">当渲染程序进程在某个 CPU 核心上运行时,所有其他进程也都可被调度到该 CPU 核心上。</translation>
 <translation id="5494322570831642650">此政策旨在指定用户可否在 <ph name="PRODUCT_NAME" /> 中以无痕模式打开网页。
 
       如果您选择了“Enabled”或未设置此政策,用户将能够以无痕模式打开网页。
@@ -8269,6 +8291,11 @@
 
 对于 <ph name="PRODUCT_NAME" />,此政策仅在已使用 <ph name="CLOUD_MANAGEMENT_ENROLLMENT_TOKEN" /> 注册相应设备后有效。
 对于 <ph name="PRODUCT_OS_NAME" />,此政策一直有效。</translation>
+<translation id="6720071484598746942">如果此政策已启用,只要因<ph name="LOCAL_NETWORK_ACCCESS" />检查失败而应在<ph name="DEV_TOOLS_NAME" />中显示警告,系统就会改为屏蔽主要请求。
+
+如果此政策已停用或未设置,系统将会通过默认方式处理<ph name="LOCAL_NETWORK_ACCESS" />请求。
+
+如需了解<ph name="LOCAL_NETWORK_ACCESS" />限制,请访问 https://wicg.github.io/local-network-access/。</translation>
 <translation id="6720330829631914048">自当天开始后已流逝的小时数(24 小时制)。</translation>
 <translation id="6721252203593581486">自 M97 起,第三方情境(例如跨网站 iframe)下的 WebSQL 默认处于关闭状态,并将在 M101 中被完全移除。
           如果此政策设为 false 或未设置,第三方情境下的 WebSQL 将保持关闭状态。
@@ -10393,6 +10420,10 @@
 <translation id="8331479227794770304">启用粘滞键</translation>
 <translation id="8332822245414537447">停用 RSA 密钥用法检查</translation>
 <translation id="8334685561819743286">在用户输入内容时停用实体键盘自动更正功能</translation>
+<translation id="8336986243404088829">此政策可将渲染程序进程隔离到单个 CPU 核心,并阻止其他进程共享该核心,从而缓解边信道跨进程内存攻击。<ph name="MS_WIN_NAME" /> 11 24H2 及更高版本支持此缓解措施。如果操作系统没有所需的调度支持,此政策将没有任何效力。在某些高负载场景下,此政策可能会导致性能降低,其影响类似于停用超线程功能。如需了解详情,请参阅 https://learn.microsoft.com/zh-cn/windows/win32/api/winnt/ns-winnt-process_mitigation_side_channel_isolation_policy
+      如果启用此政策,当渲染程序进程运行时,所有其他进程都不会被调度到同一 CPU 核心上。
+      如果停用此政策,当渲染程序进程在某个 CPU 核心上运行时,所有其他进程也都可被调度到该 CPU 核心上。
+      如果未设置此政策,当渲染程序进程在某个 CPU 核心上运行时,所有其他进程也都可被调度到该 CPU 核心上。网络沙盒的默认配置可能会因 <ph name="PRODUCT_NAME" /> 版本、当前运行的现场试验以及平台而异。</translation>
 <translation id="8337114537412769126">如果 <ph name="DEFAULT_SEARCH_PROVIDER_ENABLED_POLICY_NAME" /> 已开启,您便可通过设置 <ph name="DEFAULT_SEARCH_PROVIDER_SUGGEST_URL_POST_PARAMS_POLICY_NAME" /> 来指定在借助 POST 搜索建议时应使用的参数。所指定的内容由一系列以英文逗号分隔的名称-值对组成。如果值为模板参数(例如<ph name="SEARCH_TERM_MARKER" />),系统会将其替换成真实的搜索字词数据。
 
       如果您不设置 <ph name="DEFAULT_SEARCH_PROVIDER_SUGGEST_URL_POST_PARAMS_POLICY_NAME" />,系统将使用 GET 方法发送建议搜索请求。</translation>
@@ -11625,6 +11656,7 @@
 <translation id="9162444960513782569">不强制执行后台 JavaScript 计时器节流</translation>
 <translation id="9164656078867027374">定义允许访问 <ph name="GOOGLE_WORKSPACE_PRODUCT_NAME" /> 的网域</translation>
 <translation id="9165128017344777105">允许向这些网站授予本地字体权限</translation>
+<translation id="9165498643231979857">限制渲染程序进程共享 CPU 核心</translation>
 <translation id="9166670902476893480">此政策旨在控制 <ph name="PRODUCT_NAME" /> 能否在发出不安全的 DNS 请求时查询其他 DNS 记录类型。此政策对通过安全 DNS 进行的 DNS 查询没有影响,这类查询始终都能查询其他 DNS 类型。
 
       如果此政策已启用或未设置,即意味着除了能查询 <ph name="DNS_TYPE_A" />(DNS 类型 1)和 <ph name="DNS_TYPE_AAAA" />(DNS 类型 28)之外,还能查询其他类型,例如 <ph name="DNS_TYPE_HTTPS" />(DNS 类型 65)。
diff --git a/components/strings/components_strings_ml.xtb b/components/strings/components_strings_ml.xtb
index 8c30c0a..6d58128 100644
--- a/components/strings/components_strings_ml.xtb
+++ b/components/strings/components_strings_ml.xtb
@@ -1209,6 +1209,7 @@
 <translation id="3027915437837548462">SVG ചിത്രം</translation>
 <translation id="3030331669969285614">ഈ ഫ്ലാഗ് ചെയ്യലുകൾ ബ്രേക്കിംഗ് ചേഞ്ചിനെ തടയുകയോ പുനഃസ്ഥാപിക്കുകയോ ചെയ്യും, ഇത് പരിമിതമായ സമയത്തേക്ക് മാത്രമേ ലഭ്യമാകൂ.</translation>
 <translation id="3030542417256082866">വാഹനം സംരക്ഷിക്കണോ?</translation>
+<translation id="3033200136993730761">Google Maps-ലെ കൂടുതൽ പ്രസക്തമായ തിരയൽ ഫലങ്ങളും വഴികളും പോലെ, Google സേവനങ്ങളിലുടനീളം കാര്യങ്ങൾ ചെയ്തുതീർക്കാൻ നിങ്ങളുടെ വീട്ടുവിലാസം സഹായിക്കും. <ph name="BEGIN_LINK" />നിങ്ങളുടെ Google Account-ൽ <ph name="ACCOUNT" /><ph name="END_LINK" /> നിങ്ങളുടെ വിലാസം എഡിറ്റ് ചെയ്യാം അല്ലെങ്കിൽ ഇല്ലാതാക്കാം.</translation>
 <translation id="3034526003882782781">സ്ക്രോൾ ചെയ്യലും സൂം ചെയ്യലും അനുവദനീയം</translation>
 <translation id="3036894576201005614">വീട്ടാവശ്യങ്ങൾക്കുള്ള ക്ലീനിംഗ് സാമഗ്രികൾ</translation>
 <translation id="3037177537145227281">നിരക്ക് ട്രാക്ക് ചെയ്യുന്നു</translation>
@@ -2915,6 +2916,7 @@
 <translation id="5898767305816764989">തംബ്‌സ് അപ്പ് ബട്ടൺ, നിങ്ങൾ <ph name="THUMBS_UP_SUGGESTION_BUTTON_FOCUSED_FRIENDLY_MATCH_TEXT" /> ലൈക്ക് ചെയ്യുന്നു എന്ന ഫീഡ്‌ബാക്ക് സമർപ്പിക്കാൻ Enter അമർത്തുക</translation>
 <translation id="5901630391730855834">മഞ്ഞ</translation>
 <translation id="5903264686717710770">ശീര്‍ഷകം:</translation>
+<translation id="5905671155741555195">Google Maps-ലെ കൂടുതൽ പ്രസക്തമായ തിരയൽ ഫലങ്ങളും വഴികളും പോലെ, Google സേവനങ്ങളിലുടനീളം കാര്യങ്ങൾ ചെയ്തുതീർക്കാൻ നിങ്ങളുടെ ജോലിസ്ഥല വിലാസം സഹായിക്കും. <ph name="BEGIN_LINK" />നിങ്ങളുടെ Google Account-ൽ <ph name="ACCOUNT" /><ph name="END_LINK" /> നിങ്ങളുടെ വിലാസം എഡിറ്റ് ചെയ്യാം അല്ലെങ്കിൽ ഇല്ലാതാക്കാം.</translation>
 <translation id="5908541034548427511"><ph name="TYPE_1" /> (സമന്വയിപ്പിച്ചത്)</translation>
 <translation id="5910140988253729859">'സ്വയമേവ പൂരിപ്പിക്കൽ' പഴയപടിയാക്കുക</translation>
 <translation id="5911020115933784199">ഇവന്റുകളും ലിസ്റ്റിംഗുകളും</translation>
@@ -3812,6 +3814,7 @@
 <translation id="7403392780200267761">ലിങ്ക് പങ്കിട്ടും QR കോഡ് സൃഷ്ടിച്ചും കാസ്റ്റ് ചെയ്തും മറ്റും ഈ ടാബ് പങ്കിടുക</translation>
 <translation id="7403591733719184120">നിങ്ങളുടെ <ph name="DEVICE_NAME" /> മാനേജ് ചെയ്യപ്പെട്ടിരിക്കുന്നു</translation>
 <translation id="7405878640835614059"><ph name="ENROLLMENT_DOMAIN" /> അധിക ഫംഗ്ഷനുകൾക്കുള്ള ആപ്പുകൾ ഇൻസ്‌റ്റാൾ ചെയ്‌തിരിക്കുന്നു. ആപ്പുകൾക്ക് നിങ്ങളുടെ ചില ഡാറ്റയിലേക്ക് ആക്‌സസ് ഉണ്ട്.</translation>
+<translation id="740691708085211707">Chrome സ്വയമേവ പൂരിപ്പിക്കലിൽ നിന്ന് ജോലിസ്ഥല വിലാസം നീക്കം ചെയ്യണോ?</translation>
 <translation id="7407424307057130981">&lt;p&gt;നിങ്ങളുടെ Windows കമ്പ്യൂട്ടറിൽ Superfish സോഫ്റ്റ്‌വെയർ ഉണ്ടെങ്കിൽ, നിങ്ങൾ ഈ പിശക് കാണും.&lt;/p&gt;
       &lt;p&gt;നിങ്ങൾക്ക് വെബിലേക്ക് കണക്‌റ്റ് ചെയ്യാൻ, സോഫ്‌റ്റ്‌വെയർ താൽക്കാലികമായി പ്രവർത്തനരഹിതമാക്കാൻ ഈ ഘട്ടങ്ങൾ ഫോളോ ചെയ്യുക. നിങ്ങൾക്ക് അഡ്‌മിനിസ്ട്രേറ്ററുടെ സവിശേഷാധികാരങ്ങൾ ആവശ്യമായിവരും.&lt;/p&gt;
       &lt;ol&gt;
@@ -3906,6 +3909,7 @@
 <translation id="7534987659046836932">Envelope C7</translation>
 <translation id="7535087603100972091">മൂല്യം</translation>
 <translation id="753556296624075801">Google നൽകുന്നത്</translation>
+<translation id="753713322968419914">Chrome സ്വയമേവ പൂരിപ്പിക്കലിൽ നിന്ന് വീട്ടുവിലാസം നീക്കം ചെയ്യണോ?</translation>
 <translation id="7537536606612762813">നിർബന്ധിതം</translation>
 <translation id="7543525346216957623">നിങ്ങളുടെ രക്ഷിതാവിനോട്‌ ആവശ്യപ്പെടുക</translation>
 <translation id="7546409722674205727"><ph name="APP_NAME" /> ആരംഭിക്കുന്നു</translation>
diff --git a/components/strings/components_strings_ms.xtb b/components/strings/components_strings_ms.xtb
index d8c99f3..c17b959 100644
--- a/components/strings/components_strings_ms.xtb
+++ b/components/strings/components_strings_ms.xtb
@@ -1209,6 +1209,7 @@
 <translation id="3027915437837548462">Imej SVG</translation>
 <translation id="3030331669969285614">Bendera ini menghalang atau membalikkan perubahan memutus dan hanya tersedia untuk masa terhad.</translation>
 <translation id="3030542417256082866">Simpan kenderaan?</translation>
+<translation id="3033200136993730761">Alamat rumah anda boleh membantu anda menyelesaikan tugasan merentas perkhidmatan Google, seperti hasil carian Search yang lebih berkaitan dan arah dalam Google Maps. Anda boleh mengedit atau memadamkan alamat anda <ph name="BEGIN_LINK" />dalam Google Account <ph name="ACCOUNT" /><ph name="END_LINK" /> anda.</translation>
 <translation id="3034526003882782781">Tatal &amp; zum dibenarkan</translation>
 <translation id="3036894576201005614">Bekalan Pembersihan Rumah</translation>
 <translation id="3037177537145227281">Menjejaki harga</translation>
@@ -2917,6 +2918,7 @@
 <translation id="5898767305816764989">Butang menyukai, tekan Enter untuk menyerahkan maklum balas yang menunjukkan bahawa anda menyukai, <ph name="THUMBS_UP_SUGGESTION_BUTTON_FOCUSED_FRIENDLY_MATCH_TEXT" /></translation>
 <translation id="5901630391730855834">Kuning</translation>
 <translation id="5903264686717710770">Tajuk:</translation>
+<translation id="5905671155741555195">Alamat tempat kerja anda boleh membantu anda menyelesaikan tugasan merentas perkhidmatan Google, seperti hasil carian Search yang lebih berkaitan dan arah dalam Google Maps. Anda boleh mengedit atau memadamkan alamat anda <ph name="BEGIN_LINK" />dalam Google Account <ph name="ACCOUNT" /><ph name="END_LINK" /> anda.</translation>
 <translation id="5908541034548427511"><ph name="TYPE_1" /> (disegerakkan)</translation>
 <translation id="5910140988253729859">Buat asal autolengkap</translation>
 <translation id="5911020115933784199">Acara &amp; Penyenaraian</translation>
@@ -3814,6 +3816,7 @@
 <translation id="7403392780200267761">Kongsi tab ini dengan berkongsi pautan, membuat kod QR, menghantar dan pelbagai lagi</translation>
 <translation id="7403591733719184120"><ph name="DEVICE_NAME" /> anda diurus</translation>
 <translation id="7405878640835614059"><ph name="ENROLLMENT_DOMAIN" /> telah memasang aplikasi untuk fungsi tambahan. Aplikasi memiliki akses kepada sesetengah data anda.</translation>
+<translation id="740691708085211707">Alih keluar alamat tempat kerja daripada autolengkap Chrome?</translation>
 <translation id="7407424307057130981">&lt;p&gt;Anda akan melihat ralat ini jika anda memasang perisian Superfish pada komputer Windows anda.&lt;/p&gt;
     &lt;p&gt;Ikut langkah berikut untuk melumpuhkan perisian itu buat sementara waktu supaya anda dapat mengakses web. Anda memerlukan hak keistimewaan pentadbir.&lt;/p&gt;
     &lt;ol&gt;
@@ -3910,6 +3913,7 @@
 <translation id="7534987659046836932">Sampul C7</translation>
 <translation id="7535087603100972091">Nilai</translation>
 <translation id="753556296624075801">Dikuasakan oleh Google</translation>
+<translation id="753713322968419914">Alih keluar alamat rumah daripada autolengkap Chrome?</translation>
 <translation id="7537536606612762813">Wajib</translation>
 <translation id="7543525346216957623">Tanya ibu/bapa anda</translation>
 <translation id="7546409722674205727">Memulakan <ph name="APP_NAME" /></translation>
diff --git a/components/strings/components_strings_th.xtb b/components/strings/components_strings_th.xtb
index 8097d97..524bd0b 100644
--- a/components/strings/components_strings_th.xtb
+++ b/components/strings/components_strings_th.xtb
@@ -1209,6 +1209,7 @@
 <translation id="3027915437837548462">ภาพ SVG</translation>
 <translation id="3030331669969285614">Flag เหล่านี้จะป้องกันหรือเปลี่ยนกลับการเปลี่ยนแปลงที่ส่งผลกับส่วนอื่นในระบบและจะใช้ได้ในเวลาจำกัดเท่านั้น</translation>
 <translation id="3030542417256082866">บันทึกยานพาหนะไหม</translation>
+<translation id="3033200136993730761">ที่อยู่บ้านจะช่วยให้คุณทำสิ่งต่างๆ ให้เสร็จด้วยบริการของ Google ได้ เช่น ผลการค้นหาที่เกี่ยวข้องมากขึ้นและเส้นทางใน Google Maps คุณแก้ไขหรือลบที่อยู่ใน<ph name="BEGIN_LINK" />บัญชี Google ชื่อ <ph name="ACCOUNT" /><ph name="END_LINK" /> ได้</translation>
 <translation id="3034526003882782781">อนุญาตให้เลื่อนและซูม</translation>
 <translation id="3036894576201005614">อุปกรณ์ทำความสะอาดในครัวเรือน</translation>
 <translation id="3037177537145227281">กำลังติดตามราคา</translation>
@@ -2915,6 +2916,7 @@
 <translation id="5898767305816764989">ปุ่มชอบ กด Enter เพื่อส่งความคิดเห็นว่าคุณชอบ<ph name="THUMBS_UP_SUGGESTION_BUTTON_FOCUSED_FRIENDLY_MATCH_TEXT" /></translation>
 <translation id="5901630391730855834">สีเหลือง</translation>
 <translation id="5903264686717710770">ชื่อ:</translation>
+<translation id="5905671155741555195">ที่อยู่ที่ทำงานจะช่วยให้คุณทำสิ่งต่างๆ ให้เสร็จด้วยบริการของ Google ได้ เช่น ผลการค้นหาที่เกี่ยวข้องมากขึ้นและเส้นทางใน Google Maps คุณแก้ไขหรือลบที่อยู่ใน<ph name="BEGIN_LINK" />บัญชี Google ชื่อ <ph name="ACCOUNT" /><ph name="END_LINK" /> ได้</translation>
 <translation id="5908541034548427511"><ph name="TYPE_1" /> (ซิงค์แล้ว)</translation>
 <translation id="5910140988253729859">ยกเลิกการป้อนข้อความอัตโนมัติ</translation>
 <translation id="5911020115933784199">กิจกรรมและรายการ</translation>
@@ -3812,6 +3814,7 @@
 <translation id="7403392780200267761">แชร์แท็บนี้โดยการแชร์ลิงก์ สร้างคิวอาร์โค้ด แคสต์ และอื่นๆ</translation>
 <translation id="7403591733719184120"><ph name="DEVICE_NAME" /> ของคุณมีการจัดการ</translation>
 <translation id="7405878640835614059"><ph name="ENROLLMENT_DOMAIN" /> ได้ติดตั้งแอปพลิเคชันสำหรับฟังก์ชันเพิ่มเติม แอปพลิเคชันมีสิทธิ์เข้าถึงข้อมูลบางส่วนของคุณได้</translation>
+<translation id="740691708085211707">นำที่อยู่ที่ทำงานออกจากฟีเจอร์ป้อนข้อความอัตโนมัติของ Chrome ใช่ไหม</translation>
 <translation id="7407424307057130981">&lt;p&gt;คุณจะเห็นข้อผิดพลาดนี้หากมีซอฟต์แวร์ Superfish ในคอมพิวเตอร์ที่ใช้ระบบปฏิบัติการ Windows&lt;/p&gt;
       &lt;p&gt;ทำตามขั้นตอนการปิดใช้ซอฟต์แวร์ชั่วคราวต่อไปนี้เพื่อให้เข้าสู่เว็บได้ ทั้งนี้คุณจะต้องมีสิทธิ์ของผู้ดูแลระบบ&lt;/p&gt;
       &lt;ol&gt;
@@ -3908,6 +3911,7 @@
 <translation id="7534987659046836932">Envelope C7</translation>
 <translation id="7535087603100972091">ราคา</translation>
 <translation id="753556296624075801">ขับเคลื่อนโดย Google</translation>
+<translation id="753713322968419914">นำที่อยู่บ้านออกจากฟีเจอร์ป้อนข้อความอัตโนมัติของ Chrome ใช่ไหม</translation>
 <translation id="7537536606612762813">จำเป็น</translation>
 <translation id="7543525346216957623">ถามผู้ปกครอง</translation>
 <translation id="7546409722674205727">เริ่มใช้งาน <ph name="APP_NAME" /></translation>
diff --git a/components/strings/components_strings_zh-CN.xtb b/components/strings/components_strings_zh-CN.xtb
index 6ad04c0..3e7776aa 100644
--- a/components/strings/components_strings_zh-CN.xtb
+++ b/components/strings/components_strings_zh-CN.xtb
@@ -1209,6 +1209,7 @@
 <translation id="3027915437837548462">SVG 图片</translation>
 <translation id="3030331669969285614">这些标记可以防止或还原破坏性更改,并且只能在有限的时间内使用。</translation>
 <translation id="3030542417256082866">要保存车辆信息吗?</translation>
+<translation id="3033200136993730761">保留住址有助于您在各项 Google 服务中畅享更便利的服务,例如在 Google 地图中获得更相关的搜索结果和更精确的路线。您可以在 <ph name="BEGIN_LINK" />Google 账号 <ph name="ACCOUNT" /><ph name="END_LINK" /> 中修改或删除地址。</translation>
 <translation id="3034526003882782781">允许滚动和缩放</translation>
 <translation id="3036894576201005614">家居清洁用品</translation>
 <translation id="3037177537145227281">正在跟踪价格</translation>
@@ -2912,6 +2913,7 @@
 <translation id="5898767305816764989">“我喜欢”按钮,按 Enter 键可提交您喜欢<ph name="THUMBS_UP_SUGGESTION_BUTTON_FOCUSED_FRIENDLY_MATCH_TEXT" />的反馈</translation>
 <translation id="5901630391730855834">黄色</translation>
 <translation id="5903264686717710770">标题:</translation>
+<translation id="5905671155741555195">保留工作地址有助于您在各项 Google 服务中畅享更便利的服务,例如在 Google 地图中获得更相关的搜索结果和更精确的路线。您可以在 <ph name="BEGIN_LINK" />Google 账号 <ph name="ACCOUNT" /><ph name="END_LINK" /> 中修改或删除地址。</translation>
 <translation id="5908541034548427511"><ph name="TYPE_1" />(已同步)</translation>
 <translation id="5910140988253729859">撤消自动填充</translation>
 <translation id="5911020115933784199">活动与演出</translation>
@@ -3808,6 +3810,7 @@
 <translation id="7403392780200267761">通过分享链接、创建二维码、投放等操作分享此标签页</translation>
 <translation id="7403591733719184120">您的 <ph name="DEVICE_NAME" /> 受管理</translation>
 <translation id="7405878640835614059"><ph name="ENROLLMENT_DOMAIN" /> 已安装了一些应用来提供更多功能。这些应用有权访问您的部分数据。</translation>
+<translation id="740691708085211707">要从 Chrome 自动填充功能中移除工作地址吗?</translation>
 <translation id="7407424307057130981">&lt;p&gt;如果您的 Windows 计算机上装有 SuperFish 软件,您将会看到这条错误消息。&lt;/p&gt;
       &lt;p&gt;您可以按照下述步骤暂时停用该软件,以便连接到网络。您需要拥有管理员权限才能执行下列操作。&lt;/p&gt;
       &lt;ol&gt;
@@ -3904,6 +3907,7 @@
 <translation id="7534987659046836932">C7 信封</translation>
 <translation id="7535087603100972091">值</translation>
 <translation id="753556296624075801">由 Google 提供支持</translation>
+<translation id="753713322968419914">要从 Chrome 自动填充功能中移除住址吗?</translation>
 <translation id="7537536606612762813">强制</translation>
 <translation id="7543525346216957623">需要家长同意</translation>
 <translation id="7546409722674205727">正在启动<ph name="APP_NAME" /></translation>
diff --git a/content/browser/btm/btm_bounce_detector_browsertest.cc b/content/browser/btm/btm_bounce_detector_browsertest.cc
index e6a45813..582580a 100644
--- a/content/browser/btm/btm_bounce_detector_browsertest.cc
+++ b/content/browser/btm/btm_bounce_detector_browsertest.cc
@@ -3307,7 +3307,7 @@
     EvalJsResult result =
         EvalJs(frame, "document.cookie", EXECUTE_SCRIPT_NO_USER_GESTURE);
     if (!result.is_ok()) {
-      return base::unexpected(result.error);
+      return base::unexpected(result.ExtractError());
     }
     return base::ok(result.ExtractString());
   }
@@ -3340,7 +3340,7 @@
     EvalJsResult result = EvalJs(frame, "localStorage.getItem('value')",
                                  EXECUTE_SCRIPT_NO_USER_GESTURE);
     if (!result.is_ok()) {
-      return base::unexpected(result.error);
+      return base::unexpected(result.ExtractError());
     }
     if (result == base::Value()) {
       return base::ok("");
diff --git a/content/browser/fenced_frame/fenced_frame_browsertest.cc b/content/browser/fenced_frame/fenced_frame_browsertest.cc
index 36f51f19..ced143d 100644
--- a/content/browser/fenced_frame/fenced_frame_browsertest.cc
+++ b/content/browser/fenced_frame/fenced_frame_browsertest.cc
@@ -9367,11 +9367,11 @@
           // When eventData exceeds the length limit, a security error is thrown
           // instead of a console error.
           EXPECT_FALSE(result.is_ok());
-          EXPECT_THAT(
-              result.error,
-              testing::HasSubstr("The data provided to "
-                                 "setReportEventDataForAutomaticBeacons() "
-                                 "exceeds the maximum length, which is 64KB."));
+          EXPECT_THAT(result,
+                      content::EvalJsResult::ErrorIs(testing::HasSubstr(
+                          "The data provided to "
+                          "setReportEventDataForAutomaticBeacons() "
+                          "exceeds the maximum length, which is 64KB.")));
 
           histogram_tester_.ExpectUniqueSample(
               blink::kAutomaticBeaconEventTypeHistogram,
diff --git a/content/browser/file_system_access/file_system_access_file_handle_impl_browsertest.cc b/content/browser/file_system_access/file_system_access_file_handle_impl_browsertest.cc
index e39a28f..fd1c65c 100644
--- a/content/browser/file_system_access/file_system_access_file_handle_impl_browsertest.cc
+++ b/content/browser/file_system_access/file_system_access_file_handle_impl_browsertest.cc
@@ -102,8 +102,9 @@
              "(async () => {"
              "const sandboxRoot = await navigator.storage.getDirectory();"
              "return await self.localFile.move(sandboxRoot); })()");
-  EXPECT_TRUE(base::Contains(result.error, "can not be modified in this way"))
-      << result.error;
+  EXPECT_THAT(result, EvalJsResult::ErrorIs(testing::HasSubstr(
+                          "can not be modified in this way")))
+      << result;
 }
 
 // TODO(crbug.com/40888337): Make this a WPT once crbug.com/1114920 is fixed.
@@ -121,8 +122,9 @@
              "await writable.write('move me to the local file system');"
              "await writable.close();"
              "return await sandboxFile.move(localDir); })()");
-  EXPECT_TRUE(base::Contains(result.error, "can not be modified in this way"))
-      << result.error;
+  EXPECT_THAT(result, EvalJsResult::ErrorIs(testing::HasSubstr(
+                          "can not be modified in this way")))
+      << result;
 }
 
 IN_PROC_BROWSER_TEST_F(FileSystemAccessFileHandleImplBrowserTest, RenameLocal) {
diff --git a/content/browser/file_system_access/file_system_access_file_writer_impl_browsertest.cc b/content/browser/file_system_access/file_system_access_file_writer_impl_browsertest.cc
index bf9f57d..f141699f 100644
--- a/content/browser/file_system_access/file_system_access_file_writer_impl_browsertest.cc
+++ b/content/browser/file_system_access/file_system_access_file_writer_impl_browsertest.cc
@@ -376,14 +376,15 @@
       "{create:false});"
       "return (await self.swapFile.createWritable());"
       "})()");
-  EXPECT_TRUE(base::Contains(result.error, "modifications are not allowed."))
-      << result.error;
+  EXPECT_THAT(result, EvalJsResult::ErrorIs(
+                          testing::HasSubstr("modifications are not allowed.")))
+      << result;
 
   auto close_result = EvalJs(shell(),
                              "(async () => {"
                              "await self.writer.close();"
                              "})()");
-  EXPECT_TRUE(close_result.is_ok()) << close_result.error;
+  EXPECT_TRUE(close_result.is_ok()) << close_result;
 }
 
 // TODO(crbug.com/40639570): Files are only quarantined on windows in
@@ -435,8 +436,9 @@
   auto result = EvalJs(shell(),
                        "(async () => {"
                        "  return (await self.entry.createWritable()); })()");
-  EXPECT_TRUE(base::Contains(result.error, "Cannot write to a read-only file."))
-      << result.error;
+  EXPECT_THAT(result, EvalJsResult::ErrorIs(testing::HasSubstr(
+                          "Cannot write to a read-only file.")))
+      << result;
 }
 #endif  // BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_WIN)
 
diff --git a/content/browser/file_system_access/file_system_access_observer_browsertest.cc b/content/browser/file_system_access/file_system_access_observer_browsertest.cc
index e280ccc..c6ad791 100644
--- a/content/browser/file_system_access/file_system_access_observer_browsertest.cc
+++ b/content/browser/file_system_access/file_system_access_observer_browsertest.cc
@@ -319,8 +319,9 @@
       observer.unobserve(root);
     })()
     )""");
-  EXPECT_TRUE(result.error.find("is not a function") != std::string::npos)
-      << result.error;
+  EXPECT_TRUE(result.ExtractError().find("is not a function") !=
+              std::string::npos)
+      << result;
 }
 
 IN_PROC_BROWSER_TEST_F(FileSystemAccessObserveWithFlagBrowserTest,
@@ -489,9 +490,9 @@
   auto result = EvalJs(shell(), script);
 
   // Check if a JavaScript error occurred.
-  EXPECT_TRUE(result.error.find("InvalidModificationError") !=
+  EXPECT_TRUE(result.ExtractError().find("InvalidModificationError") !=
               std::string::npos)
-      << "Unexpected result: " << result.error;
+      << "Unexpected result: " << result;
   histogram_tester.ExpectUniqueSample(kAttemptToObserveSymlinkHistogram,
                                       /*sample=*/true, 1);
 }
@@ -567,8 +568,9 @@
       "})()";
   // clang-format on
   auto result = EvalJs(shell(), script);
-  EXPECT_TRUE(result.error.find("did not support") != std::string::npos)
-      << result.error;
+  EXPECT_TRUE(result.ExtractError().find("did not support") !=
+              std::string::npos)
+      << result;
 }
 #endif  // BUILDFLAG(IS_FUCHSIA)
 
@@ -663,8 +665,8 @@
   auto result = EvalJs(shell(), script);
 
   // Check if a JavaScript error occurred and contains "NotFoundError".
-  EXPECT_TRUE(result.error.find("NotFoundError") != std::string::npos)
-      << "Unexpected result: " << result.error;
+  EXPECT_TRUE(result.ExtractError().find("NotFoundError") != std::string::npos)
+      << "Unexpected result: " << result;
 }
 
 IN_PROC_BROWSER_TEST_P(FileSystemAccessObserverBrowserTest,
@@ -686,8 +688,8 @@
   auto result = EvalJs(shell(), script);
 
   // Check if a JavaScript error occurred and contains "NotFoundError".
-  EXPECT_TRUE(result.error.find("NotFoundError") != std::string::npos)
-      << "Unexpected result: " << result.error;
+  EXPECT_TRUE(result.ExtractError().find("NotFoundError") != std::string::npos)
+      << "Unexpected result: " << result;
 }
 
 IN_PROC_BROWSER_TEST_P(FileSystemAccessObserverBrowserTest,
diff --git a/content/browser/file_system_access/file_system_chooser_browsertest.cc b/content/browser/file_system_access/file_system_chooser_browsertest.cc
index 46ee881a..fe9aa53 100644
--- a/content/browser/file_system_access/file_system_chooser_browsertest.cc
+++ b/content/browser/file_system_access/file_system_chooser_browsertest.cc
@@ -137,8 +137,8 @@
   ASSERT_TRUE(
       NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html")));
   auto result = EvalJs(shell(), "self.showOpenFilePicker()");
-  EXPECT_TRUE(result.error.find("aborted") != std::string::npos)
-      << result.error;
+  EXPECT_TRUE(result.ExtractError().find("aborted") != std::string::npos)
+      << result;
 }
 
 IN_PROC_BROWSER_TEST_F(FileSystemChooserBrowserTest, OpenFile) {
@@ -256,8 +256,8 @@
   ASSERT_TRUE(
       NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html")));
   auto result = EvalJs(shell(), "self.showOpenFilePicker()");
-  EXPECT_TRUE(result.error.find("not allowed") != std::string::npos)
-      << result.error;
+  EXPECT_TRUE(result.ExtractError().find("not allowed") != std::string::npos)
+      << result;
   EXPECT_EQ(ui::SelectFileDialog::SELECT_NONE, dialog_params_.type);
 }
 
@@ -473,8 +473,8 @@
   ASSERT_TRUE(
       NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html")));
   auto result = EvalJs(shell(), "self.showSaveFilePicker()");
-  EXPECT_TRUE(result.error.find("not allowed") != std::string::npos)
-      << result.error;
+  EXPECT_TRUE(result.ExtractError().find("not allowed") != std::string::npos)
+      << result;
   EXPECT_EQ(ui::SelectFileDialog::SELECT_NONE, dialog_params_.type);
 }
 
@@ -593,8 +593,8 @@
   ASSERT_TRUE(
       NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html")));
   auto result = EvalJs(shell(), "self.showDirectoryPicker()");
-  EXPECT_TRUE(result.error.find("not allowed") != std::string::npos)
-      << result.error;
+  EXPECT_TRUE(result.ExtractError().find("not allowed") != std::string::npos)
+      << result;
   EXPECT_EQ(ui::SelectFileDialog::SELECT_NONE, dialog_params_.type);
 }
 
@@ -690,8 +690,8 @@
   ASSERT_TRUE(
       NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html")));
   auto result = EvalJs(shell(), "self.showDirectoryPicker()");
-  EXPECT_TRUE(result.error.find("aborted") != std::string::npos)
-      << result.error;
+  EXPECT_TRUE(result.ExtractError().find("aborted") != std::string::npos)
+      << result;
 }
 
 IN_PROC_BROWSER_TEST_F(FileSystemChooserBrowserTest,
@@ -968,8 +968,8 @@
   ASSERT_TRUE(
       NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html")));
   auto result = EvalJs(shell(), "self.showSaveFilePicker()");
-  EXPECT_TRUE(result.error.find("aborted") != std::string::npos)
-      << result.error;
+  EXPECT_TRUE(result.ExtractError().find("aborted") != std::string::npos)
+      << result;
 
   {
     // File should still exist, and be unmodified.
@@ -1042,8 +1042,8 @@
   ASSERT_TRUE(
       NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html")));
   auto result = EvalJs(shell(), "self.showSaveFilePicker()");
-  EXPECT_TRUE(result.error.find("aborted") != std::string::npos)
-      << result.error;
+  EXPECT_TRUE(result.ExtractError().find("aborted") != std::string::npos)
+      << result;
 
   {
     // File should not have been created.
@@ -1064,8 +1064,8 @@
              "  {accept: {'image/jpeg': []}},"
              "  {accept: {'image/svg+xml': '.svg'}},"
              "]})");
-  EXPECT_TRUE(result.error.find("aborted") != std::string::npos)
-      << result.error;
+  EXPECT_TRUE(result.ExtractError().find("aborted") != std::string::npos)
+      << result;
 
   ASSERT_TRUE(dialog_params_.file_types);
   EXPECT_TRUE(dialog_params_.file_types->include_all_files);
@@ -1096,8 +1096,8 @@
       NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html")));
   auto result =
       EvalJs(shell(), "self.showOpenFilePicker({types: [undefined]})");
-  EXPECT_TRUE(result.error.find("aborted") != std::string::npos)
-      << result.error;
+  EXPECT_TRUE(result.ExtractError().find("aborted") != std::string::npos)
+      << result;
 
   ASSERT_TRUE(dialog_params_.file_types);
   EXPECT_TRUE(dialog_params_.file_types->include_all_files);
diff --git a/content/browser/hid/hid_browsertest.cc b/content/browser/hid/hid_browsertest.cc
index 4b05c0a..37c573f 100644
--- a/content/browser/hid/hid_browsertest.cc
+++ b/content/browser/hid/hid_browsertest.cc
@@ -245,7 +245,8 @@
   auto result = content::EvalJs(
       render_frame_host,
       R"(navigator.hid.getDevices().then(devices => devices.length))");
-  EXPECT_THAT(result.error, ::testing::HasSubstr(kFencedFrameError));
+  EXPECT_THAT(result,
+              EvalJsResult::ErrorIs(::testing::HasSubstr(kFencedFrameError)));
 }
 
 }  // namespace content
diff --git a/content/browser/interest_group/interest_group_browsertest.cc b/content/browser/interest_group/interest_group_browsertest.cc
index 2564b6a..84f0a110 100644
--- a/content/browser/interest_group/interest_group_browsertest.cc
+++ b/content/browser/interest_group/interest_group_browsertest.cc
@@ -1978,9 +1978,9 @@
     })())",
                            urn_url, base::Value(std::move(replacement_value))));
     if (error_out != nullptr) {
-      *error_out = result.error;
+      *error_out = result.is_ok() ? "" : result.ExtractError();
     }
-    return result.error == "" && result == "done";
+    return result == "done";
   }
 
   void AttachInterestGroupObserver() {
@@ -17492,7 +17492,7 @@
       test_origin,
       embedded_https_test_server().GetURL("a.test", kDecisionLogicPath));
   EXPECT_EQ("a JavaScript error: \"manual cancel\"\n",
-            EvalJs(shell(), script).error);
+            EvalJs(shell(), script).ExtractError());
 }
 
 // Test for auctionSignals, perBuyerSignals, directFromSellerSignals, and
@@ -25739,7 +25739,7 @@
    "maxGroupLifetimeMs": %f
 })",
                   kDefaultMaxGroupLifetimeMs))))
-      << all_result.error;
+      << all_result;
 }
 
 // Worklet handling of zero seller timeout.
@@ -26821,7 +26821,7 @@
    "maxGroupLifetimeMs": %f
 })",
                   kDefaultMaxGroupLifetimeMs))))
-      << all_result.error;
+      << all_result;
 }
 
 IN_PROC_BROWSER_TEST_F(InterestGroupCrossOriginTrustedSignalsBrowserTest,
@@ -28251,7 +28251,7 @@
    "maxGroupLifetimeMs": %f
 })",
                   kDefaultMaxGroupLifetimeMs))))
-      << all_result.error;
+      << all_result;
 }
 
 class FledgeUnNoisedRealTimeReportEnabledTest
diff --git a/content/browser/pointer_lock_browsertest.cc b/content/browser/pointer_lock_browsertest.cc
index 4019fb3..b538e6ac 100644
--- a/content/browser/pointer_lock_browsertest.cc
+++ b/content/browser/pointer_lock_browsertest.cc
@@ -942,7 +942,7 @@
       "request are not supported on this platform.\"\n",
       EvalJs(child,
              "document.body.requestPointerLock({unadjustedMovement:true})")
-          .error);
+          .ExtractError());
 
   // The change errored out but the original lock should still be in place.
   EXPECT_TRUE(child_view->IsPointerLocked());
diff --git a/content/browser/preloading/prefetch/prefetch_features.cc b/content/browser/preloading/prefetch/prefetch_features.cc
index d1b5141..469c59e 100644
--- a/content/browser/preloading/prefetch/prefetch_features.cc
+++ b/content/browser/preloading/prefetch/prefetch_features.cc
@@ -64,7 +64,7 @@
 
 BASE_FEATURE(kPrefetchServiceWorker,
              "PrefetchServiceWorker",
-             base::FEATURE_DISABLED_BY_DEFAULT);
+             base::FEATURE_ENABLED_BY_DEFAULT);
 
 bool IsPrefetchServiceWorkerEnabled(content::BrowserContext* browser_context) {
   return base::FeatureList::IsEnabled(kPrefetchServiceWorker) &&
diff --git a/content/browser/preloading/prefetch/prefetch_streaming_url_loader.cc b/content/browser/preloading/prefetch/prefetch_streaming_url_loader.cc
index 090a02f..4a22bb62 100644
--- a/content/browser/preloading/prefetch/prefetch_streaming_url_loader.cc
+++ b/content/browser/preloading/prefetch/prefetch_streaming_url_loader.cc
@@ -4,6 +4,7 @@
 
 #include "content/browser/preloading/prefetch/prefetch_streaming_url_loader.h"
 
+#include "base/check_is_test.h"
 #include "base/task/sequenced_task_runner.h"
 #include "base/task/single_thread_task_runner.h"
 #include "base/trace_event/trace_event.h"
@@ -309,6 +310,19 @@
     const network::ResourceRequest& request,
     const net::NetworkTrafficAnnotationTag& network_traffic_annotation,
     base::TimeDelta timeout_duration) {
+  auto callback = base::BindOnce(
+      &PrefetchStreamingURLLoader::ServiceWorkerInterceptorLoaderCallback,
+      GetWeakPtr(), network_url_loader_factory, request,
+      network_traffic_annotation, std::move(timeout_duration));
+
+  if (!browser_context) {
+    // In tests, `browser_context` can be null. Emulate as if there are no
+    // service workers without going through the interceptor.
+    CHECK_IS_TEST();
+    std::move(callback).Run(std::nullopt);
+    return;
+  }
+
   // TODO(https://crbug.com/40947546): Set this FetchEvent's Client ID.
   std::string fetch_event_client_id;
 
@@ -330,11 +344,7 @@
       request, service_worker_handle_->AsWeakPtr(), network_url_loader_factory);
 
   interceptor_->MaybeCreateLoader(
-      request, browser_context,
-      base::BindOnce(
-          &PrefetchStreamingURLLoader::ServiceWorkerInterceptorLoaderCallback,
-          GetWeakPtr(), network_url_loader_factory, request,
-          network_traffic_annotation, std::move(timeout_duration)),
+      request, browser_context, std::move(callback),
       base::BindOnce(
           [](scoped_refptr<network::SharedURLLoaderFactory>
                  network_url_loader_factory,
diff --git a/content/browser/preloading/prefetch/prefetch_streaming_url_loader.h b/content/browser/preloading/prefetch/prefetch_streaming_url_loader.h
index dc6d455..55d6576f 100644
--- a/content/browser/preloading/prefetch/prefetch_streaming_url_loader.h
+++ b/content/browser/preloading/prefetch/prefetch_streaming_url_loader.h
@@ -54,11 +54,10 @@
       OnPrefetchResponseStartedCallback on_prefetch_response_started_callback,
       OnPrefetchRedirectCallback on_prefetch_redirect_callback,
       base::WeakPtr<PrefetchResponseReader> response_reader,
-      PrefetchServiceWorkerState initial_service_worker_state =
-          PrefetchServiceWorkerState::kDisallowed,
-      BrowserContext* browser_context_for_service_worker = nullptr,
+      PrefetchServiceWorkerState initial_service_worker_state,
+      BrowserContext* browser_context_for_service_worker,
       OnServiceWorkerStateDeterminedCallback
-          on_service_worker_state_determined_callback = base::DoNothing());
+          on_service_worker_state_determined_callback);
 
   // Must be called only from `CreateAndStart()`.
   PrefetchStreamingURLLoader(
diff --git a/content/browser/preloading/prefetch/prefetch_test_util_internal.cc b/content/browser/preloading/prefetch/prefetch_test_util_internal.cc
index a33f91b..922fbb6 100644
--- a/content/browser/preloading/prefetch/prefetch_test_util_internal.cc
+++ b/content/browser/preloading/prefetch/prefetch_test_util_internal.cc
@@ -164,7 +164,17 @@
       std::move(url_loader_factory), prefetch_request,
       TRAFFIC_ANNOTATION_FOR_TESTS, timeout_duration,
       std::move(on_receive_response_callback),
-      std::move(on_receive_redirect_callback), std::move(response_reader));
+      std::move(on_receive_redirect_callback), std::move(response_reader),
+      // Because `browser_context_for_service_worker` is null, we don't test
+      // ServiceWorker-controlled prefetches (covered by WPTs instead). Still
+      // `OnServiceWorkerStateDetermined()` callback should be passed, to go
+      // through `PrefetchServiceWorkerState` transitions for
+      // `prefetch_container` if non-null.
+      prefetch_container ? prefetch_container->service_worker_state()
+                         : PrefetchServiceWorkerState::kDisallowed,
+      /*browser_context_for_service_worker=*/nullptr,
+      base::BindOnce(&PrefetchContainer::OnServiceWorkerStateDetermined,
+                     prefetch_container));
 
   if (prefetch_container) {
     prefetch_container->SetStreamingURLLoader(streaming_loader);
diff --git a/content/browser/renderer_host/cookie_browsertest.cc b/content/browser/renderer_host/cookie_browsertest.cc
index cb40101..f0cb0e9 100644
--- a/content/browser/renderer_host/cookie_browsertest.cc
+++ b/content/browser/renderer_host/cookie_browsertest.cc
@@ -76,7 +76,7 @@
 
 void SetCookieFromJS(RenderFrameHost* frame, std::string cookie) {
   EvalJsResult result = EvalJs(frame, "document.cookie = '" + cookie + "'");
-  EXPECT_TRUE(result.is_ok()) << result.error;
+  EXPECT_TRUE(result.is_ok()) << result;
 }
 
 std::string GetCookieFromJS(RenderFrameHost* frame) {
diff --git a/content/browser/renderer_host/private_network_access_browsertest.cc b/content/browser/renderer_host/private_network_access_browsertest.cc
index 807cf88..1d7c8251 100644
--- a/content/browser/renderer_host/private_network_access_browsertest.cc
+++ b/content/browser/renderer_host/private_network_access_browsertest.cc
@@ -3779,7 +3779,7 @@
 #if !BUILDFLAG(IS_ANDROID)
   EXPECT_EQ(expected, result);
 #else
-  EXPECT_NE("", result.error);
+  EXPECT_FALSE(result.is_ok());
 #endif
 }
 
diff --git a/content/browser/renderer_host/render_frame_host_impl_browsertest.cc b/content/browser/renderer_host/render_frame_host_impl_browsertest.cc
index 970f200..bb0ba8b 100644
--- a/content/browser/renderer_host/render_frame_host_impl_browsertest.cc
+++ b/content/browser/renderer_host/render_frame_host_impl_browsertest.cc
@@ -6063,8 +6063,8 @@
       testObject.readArray(array);
     )",
                                   error_message);
-  auto error = EvalJs(web_contents(), kScript).error;
-  EXPECT_NE(error.find(error_message), std::string::npos);
+  EXPECT_THAT(EvalJs(web_contents(), kScript),
+              EvalJsResult::ErrorIs(testing::HasSubstr(error_message)));
 }
 
 // Based on testReturnedObjectIsGarbageCollected.
diff --git a/content/browser/shared_storage/shared_storage_browsertest.cc b/content/browser/shared_storage/shared_storage_browsertest.cc
index 486f7e43..c935a09 100644
--- a/content/browser/shared_storage/shared_storage_browsertest.cc
+++ b/content/browser/shared_storage/shared_storage_browsertest.cc
@@ -517,7 +517,7 @@
           '/server-redirect?shared_storage/simple_module.js');
     )");
 
-  EXPECT_EQ(expected_error, result.error);
+  EXPECT_THAT(result, content::EvalJsResult::ErrorIs(expected_error));
 
   EXPECT_EQ(1u, test_runtime_manager().GetAttachedWorkletHostsCount());
   EXPECT_EQ(0u, test_runtime_manager().GetKeepAliveWorkletHostsCount());
diff --git a/content/browser/shared_storage/shared_storage_fenced_frame_browsertest.cc b/content/browser/shared_storage/shared_storage_fenced_frame_browsertest.cc
index 5f62aa04..21f32ede 100644
--- a/content/browser/shared_storage/shared_storage_fenced_frame_browsertest.cc
+++ b/content/browser/shared_storage/shared_storage_fenced_frame_browsertest.cc
@@ -1651,7 +1651,7 @@
       {"a JavaScript error: \"OperationError: ",
        "sharedStorage.selectURL() failed because number of urn::uuid to url ",
        "mappings has reached the limit.\"\n"});
-  EXPECT_EQ(expected_error, extra_result.error);
+  EXPECT_EQ(expected_error, extra_result.ExtractError());
 }
 
 class SharedStorageFencedFrameDocumentGetFeatureDisabledBrowserTest
@@ -2215,7 +2215,7 @@
     EvalJsResult result =
         RunSelectURLScript(execution_target, num_urls, saved_query_name);
 
-    EXPECT_TRUE(result.is_ok()) << result.error;
+    EXPECT_TRUE(result.is_ok()) << result;
     const std::optional<GURL>& observed_urn_uuid = config_observer.GetUrnUuid();
     if (!observed_urn_uuid.has_value()) {
       return std::nullopt;
diff --git a/content/browser/smart_card/smart_card_browsertest.cc b/content/browser/smart_card/smart_card_browsertest.cc
index ae323eb..018cc4c 100644
--- a/content/browser/smart_card/smart_card_browsertest.cc
+++ b/content/browser/smart_card/smart_card_browsertest.cc
@@ -1873,9 +1873,9 @@
   ASSERT_TRUE(NavigateToURL(shell(), GetIsolatedContextUrl()));
 
   EXPECT_EQ(false, EvalJs(shell(), "self.crossOriginIsolated"));
-  EXPECT_THAT(
-      EvalJs(shell(), "navigator.smartCard.establishContext()").error,
-      HasSubstr("Frame is not sufficiently isolated to use smart cards."));
+  EXPECT_THAT(EvalJs(shell(), "navigator.smartCard.establishContext()"),
+              EvalJsResult::ErrorIs(HasSubstr(
+                  "Frame is not sufficiently isolated to use smart cards.")));
 }
 
 /* Tests the situation where a transaction callback erroneously returns while an
diff --git a/content/browser/speech/speech_synthesis_impl.cc b/content/browser/speech/speech_synthesis_impl.cc
index 9567ac9..1f07dd1 100644
--- a/content/browser/speech/speech_synthesis_impl.cc
+++ b/content/browser/speech/speech_synthesis_impl.cc
@@ -17,7 +17,7 @@
     std::unique_ptr<AudioStreamMonitor::AudibleClientRegistration>()>;
 
 // The lifetime of instances of this class is manually bound to the lifetime of
-// the associated TtsUtterance. See OnTtsEvent.
+// the associated TtsUtterance.
 class EventThunk : public UtteranceEventDelegate {
  public:
   EventThunk(mojo::PendingRemote<blink::mojom::SpeechSynthesisClient> client,
@@ -79,9 +79,6 @@
         client_->OnResumedSpeaking();
         break;
     }
-
-    if (utterance->IsFinished())
-      delete this;
   }
 
  private:
@@ -162,7 +159,7 @@
                                          utterance->volume);
 
   // See comments on EventThunk about how lifetime of this instance is managed.
-  tts_utterance->SetEventDelegate(new EventThunk(
+  tts_utterance->SetEventDelegate(std::make_unique<EventThunk>(
       std::move(client),
       base::BindRepeating(
           &AudioStreamMonitor::RegisterAudibleClient,
diff --git a/content/browser/speech/tts_utterance_impl.cc b/content/browser/speech/tts_utterance_impl.cc
index 55fbb4b..affdb36 100644
--- a/content/browser/speech/tts_utterance_impl.cc
+++ b/content/browser/speech/tts_utterance_impl.cc
@@ -85,19 +85,13 @@
                                   const std::string& error_message) {
   if (char_index >= 0)
     char_index_ = char_index;
-  if (IsFinalTtsEventType(event_type))
+  if (IsFinalTtsEventType(event_type)) {
     finished_ = true;
+  }
 
   if (event_delegate_) {
-    // If |finished_| is set, we need to reset |event_delegate_| because it
-    // will self destroy on the call to OnTtsEvent.
-    if (finished_) {
-      event_delegate_.ExtractAsDangling()->OnTtsEvent(
-          this, event_type, char_index, length, error_message);
-    } else {
-      event_delegate_->OnTtsEvent(this, event_type, char_index, length,
-                                  error_message);
-    }
+    event_delegate_->OnTtsEvent(this, event_type, char_index, length,
+                                error_message);
   }
 }
 
@@ -199,12 +193,12 @@
 }
 
 void TtsUtteranceImpl::SetEventDelegate(
-    UtteranceEventDelegate* event_delegate) {
-  event_delegate_ = event_delegate;
+    std::unique_ptr<UtteranceEventDelegate> event_delegate) {
+  event_delegate_ = std::move(event_delegate);
 }
 
 UtteranceEventDelegate* TtsUtteranceImpl::GetEventDelegate() {
-  return event_delegate_;
+  return event_delegate_.get();
 }
 
 BrowserContext* TtsUtteranceImpl::GetBrowserContext() {
diff --git a/content/browser/speech/tts_utterance_impl.h b/content/browser/speech/tts_utterance_impl.h
index 2666293..95212cb 100644
--- a/content/browser/speech/tts_utterance_impl.h
+++ b/content/browser/speech/tts_utterance_impl.h
@@ -85,7 +85,8 @@
   void SetEngineId(const std::string& engine_id) override;
   const std::string& GetEngineId() override;
 
-  void SetEventDelegate(UtteranceEventDelegate* event_delegate) override;
+  void SetEventDelegate(
+      std::unique_ptr<UtteranceEventDelegate> event_delegate) override;
   UtteranceEventDelegate* GetEventDelegate() override;
 
   BrowserContext* GetBrowserContext() override;
@@ -136,8 +137,9 @@
   // The URL of the page where called speak was called.
   GURL src_url_;
 
-  // The delegate to be called when an utterance event is fired.
-  raw_ptr<UtteranceEventDelegate> event_delegate_ = nullptr;
+  // The delegate to be called when an utterance event is fired. This is owned
+  // by the utterance.
+  std::unique_ptr<UtteranceEventDelegate> event_delegate_;
 
   // The parsed options.
   std::string voice_name_;
diff --git a/content/browser/webid/fedcm_metrics.cc b/content/browser/webid/fedcm_metrics.cc
index 66853a1..0cadc68 100644
--- a/content/browser/webid/fedcm_metrics.cc
+++ b/content/browser/webid/fedcm_metrics.cc
@@ -284,7 +284,8 @@
     std::optional<FedCmVerifyingDialogResult> verifying_dialog_result,
     FedCmThirdPartyCookiesStatus tpc_status,
     const FedCmRequesterFrameType& requester_frame_type,
-    std::optional<bool> has_signin_account) {
+    std::optional<bool> has_signin_account,
+    bool did_show_ui) {
   // The following check is to avoid double recording in the following scenario:
   // 1. The request has failed but we have not yet rejected the promise, e.g.
   // when the API is disabled. We record a metric immediately but only post a
@@ -325,7 +326,9 @@
     }
   };
 
-  SetUkm(GetOrCreateFedCmBuilder(), status);
+  ukm::builders::Blink_FedCm* fedcm_builder = GetOrCreateFedCmBuilder();
+  SetUkm(fedcm_builder, status);
+  fedcm_builder->SetDidShowUI(did_show_ui);
 
   for (const auto& provider : requested_providers) {
     ukm::builders::Blink_FedCmIdp* fedcm_idp_builder =
@@ -361,6 +364,7 @@
     base::UmaHistogramBoolean("Blink.FedCm.HasSigninAccount",
                               *has_signin_account);
   }
+  base::UmaHistogramBoolean("Blink.FedCm.DidShowUI", did_show_ui);
 
   // We do not expect more request token status metrics from this API call.
   has_recorded_request_token_status_ = true;
diff --git a/content/browser/webid/fedcm_metrics.h b/content/browser/webid/fedcm_metrics.h
index fcf2e65..b74110a 100644
--- a/content/browser/webid/fedcm_metrics.h
+++ b/content/browser/webid/fedcm_metrics.h
@@ -387,7 +387,8 @@
       std::optional<FedCmVerifyingDialogResult> verifying_dialog_result,
       FedCmThirdPartyCookiesStatus tpc_status,
       const FedCmRequesterFrameType& requester_frame_type,
-      std::optional<bool> has_signin_account);
+      std::optional<bool> has_signin_account,
+      bool did_show_ui);
 
   // Records whether user sign-in states between IDP and browser match.
   void RecordSignInStateMatchStatus(const GURL& provider,
diff --git a/content/browser/webid/federated_auth_request_impl.cc b/content/browser/webid/federated_auth_request_impl.cc
index c460eab8..3b74d5f 100644
--- a/content/browser/webid/federated_auth_request_impl.cc
+++ b/content/browser/webid/federated_auth_request_impl.cc
@@ -1886,7 +1886,7 @@
             : FedCmThirdPartyCookiesStatus::kDisabledInSettings,
         webid::ComputeRequesterFrameType(render_frame_host(), origin(),
                                          GetEmbeddingOrigin()),
-        has_signin_account);
+        has_signin_account, did_show_ui_);
   }
 
   if (result == FederatedAuthRequestResult::kSuccess) {
@@ -2661,7 +2661,7 @@
             : FedCmThirdPartyCookiesStatus::kDisabledInSettings,
         webid::ComputeRequesterFrameType(render_frame_host(), origin(),
                                          GetEmbeddingOrigin()),
-        /*has_signin_account=*/std::nullopt);
+        /*has_signin_account=*/std::nullopt, /*did_show_ui=*/false);
 
     AddDevToolsIssue(
         blink::mojom::FederatedAuthRequestResult::kTooManyRequests);
diff --git a/content/browser/webid/federated_auth_request_impl_unittest.cc b/content/browser/webid/federated_auth_request_impl_unittest.cc
index 5382f3c3..c48488a 100644
--- a/content/browser/webid/federated_auth_request_impl_unittest.cc
+++ b/content/browser/webid/federated_auth_request_impl_unittest.cc
@@ -1918,6 +1918,8 @@
   // expectation does not check that the client metadata was fetched because
   // client metadata is optional.
   EXPECT_TRUE(DidFetch(FetchedEndpoint::CLIENT_METADATA));
+  histogram_tester_.ExpectUniqueSample("Blink.FedCm.DidShowUI", true, 1);
+  ExpectUkmValueInEntry("DidShowUI", FedCmEntry::kEntryName, true);
 }
 
 // Test successful well-known fetching.
@@ -2162,6 +2164,8 @@
   EXPECT_FALSE(DidFetchAnyEndpoint());
 
   ExpectStatusMetrics(TokenStatus::kIdpNotPotentiallyTrustworthy);
+  histogram_tester_.ExpectUniqueSample("Blink.FedCm.DidShowUI", false, 1);
+  ExpectUkmValueInEntry("DidShowUI", FedCmEntry::kEntryName, false);
 }
 
 // Test that request fails if accounts endpoint cannot be reached.
@@ -3203,6 +3207,8 @@
 
   ukm_loop.Run();
 
+  histogram_tester_.ExpectUniqueSample("Blink.FedCm.DidShowUI", true, 1);
+  ExpectUkmValueInEntry("DidShowUI", FedCmEntry::kEntryName, true);
   histogram_tester_.ExpectTotalCount(
       "Blink.FedCm.Timing.ShowAccountsDialogBreakdown.WellKnownAndConfigFetch",
       1);
@@ -3280,6 +3286,8 @@
 
   ukm_loop.Run();
 
+  histogram_tester_.ExpectUniqueSample("Blink.FedCm.DidShowUI", true, 1);
+  ExpectUkmValueInEntry("DidShowUI", FedCmEntry::kEntryName, true);
   ASSERT_TRUE(did_show_accounts_dialog());
   EXPECT_EQ(all_accounts_for_display()[0]->browser_trusted_login_state,
             LoginState::kSignUp);
@@ -3613,6 +3621,9 @@
       /*selected_idp_config_url=*/std::nullopt};
   RunAuthTest(kDefaultRequestParameters, expectations, kConfigurationValid);
   EXPECT_FALSE(DidFetchAnyEndpoint());
+  ExpectStatusMetrics(TokenStatus::kDisabledInSettings);
+  histogram_tester_.ExpectUniqueSample("Blink.FedCm.DidShowUI", false, 1);
+  ExpectUkmValueInEntry("DidShowUI", FedCmEntry::kEntryName, false);
 }
 
 // Test that token request succeeds if FEDERATED_IDENTITY_API content setting is
diff --git a/content/browser/webid/webid_browsertest.cc b/content/browser/webid/webid_browsertest.cc
index 405a51ad..444f3efa 100644
--- a/content/browser/webid/webid_browsertest.cc
+++ b/content/browser/webid/webid_browsertest.cc
@@ -112,11 +112,15 @@
 // Extracts error from `result` removing `kJsErrorPrefix` and removing leading
 // and trailing whitespace and quotes.
 std::string ExtractJsError(const EvalJsResult& result) {
-  if (!base::StartsWith(result.error, kJsErrorPrefix)) {
-    return result.error;
+  if (result.is_ok()) {
+    return "";
+  }
+  if (!base::StartsWith(result.ExtractError(), kJsErrorPrefix)) {
+    return result.ExtractError();
   }
 
-  std::string error_message = result.error.substr(strlen(kJsErrorPrefix));
+  std::string error_message =
+      result.ExtractError().substr(strlen(kJsErrorPrefix));
   base::TrimString(error_message, "\n \"", &error_message);
   return error_message;
 }
diff --git a/content/public/browser/tts_utterance.h b/content/public/browser/tts_utterance.h
index 75fe1d3..ac74810 100644
--- a/content/public/browser/tts_utterance.h
+++ b/content/public/browser/tts_utterance.h
@@ -48,7 +48,7 @@
 // Class that wants to receive events on utterances.
 class CONTENT_EXPORT UtteranceEventDelegate {
  public:
-  virtual ~UtteranceEventDelegate() {}
+  virtual ~UtteranceEventDelegate() = default;
   // Called when the engine reaches a TTS event in an utterance. If |char_index|
   // or |length| are invalid or not applicable for the given |event_type|, they
   // should be set to -1.
@@ -126,7 +126,8 @@
   virtual void SetEngineId(const std::string& engine_id) = 0;
   virtual const std::string& GetEngineId() = 0;
 
-  virtual void SetEventDelegate(UtteranceEventDelegate* event_delegate) = 0;
+  virtual void SetEventDelegate(
+      std::unique_ptr<UtteranceEventDelegate> event_delegate) = 0;
   virtual UtteranceEventDelegate* GetEventDelegate() = 0;
 
   // Getters and setters for internal state.
diff --git a/content/public/test/browser_test_utils.cc b/content/public/test/browser_test_utils.cc
index 72dd68a..406d4b5 100644
--- a/content/public/test/browser_test_utils.cc
+++ b/content/public/test/browser_test_utils.cc
@@ -127,6 +127,7 @@
 #include "storage/browser/file_system/file_system_context.h"
 #include "testing/gmock/include/gmock/gmock-matchers.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/functional/overload.h"
 #include "third_party/blink/public/common/chrome_debug_urls.h"
 #include "third_party/blink/public/common/frame/frame_visual_properties.h"
 #include "third_party/blink/public/common/input/synthetic_web_input_event_builders.h"
@@ -1582,72 +1583,115 @@
 
 // EvalJsResult methods.
 EvalJsResult::EvalJsResult(base::Value value, std::string_view error)
-    : error(error), value_(error.empty() ? std::move(value) : base::Value()) {}
+    : data_(error.empty() ? std::variant<std::string, base::Value>(
+                                std::in_place_type_t<base::Value>(),
+                                std::move(value))
+                          : std::variant<std::string, base::Value>(
+                                std::in_place_type_t<std::string>(),
+                                error)) {}
 
 EvalJsResult::EvalJsResult(const EvalJsResult& other)
-    : error(other.error), value_(other.value_.Clone()) {}
+    : data_(std::visit(
+          absl::Overload{
+              [](const std::string& error)
+                  -> std::variant<std::string, base::Value> { return error; },
+              [](const base::Value& value)
+                  -> std::variant<std::string, base::Value> {
+                return value.Clone();
+              },
+          },
+          other.data_)) {}
+
+EvalJsResult& EvalJsResult::operator=(const EvalJsResult& other) {
+  data_ = std::visit(
+      absl::Overload{
+          [](const std::string& error)
+              -> std::variant<std::string, base::Value> { return error; },
+          [](const base::Value& value)
+              -> std::variant<std::string, base::Value> {
+            return value.Clone();
+          },
+      },
+      other.data_);
+  return *this;
+}
+
+EvalJsResult::EvalJsResult(EvalJsResult&&) = default;
+
+EvalJsResult& EvalJsResult::operator=(EvalJsResult&&) = default;
+
+EvalJsResult::~EvalJsResult() = default;
 
 const std::string& EvalJsResult::ExtractString() const {
   CHECK(is_ok())
       << "Can't ExtractString() because the script encountered a problem: "
-      << error;
-  CHECK(value_.is_string())
-      << "Can't ExtractString() because script result: " << value_
+      << *error();
+  CHECK(value()->is_string())
+      << "Can't ExtractString() because script result: " << *value()
       << "is not a string.";
-  return value_.GetString();
+  return value()->GetString();
 }
 
 int EvalJsResult::ExtractInt() const {
   CHECK(is_ok())
       << "Can't ExtractInt() because the script encountered a problem: "
-      << error;
-  CHECK(value_.is_int()) << "Can't ExtractInt() because script result: "
-                         << value_ << "is not an int.";
-  return value_.GetInt();
+      << *error();
+  CHECK(value()->is_int()) << "Can't ExtractInt() because script result: "
+                           << *value() << "is not an int.";
+  return value()->GetInt();
 }
 
 bool EvalJsResult::ExtractBool() const {
   CHECK(is_ok())
       << "Can't ExtractBool() because the script encountered a problem: "
-      << error;
-  CHECK(value_.is_bool()) << "Can't ExtractBool() because script result: "
-                          << value_ << "is not a bool.";
-  return value_.GetBool();
+      << *error();
+  CHECK(value()->is_bool())
+      << "Can't ExtractBool() because script result: " << *value()
+      << "is not a bool.";
+  return value()->GetBool();
 }
 
 double EvalJsResult::ExtractDouble() const {
   CHECK(is_ok())
       << "Can't ExtractDouble() because the script encountered a problem: "
-      << error;
-  CHECK(value_.is_double() || value_.is_int())
-      << "Can't ExtractDouble() because script result: " << value_
+      << *error();
+  CHECK(value()->is_double() || value()->is_int())
+      << "Can't ExtractDouble() because script result: " << *value()
       << "is not a double or int.";
-  return value_.GetDouble();
+  return value()->GetDouble();
 }
 
 base::Value::List EvalJsResult::ExtractList() const {
   CHECK(is_ok())
       << "Can't ExtractList() because the script encountered a problem: "
-      << error;
-  CHECK(value_.is_list()) << "Can't ExtractList() because script result: "
-                          << value_ << "is not a list.";
-  return value_.GetList().Clone();
+      << *error();
+  CHECK(value()->is_list())
+      << "Can't ExtractList() because script result: " << *value()
+      << "is not a list.";
+  return value()->GetList().Clone();
 }
 
 base::Value::Dict EvalJsResult::ExtractDict() const {
   CHECK(is_ok())
       << "Can't ExtractDict() because the script encountered a problem: "
-      << error;
-  CHECK(value_.is_dict()) << "Can't ExtractDict() because script result: "
-                          << value_ << "is not a dictionary.";
-  return value_.GetDict().Clone();
+      << *error();
+  CHECK(value()->is_dict())
+      << "Can't ExtractDict() because script result: " << *value()
+      << "is not a dictionary.";
+  return value()->GetDict().Clone();
+}
+
+const std::string& EvalJsResult::ExtractError() const {
+  CHECK(!is_ok()) << "Can't ExtractError() because the script did not fail: "
+                  << *value();
+  return error().value();
 }
 
 std::ostream& operator<<(std::ostream& os, const EvalJsResult& bar) {
   if (!bar.is_ok()) {
-    os << bar.error;
+    os << bar.ExtractError();
   } else {
-    os << bar.value_;
+    os << *bar.value();
   }
   return os;
 }
@@ -1904,7 +1948,7 @@
 
   // NOTE: |eval_result.value| is intentionally ignored by ExecJs().
   if (!eval_result.is_ok()) {
-    return ::testing::AssertionFailure() << eval_result.error;
+    return ::testing::AssertionFailure() << eval_result;
   }
   return ::testing::AssertionSuccess();
 }
@@ -1967,15 +2011,19 @@
   EvalJsResult result = EvalJsRunner(execution_target, runner_script,
                                      kWrapperURL, options, world_id);
 
-  if (base::StartsWith(result.error, "a JavaScript error: \"EvalError: Refused",
+  if (!result.is_ok() &&
+      base::StartsWith(result.ExtractError(),
+                       "a JavaScript error: \"EvalError: Refused",
                        base::CompareCase::SENSITIVE)) {
-    return EvalJsResult(
-        base::Value(),
-        "EvalJsAfterLifecycleUpdate encountered an EvalError, because eval() "
-        "is blocked by the document's CSP on this page. To test content that "
-        "is protected by CSP, consider using EvalJsAfterLifecycleUpdate in an "
-        "isolated world. Details: " +
-            result.error);
+    return EvalJsResult(base::Value(),
+                        base::StrCat({"EvalJsAfterLifecycleUpdate encountered "
+                                      "an EvalError, because eval() "
+                                      "is blocked by the document's CSP on "
+                                      "this page. To test content that "
+                                      "is protected by CSP, consider using "
+                                      "EvalJsAfterLifecycleUpdate in an "
+                                      "isolated world. Details: ",
+                                      result.ExtractError()}));
   }
   return result;
 }
diff --git a/content/public/test/browser_test_utils.h b/content/public/test/browser_test_utils.h
index 5616f81..114c949a 100644
--- a/content/public/test/browser_test_utils.h
+++ b/content/public/test/browser_test_utils.h
@@ -11,6 +11,7 @@
 #include <string>
 #include <string_view>
 #include <utility>
+#include <variant>
 #include <vector>
 
 #include "base/containers/flat_set.h"
@@ -844,28 +845,29 @@
 //      of result, or if an exception was thrown.
 class EvalJsResult {
  public:
-  // TODO(https://crbug.com/431787497): rename the `error` field, per style
-  // guide rules.
-  // Error; if things went badly.
-  const std::string error;
-
   // Creates an EvalJs result. If |error| is non-empty, |value| will be
   // ignored.
   EvalJsResult(base::Value value, std::string_view error);
 
-  // Copy ctor.
   EvalJsResult(const EvalJsResult& value);
+  EvalJsResult& operator=(const EvalJsResult&);
+  EvalJsResult(EvalJsResult&&);
+  EvalJsResult& operator=(EvalJsResult&&);
+
+  ~EvalJsResult();
 
   // Matchers for successful & unsuccessful runs.
   static auto IsOk() { return testing::Property(&EvalJsResult::is_ok, true); }
   template <typename M>
   static auto IsOkAndHolds(M m) {
-    return testing::AllOf(IsOk(), testing::Field(&EvalJsResult::value_, m));
+    return testing::Field("data_", &EvalJsResult::data_,
+                          testing::VariantWith<base::Value>(m));
   }
   static auto IsError() { return testing::Not(IsOk()); }
   template <typename M>
   static auto ErrorIs(M m) {
-    return testing::AllOf(IsError(), testing::Field(&EvalJsResult::error, m));
+    return testing::Field("data_", &EvalJsResult::data_,
+                          testing::VariantWith<std::string>(m));
   }
 
   // Extract a result value of the requested type, or die trying.
@@ -880,13 +882,14 @@
   [[nodiscard]] double ExtractDouble() const;
   [[nodiscard]] base::Value::List ExtractList() const;
   [[nodiscard]] base::Value::Dict ExtractDict() const;
+  [[nodiscard]] const std::string& ExtractError() const;
 
-  bool is_ok() const { return error.empty(); }
+  bool is_ok() const { return std::holds_alternative<base::Value>(data_); }
 
-  bool is_string() const { return is_ok() && value_.is_string(); }
-  bool is_bool() const { return is_ok() && value_.is_bool(); }
-  bool is_list() const { return is_ok() && value_.is_list(); }
-  bool is_dict() const { return is_ok() && value_.is_dict(); }
+  bool is_string() const { return is_ok() && value()->is_string(); }
+  bool is_bool() const { return is_ok() && value()->is_bool(); }
+  bool is_list() const { return is_ok() && value()->is_list(); }
+  bool is_dict() const { return is_ok() && value()->is_dict(); }
 
   // Enables EvalJsResult to be used directly in ASSERT/EXPECT macros:
   //
@@ -897,7 +900,7 @@
   // Error values are incomparable to other values (including other errors).
   template <typename T>
   bool operator==(const T& t) const {
-    return is_ok() && (JsLiteralHelper<T>::Convert(t) == value_);
+    return JsLiteralHelper<T>::Convert(t) == value();
   }
 
   template <typename T>
@@ -905,23 +908,30 @@
     if (!is_ok()) {
       return std::partial_ordering::unordered;
     }
-    return value_ <=> JsLiteralHelper<T>::Convert(t);
+    return value() <=> JsLiteralHelper<T>::Convert(t);
   }
 
   // Takes the underlying `base::Value`, presuming no error occurred.
   [[nodiscard]] base::Value TakeValue() && {
     CHECK(is_ok());
-    return std::move(value_);
+    return std::get<base::Value>(std::move(data_));
   }
 
  private:
+  base::optional_ref<const base::Value> value() const {
+    return std::get_if<base::Value>(&data_);
+  }
+
+  base::optional_ref<const std::string> error() const {
+    return std::get_if<std::string>(&data_);
+  }
+
   // Provides informative failure messages when the result of EvalJs() is
   // used in a failing ASSERT_EQ or EXPECT_EQ.
   friend std::ostream& operator<<(std::ostream& os, const EvalJsResult& bar);
 
-  // Value; if things went well. (If an error occurred, `value_.is_none()` is
-  // true.)
-  base::Value value_;
+  // Either the error that occurred, or the result value of the script.
+  std::variant<std::string, base::Value> data_;
 };
 
 enum EvalJsOptions {
diff --git a/content/test/browser_test_utils_browsertest.cc b/content/test/browser_test_utils_browsertest.cc
index bf23777..a7184a8 100644
--- a/content/test/browser_test_utils_browsertest.cc
+++ b/content/test/browser_test_utils_browsertest.cc
@@ -19,6 +19,7 @@
 namespace content {
 
 using ::testing::Eq;
+using ::testing::Optional;
 
 class NavigationObserver: public WebContentsObserver {
  public:
@@ -105,7 +106,7 @@
     std::string expected_error =
         "a JavaScript error: \"SyntaxError: Unexpected token '}'\"\n";
     EXPECT_FALSE(expected_error == result);
-    EXPECT_EQ(expected_error, result.error);
+    EXPECT_THAT(result, EvalJsResult::ErrorIs(expected_error));
   }
 
   {
@@ -121,7 +122,7 @@
                    ^^^^^
 )";
     EXPECT_FALSE(expected_error == result);
-    EXPECT_EQ(expected_error, result.error);
+    EXPECT_THAT(result, EvalJsResult::ErrorIs(expected_error));
   }
 
   {
@@ -140,7 +141,7 @@
         "            var y = z + x;\n"
         "                    ^^^^^\n";
     EXPECT_FALSE(expected_error == result);
-    EXPECT_EQ(expected_error, result.error);
+    EXPECT_THAT(result, EvalJsResult::ErrorIs(expected_error));
   }
 }
 
@@ -155,21 +156,23 @@
 
     EXPECT_FALSE(result.is_ok());
     EXPECT_THAT(
-        result.error,
-        Eq("a JavaScript error: \"SyntaxError: Unexpected token '}'\n"
-           "    at eval (<anonymous>)\n"
-           "    at \"__const_std::string&_EvalJsAfterLifecycleUpdate__\""
-           ":3:27\"\n"));
+        result,
+        EvalJsResult::ErrorIs(
+            Eq("a JavaScript error: \"SyntaxError: Unexpected token '}'\n"
+               "    at eval (<anonymous>)\n"
+               "    at \"__const_std::string&_EvalJsAfterLifecycleUpdate__\""
+               ":3:27\"\n")));
 
     auto result2 = EvalJsAfterLifecycleUpdate(shell(), "'hi'", "]]");
 
     EXPECT_FALSE(result.is_ok());
     EXPECT_THAT(
-        result2.error,
-        Eq("a JavaScript error: \"SyntaxError: Unexpected token ']'\n"
-           "    at eval (<anonymous>)\n"
-           "    at \"__const_std::string&_EvalJsAfterLifecycleUpdate__\""
-           ":5:37\"\n"));
+        result2,
+        EvalJsResult::ErrorIs(
+            Eq("a JavaScript error: \"SyntaxError: Unexpected token ']'\n"
+               "    at eval (<anonymous>)\n"
+               "    at \"__const_std::string&_EvalJsAfterLifecycleUpdate__\""
+               ":5:37\"\n")));
   }
 
   {
@@ -179,24 +182,26 @@
 
     EXPECT_FALSE(result.is_ok());
     EXPECT_THAT(
-        result.error,
-        Eq("a JavaScript error: \"Error: whoops\n"
-           "    at eval (__const_std::string&_script__:1:11)\n"
-           "    at eval (<anonymous>)\n"
-           "    at \"__const_std::string&_EvalJsAfterLifecycleUpdate__\""
-           ":3:27\"\n"));
+        result,
+        EvalJsResult::ErrorIs(
+            Eq("a JavaScript error: \"Error: whoops\n"
+               "    at eval (__const_std::string&_script__:1:11)\n"
+               "    at eval (<anonymous>)\n"
+               "    at \"__const_std::string&_EvalJsAfterLifecycleUpdate__\""
+               ":3:27\"\n")));
 
     auto result2 = EvalJsAfterLifecycleUpdate(
         shell(), "'hi'", "55; throw new Error('whoopsie');");
 
     EXPECT_FALSE(result.is_ok());
     EXPECT_THAT(
-        result2.error,
-        Eq("a JavaScript error: \"Error: whoopsie\n"
-           "    at eval (__const_std::string&_script__:1:11)\n"
-           "    at eval (<anonymous>)\n"
-           "    at \"__const_std::string&_EvalJsAfterLifecycleUpdate__\""
-           ":5:37\"\n"));
+        result2,
+        EvalJsResult::ErrorIs(
+            Eq("a JavaScript error: \"Error: whoopsie\n"
+               "    at eval (__const_std::string&_script__:1:11)\n"
+               "    at eval (<anonymous>)\n"
+               "    at \"__const_std::string&_EvalJsAfterLifecycleUpdate__\""
+               ":5:37\"\n")));
   }
 }
 
@@ -224,12 +229,13 @@
 
   // Store the promise resolve function so it doesn't get GC'd.
   static std::string script = "new Promise(resolve => {window.r = resolve})";
-  static std::string error;
+  static std::optional<EvalJsResult> result;
   static Shell* shell_ptr = shell();
-  EXPECT_NONFATAL_FAILURE(error = EvalJs(shell_ptr, script).error,
+  EXPECT_NONFATAL_FAILURE(result.emplace(EvalJs(shell_ptr, script)),
                           "RunLoop::Run() timed out.");
 
-  EXPECT_THAT(error, Eq("Timeout waiting for Javascript to execute."));
+  EXPECT_THAT(result, Optional(EvalJsResult::ErrorIs(
+                          Eq("Timeout waiting for Javascript to execute."))));
 }
 
 IN_PROC_BROWSER_TEST_F(EvalJsBrowserTest, EvalJsNotBlockedByCSP) {
@@ -252,12 +258,12 @@
   auto result = EvalJsAfterLifecycleUpdate(shell(), "'hi'", "");
   EXPECT_FALSE(result.is_ok());
   EXPECT_THAT(
-      result.error,
-      ::testing::StartsWith(
+      result,
+      EvalJsResult::ErrorIs(::testing::StartsWith(
           "EvalJsAfterLifecycleUpdate encountered an EvalError, because eval() "
           "is blocked by the document's CSP on this page. To test content that "
           "is protected by CSP, consider using EvalJsAfterLifecycleUpdate in "
-          "an isolated world. Details:"));
+          "an isolated world. Details:")));
 }
 
 IN_PROC_BROWSER_TEST_F(EvalJsBrowserTest, ExecJsWithDomAutomationController) {
diff --git a/content/test/data/gpu/wait_for_compositing.html b/content/test/data/gpu/wait_for_compositing.html
index c29db55..98c2baa 100644
--- a/content/test/data/gpu/wait_for_compositing.html
+++ b/content/test/data/gpu/wait_for_compositing.html
@@ -9,7 +9,7 @@
 }
 </style>
 <script>
-var g_swaps_before_success = 5
+var g_swaps_before_success = 7
 
 function waitForSwapsToComplete() {
   g_swaps_before_success--;
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd
index 86bcb307..3f851b5 100644
--- a/ios/chrome/app/strings/ios_strings.grd
+++ b/ios/chrome/app/strings/ios_strings.grd
@@ -1041,6 +1041,9 @@
           =1 {Item saved in your Google Account, {email}}
           other {Items saved in your Google Account, {email}}}
       </message>
+      <message name="IDS_IOS_BWG_ASK_GEMINI_ACCESSIBILITY_LABEL" desc="Accessibility label for the direct Gemini entry point button.">
+        Ask Gemini
+      </message>
       <message name="IDS_IOS_BWG_CONSENT_FIRST_BOX_TITLE" desc="First box title text for the Gemini Consent page for managed accounts.">
           Your page content is shared for more relevant answers
       </message>
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_BWG_ASK_GEMINI_ACCESSIBILITY_LABEL.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_BWG_ASK_GEMINI_ACCESSIBILITY_LABEL.png.sha1
new file mode 100644
index 0000000..ba12c5196
--- /dev/null
+++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_BWG_ASK_GEMINI_ACCESSIBILITY_LABEL.png.sha1
@@ -0,0 +1 @@
+693a5adf317f2b3e0bd9d7e7177d85d990236bb1
\ No newline at end of file
diff --git a/ios/chrome/app/strings/resources/ios_strings_lt.xtb b/ios/chrome/app/strings/resources/ios_strings_lt.xtb
index 1ef84b9..45b44b0 100644
--- a/ios/chrome/app/strings/resources/ios_strings_lt.xtb
+++ b/ios/chrome/app/strings/resources/ios_strings_lt.xtb
@@ -140,6 +140,7 @@
 <translation id="1520027731907768768">Gaukite įspėjimus apie sumažintas stebimų produktų kainas.</translation>
 <translation id="1521366073263497277">Eikite į skirtukų tinklelį</translation>
 <translation id="1521774566618522728">Aktyvus šiandien</translation>
+<translation id="1523567067736644845">Atrakinkite, kad būtų rodomas slaptažodis</translation>
 <translation id="1524563461097350801">Ačiū, ne</translation>
 <translation id="1531038290222364269">Rodyti skirtukus</translation>
 <translation id="1536390784834419204">Versti puslapį</translation>
diff --git a/ios/chrome/browser/intelligence/page_action_menu/ui/page_action_menu_entrypoint_view.mm b/ios/chrome/browser/intelligence/page_action_menu/ui/page_action_menu_entrypoint_view.mm
index fece704..f8252c0 100644
--- a/ios/chrome/browser/intelligence/page_action_menu/ui/page_action_menu_entrypoint_view.mm
+++ b/ios/chrome/browser/intelligence/page_action_menu/ui/page_action_menu_entrypoint_view.mm
@@ -53,6 +53,8 @@
     [self setPreferredSymbolConfiguration:symbolConfig
                           forImageInState:UIControlStateNormal];
     if (IsDirectBWGEntryPoint()) {
+      self.accessibilityLabel =
+          l10n_util::GetNSString(IDS_IOS_BWG_ASK_GEMINI_ACCESSIBILITY_LABEL);
 #if BUILDFLAG(IOS_USE_BRANDED_SYMBOLS)
       [self setImage:CustomSymbolWithPointSize(kGeminiBrandedLogoImage,
                                                kIconPointSize)
diff --git a/ios_internal b/ios_internal
index dcebd84..827a716 160000
--- a/ios_internal
+++ b/ios_internal
@@ -1 +1 @@
-Subproject commit dcebd8470fac682ca9ff14c7ca0f4333e532c58e
+Subproject commit 827a716dc8d91ec9f5d8ce70e0fb6f7ebcd60566
diff --git a/net/disk_cache/blockfile/backend_impl.cc b/net/disk_cache/blockfile/backend_impl.cc
index 673dae9..2e1aa32 100644
--- a/net/disk_cache/blockfile/backend_impl.cc
+++ b/net/disk_cache/blockfile/backend_impl.cc
@@ -64,6 +64,10 @@
 // Avoid trimming the cache for the first 5 minutes (10 timer ticks).
 const int kTrimDelay = 10;
 
+BASE_FEATURE(kBlockfileCacheBackendDumpWithoutCrashing,
+             "BlockfileCacheBackendDumpWithoutCrashing",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+
 int DesiredIndexTableLen(int32_t storage_size) {
   if (storage_size <= k64kEntriesStore)
     return kBaseTableLen;
@@ -1027,7 +1031,9 @@
       // so this should yield around 0.002 * 8000 = 16 crash reports per day.
       if (!has_considered_dumping) {
         has_considered_dumping = true;
-        if (base::ShouldRecordSubsampledMetric(0.002)) {
+        if (base::FeatureList::IsEnabled(
+                kBlockfileCacheBackendDumpWithoutCrashing) &&
+            base::ShouldRecordSubsampledMetric(0.002)) {
           // Capture the last file error. This may or may not be related to the
           // reason why init failed.
           base::File::Error file_error = base::File::GetLastFileError();
diff --git a/net/http/http_cache_transaction.cc b/net/http/http_cache_transaction.cc
index 4a6e35c..e0418bc 100644
--- a/net/http/http_cache_transaction.cc
+++ b/net/http/http_cache_transaction.cc
@@ -303,7 +303,7 @@
   // user wishes to read the network response (the error page).  If there is a
   // previous response in the cache then we should leave it intact.
   if (auth_response_.headers.get() && mode_ != NONE) {
-    UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_OTHER);
+    UpdateCacheEntryStatusToOther(OtherStatusReason::kReadingAuthResponse);
     DCHECK(mode_ & WRITE);
     bool stopped = StopCachingImpl(mode_ == READ_WRITE);
     DCHECK(stopped);
@@ -1924,7 +1924,7 @@
   response_.resolve_error_info = response->resolve_error_info;
 
   // Do not record requests that have network errors or restarts.
-  UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_OTHER);
+  UpdateCacheEntryStatusToOther(OtherStatusReason::kNetworkError);
   if (IsCertificateError(result)) {
     // If we get a certificate error, then there is a certificate in ssl_info,
     // so GetResponseInfo() should never return NULL here.
@@ -1992,7 +1992,7 @@
     // happening if the user cancels the authentication before we receive
     // the new response.
     net_log_.AddEvent(NetLogEventType::HTTP_CACHE_RE_SEND_PARTIAL_REQUEST);
-    UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_OTHER);
+    UpdateCacheEntryStatusToOther(OtherStatusReason::kResponseValidation);
     SetResponse(HttpResponseInfo());
     ResetNetworkTransaction();
     new_response_ = nullptr;
@@ -2003,7 +2003,7 @@
   if (handling_206_ && mode_ == READ_WRITE && !truncated_ && !is_sparse_) {
     // We have stored the full entry, but it changed and the server is
     // sending a range. We have to delete the old entry.
-    UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_OTHER);
+    UpdateCacheEntryStatusToOther(OtherStatusReason::kDeleteFullEntry);
     DoneWithEntry(false);
   }
 
@@ -2529,7 +2529,7 @@
   if (partial_) {
     // Partial requests are confusing to report in histograms because they may
     // have multiple underlying requests.
-    UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_OTHER);
+    UpdateCacheEntryStatusToOther(OtherStatusReason::kPartialRequest);
     return DoPartialCacheReadCompleted(result);
   }
 
@@ -2613,7 +2613,7 @@
   }
 
   if (range_found && !(effective_load_flags_ & LOAD_DISABLE_CACHE)) {
-    UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_OTHER);
+    UpdateCacheEntryStatusToOther(OtherStatusReason::kRangeHeaderFound);
     partial_ = std::make_unique<PartialData>();
     if (method_ == "GET" && partial_->Init(request_->extra_headers)) {
       // We will be modifying the actual range requested to the server, so
@@ -2747,7 +2747,7 @@
   if (truncated_) {
     // Truncated entries can cause partial gets, so we shouldn't record this
     // load in histograms.
-    UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_OTHER);
+    UpdateCacheEntryStatusToOther(OtherStatusReason::kTruncatedEntry);
     skip_validation = !partial_->initial_validation();
   }
 
@@ -2820,7 +2820,7 @@
   }
 
   // Partial requests should not be recorded in histograms.
-  UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_OTHER);
+  UpdateCacheEntryStatusToOther(OtherStatusReason::kPartialValidation);
   if (method_ == "HEAD") {
     return BeginCacheValidation();
   }
@@ -2868,7 +2868,7 @@
       !external_validation_->Match(*response_.headers)) {
     // The externally conditionalized request is not a validation request
     // for our existing cache entry. Proceed with caching disabled.
-    UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_OTHER);
+    UpdateCacheEntryStatusToOther(OtherStatusReason::kPreConditionalized);
     DoneWithEntry(true);
   }
 
@@ -3235,7 +3235,7 @@
 
   if (failure) {
     // We cannot truncate this entry, it has to be deleted.
-    UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_OTHER);
+    UpdateCacheEntryStatusToOther(OtherStatusReason::kValidatePartial);
     mode_ = NONE;
     if (is_sparse_ || truncated_) {
       // There was something cached to start with, either sparsed data (206), or
@@ -3263,7 +3263,7 @@
   // returned the headers), but we'll just pretend that this request is not
   // using the cache and see what happens. Most likely this is the first
   // response from the server (it's not changing its mind midway, right?).
-  UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_OTHER);
+  UpdateCacheEntryStatusToOther(OtherStatusReason::kIgnoreRangeRequest);
   DoneWithEntry(mode_ != WRITE);
   partial_.reset(nullptr);
 }
@@ -3290,7 +3290,7 @@
     if (result ==
         ERR_CACHED_IP_ADDRESS_SPACE_BLOCKED_BY_PRIVATE_NETWORK_ACCESS_POLICY) {
       DoomInconsistentEntry();
-      UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_OTHER);
+      UpdateCacheEntryStatusToOther(OtherStatusReason::kBlockedByIpSpace);
       TransitionToState(reading_ ? STATE_SEND_REQUEST
                                  : STATE_HEADERS_PHASE_CANNOT_PROCEED);
       return OK;
@@ -3733,6 +3733,15 @@
   SyncCacheEntryStatusToResponse();
 }
 
+void HttpCache::Transaction::UpdateCacheEntryStatusToOther(
+    OtherStatusReason reason) {
+  if (cache_entry_status_ == CacheEntryStatus::ENTRY_OTHER) {
+    return;
+  }
+  other_status_reason_ = reason;
+  UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_OTHER);
+}
+
 void HttpCache::Transaction::SyncCacheEntryStatusToResponse() {
   if (cache_entry_status_ == CacheEntryStatus::ENTRY_UNDEFINED) {
     return;
@@ -3771,15 +3780,16 @@
   HttpResponseHeaders* response_headers = GetResponseInfo()->headers.get();
   const bool is_no_store = response_headers && response_headers->HasHeaderValue(
                                                    "cache-control", "no-store");
+  bool is_html = false;
   if (response_headers && response_headers->GetMimeType(&mime_type)) {
     // Record the cache pattern by resource type. The type is inferred by
     // response header mime type, which could be incorrect, so this is just an
     // estimate.
-    if (mime_type == "text/html" &&
-        (effective_load_flags_ & LOAD_MAIN_FRAME_DEPRECATED)) {
+    is_html = (mime_type == "text/html");
+    if (is_html && (effective_load_flags_ & LOAD_MAIN_FRAME_DEPRECATED)) {
       CACHE_STATUS_HISTOGRAMS(".MainFrameHTML");
       IS_NO_STORE_HISTOGRAMS(".MainFrameHTML", is_no_store);
-    } else if (mime_type == "text/html") {
+    } else if (is_html) {
       CACHE_STATUS_HISTOGRAMS(".NonMainFrameHTML");
     } else if (mime_type == "text/css") {
       if (is_third_party) {
@@ -3816,6 +3826,15 @@
   IS_NO_STORE_HISTOGRAMS("", is_no_store);
 
   if (cache_entry_status_ == CacheEntryStatus::ENTRY_OTHER) {
+    CHECK_NE(other_status_reason_, OtherStatusReason::kNoReason);
+    UMA_HISTOGRAM_ENUMERATION("HttpCache.Pattern.NotCoveredReason",
+                              other_status_reason_);
+    if (is_html && (effective_load_flags_ & LOAD_MAIN_FRAME_DEPRECATED)) {
+      base::UmaHistogramEnumeration(
+          "HttpCache.Pattern.NotCoveredReason.MainFrameHTML",
+          other_status_reason_);
+    }
+
     return;
   }
 
diff --git a/net/http/http_cache_transaction.h b/net/http/http_cache_transaction.h
index fb6a301..02118a07 100644
--- a/net/http/http_cache_transaction.h
+++ b/net/http/http_cache_transaction.h
@@ -311,6 +311,30 @@
   };
   // LINT.ThenChange(//tools/metrics/histograms/metadata/net/enums.xml:NoVarySearchUseResult)
 
+  // Reason why we ended up with status ENTRY_OTHER.
+  //
+  // These values are persisted to logs. Entries should not be renumbered and
+  // numeric values should never be reused.
+  //
+  // LINT.IfChange(OtherStatusReason)
+  enum class OtherStatusReason : uint8_t {
+    kNoReason = 0,             // Status was not set to ENTRY_OTHER.
+    kReadingAuthResponse = 1,  // Stopped caching to read auth response body.
+    kNetworkError = 2,         // A network error happened.
+    kResponseValidation = 3,   // Response validation failed.
+    kDeleteFullEntry = 4,      // Need to delete a full entry.
+    kPartialRequest = 5,       // Partial requests are hard to log.
+    kRangeHeaderFound = 6,     // Request had Range header.
+    kTruncatedEntry = 7,       // Cache entry was truncated.
+    kPartialValidation = 8,    // Validating a partial entry.
+    kPreConditionalized = 9,   // Externally conditionalized request.
+    kValidatePartial = 10,     // Validating partial response failed.
+    kIgnoreRangeRequest = 11,  // Very miscellaneous range failure.
+    kBlockedByIpSpace = 12,    // Blocked by Private Network Access.
+    kMaxValue = kBlockedByIpSpace,
+  };
+  // LINT.ThenChange(//tools/metrics/histograms/metadata/net/enums.xml:HttpCacheNotCoveredReason)
+
   // Runs the state transition loop. Resets and calls |callback_| on exit,
   // unless the return value is ERR_IO_PENDING.
   int DoLoop(int result);
@@ -546,6 +570,8 @@
   void UpdateCacheEntryStatus(
       HttpResponseInfo::CacheEntryStatus new_cache_entry_status);
 
+  void UpdateCacheEntryStatusToOther(OtherStatusReason reason);
+
   // Sets the response.cache_entry_status to the current cache_entry_status_.
   void SyncCacheEntryStatusToResponse();
 
@@ -760,6 +786,10 @@
   NoVarySearchUseResult no_vary_search_use_result_ =
       NoVarySearchUseResult::kNotApplied;
 
+  // The first reason why `cache_entry_status_` ended up set to ENTRY_OTHER.
+  // Logged to UMA on destruction when `cache_entry_status_` is ENTRY_OTHER.
+  OtherStatusReason other_status_reason_ = OtherStatusReason::kNoReason;
+
   // If an entry in the NoVarySearchCache was found to be unhelpful, this
   // handle can be used to erase it. Only set if an entry was found in the
   // NoVerySearchCache and hasn't been erased already. This is also used as a
diff --git a/net/http/transport_security_state_static.pins b/net/http/transport_security_state_static.pins
index 45f1ecc2..f9981df5 100644
--- a/net/http/transport_security_state_static.pins
+++ b/net/http/transport_security_state_static.pins
@@ -43,9 +43,9 @@
 #   hash function for preloaded entries again (we have already done so once).
 #
 
-# Last updated: 2025-07-26 12:55 UTC
+# Last updated: 2025-07-27 12:54 UTC
 PinsListTimestamp
-1753534535
+1753620872
 
 TestSPKI
 sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
diff --git a/net/http/transport_security_state_static_pins.json b/net/http/transport_security_state_static_pins.json
index 66bcb71..a5cc4c6 100644
--- a/net/http/transport_security_state_static_pins.json
+++ b/net/http/transport_security_state_static_pins.json
@@ -31,7 +31,7 @@
 // the 'static_spki_hashes' and 'bad_static_spki_hashes' fields in 'pinsets'
 // refer to, and the timestamp at which the pins list was last updated.
 //
-// Last updated: 2025-07-26 12:55 UTC
+// Last updated: 2025-07-27 12:54 UTC
 //
 {
   "pinsets": [
diff --git a/sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.cc b/sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.cc
index ee52cba..420c9c80 100644
--- a/sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.cc
+++ b/sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.cc
@@ -58,7 +58,6 @@
 #endif
 
 base::debug::CrashKeyString* seccomp_crash_key = nullptr;
-base::debug::CrashKeyString* seccomp_ioctl_crash_key = nullptr;
 
 inline bool IsArchitectureX86_64() {
 #if defined(__x86_64__)
@@ -211,29 +210,6 @@
       __FILE__ ":**CRASHING**:" SECCOMP_MESSAGE_IOCTL_CONTENT "\n";
   WriteToStdErr(kSeccompIoctlError, sizeof(kSeccompIoctlError) - 1);
   PrintAndSetSeccompCrashKey(args);
-
-  // Log information about the file descriptor.
-  char message[256];
-  size_t message_len;
-  default_stat_struct stat_buf;
-  const int fstat_ret =
-      syscall(__NR_fstat_default, static_cast<int>(args.args[0]), &stat_buf);
-  if (fstat_ret == 0) {
-    message_len = base::strings::SafeSPrintf(
-        message,
-        "dev=0x%x,ino=%d,mode=0%o,nlink=%d,"
-        "uid=%d,gid=%d,rdev=0x%x,size=%d,blksize=%d,blocks=%d",
-        stat_buf.st_dev, stat_buf.st_ino, stat_buf.st_mode, stat_buf.st_nlink,
-        stat_buf.st_uid, stat_buf.st_gid, stat_buf.st_rdev, stat_buf.st_size,
-        stat_buf.st_blksize, stat_buf.st_blocks);
-  } else {
-    // fstat failed, log the errno.
-    message_len = base::strings::SafeSPrintf(message, "fstat failed, errno=%d",
-                                             -fstat_ret);
-  }
-  WriteToStdErr(message, message_len);
-  base::debug::SetCrashKeyString(seccomp_ioctl_crash_key, message);
-
   // Make "request" volatile so that we can see it on the stack in a minidump.
   volatile uint64_t request = args.args[1];
   volatile char* addr = reinterpret_cast<volatile char*>(request & 0xFFFF);
@@ -548,8 +524,6 @@
 
   seccomp_crash_key = base::debug::AllocateCrashKeyString(
       "seccomp-sigsys", base::debug::CrashKeySize::Size256);
-  seccomp_ioctl_crash_key = base::debug::AllocateCrashKeyString(
-      "seccomp-sigsys-ioctl", base::debug::CrashKeySize::Size256);
 }
 
 const char* GetErrorMessageContentForTests() {
diff --git a/sandbox/linux/seccomp-bpf-helpers/sigsys_handlers_unittest.cc b/sandbox/linux/seccomp-bpf-helpers/sigsys_handlers_unittest.cc
index 391d9ca..5a0fe9f 100644
--- a/sandbox/linux/seccomp-bpf-helpers/sigsys_handlers_unittest.cc
+++ b/sandbox/linux/seccomp-bpf-helpers/sigsys_handlers_unittest.cc
@@ -9,26 +9,15 @@
 
 #include "sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h"
 
-#include <fcntl.h>
 #include <linux/net.h>
-#include <sys/ioctl.h>
 #include <sys/socket.h>
 #include <sys/syscall.h>
-#include <sys/types.h>
-#include <termios.h>
-#include <unistd.h>
-
-#include <utility>
 
 #include "base/check_op.h"
-#include "base/files/file_util.h"
-#include "base/files/scoped_file.h"
 #include "base/strings/safe_sprintf.h"
 #include "sandbox/linux/bpf_dsl/bpf_dsl.h"
 #include "sandbox/linux/bpf_dsl/policy.h"
 #include "sandbox/linux/seccomp-bpf/bpf_tests.h"
-#include "sandbox/linux/seccomp-bpf/sandbox_bpf.h"
-#include "sandbox/linux/system_headers/linux_stat.h"
 #include "sandbox/linux/system_headers/linux_syscalls.h"
 #include "sandbox/linux/tests/unit_tests.h"
 
@@ -130,41 +119,6 @@
 #pragma GCC diagnostic pop
 }
 
-class CrashIoctlPolicy : public bpf_dsl::Policy {
- public:
-  CrashIoctlPolicy() = default;
-  ~CrashIoctlPolicy() override = default;
-
-  ResultExpr EvaluateSyscall(int sysno) const override {
-    switch (sysno) {
-      case __NR_ioctl:
-        return CrashSIGSYSIoctl();
-      // The handler needs write() and fstat() for logging.
-      case __NR_write:
-      case __NR_fstat_default:
-        return Allow();
-      default:
-        return Allow();
-    }
-  }
-};
-
-BPF_DEATH_TEST_C(
-    SigsysHandlers,
-    SIGSYSIoctlFailureLogsFdInfo,
-    DEATH_SEGV_MESSAGE_PATTERN(
-        "*dev=0x*,ino=*,mode=0*,nlink=*,uid=*,gid=*,rdev=0x*,size=*,"
-        "blksize=*,blocks=*"),
-    CrashIoctlPolicy) {
-  base::FilePath temp_path;
-  CHECK(base::CreateTemporaryFile(&temp_path));
-  base::ScopedFD fd(open(temp_path.value().c_str(), O_RDONLY));
-  CHECK(fd.is_valid());
-
-  // This ioctl should be trapped and cause a crash.
-  ioctl(fd.get(), 0, 0);
-}
-
 const char kSigsysMessage[] =
     "nr=0x42 arg1=0xffffffffffffffff arg2=0x0 arg3=0xabcdef arg4=0xffffffff";
 
diff --git a/sandbox/linux/tests/unit_tests.cc b/sandbox/linux/tests/unit_tests.cc
index f04066c..4a6305c 100644
--- a/sandbox/linux/tests/unit_tests.cc
+++ b/sandbox/linux/tests/unit_tests.cc
@@ -7,8 +7,6 @@
 #pragma allow_unsafe_libc_calls
 #endif
 
-#include "sandbox/linux/tests/unit_tests.h"
-
 #include <fcntl.h>
 #include <poll.h>
 #include <signal.h>
@@ -28,8 +26,8 @@
 #include "base/debug/leak_annotations.h"
 #include "base/files/file_util.h"
 #include "base/posix/eintr_wrapper.h"
-#include "base/strings/pattern.h"
 #include "build/build_config.h"
+#include "sandbox/linux/tests/unit_tests.h"
 
 // Specifically, PNaCl toolchain does not have this flag.
 #if !defined(POLLRDHUP)
@@ -65,16 +63,6 @@
   return num_threads;
 }
 
-// Helper for DeathSEGVMessage and DeathSEGVMessagePattern.
-// Checks that the process died with SIGSEGV.
-void CheckDeathBySEGV(int status, const std::string& details) {
-  const bool subprocess_got_sigsegv =
-      WIFSIGNALED(status) && (SIGSEGV == WTERMSIG(status));
-
-  ASSERT_TRUE(subprocess_got_sigsegv)
-      << "Exit status: " << status << " " << details;
-}
-
 }  // namespace
 
 namespace sandbox {
@@ -311,24 +299,18 @@
                                  const void* aux) {
   std::string details(TestFailedMessage(msg));
   const char* expected_msg = static_cast<const char*>(aux);
-  CheckDeathBySEGV(status, details);
+
+  const bool subprocess_got_sigsegv =
+      WIFSIGNALED(status) && (SIGSEGV == WTERMSIG(status));
+
+  ASSERT_TRUE(subprocess_got_sigsegv) << "Exit status: " << status
+                                      << " " << details;
+
   bool subprocess_exited_without_matching_message =
       !base::Contains(msg, expected_msg);
   EXPECT_FALSE(subprocess_exited_without_matching_message) << details;
 }
 
-void UnitTests::DeathSEGVMessagePattern(int status,
-                                        const std::string& msg,
-                                        const void* aux) {
-  std::string details(TestFailedMessage(msg));
-  const char* expected_msg = static_cast<const char*>(aux);
-  CheckDeathBySEGV(status, details);
-  std::string pattern(expected_msg);
-  bool subprocess_exited_without_matching_message =
-      !base::MatchPattern(msg, pattern);
-  EXPECT_FALSE(subprocess_exited_without_matching_message) << details;
-}
-
 void UnitTests::DeathExitCode(int status,
                               const std::string& msg,
                               const void* aux) {
diff --git a/sandbox/linux/tests/unit_tests.h b/sandbox/linux/tests/unit_tests.h
index d1c7cfe2..d51eff26 100644
--- a/sandbox/linux/tests/unit_tests.h
+++ b/sandbox/linux/tests/unit_tests.h
@@ -75,9 +75,6 @@
 #define DEATH_SEGV_MESSAGE(msg)         \
   sandbox::UnitTests::DeathSEGVMessage, \
       static_cast<const void*>(static_cast<const char*>(msg))
-#define DEATH_SEGV_MESSAGE_PATTERN(msg)        \
-  sandbox::UnitTests::DeathSEGVMessagePattern, \
-      static_cast<const void*>(static_cast<const char*>(msg))
 #define DEATH_EXIT_CODE(rc)          \
   sandbox::UnitTests::DeathExitCode, \
       reinterpret_cast<void*>(static_cast<intptr_t>(rc))
@@ -189,12 +186,6 @@
                                const std::string& msg,
                                const void* aux);
 
-  // A DeathCheck that verifies that the child process died with a SIGSEGV
-  // and printed a message matching a pattern.
-  static void DeathSEGVMessagePattern(int status,
-                                      const std::string& msg,
-                                      const void* aux);
-
   // A DeathCheck method that verifies that the test completed with a
   // particular exit code. If the test output any messages to stderr, they are
   // silently ignored. The expected exit code should be passed in by
@@ -212,6 +203,6 @@
                             const void* aux);
 };
 
-}  // namespace sandbox
+}  // namespace
 
 #endif  // SANDBOX_LINUX_TESTS_UNIT_TESTS_H_
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index a039f361..27628205 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -16563,7 +16563,6 @@
                         "offer_notification": "true",
                         "price_insights": "true",
                         "product_specifications": "true",
-                        "pwa_install": "true",
                         "translate": "true",
                         "zoom": "true"
                     },
@@ -18038,26 +18037,6 @@
             ]
         }
     ],
-    "PrefetchServiceWorker": [
-        {
-            "platforms": [
-                "android",
-                "android_webview",
-                "chromeos",
-                "linux",
-                "mac",
-                "windows"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled",
-                    "enable_features": [
-                        "PrefetchServiceWorker"
-                    ]
-                }
-            ]
-        }
-    ],
     "PrefetchServiceWorkerNoFetchHandlerFix": [
         {
             "platforms": [
diff --git a/third_party/blink/renderer/core/timing/window_performance.cc b/third_party/blink/renderer/core/timing/window_performance.cc
index 74e88ae..91b342b 100644
--- a/third_party/blink/renderer/core/timing/window_performance.cc
+++ b/third_party/blink/renderer/core/timing/window_performance.cc
@@ -42,6 +42,7 @@
 #include "base/trace_event/common/trace_event_common.h"
 #include "base/trace_event/trace_event.h"
 #include "base/trace_event/trace_id_helper.h"
+#include "cc/base/features.h"
 #include "components/viz/common/frame_timing_details.h"
 #include "services/metrics/public/cpp/ukm_builders.h"
 #include "services/network/public/mojom/load_timing_info.mojom-blink.h"
@@ -791,6 +792,15 @@
   bool is_presentation_for_expected_source =
       !expected_frame_source_id || !actual_frame_source_id ||
       expected_frame_source_id == actual_frame_source_id;
+  if (base::FeatureList::IsEnabled(
+          ::features::kInternalBeginFrameSourceOnManyDidNotProduceFrame)) {
+    // Switch to cc BeginFrameSource will generate kNotRestartable(0) begin
+    // frame and submit compositor frame with kManualSourceId.
+    if ((expected_frame_source_id >> 32) == 0 ||
+        actual_frame_source_id == viz::BeginFrameArgs::kManualSourceId) {
+      is_presentation_for_expected_source = true;
+    }
+  }
 
   for (auto entry : event_timing_entries_) {
     auto* timing = entry->GetEventTimingReportingInfo();
diff --git a/third_party/compiler-rt/src b/third_party/compiler-rt/src
index f6df13f7..2396bb9 160000
--- a/third_party/compiler-rt/src
+++ b/third_party/compiler-rt/src
@@ -1 +1 @@
-Subproject commit f6df13f71224eb80e35d67e67cfbfa4fb00831b9
+Subproject commit 2396bb92b4c76ab74e11474ac7ed1b13b292f6e7
diff --git a/third_party/dawn b/third_party/dawn
index d340907..4306d3c 160000
--- a/third_party/dawn
+++ b/third_party/dawn
@@ -1 +1 @@
-Subproject commit d3409072e549a8f36d9c8e16b112bd1fb064b60f
+Subproject commit 4306d3c04b77dad4f9cd3d23bfd1068a6bb191bb
diff --git a/third_party/devtools-frontend/src b/third_party/devtools-frontend/src
index 5911b6c..1c5bdf5 160000
--- a/third_party/devtools-frontend/src
+++ b/third_party/devtools-frontend/src
@@ -1 +1 @@
-Subproject commit 5911b6c9376c9eb6f430bcbc8490371b9d7e6f78
+Subproject commit 1c5bdf525e5d042bdd526e3d9c0774d84a747ca9
diff --git a/third_party/llvm-libc/src b/third_party/llvm-libc/src
index dd12cc1..f24be5d 160000
--- a/third_party/llvm-libc/src
+++ b/third_party/llvm-libc/src
@@ -1 +1 @@
-Subproject commit dd12cc11284e7845727f333a4a0c5274c161c541
+Subproject commit f24be5deb774fae412aae70877b47fa6fcf19d28
diff --git a/third_party/skia b/third_party/skia
index f248eba..eb9266c 160000
--- a/third_party/skia
+++ b/third_party/skia
@@ -1 +1 @@
-Subproject commit f248eba5e8d7d4828c0fd5390c5d5f29bb99f5be
+Subproject commit eb9266cce6c1235d0303ee37d8a86f69c1195e49
diff --git a/third_party/vulkan-headers/README.chromium b/third_party/vulkan-headers/README.chromium
index 0f7f626..be51d2d 100644
--- a/third_party/vulkan-headers/README.chromium
+++ b/third_party/vulkan-headers/README.chromium
@@ -5,6 +5,7 @@
 Revision: DEPS
 Security Critical: yes
 Shipped: yes
+CPEPrefix: cpe:/a:khronos:vulkan
 License: Apache-2.0
 License File: LICENSE.txt
 
diff --git a/third_party/webrtc b/third_party/webrtc
index 10a1bbb..732523e 160000
--- a/third_party/webrtc
+++ b/third_party/webrtc
@@ -1 +1 @@
-Subproject commit 10a1bbbf89dd5a037f99dcce418e0709604eb21a
+Subproject commit 732523e79fd5c0b726ed48e62bbdf675c583f4aa
diff --git a/tools/metrics/histograms/metadata/blink/histograms.xml b/tools/metrics/histograms/metadata/blink/histograms.xml
index 1f08aeab..81c92f8 100644
--- a/tools/metrics/histograms/metadata/blink/histograms.xml
+++ b/tools/metrics/histograms/metadata/blink/histograms.xml
@@ -1527,6 +1527,17 @@
   </summary>
 </histogram>
 
+<histogram name="Blink.FedCm.DidShowUI" enum="Boolean"
+    expires_after="2025-12-14">
+  <owner>npm@chromium.org</owner>
+  <owner>web-identity-eng@google.com</owner>
+  <summary>
+    Records whether the FedCM UI is shown or not. Records a sample when the
+    FedCM call is completed, i.e. at the same time as
+    Blink.FedCm.Status.RequestIdToken.
+  </summary>
+</histogram>
+
 <histogram name="Blink.FedCm.Disconnect.FrameType"
     enum="FedCmRequesterFrameType" expires_after="2025-12-12">
   <owner>npm@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/net/enums.xml b/tools/metrics/histograms/metadata/net/enums.xml
index df3c717..4098882 100644
--- a/tools/metrics/histograms/metadata/net/enums.xml
+++ b/tools/metrics/histograms/metadata/net/enums.xml
@@ -489,6 +489,48 @@
   <int value="19" label="SpdyProxy Secure Server (Invalid)"/>
 </enum>
 
+<!-- LINT.IfChange(HttpCacheNotCoveredReason) -->
+
+<enum name="HttpCacheNotCoveredReason">
+  <int value="0" label="No Reason">Should not happen.</int>
+  <int value="1" label="Reading Auth Response">
+    Stopped caching to read the response body of an auth response.
+  </int>
+  <int value="2" label="Network Error">
+    A network error happened in the headers phase.
+  </int>
+  <int value="3" label="Partial Response Validation">
+    A partial response could not be validated, and it was not due to auth.
+  </int>
+  <int value="4" label="Delete Full Entry">
+    We have a full entry, but the server sent a range response that should
+    replace it.
+  </int>
+  <int value="5" label="Partial Request">Partial requests are hard to log.</int>
+  <int value="6" label="Range Header Found">
+    Original request had a Range header.
+  </int>
+  <int value="7" label="Truncated Entry">The cache entry was truncated.</int>
+  <int value="8" label="Partial Validation">
+    Validating a partial entry, and they are hard to log.
+  </int>
+  <int value="9" label="Pre Conditionalized">
+    The request was externally conditionalized and didn't match our existing
+    cache entry.
+  </int>
+  <int value="10" label="Validate Partial">
+    Attempt to validate a partial response failed.
+  </int>
+  <int value="11" label="Ignore Range Request">
+    Range-related failure led to calling IgnoreRangeRequest().
+  </int>
+  <int value="12" label="Blocked By Ip Space">
+    Cached IP address space blocked by Private Network Access policy.
+  </int>
+</enum>
+
+<!-- LINT.ThenChange(//net/http/http_cache_transaction.h:OtherStatusReason) -->
+
 <enum name="HttpCachePattern">
   <int value="0" label="Undefined"/>
   <int value="1" label="Not Covered"/>
diff --git a/tools/metrics/histograms/metadata/net/histograms.xml b/tools/metrics/histograms/metadata/net/histograms.xml
index 534617b..d6bfe0d 100644
--- a/tools/metrics/histograms/metadata/net/histograms.xml
+++ b/tools/metrics/histograms/metadata/net/histograms.xml
@@ -1060,6 +1060,23 @@
   </summary>
 </histogram>
 
+<histogram name="HttpCache.Pattern.NotCoveredReason{CachedResourceType}"
+    enum="HttpCacheNotCoveredReason" expires_after="2025-12-21">
+  <owner>ricea@chromium.org</owner>
+  <owner>src/net/OWNERS</owner>
+  <summary>
+    For each http cache transaction that reported &quot;Not covered&quot; to the
+    HttpCache.Pattern histogram, the reason why it was not covered. Logged once
+    for every cache transaction that records a &quot;Not covered&quot; reason,
+    in the destructor. {CachedResourceType}
+  </summary>
+  <token key="CachedResourceType">
+    <variant name=""/>
+    <variant name=".MainFrameHTML"
+        summary="Showing reasons only for main-frame HTML resources."/>
+  </token>
+</histogram>
+
 <histogram name="HttpCache.Pattern{CachedResourceType}" enum="HttpCachePattern"
     expires_after="2025-12-21">
   <owner>morlovich@chromium.org</owner>
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml
index 4fa43d8..4cdc0ddd 100644
--- a/tools/metrics/ukm/ukm.xml
+++ b/tools/metrics/ukm/ukm.xml
@@ -3922,6 +3922,12 @@
       dialog close. Records at the time the API call is completed.
     </summary>
   </metric>
+  <metric name="DidShowUI" enum="Boolean">
+    <summary>
+      Records whether the FedCM dialog was shown. Recorded once per API call
+      when the request is fulfilled (either resolved or rejected).
+    </summary>
+  </metric>
   <metric name="Disconnect.FrameType" enum="FedCmRequesterFrameType">
     <summary>
       Records the type of frame that invokes disconnect(). Records once for each
diff --git a/v8 b/v8
index ca21aab..a6a3f18 160000
--- a/v8
+++ b/v8
@@ -1 +1 @@
-Subproject commit ca21aab0e75ca67982d39bf021cbe33f997983a5
+Subproject commit a6a3f1889b2fb25054f7b7476931f6818e12c9ff